great_guardian 0.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.md +21 -0
- data/README.md +71 -0
- data/lib/great_guardian.rb +6 -0
- data/lib/great_guardian/attribute.rb +11 -0
- data/lib/great_guardian/attribute/base.rb +161 -0
- data/lib/great_guardian/expected_value.rb +11 -0
- data/lib/great_guardian/expected_value/array.rb +41 -0
- data/lib/great_guardian/expected_value/base.rb +30 -0
- data/lib/great_guardian/expected_value/boolean.rb +24 -0
- data/lib/great_guardian/expected_value/number.rb +41 -0
- data/lib/great_guardian/expected_value/string.rb +41 -0
- data/lib/great_guardian/verdict.rb +29 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9755441c71cd68b3ec0775ef0aa266a9e8ab9591d1546bdb6bdc1bf69f813a6b
|
4
|
+
data.tar.gz: 51b9331234a489ded36dd642a3711895a603ab55cc1143ebd6e24897207a6b2f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc93e36dcab7b24a90ba0a0fb50926b78d47f68a84c6fd1643a7ddc8b949736c415f0f9c85e787cdd647ec7813813d92e7b89aac6284879d1ad7822a3b7c2f67
|
7
|
+
data.tar.gz: 9fcfe88e86a9f64a57453eca27e4dd5445ea3a8ff95bd30ea17e87baefbf550a28fdf8f262c615d0f99cee90fd8b47d1aa3d0b06529626b0a9c075f7b46bb1f8
|
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014-2020 Cyril Kato
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Great Guardian
|
2
|
+
|
3
|
+
[![Build Status](https://api.travis-ci.org/cyril/great_guardian.rb.svg?branch=master)][travis]
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/great_guardian.svg)][gem]
|
5
|
+
[![Inline docs](https://inch-ci.org/github/cyril/great_guardian.rb.svg?branch=master)][inchpages]
|
6
|
+
[![Documentation](http://img.shields.io/:yard-docs-38c800.svg)][rubydoc]
|
7
|
+
|
8
|
+
> Web parameters validation for Ruby 🛡️
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'great_guardian', '>= 0.1.0.beta1'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle install
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install great_guardian --pre
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class EmailAttribute < GreatGuardian::Attribute::Base
|
30
|
+
def self.expected_value_type
|
31
|
+
::GreatGuardian::ExpectedValue::String
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.default_constraints
|
35
|
+
{
|
36
|
+
pattern: /\A[^@]+@[^@]+$\z/i
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
email_attribute = EmailAttribute.new(required: true)
|
42
|
+
|
43
|
+
email_attribute.call(nil) # => #<GreatGuardian::Verdict:0x00007ffd3f00ad40 @attribute_name="email_attribute", @value=nil, @error_message=["attribute.email_attribute.errors.required", {:name=>["attribute.email_attribute.name"], :expected=>nil}], @medium=:body>
|
44
|
+
email_attribute.call(4) # => #<GreatGuardian::Verdict:0x00007ffd3e360590 @attribute_name="email_attribute", @value=4, @error_message=["attribute.email_attribute.errors.type", {:name=>["attribute.email_attribute.name"], :expected=>["expected_value.string.type"]}], @medium=:body>
|
45
|
+
email_attribute.call('boom') # => #<GreatGuardian::Verdict:0x00007ffd3e3d8360 @attribute_name="email_attribute", @value="boom", @error_message=["attribute.email_attribute.errors.pattern", {:name=>["attribute.email_attribute.name"], :expected=>/\A[^@]+@[^@]+$\z/i}], @medium=:body>
|
46
|
+
email_attribute.call('bob@gmail.com') # => #<GreatGuardian::Verdict:0x00007ffd3e3c23d0 @attribute_name="email_attribute", @value="bob@gmail.com", @error_message=nil, @medium=:body>
|
47
|
+
```
|
48
|
+
|
49
|
+
## Contact
|
50
|
+
|
51
|
+
* Home page: https://github.com/cyril/great_guardian.rb
|
52
|
+
* Bugs/issues: https://github.com/cyril/great_guardian.rb/issues
|
53
|
+
|
54
|
+
## Rubies
|
55
|
+
|
56
|
+
* [MRI](https://www.ruby-lang.org/)
|
57
|
+
* [Rubinius](https://rubinius.com/)
|
58
|
+
* [JRuby](https://www.jruby.org/)
|
59
|
+
|
60
|
+
## Versioning
|
61
|
+
|
62
|
+
__GreatGuardian__ follows [Semantic Versioning 2.0](https://semver.org/).
|
63
|
+
|
64
|
+
## License
|
65
|
+
|
66
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
67
|
+
|
68
|
+
[gem]: https://rubygems.org/gems/great_guardian
|
69
|
+
[travis]: https://travis-ci.org/cyril/great_guardian.rb
|
70
|
+
[inchpages]: https://inch-ci.org/github/cyril/great_guardian.rb
|
71
|
+
[rubydoc]: https://rubydoc.info/gems/great_guardian/frames
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module GreatGuardian
|
2
|
+
module Attribute
|
3
|
+
class Base
|
4
|
+
attr_reader :custom_constraints, :default_value, :medium
|
5
|
+
|
6
|
+
def initialize(required: true, medium: :body, default_value: nil, **custom_constraints)
|
7
|
+
raise ::ArgumentError, required.inspect unless [false, true].include?(required)
|
8
|
+
raise ::ArgumentError, medium.inspect unless %i[body header querystring].include?(medium)
|
9
|
+
|
10
|
+
@custom_constraints = custom_constraints
|
11
|
+
@default_value = default_value
|
12
|
+
@medium = medium
|
13
|
+
@required = required
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(actual_value)
|
17
|
+
actual_value = actual_value_or_default_value(actual_value)
|
18
|
+
error_message = compute_error_message(actual_value)
|
19
|
+
|
20
|
+
Verdict.new(to_s, actual_value, error_message, medium)
|
21
|
+
end
|
22
|
+
|
23
|
+
def constraints
|
24
|
+
self.class.default_constraints.merge(**custom_constraints)
|
25
|
+
end
|
26
|
+
|
27
|
+
def expected_value
|
28
|
+
self.class.expected_value_type.new(**constraints)
|
29
|
+
end
|
30
|
+
|
31
|
+
def required?
|
32
|
+
@required
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
self.class
|
37
|
+
.name
|
38
|
+
.split('::')
|
39
|
+
.fetch(-1)
|
40
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
41
|
+
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
42
|
+
.tr('-', '_')
|
43
|
+
.downcase
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_sym
|
47
|
+
to_s.to_sym
|
48
|
+
end
|
49
|
+
|
50
|
+
def body?
|
51
|
+
medium.equal?(:body)
|
52
|
+
end
|
53
|
+
|
54
|
+
def header_or_querystring?
|
55
|
+
!body?
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.possible_values; end
|
59
|
+
|
60
|
+
def self.default_value; end
|
61
|
+
|
62
|
+
def self.default_constraints
|
63
|
+
{}
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.first_matched_error_on_complex_validation_logic_against(_actual_value); end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def actual_value_or_default_value(actual_value)
|
71
|
+
return actual_value unless not_required_and_nil_or_empty?(actual_value)
|
72
|
+
|
73
|
+
return default_value unless default_value.nil?
|
74
|
+
return self.class.default_value unless self.class.default_value.nil?
|
75
|
+
|
76
|
+
actual_value
|
77
|
+
end
|
78
|
+
|
79
|
+
def compute_error_message(actual_value)
|
80
|
+
return if not_required_and_nil_or_empty?(actual_value)
|
81
|
+
|
82
|
+
if required_but_nil?(actual_value)
|
83
|
+
return i18n_attribute_error(:required, name: i18n_attribute_name)
|
84
|
+
end
|
85
|
+
|
86
|
+
first_error = expected_value.first_matched_error_against(actual_value, is_native: body?)
|
87
|
+
|
88
|
+
if first_error.nil?
|
89
|
+
unless self.class.possible_values.nil?
|
90
|
+
actual_value_is_included_in_possible_values = if self.class.expected_value_type.equal?(::GreatGuardian::ExpectedValue::Array)
|
91
|
+
actual_value.all? { |item| self.class.possible_values.include?(item) }
|
92
|
+
else
|
93
|
+
self.class.possible_values.include?(actual_value)
|
94
|
+
end
|
95
|
+
|
96
|
+
unless actual_value_is_included_in_possible_values
|
97
|
+
return i18n_attribute_error(:possible_values,
|
98
|
+
name: i18n_attribute_name,
|
99
|
+
expected: self.class.possible_values.map(&:inspect).sort.join(', ')
|
100
|
+
)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
error_on_complex_validation_logic = self.class.first_matched_error_on_complex_validation_logic_against(actual_value)
|
105
|
+
|
106
|
+
unless error_on_complex_validation_logic.nil?
|
107
|
+
return i18n_attribute_error(error_on_complex_validation_logic)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
return if first_error.nil?
|
112
|
+
|
113
|
+
expected = expected_value.public_send(first_error)
|
114
|
+
|
115
|
+
if first_error.equal?(:type)
|
116
|
+
expected = i18n_expected_value_type(expected_value.type)
|
117
|
+
end
|
118
|
+
|
119
|
+
i18n_attribute_error(first_error,
|
120
|
+
name: i18n_attribute_name,
|
121
|
+
expected: expected
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def not_required_and_nil_or_empty?(actual_value)
|
126
|
+
return false if required?
|
127
|
+
|
128
|
+
return true if actual_value.nil? && body?
|
129
|
+
return true if actual_value.to_s.empty? && header_or_querystring?
|
130
|
+
|
131
|
+
false
|
132
|
+
end
|
133
|
+
|
134
|
+
def required_but_nil?(actual_value)
|
135
|
+
actual_value.nil? && required?
|
136
|
+
end
|
137
|
+
|
138
|
+
def i18n_attribute_name
|
139
|
+
[
|
140
|
+
"attribute.#{self.to_sym}.name"
|
141
|
+
]
|
142
|
+
end
|
143
|
+
|
144
|
+
def i18n_expected_value_type(expected_value)
|
145
|
+
[
|
146
|
+
"expected_value.#{expected_value}.type"
|
147
|
+
]
|
148
|
+
end
|
149
|
+
|
150
|
+
def i18n_attribute_error(error, name: nil, expected: nil)
|
151
|
+
[
|
152
|
+
"attribute.#{self.to_sym}.errors.#{error}",
|
153
|
+
{
|
154
|
+
name: name,
|
155
|
+
expected: expected
|
156
|
+
}
|
157
|
+
]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module GreatGuardian
|
4
|
+
module ExpectedValue
|
5
|
+
class Array < Base
|
6
|
+
attr_reader :minlen, :maxlen
|
7
|
+
|
8
|
+
def initialize(minlen: nil, maxlen: nil)
|
9
|
+
raise ::ArgumentError, minlen.inspect if !minlen.nil? && !minlen.is_a?(::Integer)
|
10
|
+
raise ::ArgumentError, maxlen.inspect if !maxlen.nil? && !maxlen.is_a?(::Integer)
|
11
|
+
|
12
|
+
if !minlen.nil? && !maxlen.nil? && (minlen > maxlen)
|
13
|
+
raise ::ArgumentError, minlen.inspect, maxlen.inspect
|
14
|
+
end
|
15
|
+
|
16
|
+
@minlen = minlen
|
17
|
+
@maxlen = maxlen
|
18
|
+
end
|
19
|
+
|
20
|
+
def first_matched_error_against(actual_value, is_native: true)
|
21
|
+
actual_value = emulate(actual_value) unless is_native
|
22
|
+
|
23
|
+
return :type unless valid_type?(actual_value)
|
24
|
+
return :minlen if !minlen.nil? && actual_value.length < minlen
|
25
|
+
return :maxlen if !maxlen.nil? && actual_value.length > maxlen
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.types
|
29
|
+
[::Array]
|
30
|
+
end
|
31
|
+
|
32
|
+
def emulate(value)
|
33
|
+
if value.to_s.start_with?('[') && value.to_s.end_with?(']')
|
34
|
+
return value.to_s.split(',').map(&:strip)
|
35
|
+
end
|
36
|
+
|
37
|
+
value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module GreatGuardian
|
2
|
+
module ExpectedValue
|
3
|
+
class Base
|
4
|
+
def initialize(**)
|
5
|
+
end
|
6
|
+
|
7
|
+
def valid_type?(actual_value)
|
8
|
+
self.class.types.any? { |type| actual_value.is_a?(type) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def type
|
12
|
+
self.class
|
13
|
+
.name
|
14
|
+
.split('::')
|
15
|
+
.fetch(-1)
|
16
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
17
|
+
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
18
|
+
.tr('-', '_')
|
19
|
+
.downcase
|
20
|
+
.to_sym
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.types
|
24
|
+
raise ::NotImplementedError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# require_relative ::File.join('..', 'expected_value')
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module GreatGuardian
|
4
|
+
module ExpectedValue
|
5
|
+
class Boolean < Base
|
6
|
+
def first_matched_error_against(actual_value, is_native: true)
|
7
|
+
actual_value = emulate(actual_value) unless is_native
|
8
|
+
|
9
|
+
return :type unless valid_type?(actual_value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.types
|
13
|
+
[::FalseClass, ::TrueClass]
|
14
|
+
end
|
15
|
+
|
16
|
+
def emulate(value)
|
17
|
+
return true if value.eql?('true')
|
18
|
+
return false if value.eql?('false')
|
19
|
+
|
20
|
+
value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module GreatGuardian
|
4
|
+
module ExpectedValue
|
5
|
+
class Number < Base
|
6
|
+
attr_reader :min, :max
|
7
|
+
|
8
|
+
def initialize(min: nil, max: nil)
|
9
|
+
raise ::ArgumentError, min.inspect if !min.nil? && !min.is_a?(::Numeric)
|
10
|
+
raise ::ArgumentError, max.inspect if !max.nil? && !max.is_a?(::Numeric)
|
11
|
+
|
12
|
+
if !min.nil? && !max.nil? && (min > max)
|
13
|
+
raise ::ArgumentError, min.inspect, max.inspect
|
14
|
+
end
|
15
|
+
|
16
|
+
@min = min
|
17
|
+
@max = max
|
18
|
+
end
|
19
|
+
|
20
|
+
def first_matched_error_against(actual_value, is_native: true)
|
21
|
+
actual_value = emulate(actual_value) unless is_native
|
22
|
+
|
23
|
+
return :type unless valid_type?(actual_value)
|
24
|
+
return :min if !min.nil? && actual_value < min
|
25
|
+
return :max if !max.nil? && actual_value > max
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.types
|
29
|
+
[::Numeric]
|
30
|
+
end
|
31
|
+
|
32
|
+
def emulate(value)
|
33
|
+
if value.match?(/\A-?([0-9]+.)?[0-9]+\z/)
|
34
|
+
return value.include?('.') ? value.to_f : value.to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module GreatGuardian
|
4
|
+
module ExpectedValue
|
5
|
+
class String < Base
|
6
|
+
attr_reader :minlen, :maxlen, :pattern
|
7
|
+
|
8
|
+
def initialize(minlen: nil, maxlen: nil, pattern: nil)
|
9
|
+
raise ::ArgumentError, minlen.inspect if !minlen.nil? && !minlen.is_a?(::Integer)
|
10
|
+
raise ::ArgumentError, maxlen.inspect if !maxlen.nil? && !maxlen.is_a?(::Integer)
|
11
|
+
|
12
|
+
if !minlen.nil? && !maxlen.nil? && (minlen > maxlen)
|
13
|
+
raise ::ArgumentError, minlen.inspect, maxlen.inspect
|
14
|
+
end
|
15
|
+
|
16
|
+
raise ::ArgumentError, pattern.inspect if !pattern.nil? && !pattern.is_a?(::Regexp)
|
17
|
+
|
18
|
+
@minlen = minlen
|
19
|
+
@maxlen = maxlen
|
20
|
+
@pattern = pattern
|
21
|
+
end
|
22
|
+
|
23
|
+
def first_matched_error_against(actual_value, is_native: true)
|
24
|
+
actual_value = emulate(actual_value) unless is_native
|
25
|
+
|
26
|
+
return :type unless valid_type?(actual_value)
|
27
|
+
return :minlen if !minlen.nil? && actual_value.length < minlen
|
28
|
+
return :maxlen if !maxlen.nil? && actual_value.length > maxlen
|
29
|
+
return :pattern if !pattern.nil? && !actual_value.match?(pattern)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.types
|
33
|
+
[::String]
|
34
|
+
end
|
35
|
+
|
36
|
+
def emulate(value)
|
37
|
+
value.to_s
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GreatGuardian
|
4
|
+
# Decision of Great Guardian.
|
5
|
+
class Verdict
|
6
|
+
attr_reader :value, :error_message, :medium
|
7
|
+
|
8
|
+
def initialize(attribute_name, value, error_message, medium)
|
9
|
+
raise ::ArgumentError, medium.inspect unless %i[body header querystring].include?(medium)
|
10
|
+
|
11
|
+
@attribute_name = attribute_name
|
12
|
+
@value = value
|
13
|
+
@error_message = error_message
|
14
|
+
@medium = medium
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
error_message.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def invalid?
|
22
|
+
!valid?
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@attribute_name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: great_guardian
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.beta1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cyril Kato
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.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: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-performance
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.17'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.17'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.9'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.9'
|
97
|
+
description: "Web parameters validation for Ruby \U0001F6E1️"
|
98
|
+
email: contact@cyril.email
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- LICENSE.md
|
104
|
+
- README.md
|
105
|
+
- lib/great_guardian.rb
|
106
|
+
- lib/great_guardian/attribute.rb
|
107
|
+
- lib/great_guardian/attribute/base.rb
|
108
|
+
- lib/great_guardian/expected_value.rb
|
109
|
+
- lib/great_guardian/expected_value/array.rb
|
110
|
+
- lib/great_guardian/expected_value/base.rb
|
111
|
+
- lib/great_guardian/expected_value/boolean.rb
|
112
|
+
- lib/great_guardian/expected_value/number.rb
|
113
|
+
- lib/great_guardian/expected_value/string.rb
|
114
|
+
- lib/great_guardian/verdict.rb
|
115
|
+
homepage: https://github.com/cyril/great_guardian.rb
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 1.3.1
|
133
|
+
requirements: []
|
134
|
+
rubygems_version: 3.1.2
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: "Web parameters validation for Ruby \U0001F6E1️"
|
138
|
+
test_files: []
|