mini_defender 0.1.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.
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: []