mini_defender 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +70 -0
  5. data/LICENSE.md +21 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +33 -0
  8. data/RULES.md +92 -0
  9. data/Rakefile +12 -0
  10. data/lib/mini_defender/extensions/enumerable.rb +34 -0
  11. data/lib/mini_defender/extensions/hash.rb +28 -0
  12. data/lib/mini_defender/rule.rb +77 -0
  13. data/lib/mini_defender/rules/accepted.rb +17 -0
  14. data/lib/mini_defender/rules/accepted_if.rb +26 -0
  15. data/lib/mini_defender/rules/alpha.rb +15 -0
  16. data/lib/mini_defender/rules/alpha_dash.rb +15 -0
  17. data/lib/mini_defender/rules/alpha_num.rb +15 -0
  18. data/lib/mini_defender/rules/array.rb +15 -0
  19. data/lib/mini_defender/rules/bail.rb +19 -0
  20. data/lib/mini_defender/rules/between.rb +29 -0
  21. data/lib/mini_defender/rules/boolean.rb +26 -0
  22. data/lib/mini_defender/rules/confirmed.rb +24 -0
  23. data/lib/mini_defender/rules/country_code.rb +23 -0
  24. data/lib/mini_defender/rules/credit_card.rb +13 -0
  25. data/lib/mini_defender/rules/date.rb +27 -0
  26. data/lib/mini_defender/rules/date_eq.rb +43 -0
  27. data/lib/mini_defender/rules/date_format.rb +38 -0
  28. data/lib/mini_defender/rules/date_gt.rb +24 -0
  29. data/lib/mini_defender/rules/date_gte.rb +24 -0
  30. data/lib/mini_defender/rules/date_lt.rb +24 -0
  31. data/lib/mini_defender/rules/date_lte.rb +24 -0
  32. data/lib/mini_defender/rules/declined.rb +17 -0
  33. data/lib/mini_defender/rules/declined_if.rb +26 -0
  34. data/lib/mini_defender/rules/default.rb +33 -0
  35. data/lib/mini_defender/rules/different.rb +31 -0
  36. data/lib/mini_defender/rules/digits.rb +26 -0
  37. data/lib/mini_defender/rules/digits_between.rb +29 -0
  38. data/lib/mini_defender/rules/distinct.rb +18 -0
  39. data/lib/mini_defender/rules/email.rb +19 -0
  40. data/lib/mini_defender/rules/ending_with.rb +31 -0
  41. data/lib/mini_defender/rules/equal.rb +9 -0
  42. data/lib/mini_defender/rules/excluded.rb +15 -0
  43. data/lib/mini_defender/rules/excluded_if.rb +28 -0
  44. data/lib/mini_defender/rules/excluded_unless.rb +28 -0
  45. data/lib/mini_defender/rules/excluded_with.rb +27 -0
  46. data/lib/mini_defender/rules/excluded_without.rb +27 -0
  47. data/lib/mini_defender/rules/exists.rb +29 -0
  48. data/lib/mini_defender/rules/expiry_date.rb +28 -0
  49. data/lib/mini_defender/rules/file.rb +17 -0
  50. data/lib/mini_defender/rules/filled.rb +22 -0
  51. data/lib/mini_defender/rules/greater_than.rb +34 -0
  52. data/lib/mini_defender/rules/greater_than_or_equal.rb +34 -0
  53. data/lib/mini_defender/rules/hash.rb +15 -0
  54. data/lib/mini_defender/rules/image.rb +19 -0
  55. data/lib/mini_defender/rules/in.rb +27 -0
  56. data/lib/mini_defender/rules/in_field.rb +40 -0
  57. data/lib/mini_defender/rules/integer.rb +19 -0
  58. data/lib/mini_defender/rules/ip.rb +43 -0
  59. data/lib/mini_defender/rules/ipv4.rb +43 -0
  60. data/lib/mini_defender/rules/ipv6.rb +43 -0
  61. data/lib/mini_defender/rules/json.rb +19 -0
  62. data/lib/mini_defender/rules/less_than.rb +34 -0
  63. data/lib/mini_defender/rules/less_than_or_equal.rb +34 -0
  64. data/lib/mini_defender/rules/luhn.rb +33 -0
  65. data/lib/mini_defender/rules/mac_address.rb +39 -0
  66. data/lib/mini_defender/rules/max.rb +9 -0
  67. data/lib/mini_defender/rules/max_digits.rb +32 -0
  68. data/lib/mini_defender/rules/mime_types.rb +37 -0
  69. data/lib/mini_defender/rules/min.rb +9 -0
  70. data/lib/mini_defender/rules/min_digits.rb +32 -0
  71. data/lib/mini_defender/rules/national_id.rb +13 -0
  72. data/lib/mini_defender/rules/not_ending_with.rb +31 -0
  73. data/lib/mini_defender/rules/not_in.rb +27 -0
  74. data/lib/mini_defender/rules/not_regex.rb +27 -0
  75. data/lib/mini_defender/rules/not_starting_with.rb +31 -0
  76. data/lib/mini_defender/rules/numeric.rb +19 -0
  77. data/lib/mini_defender/rules/present.rb +19 -0
  78. data/lib/mini_defender/rules/prohibited.rb +15 -0
  79. data/lib/mini_defender/rules/prohibited_if.rb +32 -0
  80. data/lib/mini_defender/rules/prohibited_unless.rb +32 -0
  81. data/lib/mini_defender/rules/regex.rb +27 -0
  82. data/lib/mini_defender/rules/required.rb +32 -0
  83. data/lib/mini_defender/rules/required_if.rb +26 -0
  84. data/lib/mini_defender/rules/required_unless.rb +26 -0
  85. data/lib/mini_defender/rules/required_with.rb +27 -0
  86. data/lib/mini_defender/rules/required_with_all.rb +27 -0
  87. data/lib/mini_defender/rules/required_without.rb +27 -0
  88. data/lib/mini_defender/rules/required_without_all.rb +27 -0
  89. data/lib/mini_defender/rules/size.rb +45 -0
  90. data/lib/mini_defender/rules/starting_with.rb +31 -0
  91. data/lib/mini_defender/rules/string.rb +15 -0
  92. data/lib/mini_defender/rules/timezone.rb +19 -0
  93. data/lib/mini_defender/rules/unique.rb +37 -0
  94. data/lib/mini_defender/rules/url.rb +17 -0
  95. data/lib/mini_defender/rules/uuid.rb +37 -0
  96. data/lib/mini_defender/rules.rb +8 -0
  97. data/lib/mini_defender/rules_expander.rb +19 -0
  98. data/lib/mini_defender/rules_factory.rb +36 -0
  99. data/lib/mini_defender/validates_input.rb +12 -0
  100. data/lib/mini_defender/validation_error.rb +10 -0
  101. data/lib/mini_defender/validator.rb +127 -0
  102. data/lib/mini_defender/version.rb +5 -0
  103. data/lib/mini_defender.rb +24 -0
  104. data/mini_defender.gemspec +38 -0
  105. data/sig/mini_defender.rbs +4 -0
  106. metadata +206 -0
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniDefender
4
+ class RulesFactory
5
+ def self.blueprints
6
+ @@blueprints ||= []
7
+ end
8
+
9
+ def self.register(klass)
10
+ blueprints << klass
11
+ end
12
+
13
+ def init_set(rule_set)
14
+ rule_set = rule_set.split('|') if rule_set.is_a?(String)
15
+ raise ArgumentError, 'Rule set must be a string or an array' unless rule_set.is_a?(Array)
16
+
17
+ rule_set.map do |rule|
18
+ unless rule.is_a?(String) || rule.is_a?(Rule)
19
+ raise ArgumentError, 'Rule must be a string or an instance of MiniDefender::Rule'
20
+ end
21
+
22
+ rule.is_a?(String) ? init_rule(rule) : rule
23
+ end
24
+ end
25
+
26
+ def init_rule(signature)
27
+ @blueprints ||= RulesFactory.blueprints
28
+
29
+ signature = signature.split(':')
30
+ blueprint = @blueprints.find { |b| b.available? && b.signature == signature[0] }
31
+ raise ArgumentError, "The rule name #{signature[0]} is invalid or not available" if blueprint.nil?
32
+
33
+ blueprint.make(signature[1..].join(':').split(','))
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniDefender::ValidatesInput
4
+ extend ActiveSupport::Concern
5
+
6
+ def validate!(rules, coerced = false)
7
+ data = params.to_unsafe_hash.deep_stringify_keys
8
+ validator = MiniDefender::Validator.new(rules, data)
9
+ validator.validate!
10
+ coerced ? validator.coerced : validator.data
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MiniDefender::ValidationError < StandardError
4
+ attr_reader :errors
5
+
6
+ def initialize(msg, errors = {})
7
+ super(msg)
8
+ @errors = errors
9
+ end
10
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniDefender
4
+ class Validator
5
+ attr_reader :rules, :data, :errors
6
+
7
+ def initialize(rules, data)
8
+ @rules = rules
9
+ @data = data.flatten_keys(keep_roots: true)
10
+ @errors = nil
11
+ @validated = {}
12
+ @coerced = {}
13
+ @expander = RulesExpander.new
14
+ @factory = RulesFactory.new
15
+ end
16
+
17
+ def validate
18
+ return unless @errors.nil?
19
+
20
+ @errors = {}
21
+
22
+ data_rules = @rules.to_h do |k, set|
23
+ [k, @factory.init_set(set)]
24
+ end
25
+
26
+ data_rules.each do |k, set|
27
+ if !@data.key?(k) || @data[k].blank?
28
+ set.filter{ |r| r.defaults?(self) }.each do |r|
29
+ @data.merge!({k => r.default_value(self)}.flatten_keys(keep_roots: true))
30
+ end
31
+ end
32
+ end
33
+
34
+ data_rules = @expander.expand(data_rules, @data)
35
+
36
+ data_rules.each do |k, rule_set|
37
+ @errors[k] = []
38
+
39
+ value_included = true
40
+ required = rule_set.any? { |r| r.implicit?(self) }
41
+
42
+ if !@data.key?(k) || @data[k].blank?
43
+ rule_set.filter{ |r| r.defaults?(self) }.each do |r|
44
+ @data.merge!({k => r.default_value(self)}.flatten_keys(keep_roots: true))
45
+ end
46
+ end
47
+
48
+ unless @data.key?(k)
49
+ @errors[k] << 'The field is missing' if required
50
+ next
51
+ end
52
+
53
+ value = @data[k]
54
+ rule_set.each do |rule|
55
+ next unless rule.active?(self)
56
+
57
+ value_included &= !rule.excluded?(self)
58
+
59
+ unless rule.passes?(k, value, self)
60
+ @errors[k] << rule.message(k, value, self)
61
+ end
62
+ end
63
+
64
+ if @errors[k].empty? && value_included
65
+ @validated[k] = value
66
+ @coerced[k] = rule_set.inject(value) { |coerced, rule| rule.coerce(coerced) }
67
+ end
68
+ end
69
+
70
+ @validated = @validated.expand
71
+ @coerced = @coerced.expand
72
+
73
+ @errors.reject! { |_, v| v.empty? }
74
+ end
75
+
76
+ def validate!
77
+ validate if @errors.nil?
78
+ raise ValidationError.new('Data validation failed', @errors) unless @errors.empty?
79
+ end
80
+
81
+ def passes?
82
+ validate if @errors.nil?
83
+ @errors.empty?
84
+ end
85
+
86
+ def fails?
87
+ !passes?
88
+ end
89
+
90
+ def validated
91
+ validate! if @errors.nil?
92
+ @validated
93
+ end
94
+
95
+ def coerced
96
+ validate! if @errors.nil?
97
+ @coerced
98
+ end
99
+
100
+ # @return [Hash]
101
+ def neighbors(key, level = 1)
102
+ pattern = leveled_search_pattern(key, level)
103
+ @data.filter { |k, _| k.match?(pattern) }
104
+ end
105
+
106
+ # @return [Array]
107
+ def neighbor_values(key, level = 1)
108
+ neighbors(key, level).values
109
+ end
110
+
111
+ private
112
+
113
+ def leveled_search_pattern(key, level = 1)
114
+ search_key = key.split('.').map{ |part| Regexp.quote(part) }.reverse
115
+
116
+ # Change array indexes to digits pattern according to the desired level
117
+ while level > 0
118
+ target_index = search_key.index { |p| p.match?(/\A\d+\z/) }
119
+ break if target_index.nil?
120
+ search_key[target_index] = '\d+'
121
+ level -= 1
122
+ end
123
+
124
+ Regexp.compile("\\A#{search_key.reverse.join('\.')}\\z")
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniDefender
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'mini_defender/version'
4
+ require_relative 'mini_defender/validator'
5
+ require_relative 'mini_defender/rule'
6
+ require_relative 'mini_defender/rules'
7
+ require_relative 'mini_defender/rules_expander'
8
+ require_relative 'mini_defender/rules_factory'
9
+ require_relative 'mini_defender/validation_error'
10
+ require_relative 'mini_defender/validates_input'
11
+
12
+ # Extensions to Ruby Core
13
+ require_relative 'mini_defender/extensions/enumerable'
14
+ require_relative 'mini_defender/extensions/hash'
15
+
16
+ module MiniDefender
17
+ end
18
+
19
+ # Register Library Rules
20
+ MiniDefender::Rules.constants
21
+ .map { |id| MiniDefender::Rules.const_get(id) }
22
+ .filter { |const| const.ancestors.include?(MiniDefender::Rule) }
23
+ .filter { |const| const.available? }
24
+ .each { |klass| MiniDefender::RulesFactory.register(klass) }
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/mini_defender/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "mini_defender"
7
+ spec.version = MiniDefender::VERSION
8
+ spec.authors = ["Ali Alhoshaiyan"]
9
+ spec.email = ["ahoshaiyan@fastmail.com"]
10
+
11
+ spec.summary = "A small and efficient validation library for Rails and anything that uses Ruby."
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://mini.ahoshaiyan.com"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
18
+
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
21
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(__dir__) do
26
+ `git ls-files -z`.split("\x0").reject do |f|
27
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
28
+ end
29
+ end
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_runtime_dependency 'activesupport', '>= 6.0'
35
+ spec.add_runtime_dependency 'activemodel', '>= 6.0'
36
+ spec.add_runtime_dependency 'actionpack', '>= 6.0'
37
+ spec.add_runtime_dependency 'countries'
38
+ end
@@ -0,0 +1,4 @@
1
+ module MiniDefender
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,206 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mini_defender
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ali Alhoshaiyan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-11-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: actionpack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '6.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '6.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: countries
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A small and efficient validation library for Rails and anything that
70
+ uses Ruby.
71
+ email:
72
+ - ahoshaiyan@fastmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - CHANGELOG.md
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE.md
81
+ - LICENSE.txt
82
+ - README.md
83
+ - RULES.md
84
+ - Rakefile
85
+ - lib/mini_defender.rb
86
+ - lib/mini_defender/extensions/enumerable.rb
87
+ - lib/mini_defender/extensions/hash.rb
88
+ - lib/mini_defender/rule.rb
89
+ - lib/mini_defender/rules.rb
90
+ - lib/mini_defender/rules/accepted.rb
91
+ - lib/mini_defender/rules/accepted_if.rb
92
+ - lib/mini_defender/rules/alpha.rb
93
+ - lib/mini_defender/rules/alpha_dash.rb
94
+ - lib/mini_defender/rules/alpha_num.rb
95
+ - lib/mini_defender/rules/array.rb
96
+ - lib/mini_defender/rules/bail.rb
97
+ - lib/mini_defender/rules/between.rb
98
+ - lib/mini_defender/rules/boolean.rb
99
+ - lib/mini_defender/rules/confirmed.rb
100
+ - lib/mini_defender/rules/country_code.rb
101
+ - lib/mini_defender/rules/credit_card.rb
102
+ - lib/mini_defender/rules/date.rb
103
+ - lib/mini_defender/rules/date_eq.rb
104
+ - lib/mini_defender/rules/date_format.rb
105
+ - lib/mini_defender/rules/date_gt.rb
106
+ - lib/mini_defender/rules/date_gte.rb
107
+ - lib/mini_defender/rules/date_lt.rb
108
+ - lib/mini_defender/rules/date_lte.rb
109
+ - lib/mini_defender/rules/declined.rb
110
+ - lib/mini_defender/rules/declined_if.rb
111
+ - lib/mini_defender/rules/default.rb
112
+ - lib/mini_defender/rules/different.rb
113
+ - lib/mini_defender/rules/digits.rb
114
+ - lib/mini_defender/rules/digits_between.rb
115
+ - lib/mini_defender/rules/distinct.rb
116
+ - lib/mini_defender/rules/email.rb
117
+ - lib/mini_defender/rules/ending_with.rb
118
+ - lib/mini_defender/rules/equal.rb
119
+ - lib/mini_defender/rules/excluded.rb
120
+ - lib/mini_defender/rules/excluded_if.rb
121
+ - lib/mini_defender/rules/excluded_unless.rb
122
+ - lib/mini_defender/rules/excluded_with.rb
123
+ - lib/mini_defender/rules/excluded_without.rb
124
+ - lib/mini_defender/rules/exists.rb
125
+ - lib/mini_defender/rules/expiry_date.rb
126
+ - lib/mini_defender/rules/file.rb
127
+ - lib/mini_defender/rules/filled.rb
128
+ - lib/mini_defender/rules/greater_than.rb
129
+ - lib/mini_defender/rules/greater_than_or_equal.rb
130
+ - lib/mini_defender/rules/hash.rb
131
+ - lib/mini_defender/rules/image.rb
132
+ - lib/mini_defender/rules/in.rb
133
+ - lib/mini_defender/rules/in_field.rb
134
+ - lib/mini_defender/rules/integer.rb
135
+ - lib/mini_defender/rules/ip.rb
136
+ - lib/mini_defender/rules/ipv4.rb
137
+ - lib/mini_defender/rules/ipv6.rb
138
+ - lib/mini_defender/rules/json.rb
139
+ - lib/mini_defender/rules/less_than.rb
140
+ - lib/mini_defender/rules/less_than_or_equal.rb
141
+ - lib/mini_defender/rules/luhn.rb
142
+ - lib/mini_defender/rules/mac_address.rb
143
+ - lib/mini_defender/rules/max.rb
144
+ - lib/mini_defender/rules/max_digits.rb
145
+ - lib/mini_defender/rules/mime_types.rb
146
+ - lib/mini_defender/rules/min.rb
147
+ - lib/mini_defender/rules/min_digits.rb
148
+ - lib/mini_defender/rules/national_id.rb
149
+ - lib/mini_defender/rules/not_ending_with.rb
150
+ - lib/mini_defender/rules/not_in.rb
151
+ - lib/mini_defender/rules/not_regex.rb
152
+ - lib/mini_defender/rules/not_starting_with.rb
153
+ - lib/mini_defender/rules/numeric.rb
154
+ - lib/mini_defender/rules/present.rb
155
+ - lib/mini_defender/rules/prohibited.rb
156
+ - lib/mini_defender/rules/prohibited_if.rb
157
+ - lib/mini_defender/rules/prohibited_unless.rb
158
+ - lib/mini_defender/rules/regex.rb
159
+ - lib/mini_defender/rules/required.rb
160
+ - lib/mini_defender/rules/required_if.rb
161
+ - lib/mini_defender/rules/required_unless.rb
162
+ - lib/mini_defender/rules/required_with.rb
163
+ - lib/mini_defender/rules/required_with_all.rb
164
+ - lib/mini_defender/rules/required_without.rb
165
+ - lib/mini_defender/rules/required_without_all.rb
166
+ - lib/mini_defender/rules/size.rb
167
+ - lib/mini_defender/rules/starting_with.rb
168
+ - lib/mini_defender/rules/string.rb
169
+ - lib/mini_defender/rules/timezone.rb
170
+ - lib/mini_defender/rules/unique.rb
171
+ - lib/mini_defender/rules/url.rb
172
+ - lib/mini_defender/rules/uuid.rb
173
+ - lib/mini_defender/rules_expander.rb
174
+ - lib/mini_defender/rules_factory.rb
175
+ - lib/mini_defender/validates_input.rb
176
+ - lib/mini_defender/validation_error.rb
177
+ - lib/mini_defender/validator.rb
178
+ - lib/mini_defender/version.rb
179
+ - mini_defender.gemspec
180
+ - sig/mini_defender.rbs
181
+ homepage: https://mini.ahoshaiyan.com
182
+ licenses:
183
+ - MIT
184
+ metadata:
185
+ homepage_uri: https://mini.ahoshaiyan.com
186
+ post_install_message:
187
+ rdoc_options: []
188
+ require_paths:
189
+ - lib
190
+ required_ruby_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: 2.6.0
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ requirements: []
201
+ rubygems_version: 3.3.7
202
+ signing_key:
203
+ specification_version: 4
204
+ summary: A small and efficient validation library for Rails and anything that uses
205
+ Ruby.
206
+ test_files: []