sinatra-param-validator 0.1.0 → 0.4.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 +3 -0
- data/CHANGELOG.md +37 -0
- data/Gemfile +0 -7
- data/Gemfile.lock +28 -5
- data/README.md +159 -2
- data/lib/sinatra/param_validator/camelize.rb +12 -0
- data/lib/sinatra/param_validator/definitions.rb +24 -0
- data/lib/sinatra/param_validator/helpers.rb +25 -0
- data/lib/sinatra/param_validator/identifier.rb +15 -0
- data/lib/sinatra/param_validator/invalid_parameter_error.rb +9 -0
- data/lib/sinatra/param_validator/parameter/array.rb +25 -0
- data/lib/sinatra/param_validator/parameter/boolean.rb +26 -0
- data/lib/sinatra/param_validator/parameter/common.rb +98 -0
- data/lib/sinatra/param_validator/parameter/date.rb +24 -0
- data/lib/sinatra/param_validator/parameter/float.rb +23 -0
- data/lib/sinatra/param_validator/parameter/hash.rb +25 -0
- data/lib/sinatra/param_validator/parameter/integer.rb +23 -0
- data/lib/sinatra/param_validator/parameter/string.rb +27 -0
- data/lib/sinatra/param_validator/parameter/time.rb +24 -0
- data/lib/sinatra/param_validator/parameter.rb +28 -0
- data/lib/sinatra/param_validator/parser.rb +56 -0
- data/lib/sinatra/param_validator/rule/all_or_none_of.rb +31 -0
- data/lib/sinatra/param_validator/rule/any_of.rb +29 -0
- data/lib/sinatra/param_validator/rule/one_of.rb +30 -0
- data/lib/sinatra/param_validator/rule.rb +23 -0
- data/lib/sinatra/param_validator/snake_case.rb +12 -0
- data/lib/sinatra/param_validator/validation_failed_error.rb +15 -0
- data/lib/sinatra/param_validator/validator/form.rb +37 -0
- data/lib/sinatra/param_validator/validator/url_param.rb +14 -0
- data/lib/sinatra/param_validator/validator.rb +42 -0
- data/lib/sinatra/param_validator/version.rb +1 -1
- data/lib/sinatra/param_validator.rb +40 -2
- data/sinatra-param-validator.gemspec +9 -3
- metadata +140 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f474d7b6ff2e2ed3de6f58e3bd0ab0b328cc11886ac36701c5a1557a8713e5be
|
4
|
+
data.tar.gz: 378f0b0bb00df8adca7f951175133833d68ce457066f79423aadb52cab1ba6fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 045a26ac9992b92e1dab3c63527b6ebfd2b70c84b554d20a7f38abfa070f0402da47776d663619c0ae1ff95c681a52ccfb7da34fa2f5c10928c28626c77f75a9
|
7
|
+
data.tar.gz: cefd05d4f4babca139755e05d891802e375732bc944d278a8313e14759e87cd58b300c567e236ccf844897233072ce37e79d9c70f27385babd8b35435008a5c3
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.4.0] - 2022-06-09
|
4
|
+
|
5
|
+
- Allow custom error messages to be used when validation fails
|
6
|
+
- Ensure running multiple validations for a single parameter merges the errors correctly
|
7
|
+
- Allow validations to run code if successful
|
8
|
+
- Allow exceptions to be raised by the parameter block to indicate failure
|
9
|
+
- Allow parameters to be passed to validators
|
10
|
+
|
11
|
+
## [0.3.0] - 2022-06-08
|
12
|
+
|
13
|
+
- Don't create entries in `params` for parameters that are not passed
|
14
|
+
- Don't set validator type during definition
|
15
|
+
- Add unique validator conditionals for each validator:
|
16
|
+
- validate
|
17
|
+
- validate_form
|
18
|
+
- validate_url_param
|
19
|
+
|
20
|
+
## [0.2.0] - 2022-06-08
|
21
|
+
|
22
|
+
- Add validators:
|
23
|
+
- Standard
|
24
|
+
- URL Parameter
|
25
|
+
- Form
|
26
|
+
- Add parameters:
|
27
|
+
- Array
|
28
|
+
- Boolean
|
29
|
+
- Date
|
30
|
+
- Float
|
31
|
+
- Hash
|
32
|
+
- Integer
|
33
|
+
- String
|
34
|
+
- Time
|
35
|
+
- Add rules:
|
36
|
+
- All or none of
|
37
|
+
- Any of
|
38
|
+
- One of
|
39
|
+
|
3
40
|
## [0.1.0] - 2022-05-16
|
4
41
|
|
5
42
|
- Initial release
|
data/Gemfile
CHANGED
@@ -4,10 +4,3 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in sinatra-param_validator-validator.gemspec
|
6
6
|
gemspec
|
7
|
-
|
8
|
-
gem 'rake', '~> 13.0'
|
9
|
-
gem 'rspec', '~> 3.0'
|
10
|
-
gem 'rubocop', '~> 1.21'
|
11
|
-
gem 'rubocop-performance', '~> 1.0'
|
12
|
-
gem 'rubocop-rake', '~> 0.5'
|
13
|
-
gem 'rubocop-rspec', '~> 2.0'
|
data/Gemfile.lock
CHANGED
@@ -1,19 +1,27 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sinatra-param-validator (0.
|
4
|
+
sinatra-param-validator (0.4.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
ast (2.4.2)
|
10
10
|
diff-lcs (1.5.0)
|
11
|
+
multi_json (1.15.0)
|
12
|
+
mustermann (1.1.1)
|
13
|
+
ruby2_keywords (~> 0.0.1)
|
11
14
|
parallel (1.22.1)
|
12
15
|
parser (3.1.2.0)
|
13
16
|
ast (~> 2.4.1)
|
17
|
+
rack (2.2.3)
|
18
|
+
rack-protection (2.2.0)
|
19
|
+
rack
|
20
|
+
rack-test (1.1.0)
|
21
|
+
rack (>= 1.0, < 3)
|
14
22
|
rainbow (3.1.1)
|
15
23
|
rake (13.0.6)
|
16
|
-
regexp_parser (2.
|
24
|
+
regexp_parser (2.4.0)
|
17
25
|
rexml (3.2.5)
|
18
26
|
rspec (3.11.0)
|
19
27
|
rspec-core (~> 3.11.0)
|
@@ -28,7 +36,7 @@ GEM
|
|
28
36
|
diff-lcs (>= 1.2.0, < 2.0)
|
29
37
|
rspec-support (~> 3.11.0)
|
30
38
|
rspec-support (3.11.0)
|
31
|
-
rubocop (1.29.
|
39
|
+
rubocop (1.29.1)
|
32
40
|
parallel (~> 1.10)
|
33
41
|
parser (>= 3.1.0.0)
|
34
42
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -37,7 +45,7 @@ GEM
|
|
37
45
|
rubocop-ast (>= 1.17.0, < 2.0)
|
38
46
|
ruby-progressbar (~> 1.7)
|
39
47
|
unicode-display_width (>= 1.4.0, < 3.0)
|
40
|
-
rubocop-ast (1.
|
48
|
+
rubocop-ast (1.18.0)
|
41
49
|
parser (>= 3.1.1.0)
|
42
50
|
rubocop-performance (1.13.3)
|
43
51
|
rubocop (>= 1.7.0, < 2.0)
|
@@ -47,18 +55,33 @@ GEM
|
|
47
55
|
rubocop-rspec (2.10.0)
|
48
56
|
rubocop (~> 1.19)
|
49
57
|
ruby-progressbar (1.11.0)
|
58
|
+
ruby2_keywords (0.0.5)
|
59
|
+
sinatra (2.2.0)
|
60
|
+
mustermann (~> 1.0)
|
61
|
+
rack (~> 2.2)
|
62
|
+
rack-protection (= 2.2.0)
|
63
|
+
tilt (~> 2.0)
|
64
|
+
sinatra-contrib (2.2.0)
|
65
|
+
multi_json
|
66
|
+
mustermann (~> 1.0)
|
67
|
+
rack-protection (= 2.2.0)
|
68
|
+
sinatra (= 2.2.0)
|
69
|
+
tilt (~> 2.0)
|
70
|
+
tilt (2.0.10)
|
50
71
|
unicode-display_width (2.1.0)
|
51
72
|
|
52
73
|
PLATFORMS
|
53
74
|
x86_64-linux
|
54
75
|
|
55
76
|
DEPENDENCIES
|
77
|
+
rack-test (~> 1.1)
|
56
78
|
rake (~> 13.0)
|
57
79
|
rspec (~> 3.0)
|
58
|
-
rubocop (~> 1.
|
80
|
+
rubocop (~> 1.0)
|
59
81
|
rubocop-performance (~> 1.0)
|
60
82
|
rubocop-rake (~> 0.5)
|
61
83
|
rubocop-rspec (~> 2.0)
|
84
|
+
sinatra-contrib (~> 2.0)
|
62
85
|
sinatra-param-validator!
|
63
86
|
|
64
87
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Sinatra::Param::Validator
|
2
2
|
|
3
|
+
Validate parameters in a Sinatra app.
|
3
4
|
|
4
5
|
## Installation
|
5
6
|
|
@@ -11,9 +12,165 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
11
12
|
|
12
13
|
$ gem install sinatra-param-validator
|
13
14
|
|
14
|
-
## Usage
|
15
|
+
## Sample Usage
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
validator :user_id do
|
19
|
+
param :id, Integer, required: true
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/user/:id', validate: :user_id do
|
23
|
+
# ...
|
24
|
+
end
|
25
|
+
|
26
|
+
validator :new_user do
|
27
|
+
param :name, String, required: true
|
28
|
+
param :age, Integer, required: true, min: 0
|
29
|
+
end
|
30
|
+
|
31
|
+
post '/new-user', validate: :new_user do
|
32
|
+
# ...
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
## Parameter Types
|
37
|
+
|
38
|
+
The following parameter types are built-in,
|
39
|
+
and values will be coerced to an object of that type.
|
40
|
+
|
41
|
+
* `Array`
|
42
|
+
* Accepts a comma-separated list of values, as well as an array
|
43
|
+
* e.g. `a,b,c`
|
44
|
+
* `Boolean`
|
45
|
+
* `false|f|no|n|0` or `true|t|yes|y|1`
|
46
|
+
* `Date`
|
47
|
+
* All formats accepted by `Date.parse`
|
48
|
+
* `Float`
|
49
|
+
* `Hash`
|
50
|
+
* Accepts a comma-separated list of colon-separated key-value pairs
|
51
|
+
* e.g. `a:1,b:2,c:3`
|
52
|
+
* `Integer`
|
53
|
+
* `String`
|
54
|
+
* `Time`
|
55
|
+
* All formats accepted by `Time.parse`
|
56
|
+
|
57
|
+
Types can be defined using class names or symbols:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
param :name, String
|
61
|
+
param :tick_box, :boolean
|
62
|
+
```
|
63
|
+
|
64
|
+
## Parameter Validations
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
param :number, Integer, required: true, in: 0..100
|
68
|
+
```
|
69
|
+
|
70
|
+
All parameters have the following validations available:
|
71
|
+
|
72
|
+
* `nillable`
|
73
|
+
* If this is set, all other validations are skipped if the value is nil
|
74
|
+
* `required`
|
75
|
+
* The parameter must be present and cannot be nil
|
76
|
+
* `in`
|
77
|
+
* The value is in the given array / range
|
78
|
+
* `is`
|
79
|
+
* Match a specific value
|
80
|
+
|
81
|
+
`Array`, `Hash` and `String` have the following validations:
|
82
|
+
|
83
|
+
* `min_length` / `max_length`
|
84
|
+
|
85
|
+
`Date`, `Time`, `Float` and `Integer` have the following validations:
|
86
|
+
|
87
|
+
* `min` / `max`
|
88
|
+
|
89
|
+
## Custom Messages
|
90
|
+
|
91
|
+
It is possible to return a custom error message when a validation fails:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
param :number, Integer, required: true, message: 'The number is required'
|
95
|
+
```
|
96
|
+
|
97
|
+
It is also possible to run multiple validations against a single parameter.
|
98
|
+
This can be useful if different failures require different messages.
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
param :number, Integer, required: true, message: 'The number is required'
|
102
|
+
param :number, Integer, min: 100, message: 'The number is not large enough'
|
103
|
+
```
|
104
|
+
|
105
|
+
## Validation blocks
|
106
|
+
|
107
|
+
It is possible to run code after a validation succeeds, by passing a block to `param`:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
param :number, Integer, required: true do
|
111
|
+
# ...
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
If you wish to indicate a validation failure within a block, raise `Sinatra::ParameterValidator::InvalidParameterError`
|
116
|
+
with a message, and it will be passed through as an error for the parameter.
|
117
|
+
|
118
|
+
## Rules
|
119
|
+
|
120
|
+
Rules work on multiple parameters:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
rule :all_or_none_of, :a, :b
|
124
|
+
```
|
125
|
+
|
126
|
+
* `all_or_none_of`
|
127
|
+
* `any_of`
|
128
|
+
* At least one of the given fields must be present
|
129
|
+
* `one_of`
|
130
|
+
* Only one of the given fields can be present
|
131
|
+
|
132
|
+
## Validator Types
|
133
|
+
|
134
|
+
The default validator will raise `Sinatra::ParamValidator::ValidationFailedError` when validation fails.
|
135
|
+
|
136
|
+
There are two other provided validators, that handle failure differently:
|
137
|
+
|
138
|
+
* `url_param`
|
139
|
+
* will `halt 403`
|
140
|
+
* `form`
|
141
|
+
* if [sinatra-flash](https://github.com/SFEley/sinatra-flash) is available, it will flash the errors and `redirect back`
|
142
|
+
* will provide a JSON object with errors to an XHR request
|
143
|
+
* will `halt 400`
|
144
|
+
|
145
|
+
These validators can be invoked with a different conditional on the route:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
post '/new-user', validate_form: :new_user do
|
149
|
+
# ...
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
get '/user/:id', validate_url_param: :user_id do
|
154
|
+
# ...
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
## Validators with parameters
|
159
|
+
|
160
|
+
It is possible to define a validator with a parameter.
|
161
|
+
To call the validator, you can use the `vi` helper to wrap a validator identifier with arguments:
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
validator :number do |min|
|
165
|
+
param :id, Integer, min: min
|
166
|
+
end
|
167
|
+
|
168
|
+
post '/number', validate: vi(:new_user, 10) do
|
169
|
+
# ...
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
15
173
|
|
16
|
-
TODO: Write usage instructions here
|
17
174
|
|
18
175
|
## Development
|
19
176
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
# Store of valid definitions
|
6
|
+
class Definitions
|
7
|
+
def initialize
|
8
|
+
@definitions = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(identifier, validator)
|
12
|
+
raise "Validator already defined: '#{identifier}'" if @definitions.key? identifier
|
13
|
+
|
14
|
+
@definitions[identifier] = validator
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(identifier)
|
18
|
+
raise "Unknown validator: '#{identifier}'" unless @definitions.key? identifier
|
19
|
+
|
20
|
+
@definitions[identifier]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
# Helpers for validating parameters
|
6
|
+
module Helpers
|
7
|
+
def filter_params
|
8
|
+
params.each do |(param, value)|
|
9
|
+
params[param] = nil if value == ''
|
10
|
+
params[param] = [] if value == ['']
|
11
|
+
end
|
12
|
+
rescue StandardError => e
|
13
|
+
raise "Filter params failed: #{e}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate(klass, identifier)
|
17
|
+
identifier = Identifier.new(identifier) if identifier.is_a? Symbol
|
18
|
+
definition = settings.validator_definitions.get(identifier.identifier)
|
19
|
+
validator = klass.new(&definition)
|
20
|
+
validator.run(self, *identifier.args)
|
21
|
+
validator.handle_failure(self) unless validator.success?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
# Class to hold a validator identifier plus arguments
|
6
|
+
class Identifier
|
7
|
+
attr_reader :identifier, :args
|
8
|
+
|
9
|
+
def initialize(identifier, *args)
|
10
|
+
@identifier = identifier
|
11
|
+
@args = args
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module ParamValidator
|
7
|
+
class Parameter
|
8
|
+
# Validation for arrays
|
9
|
+
class Array
|
10
|
+
include Common
|
11
|
+
include CommonMinMaxLength
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def coerce(value)
|
16
|
+
return nil if value.nil?
|
17
|
+
return value if value.is_a? ::Array
|
18
|
+
return value.split(',') if value.is_a? ::String
|
19
|
+
|
20
|
+
raise ArgumentError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module ParamValidator
|
7
|
+
class Parameter
|
8
|
+
# Validation for booleans
|
9
|
+
class Boolean
|
10
|
+
include Common
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def coerce(value)
|
15
|
+
return nil if value.nil?
|
16
|
+
|
17
|
+
case value.to_s
|
18
|
+
when /^(false|f|no|n|0)$/i then false
|
19
|
+
when /^(true|t|yes|y|1)$/i then true
|
20
|
+
else raise ArgumentError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
class Parameter
|
6
|
+
# Common validation methods shared between parameters
|
7
|
+
module Common
|
8
|
+
attr_reader :coerced, :errors
|
9
|
+
|
10
|
+
def initialize(value, **options)
|
11
|
+
@errors = []
|
12
|
+
@coerced = coerce value
|
13
|
+
@options = options
|
14
|
+
|
15
|
+
validate_options
|
16
|
+
validate unless nil_and_ok?
|
17
|
+
rescue ArgumentError
|
18
|
+
@errors.push "'#{value}' is not a valid #{self.class}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid?
|
22
|
+
@errors.empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate_options
|
26
|
+
@options.each { |key, _| raise "Unknown option '#{key}' for #{self.class}" unless respond_to? key }
|
27
|
+
end
|
28
|
+
private :validate_options
|
29
|
+
|
30
|
+
def validate
|
31
|
+
@options.each { |key, value| method(key).call(value) }
|
32
|
+
end
|
33
|
+
private :validate
|
34
|
+
|
35
|
+
def in(options)
|
36
|
+
@errors.push "Parameter must be within #{options}" unless in? options
|
37
|
+
end
|
38
|
+
|
39
|
+
def in?(options)
|
40
|
+
case options
|
41
|
+
when Range
|
42
|
+
options.include? @coerced
|
43
|
+
else
|
44
|
+
Array(options).include? @coerced
|
45
|
+
end
|
46
|
+
end
|
47
|
+
private :in?
|
48
|
+
|
49
|
+
def is(option_value)
|
50
|
+
@errors.push "Parameter must be #{option_value}" unless @coerced == option_value
|
51
|
+
end
|
52
|
+
|
53
|
+
def nillable(_)
|
54
|
+
# Does nothing. Allows other tests to ignore nil values if present in the options
|
55
|
+
end
|
56
|
+
|
57
|
+
def nil_and_ok?
|
58
|
+
@options.key?(:nillable) && @coerced.nil?
|
59
|
+
end
|
60
|
+
private :nil_and_ok?
|
61
|
+
|
62
|
+
def required(enabled)
|
63
|
+
@errors.push 'Parameter is required' if enabled && @coerced.nil?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# min/max tests
|
68
|
+
module CommonMinMax
|
69
|
+
def max(maximum)
|
70
|
+
return if @coerced.respond_to?(:<=) && @coerced <= maximum
|
71
|
+
|
72
|
+
@errors.push "Parameter cannot be greater than #{maximum}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def min(minimum)
|
76
|
+
return if @coerced.respond_to?(:>=) && @coerced >= minimum
|
77
|
+
|
78
|
+
@errors.push "Parameter cannot be less than #{minimum}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# min/max length tests
|
83
|
+
module CommonMinMaxLength
|
84
|
+
def max_length(length)
|
85
|
+
return if @coerced.respond_to?(:length) && @coerced.length <= length
|
86
|
+
|
87
|
+
@errors.push "Parameter cannot have length greater than #{length}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def min_length(length)
|
91
|
+
return if @coerced.respond_to?(:length) && @coerced.length >= length
|
92
|
+
|
93
|
+
@errors.push "Parameter cannot have length less than #{length}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require_relative 'common'
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
module ParamValidator
|
8
|
+
class Parameter
|
9
|
+
# Validation for dates
|
10
|
+
class Date
|
11
|
+
include Common
|
12
|
+
include CommonMinMax
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def coerce(value)
|
17
|
+
return nil if value.nil?
|
18
|
+
|
19
|
+
::Date.parse(value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module ParamValidator
|
7
|
+
class Parameter
|
8
|
+
# Validation for floats
|
9
|
+
class Float
|
10
|
+
include Common
|
11
|
+
include CommonMinMax
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def coerce(value)
|
16
|
+
return nil if value.nil?
|
17
|
+
|
18
|
+
Float(value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module ParamValidator
|
7
|
+
class Parameter
|
8
|
+
# Validation for hashes
|
9
|
+
class Hash
|
10
|
+
include Common
|
11
|
+
include CommonMinMaxLength
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def coerce(value)
|
16
|
+
return nil if value.nil?
|
17
|
+
return value if value.is_a? ::Hash
|
18
|
+
return value.split(',').to_h { |s| s.split(':') } if value.is_a? ::String
|
19
|
+
|
20
|
+
raise ArgumentError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module ParamValidator
|
7
|
+
class Parameter
|
8
|
+
# Validation for integers
|
9
|
+
class Integer
|
10
|
+
include Common
|
11
|
+
include CommonMinMax
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def coerce(value)
|
16
|
+
return nil if value.nil?
|
17
|
+
|
18
|
+
Integer(value, 10)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
module ParamValidator
|
7
|
+
class Parameter
|
8
|
+
# Validation for strings
|
9
|
+
class String
|
10
|
+
include Common
|
11
|
+
include CommonMinMaxLength
|
12
|
+
|
13
|
+
def format(format_string)
|
14
|
+
@errors.push "Parameter must match the format #{format_string}" unless @coerced&.match?(format_string)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def coerce(value)
|
20
|
+
return nil if value.nil?
|
21
|
+
|
22
|
+
String(value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
require_relative 'common'
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
module ParamValidator
|
8
|
+
class Parameter
|
9
|
+
# Validation for times
|
10
|
+
class Time
|
11
|
+
include Common
|
12
|
+
include CommonMinMax
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def coerce(value)
|
17
|
+
return nil if value.nil?
|
18
|
+
|
19
|
+
::Time.parse(value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'camelize'
|
4
|
+
require_relative 'parameter/array'
|
5
|
+
require_relative 'parameter/boolean'
|
6
|
+
require_relative 'parameter/date'
|
7
|
+
require_relative 'parameter/float'
|
8
|
+
require_relative 'parameter/hash'
|
9
|
+
require_relative 'parameter/integer'
|
10
|
+
require_relative 'parameter/string'
|
11
|
+
require_relative 'parameter/time'
|
12
|
+
|
13
|
+
module Sinatra
|
14
|
+
module ParamValidator
|
15
|
+
# Load and validate a single parameter
|
16
|
+
class Parameter
|
17
|
+
class << self
|
18
|
+
include Camelize
|
19
|
+
|
20
|
+
def new(value, type, **args)
|
21
|
+
type = camelize(type) if type.is_a? Symbol
|
22
|
+
klass = Object.const_get "Sinatra::ParamValidator::Parameter::#{type}"
|
23
|
+
klass.new(value, **args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'delegate'
|
4
|
+
|
5
|
+
require_relative 'invalid_parameter_error'
|
6
|
+
require_relative 'parameter'
|
7
|
+
require_relative 'rule'
|
8
|
+
|
9
|
+
module Sinatra
|
10
|
+
module ParamValidator
|
11
|
+
# Run the definition in the given scope
|
12
|
+
class Parser < SimpleDelegator
|
13
|
+
attr_reader :errors
|
14
|
+
|
15
|
+
def initialize(definition, context, *args)
|
16
|
+
super(context)
|
17
|
+
@context = context
|
18
|
+
@errors = {}
|
19
|
+
|
20
|
+
instance_exec(*args, &definition)
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_error(key, error)
|
24
|
+
@errors[key] = @errors.fetch(key, []).concat(Array(error))
|
25
|
+
end
|
26
|
+
|
27
|
+
def param(key, type, message: nil, **args, &block)
|
28
|
+
parameter = Parameter.new(@context.params[key], type, **args)
|
29
|
+
@context.params[key] = parameter.coerced if @context.params.key?(key) && parameter.coerced
|
30
|
+
if parameter.valid?
|
31
|
+
run_block(key, block) if block
|
32
|
+
else
|
33
|
+
add_error key, message || parameter.errors
|
34
|
+
end
|
35
|
+
rescue NameError
|
36
|
+
raise 'Invalid parameter type'
|
37
|
+
end
|
38
|
+
|
39
|
+
def rule(name, *args, **kwargs)
|
40
|
+
rule = Rule.new(name, @context.params, *args, **kwargs)
|
41
|
+
unless rule.passes?
|
42
|
+
@errors[:rules] ||= []
|
43
|
+
@errors[:rules].push(rule.errors)
|
44
|
+
end
|
45
|
+
rescue NameError
|
46
|
+
raise 'Invalid rule type'
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_block(key, block)
|
50
|
+
@context.instance_exec(&block)
|
51
|
+
rescue InvalidParameterError => e
|
52
|
+
add_error key, e.message
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
class Rule
|
6
|
+
# Rule to enforce all given params, or none of them
|
7
|
+
class AllOrNoneOf
|
8
|
+
attr_reader :errors
|
9
|
+
|
10
|
+
def initialize(params, *fields, **_kwargs)
|
11
|
+
@errors = []
|
12
|
+
@params = params
|
13
|
+
@fields = fields
|
14
|
+
|
15
|
+
validate(fields)
|
16
|
+
end
|
17
|
+
|
18
|
+
def passes?
|
19
|
+
@errors.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate(fields)
|
23
|
+
count = fields.count { |f| @params.key? f }
|
24
|
+
return if count.zero? || count == fields.count
|
25
|
+
|
26
|
+
@errors.push "All or none of [#{fields.join ', '}] must be provided"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
class Rule
|
6
|
+
# Rule to enforce at least one of the given params exists
|
7
|
+
class AnyOf
|
8
|
+
attr_reader :errors
|
9
|
+
|
10
|
+
def initialize(params, *fields, **_kwargs)
|
11
|
+
@errors = []
|
12
|
+
@params = params
|
13
|
+
@fields = fields
|
14
|
+
|
15
|
+
validate(fields)
|
16
|
+
end
|
17
|
+
|
18
|
+
def passes?
|
19
|
+
@errors.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate(fields)
|
23
|
+
count = fields.count { |f| @params.key? f }
|
24
|
+
@errors.push "One of [#{fields.join ', '}] must be provided" if count < 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
class Rule
|
6
|
+
# Rule to enforce only one of the given params has been given
|
7
|
+
class OneOf
|
8
|
+
attr_reader :errors
|
9
|
+
|
10
|
+
def initialize(params, *fields, **_kwargs)
|
11
|
+
@errors = []
|
12
|
+
@params = params
|
13
|
+
@fields = fields
|
14
|
+
|
15
|
+
validate(fields)
|
16
|
+
end
|
17
|
+
|
18
|
+
def passes?
|
19
|
+
@errors.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate(fields)
|
23
|
+
count = fields.count { |f| @params.key? f }
|
24
|
+
@errors.push "Only one of [#{fields.join ', '}] is allowed" if count > 1
|
25
|
+
@errors.push "One of [#{fields.join ', '}] must be provided" if count < 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'camelize'
|
4
|
+
require_relative 'rule/all_or_none_of'
|
5
|
+
require_relative 'rule/any_of'
|
6
|
+
require_relative 'rule/one_of'
|
7
|
+
|
8
|
+
module Sinatra
|
9
|
+
module ParamValidator
|
10
|
+
# Class to check a single rule
|
11
|
+
class Rule
|
12
|
+
class << self
|
13
|
+
include Camelize
|
14
|
+
|
15
|
+
def new(name, params, *args, **kwargs)
|
16
|
+
name = camelize(name) if name.is_a? Symbol
|
17
|
+
klass = Object.const_get "Sinatra::ParamValidator::Rule::#{name}"
|
18
|
+
klass.new(params, *args, **kwargs)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
# Error raised when validation fails
|
6
|
+
class ValidationFailedError < StandardError
|
7
|
+
attr_reader :errors
|
8
|
+
|
9
|
+
def initialize(errors)
|
10
|
+
@errors = errors
|
11
|
+
super("Validation failed: #{errors}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
class Validator
|
6
|
+
# A form validator
|
7
|
+
class Form < Validator
|
8
|
+
def handle_failure(context)
|
9
|
+
case context.request.preferred_type.to_s
|
10
|
+
when 'application/json' then return json_failure(context)
|
11
|
+
when 'text/html'
|
12
|
+
return flash_failure(context) if defined? Sinatra::Flash
|
13
|
+
end
|
14
|
+
|
15
|
+
context.halt 400
|
16
|
+
end
|
17
|
+
|
18
|
+
def run(context)
|
19
|
+
@original_params = context.params
|
20
|
+
super(context)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def json_failure(context)
|
26
|
+
context.halt 400, { error: 'Validation failed', fields: @errors }.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
def flash_failure(context)
|
30
|
+
context.flash[:params] = @original_params
|
31
|
+
context.flash[:form_errors] = @errors
|
32
|
+
context.redirect context.back
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
class Validator
|
6
|
+
# A URL parameter; handle validation failure with
|
7
|
+
class UrlParam < Validator
|
8
|
+
def handle_failure(context)
|
9
|
+
context.halt 403
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module ParamValidator
|
5
|
+
# Definition of a single validator
|
6
|
+
class Validator
|
7
|
+
attr_reader :errors
|
8
|
+
|
9
|
+
def initialize(&definition)
|
10
|
+
@definition = definition
|
11
|
+
@errors = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def handle_failure(_context)
|
15
|
+
raise ValidationFailedError, @errors
|
16
|
+
end
|
17
|
+
|
18
|
+
def run(context, *args)
|
19
|
+
@errors = Parser.new(@definition, context, *args).errors
|
20
|
+
end
|
21
|
+
|
22
|
+
def success?
|
23
|
+
@errors.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
@validators = []
|
27
|
+
|
28
|
+
class << self
|
29
|
+
attr_reader :validators
|
30
|
+
|
31
|
+
def inherited(subclass)
|
32
|
+
super
|
33
|
+
@validators << subclass
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
require_relative 'validation_failed_error'
|
41
|
+
require_relative 'validator/form'
|
42
|
+
require_relative 'validator/url_param'
|
@@ -1,10 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'param_validator/camelize'
|
4
|
+
require_relative 'param_validator/definitions'
|
5
|
+
require_relative 'param_validator/helpers'
|
6
|
+
require_relative 'param_validator/identifier'
|
7
|
+
require_relative 'param_validator/parser'
|
8
|
+
require_relative 'param_validator/snake_case'
|
9
|
+
require_relative 'param_validator/validator'
|
3
10
|
require_relative 'param_validator/version'
|
4
11
|
|
5
12
|
module Sinatra
|
6
|
-
#
|
13
|
+
# Module to register in Sinatra app
|
7
14
|
module ParamValidator
|
8
|
-
|
15
|
+
include Camelize
|
16
|
+
|
17
|
+
def validator(identifier, &definition)
|
18
|
+
settings.validator_definitions.add(identifier, definition)
|
19
|
+
end
|
20
|
+
|
21
|
+
def vi(identifier, *args)
|
22
|
+
Identifier.new(identifier, *args)
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
include SnakeCase
|
27
|
+
|
28
|
+
def registered(app)
|
29
|
+
app.helpers Helpers
|
30
|
+
app.before { filter_params }
|
31
|
+
app.set(:validator_definitions, Definitions.new)
|
32
|
+
validator_conditional app, :validate, Sinatra::ParamValidator::Validator
|
33
|
+
|
34
|
+
Sinatra::ParamValidator::Validator.validators.each do |validator|
|
35
|
+
validator_conditional app, :"validate_#{snake_case(validator.to_s.split('::').last)}", validator
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def validator_conditional(app, name, klass)
|
40
|
+
app.set(name) do |*identifiers|
|
41
|
+
condition do
|
42
|
+
identifiers.each { |identifier| validate klass, identifier }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
9
47
|
end
|
10
48
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'lib/sinatra/param_validator'
|
3
|
+
require_relative 'lib/sinatra/param_validator/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'sinatra-param-validator'
|
@@ -27,6 +27,12 @@ Gem::Specification.new do |spec|
|
|
27
27
|
end
|
28
28
|
spec.require_paths = ['lib']
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
spec.add_development_dependency 'rack-test', '~> 1.1'
|
31
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
33
|
+
spec.add_development_dependency 'rubocop', '~> 1.0'
|
34
|
+
spec.add_development_dependency 'rubocop-performance', '~> 1.0'
|
35
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0.5'
|
36
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
|
37
|
+
spec.add_development_dependency 'sinatra-contrib', '~> 2.0'
|
32
38
|
end
|
metadata
CHANGED
@@ -1,15 +1,127 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-param-validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Selby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
12
|
-
dependencies:
|
11
|
+
date: 2022-06-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack-test
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '13.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '13.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-performance
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sinatra-contrib
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.0'
|
13
125
|
description:
|
14
126
|
email:
|
15
127
|
- rick@selby-family.co.uk
|
@@ -27,6 +139,31 @@ files:
|
|
27
139
|
- README.md
|
28
140
|
- Rakefile
|
29
141
|
- lib/sinatra/param_validator.rb
|
142
|
+
- lib/sinatra/param_validator/camelize.rb
|
143
|
+
- lib/sinatra/param_validator/definitions.rb
|
144
|
+
- lib/sinatra/param_validator/helpers.rb
|
145
|
+
- lib/sinatra/param_validator/identifier.rb
|
146
|
+
- lib/sinatra/param_validator/invalid_parameter_error.rb
|
147
|
+
- lib/sinatra/param_validator/parameter.rb
|
148
|
+
- lib/sinatra/param_validator/parameter/array.rb
|
149
|
+
- lib/sinatra/param_validator/parameter/boolean.rb
|
150
|
+
- lib/sinatra/param_validator/parameter/common.rb
|
151
|
+
- lib/sinatra/param_validator/parameter/date.rb
|
152
|
+
- lib/sinatra/param_validator/parameter/float.rb
|
153
|
+
- lib/sinatra/param_validator/parameter/hash.rb
|
154
|
+
- lib/sinatra/param_validator/parameter/integer.rb
|
155
|
+
- lib/sinatra/param_validator/parameter/string.rb
|
156
|
+
- lib/sinatra/param_validator/parameter/time.rb
|
157
|
+
- lib/sinatra/param_validator/parser.rb
|
158
|
+
- lib/sinatra/param_validator/rule.rb
|
159
|
+
- lib/sinatra/param_validator/rule/all_or_none_of.rb
|
160
|
+
- lib/sinatra/param_validator/rule/any_of.rb
|
161
|
+
- lib/sinatra/param_validator/rule/one_of.rb
|
162
|
+
- lib/sinatra/param_validator/snake_case.rb
|
163
|
+
- lib/sinatra/param_validator/validation_failed_error.rb
|
164
|
+
- lib/sinatra/param_validator/validator.rb
|
165
|
+
- lib/sinatra/param_validator/validator/form.rb
|
166
|
+
- lib/sinatra/param_validator/validator/url_param.rb
|
30
167
|
- lib/sinatra/param_validator/version.rb
|
31
168
|
- sinatra-param-validator.gemspec
|
32
169
|
homepage: https://github.com/rickselby/sinatra-param_validator-validator
|