dry-validation 1.4.0 → 1.5.2
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 +207 -112
- data/LICENSE +1 -1
- data/README.md +9 -10
- data/dry-validation.gemspec +41 -0
- data/lib/dry-validation.rb +1 -1
- data/lib/dry/validation.rb +6 -8
- data/lib/dry/validation/config.rb +2 -2
- data/lib/dry/validation/constants.rb +5 -5
- data/lib/dry/validation/contract.rb +13 -13
- data/lib/dry/validation/contract/class_interface.rb +40 -32
- data/lib/dry/validation/evaluator.rb +21 -7
- data/lib/dry/validation/extensions/hints.rb +1 -3
- data/lib/dry/validation/extensions/monads.rb +1 -1
- data/lib/dry/validation/extensions/predicates_as_macros.rb +3 -3
- data/lib/dry/validation/failures.rb +8 -3
- data/lib/dry/validation/function.rb +2 -2
- data/lib/dry/validation/macro.rb +2 -2
- data/lib/dry/validation/macros.rb +3 -3
- data/lib/dry/validation/message.rb +3 -3
- data/lib/dry/validation/message_set.rb +4 -50
- data/lib/dry/validation/messages/resolver.rb +35 -3
- data/lib/dry/validation/result.rb +21 -5
- data/lib/dry/validation/rule.rb +10 -4
- data/lib/dry/validation/schema_ext.rb +1 -28
- data/lib/dry/validation/values.rb +11 -5
- data/lib/dry/validation/version.rb +1 -1
- metadata +27 -28
data/lib/dry/validation/macro.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/container"
|
4
|
+
require "dry/validation/macro"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Validation
|
@@ -25,7 +25,7 @@ module Dry
|
|
25
25
|
# end
|
26
26
|
#
|
27
27
|
# @param [Symbol] name The name of the macro
|
28
|
-
# @param [Array]
|
28
|
+
# @param [Array] args Optional default positional arguments for the macro
|
29
29
|
#
|
30
30
|
# @return [self]
|
31
31
|
#
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/schema/message_set"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
5
|
+
require "dry/validation/constants"
|
6
|
+
require "dry/validation/message"
|
7
7
|
|
8
8
|
module Dry
|
9
9
|
module Validation
|
@@ -57,7 +57,6 @@ module Dry
|
|
57
57
|
@empty = nil
|
58
58
|
source_messages << message
|
59
59
|
messages << message
|
60
|
-
initialize_placeholders!
|
61
60
|
self
|
62
61
|
end
|
63
62
|
|
@@ -86,58 +85,13 @@ module Dry
|
|
86
85
|
# @api private
|
87
86
|
def freeze
|
88
87
|
source_messages.select { |err| err.respond_to?(:evaluate) }.each do |err|
|
89
|
-
idx = source_messages.index(err)
|
88
|
+
idx = messages.index(err) || source_messages.index(err)
|
90
89
|
msg = err.evaluate(locale: locale, full: options[:full])
|
91
90
|
messages[idx] = msg
|
92
91
|
end
|
93
92
|
to_h
|
94
93
|
self
|
95
94
|
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
# @api private
|
100
|
-
def unique_paths
|
101
|
-
source_messages.uniq(&:path).map(&:path)
|
102
|
-
end
|
103
|
-
|
104
|
-
# @api private
|
105
|
-
def messages_map
|
106
|
-
@messages_map ||= reduce(placeholders) { |hash, msg|
|
107
|
-
node = msg.path.reduce(hash) { |a, e| a.is_a?(Hash) ? a[e] : a.last[e] }
|
108
|
-
(node[0].is_a?(::Array) ? node[0] : node) << msg.dump
|
109
|
-
hash
|
110
|
-
}
|
111
|
-
end
|
112
|
-
|
113
|
-
# @api private
|
114
|
-
#
|
115
|
-
# rubocop:disable Metrics/AbcSize
|
116
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
117
|
-
def initialize_placeholders!
|
118
|
-
@placeholders = unique_paths.sort_by(&:size).each_with_object(EMPTY_HASH.dup) { |path, hash|
|
119
|
-
curr_idx = 0
|
120
|
-
last_idx = path.size - 1
|
121
|
-
node = hash
|
122
|
-
|
123
|
-
while curr_idx <= last_idx
|
124
|
-
key = path[curr_idx]
|
125
|
-
|
126
|
-
next_node =
|
127
|
-
if node.is_a?(Array) && key.is_a?(Symbol)
|
128
|
-
node_hash = (node << [] << {}).last
|
129
|
-
node_hash[key] || (node_hash[key] = curr_idx < last_idx ? {} : [])
|
130
|
-
else
|
131
|
-
node[key] || (node[key] = curr_idx < last_idx ? {} : [])
|
132
|
-
end
|
133
|
-
|
134
|
-
node = next_node
|
135
|
-
curr_idx += 1
|
136
|
-
end
|
137
|
-
}
|
138
|
-
end
|
139
|
-
# rubocop:enable Metrics/AbcSize
|
140
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
141
95
|
end
|
142
96
|
end
|
143
97
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/validation/message"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Validation
|
@@ -33,7 +33,7 @@ module Dry
|
|
33
33
|
when Symbol
|
34
34
|
Message[->(**opts) { message(message, path: path, tokens: tokens, **opts) }, path, meta]
|
35
35
|
when String
|
36
|
-
Message[message, path, meta]
|
36
|
+
Message[->(**opts) { [message_text(message, path, **opts), meta] }, path, meta]
|
37
37
|
when Hash
|
38
38
|
meta = message.dup
|
39
39
|
text = meta.delete(:text) { |key|
|
@@ -51,6 +51,18 @@ module Dry
|
|
51
51
|
end
|
52
52
|
alias_method :[], :call
|
53
53
|
|
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
|
+
|
54
66
|
# Resolve a message
|
55
67
|
#
|
56
68
|
# @return [String]
|
@@ -75,11 +87,31 @@ module Dry
|
|
75
87
|
STR
|
76
88
|
end
|
77
89
|
|
78
|
-
|
90
|
+
parsed_tokens = parse_tokens(tokens)
|
91
|
+
text = template.(template.data(parsed_tokens))
|
79
92
|
|
80
93
|
[full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text, meta]
|
81
94
|
end
|
82
95
|
# rubocop:enable Metrics/AbcSize
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def parse_tokens(tokens)
|
100
|
+
Hash[
|
101
|
+
tokens.map do |key, token|
|
102
|
+
[key, parse_token(token)]
|
103
|
+
end
|
104
|
+
]
|
105
|
+
end
|
106
|
+
|
107
|
+
def parse_token(token)
|
108
|
+
case token
|
109
|
+
when Array
|
110
|
+
token.join(", ")
|
111
|
+
else
|
112
|
+
token
|
113
|
+
end
|
114
|
+
end
|
83
115
|
end
|
84
116
|
end
|
85
117
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "concurrent/map"
|
4
|
+
require "dry/equalizer"
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
6
|
+
require "dry/validation/constants"
|
7
|
+
require "dry/validation/message_set"
|
8
|
+
require "dry/validation/values"
|
9
9
|
|
10
10
|
module Dry
|
11
11
|
module Validation
|
@@ -179,6 +179,22 @@ module Dry
|
|
179
179
|
super
|
180
180
|
end
|
181
181
|
|
182
|
+
if RUBY_VERSION >= "2.7"
|
183
|
+
# Pattern matching
|
184
|
+
#
|
185
|
+
# @api private
|
186
|
+
def deconstruct_keys(keys)
|
187
|
+
values.deconstruct_keys(keys)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Pattern matching
|
191
|
+
#
|
192
|
+
# @api private
|
193
|
+
def deconstruct
|
194
|
+
[values, context.each.to_h]
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
182
198
|
private
|
183
199
|
|
184
200
|
# @api private
|
data/lib/dry/validation/rule.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/equalizer"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
5
|
+
require "dry/validation/constants"
|
6
|
+
require "dry/validation/function"
|
7
7
|
|
8
8
|
module Dry
|
9
9
|
module Validation
|
@@ -118,12 +118,18 @@ module Dry
|
|
118
118
|
args.each_with_object([]) do |spec, macros|
|
119
119
|
case spec
|
120
120
|
when Hash
|
121
|
-
|
121
|
+
add_macro_from_hash(macros, spec)
|
122
122
|
else
|
123
123
|
macros << Array(spec)
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
127
|
+
|
128
|
+
def add_macro_from_hash(macros, spec)
|
129
|
+
spec.each do |k, v|
|
130
|
+
macros << [k, v.is_a?(Array) ? v : [v]]
|
131
|
+
end
|
132
|
+
end
|
127
133
|
end
|
128
134
|
end
|
129
135
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'dry/schema/key_map'
|
3
|
+
require "dry/schema/path"
|
5
4
|
|
6
5
|
module Dry
|
7
6
|
module Schema
|
@@ -16,31 +15,5 @@ module Dry
|
|
16
15
|
to_a[0..-2].product(last).map { |spec| self.class[spec] }
|
17
16
|
end
|
18
17
|
end
|
19
|
-
|
20
|
-
# @api private
|
21
|
-
#
|
22
|
-
# TODO: this should be moved to dry-schema at some point
|
23
|
-
class Key
|
24
|
-
# @api private
|
25
|
-
def to_dot_notation
|
26
|
-
[name.to_s]
|
27
|
-
end
|
28
|
-
|
29
|
-
# @api private
|
30
|
-
class Hash < Key
|
31
|
-
# @api private
|
32
|
-
def to_dot_notation
|
33
|
-
[name].product(members.flat_map(&:to_dot_notation)).map { |e| e.join(DOT) }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# @api private
|
39
|
-
class KeyMap
|
40
|
-
# @api private
|
41
|
-
def to_dot_notation
|
42
|
-
@to_dot_notation ||= map(&:to_dot_notation).flatten
|
43
|
-
end
|
44
|
-
end
|
45
18
|
end
|
46
19
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "dry/equalizer"
|
4
|
+
require "dry/schema/path"
|
5
|
+
require "dry/validation/constants"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Validation
|
@@ -35,7 +35,10 @@ module Dry
|
|
35
35
|
# key.failure('must be > 18') if values[:age] <= 18
|
36
36
|
# end
|
37
37
|
#
|
38
|
-
# @param [Symbol]
|
38
|
+
# @param args [Symbol, String, Hash, Array<Symbol>] If given as a single
|
39
|
+
# Symbol, String, Array or Hash, build a key array using
|
40
|
+
# {Dry::Schema::Path} digging for data. If given as positional
|
41
|
+
# arguments, use these with Hash#dig on the data directly.
|
39
42
|
#
|
40
43
|
# @return [Object]
|
41
44
|
#
|
@@ -53,7 +56,7 @@ module Dry
|
|
53
56
|
vals = self.class.new(data.dig(*keys))
|
54
57
|
vals.fetch_values(*last) { nil }
|
55
58
|
else
|
56
|
-
raise ArgumentError,
|
59
|
+
raise ArgumentError, "+key+ must be a valid path specification"
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
@@ -65,6 +68,8 @@ module Dry
|
|
65
68
|
if e.is_a?(Array)
|
66
69
|
result = e.all? { |k| key?(k, a) }
|
67
70
|
return result
|
71
|
+
elsif e.is_a?(Symbol) && a.is_a?(Array)
|
72
|
+
return false
|
68
73
|
else
|
69
74
|
return false unless a.is_a?(Array) ? (e >= 0 && e < a.size) : a.key?(e)
|
70
75
|
end
|
@@ -89,6 +94,7 @@ module Dry
|
|
89
94
|
super
|
90
95
|
end
|
91
96
|
end
|
97
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
92
98
|
end
|
93
99
|
end
|
94
100
|
end
|
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.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -25,53 +25,53 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: dry-
|
28
|
+
name: dry-container
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.7'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.7.1
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
43
|
+
version: '0.7'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.7.1
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: dry-
|
48
|
+
name: dry-core
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
51
|
- - "~>"
|
46
52
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0.
|
53
|
+
version: '0.4'
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
51
57
|
requirements:
|
52
58
|
- - "~>"
|
53
59
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0.
|
60
|
+
version: '0.4'
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: dry-
|
62
|
+
name: dry-equalizer
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|
58
64
|
requirements:
|
59
65
|
- - "~>"
|
60
66
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
62
|
-
- - ">="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: 0.7.1
|
67
|
+
version: '0.2'
|
65
68
|
type: :runtime
|
66
69
|
prerelease: false
|
67
70
|
version_requirements: !ruby/object:Gem::Requirement
|
68
71
|
requirements:
|
69
72
|
- - "~>"
|
70
73
|
- !ruby/object:Gem::Version
|
71
|
-
version: '0.
|
72
|
-
- - ">="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: 0.7.1
|
74
|
+
version: '0.2'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: dry-initializer
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,20 +92,14 @@ dependencies:
|
|
92
92
|
requirements:
|
93
93
|
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: '1.
|
96
|
-
- - ">="
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version: 1.3.1
|
95
|
+
version: '1.5'
|
99
96
|
type: :runtime
|
100
97
|
prerelease: false
|
101
98
|
version_requirements: !ruby/object:Gem::Requirement
|
102
99
|
requirements:
|
103
100
|
- - "~>"
|
104
101
|
- !ruby/object:Gem::Version
|
105
|
-
version: '1.
|
106
|
-
- - ">="
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: 1.3.1
|
102
|
+
version: '1.5'
|
109
103
|
- !ruby/object:Gem::Dependency
|
110
104
|
name: bundler
|
111
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -148,7 +142,7 @@ dependencies:
|
|
148
142
|
- - ">="
|
149
143
|
- !ruby/object:Gem::Version
|
150
144
|
version: '0'
|
151
|
-
description:
|
145
|
+
description: Validation library
|
152
146
|
email:
|
153
147
|
- piotr.solnica@gmail.com
|
154
148
|
executables: []
|
@@ -159,6 +153,7 @@ files:
|
|
159
153
|
- LICENSE
|
160
154
|
- README.md
|
161
155
|
- config/errors.yml
|
156
|
+
- dry-validation.gemspec
|
162
157
|
- lib/dry-validation.rb
|
163
158
|
- lib/dry/validation.rb
|
164
159
|
- lib/dry/validation/config.rb
|
@@ -184,7 +179,11 @@ files:
|
|
184
179
|
homepage: https://dry-rb.org/gems/dry-validation
|
185
180
|
licenses:
|
186
181
|
- MIT
|
187
|
-
metadata:
|
182
|
+
metadata:
|
183
|
+
allowed_push_host: https://rubygems.org
|
184
|
+
changelog_uri: https://github.com/dry-rb/dry-validation/blob/master/CHANGELOG.md
|
185
|
+
source_code_uri: https://github.com/dry-rb/dry-validation
|
186
|
+
bug_tracker_uri: https://github.com/dry-rb/dry-validation/issues
|
188
187
|
post_install_message:
|
189
188
|
rdoc_options: []
|
190
189
|
require_paths:
|
@@ -193,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
193
192
|
requirements:
|
194
193
|
- - ">="
|
195
194
|
- !ruby/object:Gem::Version
|
196
|
-
version:
|
195
|
+
version: 2.4.0
|
197
196
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
197
|
requirements:
|
199
198
|
- - ">="
|