dry-validation 1.3.1 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +378 -164
- data/LICENSE +1 -1
- data/README.md +10 -10
- data/dry-validation.gemspec +41 -0
- data/lib/dry/validation/config.rb +3 -3
- data/lib/dry/validation/constants.rb +5 -5
- data/lib/dry/validation/contract/class_interface.rb +55 -46
- data/lib/dry/validation/contract.rb +29 -16
- data/lib/dry/validation/evaluator.rb +53 -17
- 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 +15 -3
- data/lib/dry/validation/function.rb +3 -4
- data/lib/dry/validation/macro.rb +3 -3
- data/lib/dry/validation/macros.rb +3 -3
- data/lib/dry/validation/message.rb +6 -4
- data/lib/dry/validation/message_set.rb +6 -51
- data/lib/dry/validation/messages/resolver.rb +56 -6
- data/lib/dry/validation/result.rb +44 -7
- data/lib/dry/validation/rule.rb +18 -9
- data/lib/dry/validation/schema_ext.rb +1 -28
- data/lib/dry/validation/values.rb +17 -6
- data/lib/dry/validation/version.rb +1 -1
- data/lib/dry/validation.rb +6 -8
- data/lib/dry-validation.rb +1 -1
- metadata +31 -34
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
+
<!--- this file is synced from dry-rb/template-gem project -->
|
1
2
|
[gem]: https://rubygems.org/gems/dry-validation
|
2
|
-
[
|
3
|
-
[
|
3
|
+
[actions]: https://github.com/dry-rb/dry-validation/actions
|
4
|
+
[codacy]: https://www.codacy.com/gh/dry-rb/dry-validation
|
4
5
|
[chat]: https://dry-rb.zulipchat.com
|
5
6
|
[inchpages]: http://inch-ci.org/github/dry-rb/dry-validation
|
6
7
|
|
7
8
|
# dry-validation [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
|
8
9
|
|
9
10
|
[![Gem Version](https://badge.fury.io/rb/dry-validation.svg)][gem]
|
10
|
-
[![
|
11
|
-
[![
|
12
|
-
[![
|
13
|
-
[![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=
|
11
|
+
[![CI Status](https://github.com/dry-rb/dry-validation/workflows/ci/badge.svg)][actions]
|
12
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
|
13
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
|
14
|
+
[![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=main)][inchpages]
|
14
15
|
|
15
16
|
## Links
|
16
17
|
|
17
18
|
* [User documentation](https://dry-rb.org/gems/dry-validation)
|
18
19
|
* [API documentation](http://rubydoc.info/gems/dry-validation)
|
19
|
-
* [Guidelines for contributing](CONTRIBUTING.md)
|
20
20
|
|
21
21
|
## Supported Ruby versions
|
22
22
|
|
23
|
-
This library officially supports following Ruby versions:
|
23
|
+
This library officially supports the following Ruby versions:
|
24
24
|
|
25
|
-
* MRI
|
26
|
-
* jruby
|
25
|
+
* MRI `>= 2.7.0`
|
26
|
+
* jruby `>= 9.3` (postponed until 2.7 is supported)
|
27
27
|
|
28
28
|
## License
|
29
29
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# this file is synced from dry-rb/template-gem project
|
4
|
+
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
6
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
7
|
+
require "dry/validation/version"
|
8
|
+
|
9
|
+
Gem::Specification.new do |spec|
|
10
|
+
spec.name = "dry-validation"
|
11
|
+
spec.authors = ["Piotr Solnica"]
|
12
|
+
spec.email = ["piotr.solnica@gmail.com"]
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.version = Dry::Validation::VERSION.dup
|
15
|
+
|
16
|
+
spec.summary = "Validation library"
|
17
|
+
spec.description = spec.summary
|
18
|
+
spec.homepage = "https://dry-rb.org/gems/dry-validation"
|
19
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-validation.gemspec", "lib/**/*", "config/*.yml"]
|
20
|
+
spec.bindir = "bin"
|
21
|
+
spec.executables = []
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
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"
|
28
|
+
|
29
|
+
spec.required_ruby_version = ">= 2.7.0"
|
30
|
+
|
31
|
+
# to update dependencies edit project.yml
|
32
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
33
|
+
spec.add_runtime_dependency "dry-container", "~> 0.7", ">= 0.7.1"
|
34
|
+
spec.add_runtime_dependency "dry-core", "~> 0.5", ">= 0.5"
|
35
|
+
spec.add_runtime_dependency "dry-initializer", "~> 3.0"
|
36
|
+
spec.add_runtime_dependency "dry-schema", "~> 1.8", ">= 1.8.0"
|
37
|
+
|
38
|
+
spec.add_development_dependency "bundler"
|
39
|
+
spec.add_development_dependency "rake"
|
40
|
+
spec.add_development_dependency "rspec"
|
41
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/schema/config"
|
4
|
+
require "dry/validation/macros"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Validation
|
@@ -11,7 +11,7 @@ module Dry
|
|
11
11
|
#
|
12
12
|
# @api public
|
13
13
|
class Config < Schema::Config
|
14
|
-
setting :macros, Macros::Container.new,
|
14
|
+
setting :macros, default: Macros::Container.new, constructor: :dup.to_proc
|
15
15
|
|
16
16
|
# @api private
|
17
17
|
def dup
|
@@ -1,22 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "pathname"
|
4
|
+
require "dry/core/constants"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Validation
|
8
8
|
include Dry::Core::Constants
|
9
9
|
|
10
|
-
DOT =
|
10
|
+
DOT = "."
|
11
11
|
|
12
12
|
# Root path is used for base errors in hash representation of error messages
|
13
13
|
ROOT_PATH = [nil].freeze
|
14
14
|
|
15
15
|
# Path to the default errors locale file
|
16
|
-
DEFAULT_ERRORS_NAMESPACE =
|
16
|
+
DEFAULT_ERRORS_NAMESPACE = "dry_validation"
|
17
17
|
|
18
18
|
# Path to the default errors locale file
|
19
|
-
DEFAULT_ERRORS_PATH = Pathname(__FILE__).join(
|
19
|
+
DEFAULT_ERRORS_PATH = Pathname(__FILE__).join("../../../../config/errors.yml").realpath.freeze
|
20
20
|
|
21
21
|
# Mapping for block kwarg options used by block_options
|
22
22
|
#
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "dry/schema"
|
4
|
+
require "dry/schema/messages"
|
5
|
+
require "dry/schema/path"
|
6
|
+
require "dry/schema/key_map"
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
8
|
+
require "dry/validation/constants"
|
9
|
+
require "dry/validation/macros"
|
10
|
+
require "dry/validation/schema_ext"
|
11
11
|
|
12
12
|
module Dry
|
13
13
|
module Validation
|
@@ -23,7 +23,7 @@ module Dry
|
|
23
23
|
# @api private
|
24
24
|
def inherited(klass)
|
25
25
|
super
|
26
|
-
klass.instance_variable_set(
|
26
|
+
klass.instance_variable_set("@config", config.dup)
|
27
27
|
end
|
28
28
|
|
29
29
|
# Configuration
|
@@ -57,8 +57,8 @@ module Dry
|
|
57
57
|
# @see https://dry-rb.org/gems/dry-schema/params/
|
58
58
|
#
|
59
59
|
# @api public
|
60
|
-
def params(
|
61
|
-
define(:Params,
|
60
|
+
def params(*external_schemas, &block)
|
61
|
+
define(:Params, external_schemas, &block)
|
62
62
|
end
|
63
63
|
|
64
64
|
# Define a JSON schema for your contract
|
@@ -69,8 +69,8 @@ module Dry
|
|
69
69
|
# @see https://dry-rb.org/gems/dry-schema/json/
|
70
70
|
#
|
71
71
|
# @api public
|
72
|
-
def json(
|
73
|
-
define(:JSON,
|
72
|
+
def json(*external_schemas, &block)
|
73
|
+
define(:JSON, external_schemas, &block)
|
74
74
|
end
|
75
75
|
|
76
76
|
# Define a plain schema for your contract
|
@@ -81,8 +81,8 @@ module Dry
|
|
81
81
|
# @see https://dry-rb.org/gems/dry-schema/
|
82
82
|
#
|
83
83
|
# @api public
|
84
|
-
def schema(
|
85
|
-
define(:schema,
|
84
|
+
def schema(*external_schemas, &block)
|
85
|
+
define(:schema, external_schemas, &block)
|
86
86
|
end
|
87
87
|
|
88
88
|
# Define a rule for your contract
|
@@ -123,7 +123,7 @@ module Dry
|
|
123
123
|
#
|
124
124
|
# @api public
|
125
125
|
def build(options = EMPTY_HASH, &block)
|
126
|
-
Class.new(self, &block).new(options)
|
126
|
+
Class.new(self, &block).new(**options)
|
127
127
|
end
|
128
128
|
|
129
129
|
# @api private
|
@@ -154,29 +154,17 @@ module Dry
|
|
154
154
|
private
|
155
155
|
|
156
156
|
# @api private
|
157
|
-
# rubocop:disable Metrics/AbcSize
|
158
157
|
def ensure_valid_keys(*keys)
|
159
|
-
valid_paths = key_map.to_dot_notation
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
[path_key, Schema::Path[path_key]]
|
170
|
-
}
|
171
|
-
else
|
172
|
-
[[key, path]]
|
173
|
-
end
|
174
|
-
}
|
175
|
-
.flatten(1)
|
176
|
-
.reject { |(_, path)|
|
177
|
-
valid_paths.any? { |valid_path| valid_path.include?(path) }
|
178
|
-
}
|
179
|
-
.map(&:first)
|
158
|
+
valid_paths = key_map.to_dot_notation
|
159
|
+
key_paths = key_paths(keys)
|
160
|
+
|
161
|
+
invalid_keys = key_paths.filter_map { |(key, path)|
|
162
|
+
if valid_paths.none? { |vp|
|
163
|
+
vp == path || vp.start_with?("#{path}.", "#{path}[]")
|
164
|
+
}
|
165
|
+
key
|
166
|
+
end
|
167
|
+
}.uniq
|
180
168
|
|
181
169
|
return if invalid_keys.empty?
|
182
170
|
|
@@ -184,7 +172,28 @@ module Dry
|
|
184
172
|
#{name}.rule specifies keys that are not defined by the schema: #{invalid_keys.inspect}
|
185
173
|
STR
|
186
174
|
end
|
187
|
-
|
175
|
+
|
176
|
+
# @api private
|
177
|
+
def key_paths(keys)
|
178
|
+
keys.map { |key|
|
179
|
+
case key
|
180
|
+
when Hash
|
181
|
+
path = Schema::Path[key]
|
182
|
+
if path.multi_value?
|
183
|
+
*head, tail = Array(path)
|
184
|
+
[key].product(
|
185
|
+
tail.map { |el| [*head, *el] }.map { |parts| parts.join(DOT) }
|
186
|
+
)
|
187
|
+
else
|
188
|
+
[[key, path.to_a.join(DOT)]]
|
189
|
+
end
|
190
|
+
when Array
|
191
|
+
[[key, Schema::Path[key].to_a.join(DOT)]]
|
192
|
+
else
|
193
|
+
[[key, key.to_s]]
|
194
|
+
end
|
195
|
+
}.flatten(1)
|
196
|
+
end
|
188
197
|
|
189
198
|
# @api private
|
190
199
|
def key_map
|
@@ -193,28 +202,28 @@ module Dry
|
|
193
202
|
|
194
203
|
# @api private
|
195
204
|
def core_schema_opts
|
196
|
-
{
|
205
|
+
{parent: superclass&.__schema__, config: config}
|
197
206
|
end
|
198
207
|
|
199
208
|
# @api private
|
200
|
-
def define(method_name,
|
201
|
-
return __schema__ if
|
209
|
+
def define(method_name, external_schemas, &block)
|
210
|
+
return __schema__ if external_schemas.empty? && block.nil?
|
202
211
|
|
203
212
|
unless __schema__.nil?
|
204
|
-
raise ::Dry::Validation::DuplicateSchemaError,
|
213
|
+
raise ::Dry::Validation::DuplicateSchemaError, "Schema has already been defined"
|
205
214
|
end
|
206
215
|
|
207
216
|
schema_opts = core_schema_opts
|
208
217
|
|
209
|
-
schema_opts.update(parent:
|
218
|
+
schema_opts.update(parent: external_schemas) if external_schemas.any?
|
210
219
|
|
211
220
|
case method_name
|
212
221
|
when :schema
|
213
|
-
@__schema__ = Schema.define(schema_opts, &block)
|
222
|
+
@__schema__ = Schema.define(**schema_opts, &block)
|
214
223
|
when :Params
|
215
|
-
@__schema__ = Schema.Params(schema_opts, &block)
|
224
|
+
@__schema__ = Schema.Params(**schema_opts, &block)
|
216
225
|
when :JSON
|
217
|
-
@__schema__ = Schema.JSON(schema_opts, &block)
|
226
|
+
@__schema__ = Schema.JSON(**schema_opts, &block)
|
218
227
|
end
|
219
228
|
end
|
220
229
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "concurrent/map"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
5
|
+
require "dry/core/equalizer"
|
6
|
+
require "dry/initializer"
|
7
|
+
require "dry/schema/path"
|
8
8
|
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
9
|
+
require "dry/validation/config"
|
10
|
+
require "dry/validation/constants"
|
11
|
+
require "dry/validation/rule"
|
12
|
+
require "dry/validation/evaluator"
|
13
|
+
require "dry/validation/messages/resolver"
|
14
|
+
require "dry/validation/result"
|
15
|
+
require "dry/validation/contract/class_interface"
|
16
16
|
|
17
17
|
module Dry
|
18
18
|
module Validation
|
@@ -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,23 +91,31 @@ 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
|
|
98
110
|
rule_result = rule.(self, result)
|
99
111
|
|
100
112
|
rule_result.failures.each do |failure|
|
101
|
-
result.add_error(message_resolver
|
113
|
+
result.add_error(message_resolver.(**failure))
|
102
114
|
end
|
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
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/initializer"
|
4
|
+
require "dry/core/deprecations"
|
4
5
|
|
5
|
-
require
|
6
|
-
require
|
6
|
+
require "dry/validation/constants"
|
7
|
+
require "dry/validation/failures"
|
7
8
|
|
8
9
|
module Dry
|
9
10
|
module Validation
|
@@ -16,6 +17,9 @@ module Dry
|
|
16
17
|
# @api public
|
17
18
|
class Evaluator
|
18
19
|
extend Dry::Initializer
|
20
|
+
extend Dry::Core::Deprecations[:"dry-validation"]
|
21
|
+
|
22
|
+
deprecate :error?, :schema_error?
|
19
23
|
|
20
24
|
# @!attribute [r] _contract
|
21
25
|
# @return [Contract]
|
@@ -63,19 +67,19 @@ module Dry
|
|
63
67
|
# Initialize a new evaluator
|
64
68
|
#
|
65
69
|
# @api private
|
66
|
-
def initialize(contract, options, &block)
|
67
|
-
super(contract, options)
|
70
|
+
def initialize(contract, **options, &block)
|
71
|
+
super(contract, **options)
|
68
72
|
|
69
73
|
@_options = options
|
70
74
|
|
71
75
|
if block
|
72
|
-
exec_opts = block_options.
|
73
|
-
instance_exec(exec_opts, &block)
|
76
|
+
exec_opts = block_options.transform_values { _options[_1] }
|
77
|
+
instance_exec(**exec_opts, &block)
|
74
78
|
end
|
75
79
|
|
76
80
|
macros.each do |args|
|
77
81
|
macro = macro(*args.flatten(1))
|
78
|
-
instance_exec(macro.extract_block_options(_options.merge(macro: macro)), ¯o.block)
|
82
|
+
instance_exec(**macro.extract_block_options(_options.merge(macro: macro)), ¯o.block)
|
79
83
|
end
|
80
84
|
end
|
81
85
|
|
@@ -117,7 +121,7 @@ module Dry
|
|
117
121
|
|
118
122
|
# @api private
|
119
123
|
def with(new_opts, &block)
|
120
|
-
self.class.new(_contract, _options
|
124
|
+
self.class.new(_contract, **_options, **new_opts, &block)
|
121
125
|
end
|
122
126
|
|
123
127
|
# Return default (first) key name
|
@@ -142,7 +146,7 @@ module Dry
|
|
142
146
|
#
|
143
147
|
# @return [Object]
|
144
148
|
#
|
145
|
-
# @public
|
149
|
+
# @api public
|
146
150
|
def value
|
147
151
|
values[key_name]
|
148
152
|
end
|
@@ -151,27 +155,58 @@ module Dry
|
|
151
155
|
#
|
152
156
|
# This is useful when dealing with rules for optional keys
|
153
157
|
#
|
154
|
-
# @example
|
158
|
+
# @example use the default key name
|
155
159
|
# rule(:age) do
|
156
160
|
# key.failure(:invalid) if key? && value < 18
|
157
161
|
# end
|
158
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
|
+
#
|
170
|
+
# @return [Boolean]
|
171
|
+
#
|
172
|
+
# @api public
|
173
|
+
def key?(name = key_name)
|
174
|
+
values.key?(name)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Check if there are any errors on the schema under the provided path
|
178
|
+
#
|
179
|
+
# @param path [Symbol, String, Array] A Path-compatible spec
|
180
|
+
#
|
159
181
|
# @return [Boolean]
|
160
182
|
#
|
161
183
|
# @api public
|
162
|
-
def
|
163
|
-
|
184
|
+
def schema_error?(path)
|
185
|
+
result.schema_error?(path)
|
164
186
|
end
|
165
187
|
|
166
|
-
# Check if there are any errors
|
188
|
+
# Check if there are any errors on the current rule
|
189
|
+
#
|
190
|
+
# @param path [Symbol, String, Array] A Path-compatible spec
|
191
|
+
#
|
192
|
+
# @return [Boolean]
|
167
193
|
#
|
168
|
-
# @
|
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
|
169
204
|
#
|
170
205
|
# @return [Boolean]
|
171
206
|
#
|
172
207
|
# @api public
|
173
|
-
def
|
174
|
-
result.
|
208
|
+
def base_rule_error?
|
209
|
+
!base.empty? || result.base_rule_error?
|
175
210
|
end
|
176
211
|
|
177
212
|
# @api private
|
@@ -192,6 +227,7 @@ module Dry
|
|
192
227
|
super
|
193
228
|
end
|
194
229
|
end
|
230
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
195
231
|
end
|
196
232
|
end
|
197
233
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dry/monads/result'
|
4
|
-
|
5
3
|
module Dry
|
6
4
|
module Validation
|
7
5
|
# Hints extension
|
@@ -46,7 +44,7 @@ module Dry
|
|
46
44
|
#
|
47
45
|
# @api public
|
48
46
|
def messages(new_options = EMPTY_HASH)
|
49
|
-
errors.with(hints.to_a, options.merge(**new_options))
|
47
|
+
errors.with(hints(new_options).to_a, options.merge(**new_options))
|
50
48
|
end
|
51
49
|
|
52
50
|
# Return hint messages
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/schema/predicate_registry"
|
4
|
+
require "dry/validation/contract"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Validation
|
@@ -12,7 +12,7 @@ module Dry
|
|
12
12
|
#
|
13
13
|
# @see Dry::Validation::Contract
|
14
14
|
WHITELIST = %i[
|
15
|
-
filled? gt? gteq? included_in? includes? inclusion? is? lt?
|
15
|
+
filled? format? gt? gteq? included_in? includes? inclusion? is? lt?
|
16
16
|
lteq? max_size? min_size? not_eql? odd? respond_to? size? true?
|
17
17
|
uuid_v4?
|
18
18
|
].freeze
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/schema/path"
|
4
|
+
require "dry/validation/constants"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Validation
|
@@ -45,14 +45,26 @@ module Dry
|
|
45
45
|
# @example
|
46
46
|
# failure(:taken)
|
47
47
|
#
|
48
|
+
# @overload failure(meta_hash)
|
49
|
+
# Use meta_hash[:text] as a message (either explicitely or as an identifier),
|
50
|
+
# setting the rest of the hash as error meta attribute
|
51
|
+
# @param meta [Hash] The hash containing the message as value for the :text key
|
52
|
+
# @example
|
53
|
+
# failure({text: :invalid, key: value})
|
54
|
+
#
|
48
55
|
# @see Evaluator#key
|
49
56
|
# @see Evaluator#base
|
50
57
|
#
|
51
58
|
# @api public
|
52
59
|
def failure(message, tokens = EMPTY_HASH)
|
53
|
-
opts << {
|
60
|
+
opts << {message: message, tokens: tokens, path: path}
|
54
61
|
self
|
55
62
|
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def empty?
|
66
|
+
opts.empty?
|
67
|
+
end
|
56
68
|
end
|
57
69
|
end
|
58
70
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/initializer"
|
4
|
+
require "dry/validation/constants"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Validation
|
@@ -36,8 +36,7 @@ module Dry
|
|
36
36
|
block
|
37
37
|
.parameters
|
38
38
|
.select { |arg,| arg.equal?(:keyreq) }
|
39
|
-
.
|
40
|
-
.to_h
|
39
|
+
.to_h { [_2, BLOCK_OPTIONS_MAPPINGS[_2]] }
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
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/validation/constants"
|
4
|
+
require "dry/validation/function"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Validation
|
@@ -31,7 +31,7 @@ module Dry
|
|
31
31
|
|
32
32
|
# @api private
|
33
33
|
def extract_block_options(options)
|
34
|
-
block_options.
|
34
|
+
block_options.transform_values { options[_1] }
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|