dry-validation 1.5.1 → 1.8.1
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/CHANGELOG.md +116 -3
- data/LICENSE +1 -1
- data/README.md +5 -4
- data/dry-validation.gemspec +16 -16
- data/lib/dry/validation/config.rb +1 -1
- data/lib/dry/validation/contract/class_interface.rb +5 -3
- data/lib/dry/validation/contract.rb +18 -5
- data/lib/dry/validation/evaluator.rb +30 -8
- data/lib/dry/validation/function.rb +1 -2
- data/lib/dry/validation/macro.rb +1 -1
- data/lib/dry/validation/message.rb +3 -1
- data/lib/dry/validation/messages/resolver.rb +31 -20
- data/lib/dry/validation/result.rb +24 -3
- data/lib/dry/validation/rule.rb +9 -6
- data/lib/dry/validation/values.rb +9 -2
- data/lib/dry/validation/version.rb +1 -1
- metadata +23 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1cbb33c9bad218b481c727b04080736ad0d974f47b552ed305de4f50e5bd8d6d
|
|
4
|
+
data.tar.gz: e464d56a10afa52ab975d44d204a0879649007eeb98a1a15038e5c6d29b78b21
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94637a8714ffc4111c0279a7aeb52613fccf894abd33207600131e7af59803371b044691949c9a457c85bbdbb9d063c7c050aa58fc51966e7469b62f97156008
|
|
7
|
+
data.tar.gz: f15fbb334bd99fe79348a750bca344beff68156394c314f1845307a1b5b2462446117a80e47d0d3eb40108e3042de99744c205a7ffc99ef48bebd179a5fa0299
|
data/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,127 @@
|
|
|
1
|
-
|
|
1
|
+
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
|
2
|
+
|
|
3
|
+
## 1.8.1 2022-05-28
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Fixed
|
|
7
|
+
|
|
8
|
+
- Raise an InvalidKeyErrors on substring of valid keys (issue #705 fixed via #706) (@MatElGran)
|
|
9
|
+
- Using `rule(:arr).each { .. }` doesn't crash when `:arr` turns out to be `nil` (issue #708 fixed via #709) (@bautrey37)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
[Compare v1.8.0...v1.8.1](https://github.com/dry-rb/dry-validation/compare/v1.8.0...v1.8.1)
|
|
13
|
+
|
|
14
|
+
## 1.8.0 2022-02-17
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- New rule helper `base_rule_error?` which checks if there's any base error set (via #690) (@wuarmin)
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Dependency on dry-schema was bumped to 1.9.1 (@solnic)
|
|
24
|
+
|
|
25
|
+
[Compare v1.7.0...v1.8.0](https://github.com/dry-rb/dry-validation/compare/v1.7.0...v1.8.0)
|
|
26
|
+
|
|
27
|
+
## 1.7.0 2021-09-12
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- [internal] Upgraded to new `setting` API provided in dry-configurable 0.13.0 (@timriley in #686 and 3f8f7d8)
|
|
33
|
+
- Bumped dry-schema dependency to 1.8.0 (in part, to ensure dry-configurable 0.13.0 is available) (@timriley)
|
|
34
|
+
|
|
35
|
+
[Compare v1.6.0...v1.7.0](https://github.com/dry-rb/dry-validation/compare/v1.6.0...v1.7.0)
|
|
36
|
+
|
|
37
|
+
## 1.6.0 2020-12-05
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- You can now pass a key name or path to `rule_error?` predicate (issue #658 closed via #673) (@moofkit)
|
|
43
|
+
- You can now pass initial context object to `Contract#call` (issue #674 via #675) (@pyromaniac)
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- Checking `key?` within a rule no longer crashes when value is `nil` or an empty string (issue #670 fixed via #672) (@alexxty7)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
[Compare v1.5.6...v1.6.0](https://github.com/dry-rb/dry-validation/compare/v1.5.6...v1.6.0)
|
|
51
|
+
|
|
52
|
+
## 1.5.6 2020-09-04
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- Dependency on dry-schema was bumped to >= 1.5.1. This time for real (@solnic)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
[Compare v1.5.5...v1.5.6](https://github.com/dry-rb/dry-validation/compare/v1.5.5...v1.5.6)
|
|
61
|
+
|
|
62
|
+
## 1.5.5 2020-09-03
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- Dependency on dry-schema was bumped to >= 1.5.2 (see #666 for more info) (@artofhuman)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
[Compare v1.5.4...v1.5.5](https://github.com/dry-rb/dry-validation/compare/v1.5.4...v1.5.5)
|
|
71
|
+
|
|
72
|
+
## 1.5.4 2020-08-21
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- You can now pass any key or a path to the rule's `key?` helper (see #664 for more info) (@alassek)
|
|
78
|
+
|
|
79
|
+
### Fixed
|
|
80
|
+
|
|
81
|
+
- Full messages work correctly with rule failures now (issue #661 fixed via #662) (@stind)
|
|
82
|
+
- Providing a custom message template for array errors works correctly (issue #663 fixed via #665) (@tadeusz-niemiec)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
[Compare v1.5.3...v1.5.4](https://github.com/dry-rb/dry-validation/compare/v1.5.3...v1.5.4)
|
|
86
|
+
|
|
87
|
+
## 1.5.3 2020-07-27
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
|
|
92
|
+
- You can now access current value's index via `rule(:foo).each do |index:|` (issue #606 done via #657) (@mrbongiolo)
|
|
93
|
+
|
|
94
|
+
### Fixed
|
|
95
|
+
|
|
96
|
+
- Using `.each(:foo)` works as expected when there are errors related to other keys (issue #659 fixed via #660) (@solnic)
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- `Result#error?` is now a public API and it takes into consideration both schema and rule errors (issue #655 fixed via #656) (@PragTob)
|
|
101
|
+
|
|
102
|
+
[Compare v1.5.2...v1.5.3](https://github.com/dry-rb/dry-validation/compare/v1.5.2...v1.5.3)
|
|
103
|
+
|
|
104
|
+
## 1.5.2 2020-07-14
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
### Fixed
|
|
108
|
+
|
|
109
|
+
- `key?` predicate in rules no longer crashes when the rule path points to a non-existent array value (issue #653 fixed via #654) (@solnic)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
[Compare v1.5.1...v1.5.2](https://github.com/dry-rb/dry-validation/compare/v1.5.1...v1.5.2)
|
|
113
|
+
|
|
114
|
+
## 1.5.1 2020-06-18
|
|
2
115
|
|
|
3
116
|
|
|
4
117
|
### Fixed
|
|
5
118
|
|
|
6
119
|
- dry-monads no longer required for the `:hints` extension (@schokomarie)
|
|
7
120
|
- Using `full: true` option works as expected with custom rule messages (issue #618 fixed via #651) (@sirfilip)
|
|
8
|
-
- Using `locale: ...` option works as expected with hints (issue #589 fixed via
|
|
121
|
+
- Using `locale: ...` option works as expected with hints (issue #589 fixed via 652) (@sirfilip)
|
|
9
122
|
|
|
10
123
|
|
|
11
|
-
[Compare v1.5.0...
|
|
124
|
+
[Compare v1.5.0...v1.5.1](https://github.com/dry-rb/dry-validation/compare/v1.5.0...v1.5.1)
|
|
12
125
|
|
|
13
126
|
## 1.5.0 2020-03-11
|
|
14
127
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!--- this file is synced from dry-rb/template-gem project -->
|
|
1
2
|
[gem]: https://rubygems.org/gems/dry-validation
|
|
2
3
|
[actions]: https://github.com/dry-rb/dry-validation/actions
|
|
3
4
|
[codacy]: https://www.codacy.com/gh/dry-rb/dry-validation
|
|
@@ -10,19 +11,19 @@
|
|
|
10
11
|
[][actions]
|
|
11
12
|
[][codacy]
|
|
12
13
|
[][codacy]
|
|
13
|
-
[][inchpages]
|
|
14
15
|
|
|
15
16
|
## Links
|
|
16
17
|
|
|
17
|
-
* [User documentation](
|
|
18
|
+
* [User documentation](https://dry-rb.org/gems/dry-validation)
|
|
18
19
|
* [API documentation](http://rubydoc.info/gems/dry-validation)
|
|
19
20
|
|
|
20
21
|
## Supported Ruby versions
|
|
21
22
|
|
|
22
23
|
This library officially supports the following Ruby versions:
|
|
23
24
|
|
|
24
|
-
* MRI
|
|
25
|
-
* jruby
|
|
25
|
+
* MRI `>= 2.7.0`
|
|
26
|
+
* jruby `>= 9.3` (postponed until 2.7 is supported)
|
|
26
27
|
|
|
27
28
|
## License
|
|
28
29
|
|
data/dry-validation.gemspec
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# this file is managed by dry-rb/devtools project
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
# this file is synced from dry-rb/template-gem project
|
|
4
|
+
|
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
|
5
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
|
-
require
|
|
7
|
+
require "dry/validation/version"
|
|
7
8
|
|
|
8
9
|
Gem::Specification.new do |spec|
|
|
9
|
-
spec.name =
|
|
10
|
+
spec.name = "dry-validation"
|
|
10
11
|
spec.authors = ["Piotr Solnica"]
|
|
11
12
|
spec.email = ["piotr.solnica@gmail.com"]
|
|
12
|
-
spec.license =
|
|
13
|
+
spec.license = "MIT"
|
|
13
14
|
spec.version = Dry::Validation::VERSION.dup
|
|
14
15
|
|
|
15
16
|
spec.summary = "Validation library"
|
|
16
17
|
spec.description = spec.summary
|
|
17
|
-
spec.homepage =
|
|
18
|
+
spec.homepage = "https://dry-rb.org/gems/dry-validation"
|
|
18
19
|
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-validation.gemspec", "lib/**/*", "config/*.yml"]
|
|
19
|
-
spec.bindir =
|
|
20
|
+
spec.bindir = "bin"
|
|
20
21
|
spec.executables = []
|
|
21
|
-
spec.require_paths = [
|
|
22
|
+
spec.require_paths = ["lib"]
|
|
22
23
|
|
|
23
|
-
spec.metadata[
|
|
24
|
-
spec.metadata[
|
|
25
|
-
spec.metadata[
|
|
26
|
-
spec.metadata[
|
|
24
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
25
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-validation/blob/main/CHANGELOG.md"
|
|
26
|
+
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-validation"
|
|
27
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-validation/issues"
|
|
27
28
|
|
|
28
|
-
spec.required_ruby_version = ">= 2.
|
|
29
|
+
spec.required_ruby_version = ">= 2.7.0"
|
|
29
30
|
|
|
30
31
|
# to update dependencies edit project.yml
|
|
31
32
|
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
|
32
33
|
spec.add_runtime_dependency "dry-container", "~> 0.7", ">= 0.7.1"
|
|
33
|
-
spec.add_runtime_dependency "dry-core", "~> 0.
|
|
34
|
-
spec.add_runtime_dependency "dry-equalizer", "~> 0.2"
|
|
34
|
+
spec.add_runtime_dependency "dry-core", "~> 0.5", ">= 0.5"
|
|
35
35
|
spec.add_runtime_dependency "dry-initializer", "~> 3.0"
|
|
36
|
-
spec.add_runtime_dependency "dry-schema", "~> 1.
|
|
36
|
+
spec.add_runtime_dependency "dry-schema", "~> 1.8", ">= 1.8.0"
|
|
37
37
|
|
|
38
38
|
spec.add_development_dependency "bundler"
|
|
39
39
|
spec.add_development_dependency "rake"
|
|
@@ -158,11 +158,13 @@ module Dry
|
|
|
158
158
|
valid_paths = key_map.to_dot_notation
|
|
159
159
|
key_paths = key_paths(keys)
|
|
160
160
|
|
|
161
|
-
invalid_keys = key_paths.
|
|
162
|
-
|
|
161
|
+
invalid_keys = key_paths.filter_map { |(key, path)|
|
|
162
|
+
if valid_paths.none? { |vp|
|
|
163
|
+
vp == path || vp.start_with?("#{path}.", "#{path}[]")
|
|
164
|
+
}
|
|
163
165
|
key
|
|
164
166
|
end
|
|
165
|
-
}.
|
|
167
|
+
}.uniq
|
|
166
168
|
|
|
167
169
|
return if invalid_keys.empty?
|
|
168
170
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "concurrent/map"
|
|
4
4
|
|
|
5
|
-
require "dry/equalizer"
|
|
5
|
+
require "dry/core/equalizer"
|
|
6
6
|
require "dry/initializer"
|
|
7
7
|
require "dry/schema/path"
|
|
8
8
|
|
|
@@ -68,6 +68,11 @@ module Dry
|
|
|
68
68
|
# @api public
|
|
69
69
|
option :macros, default: -> { config.macros }
|
|
70
70
|
|
|
71
|
+
# @!attribute [r] default_context
|
|
72
|
+
# @return [Hash] Default context for rules
|
|
73
|
+
# @api public
|
|
74
|
+
option :default_context, default: -> { EMPTY_HASH }
|
|
75
|
+
|
|
71
76
|
# @!attribute [r] schema
|
|
72
77
|
# @return [Dry::Schema::Params, Dry::Schema::JSON, Dry::Schema::Processor]
|
|
73
78
|
# @api private
|
|
@@ -86,12 +91,19 @@ module Dry
|
|
|
86
91
|
# Apply the contract to an input
|
|
87
92
|
#
|
|
88
93
|
# @param [Hash] input The input to validate
|
|
94
|
+
# @param [Hash] context Initial context for rules
|
|
89
95
|
#
|
|
90
96
|
# @return [Result]
|
|
91
97
|
#
|
|
92
98
|
# @api public
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
# rubocop: disable Metrics/AbcSize
|
|
100
|
+
def call(input, context = EMPTY_HASH)
|
|
101
|
+
context_map = Concurrent::Map.new.tap do |map|
|
|
102
|
+
default_context.each { |key, value| map[key] = value }
|
|
103
|
+
context.each { |key, value| map[key] = value }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
Result.new(schema.(input), context_map) do |result|
|
|
95
107
|
rules.each do |rule|
|
|
96
108
|
next if rule.keys.any? { |key| error?(result, key) }
|
|
97
109
|
|
|
@@ -103,6 +115,7 @@ module Dry
|
|
|
103
115
|
end
|
|
104
116
|
end
|
|
105
117
|
end
|
|
118
|
+
# rubocop: enable Metrics/AbcSize
|
|
106
119
|
|
|
107
120
|
# Return a nice string representation
|
|
108
121
|
#
|
|
@@ -123,14 +136,14 @@ module Dry
|
|
|
123
136
|
return path.expand.any? { |nested_path| error?(result, nested_path) }
|
|
124
137
|
end
|
|
125
138
|
|
|
126
|
-
return true if result.
|
|
139
|
+
return true if result.schema_error?(path)
|
|
127
140
|
|
|
128
141
|
path
|
|
129
142
|
.to_a[0..-2]
|
|
130
143
|
.any? { |key|
|
|
131
144
|
curr_path = Schema::Path[path.keys[0..path.keys.index(key)]]
|
|
132
145
|
|
|
133
|
-
return false unless result.
|
|
146
|
+
return false unless result.schema_error?(curr_path)
|
|
134
147
|
|
|
135
148
|
result.errors.any? { |err|
|
|
136
149
|
(other = Schema::Path[err.path]).same_root?(curr_path) && other == curr_path
|
|
@@ -17,7 +17,7 @@ module Dry
|
|
|
17
17
|
# @api public
|
|
18
18
|
class Evaluator
|
|
19
19
|
extend Dry::Initializer
|
|
20
|
-
extend Dry::Core::Deprecations[:
|
|
20
|
+
extend Dry::Core::Deprecations[:"dry-validation"]
|
|
21
21
|
|
|
22
22
|
deprecate :error?, :schema_error?
|
|
23
23
|
|
|
@@ -73,7 +73,7 @@ module Dry
|
|
|
73
73
|
@_options = options
|
|
74
74
|
|
|
75
75
|
if block
|
|
76
|
-
exec_opts = block_options.
|
|
76
|
+
exec_opts = block_options.transform_values { _options[_1] }
|
|
77
77
|
instance_exec(**exec_opts, &block)
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -155,16 +155,23 @@ module Dry
|
|
|
155
155
|
#
|
|
156
156
|
# This is useful when dealing with rules for optional keys
|
|
157
157
|
#
|
|
158
|
-
# @example
|
|
158
|
+
# @example use the default key name
|
|
159
159
|
# rule(:age) do
|
|
160
160
|
# key.failure(:invalid) if key? && value < 18
|
|
161
161
|
# end
|
|
162
162
|
#
|
|
163
|
+
# @example specify the key name
|
|
164
|
+
# rule(:start_date, :end_date) do
|
|
165
|
+
# if key?(:start_date) && !key?(:end_date)
|
|
166
|
+
# key(:end_date).failure("must provide an end_date with start_date")
|
|
167
|
+
# end
|
|
168
|
+
# end
|
|
169
|
+
#
|
|
163
170
|
# @return [Boolean]
|
|
164
171
|
#
|
|
165
172
|
# @api public
|
|
166
|
-
def key?
|
|
167
|
-
values.key?(
|
|
173
|
+
def key?(name = key_name)
|
|
174
|
+
values.key?(name)
|
|
168
175
|
end
|
|
169
176
|
|
|
170
177
|
# Check if there are any errors on the schema under the provided path
|
|
@@ -175,16 +182,31 @@ module Dry
|
|
|
175
182
|
#
|
|
176
183
|
# @api public
|
|
177
184
|
def schema_error?(path)
|
|
178
|
-
result.
|
|
185
|
+
result.schema_error?(path)
|
|
179
186
|
end
|
|
180
187
|
|
|
181
188
|
# Check if there are any errors on the current rule
|
|
182
189
|
#
|
|
190
|
+
# @param path [Symbol, String, Array] A Path-compatible spec
|
|
191
|
+
#
|
|
192
|
+
# @return [Boolean]
|
|
193
|
+
#
|
|
194
|
+
# @api public
|
|
195
|
+
def rule_error?(path = nil)
|
|
196
|
+
if path.nil?
|
|
197
|
+
!key(self.path).empty?
|
|
198
|
+
else
|
|
199
|
+
result.rule_error?(path)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Check if there are any base rule errors
|
|
204
|
+
#
|
|
183
205
|
# @return [Boolean]
|
|
184
206
|
#
|
|
185
207
|
# @api public
|
|
186
|
-
def
|
|
187
|
-
!
|
|
208
|
+
def base_rule_error?
|
|
209
|
+
!base.empty? || result.base_rule_error?
|
|
188
210
|
end
|
|
189
211
|
|
|
190
212
|
# @api private
|
data/lib/dry/validation/macro.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "dry/equalizer"
|
|
3
|
+
require "dry/core/equalizer"
|
|
4
4
|
|
|
5
5
|
require "dry/schema/constants"
|
|
6
6
|
require "dry/schema/message"
|
|
@@ -70,11 +70,13 @@ module Dry
|
|
|
70
70
|
# Initialize a new error object
|
|
71
71
|
#
|
|
72
72
|
# @api private
|
|
73
|
+
# rubocop: disable Lint/MissingSuper
|
|
73
74
|
def initialize(text, path:, meta: EMPTY_HASH)
|
|
74
75
|
@text = text
|
|
75
76
|
@path = Array(path)
|
|
76
77
|
@meta = meta
|
|
77
78
|
end
|
|
79
|
+
# rubocop: enable Lint/MissingSuper
|
|
78
80
|
|
|
79
81
|
# Check if this is a base error not associated with any key
|
|
80
82
|
#
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "dry/validation/message"
|
|
4
|
+
require "dry/schema/message_compiler"
|
|
4
5
|
|
|
5
6
|
module Dry
|
|
6
7
|
module Validation
|
|
7
8
|
module Messages
|
|
9
|
+
FULL_MESSAGE_WHITESPACE = Dry::Schema::MessageCompiler::FULL_MESSAGE_WHITESPACE
|
|
10
|
+
|
|
8
11
|
# Resolve translated messages from failure arguments
|
|
9
12
|
#
|
|
10
13
|
# @api public
|
|
@@ -33,7 +36,7 @@ module Dry
|
|
|
33
36
|
when Symbol
|
|
34
37
|
Message[->(**opts) { message(message, path: path, tokens: tokens, **opts) }, path, meta]
|
|
35
38
|
when String
|
|
36
|
-
Message[->(**opts) { [message_text(message, path, **opts), meta] }, path, meta]
|
|
39
|
+
Message[->(**opts) { [message_text(message, path: path, **opts), meta] }, path, meta]
|
|
37
40
|
when Hash
|
|
38
41
|
meta = message.dup
|
|
39
42
|
text = meta.delete(:text) { |key|
|
|
@@ -51,18 +54,6 @@ module Dry
|
|
|
51
54
|
end
|
|
52
55
|
alias_method :[], :call
|
|
53
56
|
|
|
54
|
-
# Resolve a message
|
|
55
|
-
#
|
|
56
|
-
# @return String
|
|
57
|
-
#
|
|
58
|
-
# @api public
|
|
59
|
-
def message_text(message, path, locale: nil, full: false, **opts)
|
|
60
|
-
keys = path.to_a.compact
|
|
61
|
-
msg_opts = EMPTY_HASH.merge(path: keys, locale: locale || messages.default_locale)
|
|
62
|
-
|
|
63
|
-
full ? "#{messages.rule(keys.last, msg_opts) || keys.last} #{message}" : message
|
|
64
|
-
end
|
|
65
|
-
|
|
66
57
|
# Resolve a message
|
|
67
58
|
#
|
|
68
59
|
# @return [String]
|
|
@@ -70,7 +61,8 @@ module Dry
|
|
|
70
61
|
# @api public
|
|
71
62
|
#
|
|
72
63
|
# rubocop:disable Metrics/AbcSize
|
|
73
|
-
|
|
64
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
65
|
+
def message(rule, path:, tokens: EMPTY_HASH, locale: nil, full: false)
|
|
74
66
|
keys = path.to_a.compact
|
|
75
67
|
msg_opts = tokens.merge(path: keys, locale: locale || messages.default_locale)
|
|
76
68
|
|
|
@@ -81,6 +73,11 @@ module Dry
|
|
|
81
73
|
template, meta = messages[rule, msg_opts.merge(path: keys.last)] unless template
|
|
82
74
|
end
|
|
83
75
|
|
|
76
|
+
if !template && keys.size > 1
|
|
77
|
+
non_index_keys = keys.reject { |k| k.is_a?(Integer) }
|
|
78
|
+
template, meta = messages[rule, msg_opts.merge(path: non_index_keys.join(DOT))]
|
|
79
|
+
end
|
|
80
|
+
|
|
84
81
|
unless template
|
|
85
82
|
raise MissingMessageError, <<~STR
|
|
86
83
|
Message template for #{rule.inspect} under #{keys.join(DOT).inspect} was not found
|
|
@@ -90,18 +87,32 @@ module Dry
|
|
|
90
87
|
parsed_tokens = parse_tokens(tokens)
|
|
91
88
|
text = template.(template.data(parsed_tokens))
|
|
92
89
|
|
|
93
|
-
[
|
|
90
|
+
[message_text(text, path: path, locale: locale, full: full), meta]
|
|
94
91
|
end
|
|
92
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
95
93
|
# rubocop:enable Metrics/AbcSize
|
|
96
94
|
|
|
97
95
|
private
|
|
98
96
|
|
|
97
|
+
def message_text(text, path:, locale: nil, full: false)
|
|
98
|
+
return text unless full
|
|
99
|
+
|
|
100
|
+
key = key_text(path: path, locale: locale)
|
|
101
|
+
|
|
102
|
+
[key, text].compact.join(FULL_MESSAGE_WHITESPACE[locale])
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def key_text(path:, locale: nil)
|
|
106
|
+
locale ||= messages.default_locale
|
|
107
|
+
|
|
108
|
+
keys = path.to_a.compact
|
|
109
|
+
msg_opts = {path: keys, locale: locale}
|
|
110
|
+
|
|
111
|
+
messages.rule(keys.last, msg_opts) || keys.last
|
|
112
|
+
end
|
|
113
|
+
|
|
99
114
|
def parse_tokens(tokens)
|
|
100
|
-
|
|
101
|
-
tokens.map do |key, token|
|
|
102
|
-
[key, parse_token(token)]
|
|
103
|
-
end
|
|
104
|
-
]
|
|
115
|
+
tokens.transform_values { parse_token(_1) }
|
|
105
116
|
end
|
|
106
117
|
|
|
107
118
|
def parse_token(token)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "concurrent/map"
|
|
4
|
-
require "dry/equalizer"
|
|
4
|
+
require "dry/core/equalizer"
|
|
5
5
|
|
|
6
6
|
require "dry/validation/constants"
|
|
7
7
|
require "dry/validation/message_set"
|
|
@@ -101,11 +101,32 @@ module Dry
|
|
|
101
101
|
|
|
102
102
|
# Check if values include an error for the provided key
|
|
103
103
|
#
|
|
104
|
-
# @api
|
|
104
|
+
# @api public
|
|
105
105
|
def error?(key)
|
|
106
|
+
errors.any? { |msg| Schema::Path[msg.path].include?(Schema::Path[key]) }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Check if the base schema (without rules) includes an error for the provided key
|
|
110
|
+
#
|
|
111
|
+
# @api private
|
|
112
|
+
def schema_error?(key)
|
|
106
113
|
schema_result.error?(key)
|
|
107
114
|
end
|
|
108
115
|
|
|
116
|
+
# Check if the rules includes an error for the provided key
|
|
117
|
+
#
|
|
118
|
+
# @api private
|
|
119
|
+
def rule_error?(key)
|
|
120
|
+
!schema_error?(key) && error?(key)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Check if the result contains any base rule errors
|
|
124
|
+
#
|
|
125
|
+
# @api private
|
|
126
|
+
def base_rule_error?
|
|
127
|
+
!errors.filter(:base?).empty?
|
|
128
|
+
end
|
|
129
|
+
|
|
109
130
|
# Check if there's any error for the provided key
|
|
110
131
|
#
|
|
111
132
|
# This does not consider errors from the nested values
|
|
@@ -116,7 +137,7 @@ module Dry
|
|
|
116
137
|
key_path = Schema::Path[key]
|
|
117
138
|
err_path = Schema::Path[error.path]
|
|
118
139
|
|
|
119
|
-
|
|
140
|
+
next unless key_path.same_root?(err_path)
|
|
120
141
|
|
|
121
142
|
key_path == err_path
|
|
122
143
|
}
|
data/lib/dry/validation/rule.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "dry/equalizer"
|
|
3
|
+
require "dry/core/equalizer"
|
|
4
4
|
|
|
5
5
|
require "dry/validation/constants"
|
|
6
6
|
require "dry/validation/function"
|
|
@@ -65,8 +65,8 @@ module Dry
|
|
|
65
65
|
# for a given array item.
|
|
66
66
|
#
|
|
67
67
|
# @example
|
|
68
|
-
# rule(:nums).each do
|
|
69
|
-
# key.failure("must be greater than 0") if value < 0
|
|
68
|
+
# rule(:nums).each do |index:|
|
|
69
|
+
# key([:number, index]).failure("must be greater than 0") if value < 0
|
|
70
70
|
# end
|
|
71
71
|
# rule(:nums).each(min: 3)
|
|
72
72
|
# rule(address: :city) do
|
|
@@ -76,19 +76,21 @@ module Dry
|
|
|
76
76
|
# @return [Rule]
|
|
77
77
|
#
|
|
78
78
|
# @api public
|
|
79
|
+
#
|
|
80
|
+
# rubocop:disable Metrics/AbcSize
|
|
79
81
|
def each(*macros, &block)
|
|
80
82
|
root = keys[0]
|
|
81
83
|
macros = parse_macros(*macros)
|
|
82
84
|
@keys = []
|
|
83
85
|
|
|
84
86
|
@block = proc do
|
|
85
|
-
unless result.base_error?(root) || !values.key?(root)
|
|
87
|
+
unless result.base_error?(root) || !values.key?(root) || values[root].nil?
|
|
86
88
|
values[root].each_with_index do |_, idx|
|
|
87
89
|
path = [*Schema::Path[root].to_a, idx]
|
|
88
90
|
|
|
89
|
-
next if result.
|
|
91
|
+
next if result.schema_error?(path)
|
|
90
92
|
|
|
91
|
-
evaluator = with(macros: macros, keys: [path], &block)
|
|
93
|
+
evaluator = with(macros: macros, keys: [path], index: idx, &block)
|
|
92
94
|
|
|
93
95
|
failures.concat(evaluator.failures)
|
|
94
96
|
end
|
|
@@ -99,6 +101,7 @@ module Dry
|
|
|
99
101
|
|
|
100
102
|
self
|
|
101
103
|
end
|
|
104
|
+
# rubocop:enable Metrics/AbcSize
|
|
102
105
|
|
|
103
106
|
# Return a nice string representation
|
|
104
107
|
#
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "dry/equalizer"
|
|
3
|
+
require "dry/core/equalizer"
|
|
4
4
|
require "dry/schema/path"
|
|
5
5
|
require "dry/validation/constants"
|
|
6
6
|
|
|
@@ -61,6 +61,7 @@ module Dry
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# @api public
|
|
64
|
+
# rubocop: disable Metrics/PerceivedComplexity
|
|
64
65
|
def key?(key, hash = data)
|
|
65
66
|
return hash.key?(key) if key.is_a?(Symbol)
|
|
66
67
|
|
|
@@ -68,14 +69,20 @@ module Dry
|
|
|
68
69
|
if e.is_a?(Array)
|
|
69
70
|
result = e.all? { |k| key?(k, a) }
|
|
70
71
|
return result
|
|
72
|
+
elsif e.is_a?(Symbol) && a.is_a?(Array)
|
|
73
|
+
return false
|
|
74
|
+
elsif a.nil?
|
|
75
|
+
return false
|
|
76
|
+
elsif a.is_a?(String)
|
|
77
|
+
return false
|
|
71
78
|
else
|
|
72
79
|
return false unless a.is_a?(Array) ? (e >= 0 && e < a.size) : a.key?(e)
|
|
73
80
|
end
|
|
74
81
|
a[e]
|
|
75
82
|
end
|
|
76
|
-
|
|
77
83
|
true
|
|
78
84
|
end
|
|
85
|
+
# rubocop: enable Metrics/PerceivedComplexity
|
|
79
86
|
|
|
80
87
|
# @api private
|
|
81
88
|
def respond_to_missing?(meth, include_private = false)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dry-validation
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Piotr Solnica
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-05-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -50,28 +50,20 @@ dependencies:
|
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '0.
|
|
54
|
-
|
|
55
|
-
prerelease: false
|
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - "~>"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '0.4'
|
|
61
|
-
- !ruby/object:Gem::Dependency
|
|
62
|
-
name: dry-equalizer
|
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - "~>"
|
|
53
|
+
version: '0.5'
|
|
54
|
+
- - ">="
|
|
66
55
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '0.
|
|
56
|
+
version: '0.5'
|
|
68
57
|
type: :runtime
|
|
69
58
|
prerelease: false
|
|
70
59
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
60
|
requirements:
|
|
72
61
|
- - "~>"
|
|
73
62
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0.
|
|
63
|
+
version: '0.5'
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '0.5'
|
|
75
67
|
- !ruby/object:Gem::Dependency
|
|
76
68
|
name: dry-initializer
|
|
77
69
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -92,14 +84,20 @@ dependencies:
|
|
|
92
84
|
requirements:
|
|
93
85
|
- - "~>"
|
|
94
86
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: '1.
|
|
87
|
+
version: '1.8'
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: 1.8.0
|
|
96
91
|
type: :runtime
|
|
97
92
|
prerelease: false
|
|
98
93
|
version_requirements: !ruby/object:Gem::Requirement
|
|
99
94
|
requirements:
|
|
100
95
|
- - "~>"
|
|
101
96
|
- !ruby/object:Gem::Version
|
|
102
|
-
version: '1.
|
|
97
|
+
version: '1.8'
|
|
98
|
+
- - ">="
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: 1.8.0
|
|
103
101
|
- !ruby/object:Gem::Dependency
|
|
104
102
|
name: bundler
|
|
105
103
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -181,10 +179,10 @@ licenses:
|
|
|
181
179
|
- MIT
|
|
182
180
|
metadata:
|
|
183
181
|
allowed_push_host: https://rubygems.org
|
|
184
|
-
changelog_uri: https://github.com/dry-rb/dry-validation/blob/
|
|
182
|
+
changelog_uri: https://github.com/dry-rb/dry-validation/blob/main/CHANGELOG.md
|
|
185
183
|
source_code_uri: https://github.com/dry-rb/dry-validation
|
|
186
184
|
bug_tracker_uri: https://github.com/dry-rb/dry-validation/issues
|
|
187
|
-
post_install_message:
|
|
185
|
+
post_install_message:
|
|
188
186
|
rdoc_options: []
|
|
189
187
|
require_paths:
|
|
190
188
|
- lib
|
|
@@ -192,15 +190,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
192
190
|
requirements:
|
|
193
191
|
- - ">="
|
|
194
192
|
- !ruby/object:Gem::Version
|
|
195
|
-
version: 2.
|
|
193
|
+
version: 2.7.0
|
|
196
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
195
|
requirements:
|
|
198
196
|
- - ">="
|
|
199
197
|
- !ruby/object:Gem::Version
|
|
200
198
|
version: '0'
|
|
201
199
|
requirements: []
|
|
202
|
-
rubygems_version: 3.
|
|
203
|
-
signing_key:
|
|
200
|
+
rubygems_version: 3.2.32
|
|
201
|
+
signing_key:
|
|
204
202
|
specification_version: 4
|
|
205
203
|
summary: Validation library
|
|
206
204
|
test_files: []
|