sinatra-param-validator 0.1.0 → 0.2.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/Gemfile +0 -7
- data/Gemfile.lock +28 -5
- data/README.md +109 -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 +23 -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 +41 -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/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 +31 -0
- data/lib/sinatra/param_validator/version.rb +1 -1
- data/lib/sinatra/param_validator.rb +23 -2
- data/sinatra-param-validator.gemspec +9 -3
- metadata +137 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dda1b5487b870b26f4b2ca5c6a575a57c91441ac319b78567295ab0b4517a8bc
|
|
4
|
+
data.tar.gz: 331f3cace8d87a35fa410ae28c3df15e07f851d276ad2a2173ce799572cfae04
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: caceb492da8562135850ecf1c7a77ecd4fd850ab31d714ff1fa555c4316e63074aa7ed9f75e331336ddf30c1921a5d3cc2f895447d7ec76f3767b46448e6a7c4
|
|
7
|
+
data.tar.gz: 729686317687d72ff23ce570991a88e6731314320f3e702ba631c7452b75e117997fc30207c2cee7be52c1aa458424311666b734061bb7c3aefb6911b07a9dc2
|
data/.rubocop.yml
CHANGED
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.2.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,115 @@ 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
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
```ruby
|
|
18
|
+
validator identifier: :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 identifier: :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
|
+
## Rules
|
|
90
|
+
|
|
91
|
+
Rules work on multiple parameters:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
rule :all_or_none_of, :a, :b
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
* `all_or_none_of`
|
|
98
|
+
* `any_of`
|
|
99
|
+
* At least one of the given fields must be present
|
|
100
|
+
* `one_of`
|
|
101
|
+
* Only one of the given fields can be present
|
|
102
|
+
|
|
103
|
+
## Validator Types
|
|
104
|
+
|
|
105
|
+
The default validator will raise `Sinatra::ParamValidator::ValidationFailedError` when validation fails.
|
|
106
|
+
|
|
107
|
+
There are two other provided validators, that handle failure differently:
|
|
108
|
+
|
|
109
|
+
* `url_param`
|
|
110
|
+
* will `halt 403`
|
|
111
|
+
* `form`
|
|
112
|
+
* if [sinatra-flash](https://github.com/SFEley/sinatra-flash) is available, it will flash the errors and `redirect back`
|
|
113
|
+
* will provide a JSON object with errors to an XHR request
|
|
114
|
+
* will `halt 400`
|
|
115
|
+
|
|
116
|
+
These validators can be set when a validator is defined:
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
validator type: :form, identifier: :new_user do
|
|
120
|
+
param :name, String, required: true
|
|
121
|
+
param :age, Integer, required: true, min: 0
|
|
122
|
+
end
|
|
123
|
+
```
|
|
17
124
|
|
|
18
125
|
## Development
|
|
19
126
|
|
|
@@ -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,23 @@
|
|
|
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(identifier, args = {})
|
|
17
|
+
validator = settings.validator_definitions.get(identifier)
|
|
18
|
+
validator.run(self, *args)
|
|
19
|
+
validator.handle_failure(self) unless validator.success?
|
|
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 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,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'delegate'
|
|
4
|
+
|
|
5
|
+
require_relative 'parameter'
|
|
6
|
+
require_relative 'rule'
|
|
7
|
+
|
|
8
|
+
module Sinatra
|
|
9
|
+
module ParamValidator
|
|
10
|
+
# Run the definition in the given scope
|
|
11
|
+
class Parser < SimpleDelegator
|
|
12
|
+
attr_reader :errors
|
|
13
|
+
|
|
14
|
+
def initialize(definition, context)
|
|
15
|
+
super(context)
|
|
16
|
+
@context = context
|
|
17
|
+
@errors = {}
|
|
18
|
+
|
|
19
|
+
instance_exec({}, &definition)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def param(key, type, **args)
|
|
23
|
+
parameter = Parameter.new(@context.params[key], type, **args)
|
|
24
|
+
@context.params[key] = parameter.coerced
|
|
25
|
+
@errors[key] = parameter.errors unless parameter.valid?
|
|
26
|
+
rescue NameError
|
|
27
|
+
raise 'Invalid parameter type'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def rule(name, *args, **kwargs)
|
|
31
|
+
rule = Rule.new(name, @context.params, *args, **kwargs)
|
|
32
|
+
unless rule.passes?
|
|
33
|
+
@errors[:rules] ||= []
|
|
34
|
+
@errors[:rules].push(rule.errors)
|
|
35
|
+
end
|
|
36
|
+
rescue NameError
|
|
37
|
+
raise 'Invalid rule type'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
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, msg = nil)
|
|
10
|
+
@errors = errors
|
|
11
|
+
super(msg)
|
|
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,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'validation_failed_error'
|
|
4
|
+
require_relative 'validator/form'
|
|
5
|
+
require_relative 'validator/url_param'
|
|
6
|
+
|
|
7
|
+
module Sinatra
|
|
8
|
+
module ParamValidator
|
|
9
|
+
# Definition of a single validator
|
|
10
|
+
class Validator
|
|
11
|
+
attr_reader :errors
|
|
12
|
+
|
|
13
|
+
def initialize(&definition)
|
|
14
|
+
@definition = definition
|
|
15
|
+
@errors = {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def handle_failure(_context)
|
|
19
|
+
raise ValidationFailedError, @errors
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run(context)
|
|
23
|
+
@errors = Parser.new(@definition, context).errors
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def success?
|
|
27
|
+
@errors.empty?
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'param_validator/definitions'
|
|
4
|
+
require_relative 'param_validator/helpers'
|
|
5
|
+
require_relative 'param_validator/parser'
|
|
6
|
+
require_relative 'param_validator/validator'
|
|
3
7
|
require_relative 'param_validator/version'
|
|
4
8
|
|
|
5
9
|
module Sinatra
|
|
6
|
-
#
|
|
10
|
+
# Module to register in Sinatra app
|
|
7
11
|
module ParamValidator
|
|
8
|
-
|
|
12
|
+
include Camelize
|
|
13
|
+
|
|
14
|
+
def validator(identifier:, type: nil, &definition)
|
|
15
|
+
class_name = 'Sinatra::ParamValidator::Validator'
|
|
16
|
+
class_name = "#{class_name}::#{camelize(type)}" unless type.nil?
|
|
17
|
+
settings.validator_definitions.add(identifier, Object.const_get(class_name).new(&definition))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.registered(app)
|
|
21
|
+
app.helpers Helpers
|
|
22
|
+
app.before { filter_params }
|
|
23
|
+
app.set(:validator_definitions, Definitions.new)
|
|
24
|
+
app.set(:validate) do |*identifiers|
|
|
25
|
+
condition do
|
|
26
|
+
identifiers.each { |identifier| validate identifier }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
9
30
|
end
|
|
10
31
|
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.2.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-08 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,28 @@ 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/parameter.rb
|
|
146
|
+
- lib/sinatra/param_validator/parameter/array.rb
|
|
147
|
+
- lib/sinatra/param_validator/parameter/boolean.rb
|
|
148
|
+
- lib/sinatra/param_validator/parameter/common.rb
|
|
149
|
+
- lib/sinatra/param_validator/parameter/date.rb
|
|
150
|
+
- lib/sinatra/param_validator/parameter/float.rb
|
|
151
|
+
- lib/sinatra/param_validator/parameter/hash.rb
|
|
152
|
+
- lib/sinatra/param_validator/parameter/integer.rb
|
|
153
|
+
- lib/sinatra/param_validator/parameter/string.rb
|
|
154
|
+
- lib/sinatra/param_validator/parameter/time.rb
|
|
155
|
+
- lib/sinatra/param_validator/parser.rb
|
|
156
|
+
- lib/sinatra/param_validator/rule.rb
|
|
157
|
+
- lib/sinatra/param_validator/rule/all_or_none_of.rb
|
|
158
|
+
- lib/sinatra/param_validator/rule/any_of.rb
|
|
159
|
+
- lib/sinatra/param_validator/rule/one_of.rb
|
|
160
|
+
- lib/sinatra/param_validator/validation_failed_error.rb
|
|
161
|
+
- lib/sinatra/param_validator/validator.rb
|
|
162
|
+
- lib/sinatra/param_validator/validator/form.rb
|
|
163
|
+
- lib/sinatra/param_validator/validator/url_param.rb
|
|
30
164
|
- lib/sinatra/param_validator/version.rb
|
|
31
165
|
- sinatra-param-validator.gemspec
|
|
32
166
|
homepage: https://github.com/rickselby/sinatra-param_validator-validator
|