dry-validation 0.1.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +969 -1
- data/LICENSE +1 -1
- data/README.md +19 -286
- data/config/errors.yml +4 -35
- data/dry-validation.gemspec +38 -22
- data/lib/dry/validation/config.rb +24 -0
- data/lib/dry/validation/constants.rb +43 -0
- data/lib/dry/validation/contract/class_interface.rb +230 -0
- data/lib/dry/validation/contract.rb +173 -0
- data/lib/dry/validation/evaluator.rb +233 -0
- data/lib/dry/validation/extensions/hints.rb +67 -0
- data/lib/dry/validation/extensions/monads.rb +34 -0
- data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
- data/lib/dry/validation/failures.rb +70 -0
- data/lib/dry/validation/function.rb +43 -0
- data/lib/dry/validation/macro.rb +38 -0
- data/lib/dry/validation/macros.rb +104 -0
- data/lib/dry/validation/message.rb +100 -0
- data/lib/dry/validation/message_set.rb +97 -0
- data/lib/dry/validation/messages/resolver.rb +129 -0
- data/lib/dry/validation/result.rb +206 -38
- data/lib/dry/validation/rule.rb +116 -106
- data/lib/dry/validation/schema_ext.rb +19 -0
- data/lib/dry/validation/values.rb +108 -0
- data/lib/dry/validation/version.rb +3 -1
- data/lib/dry/validation.rb +55 -7
- data/lib/dry-validation.rb +3 -1
- metadata +80 -106
- data/.gitignore +0 -8
- data/.rspec +0 -3
- data/.rubocop.yml +0 -16
- data/.rubocop_todo.yml +0 -7
- data/.travis.yml +0 -29
- data/Gemfile +0 -11
- data/Rakefile +0 -12
- data/examples/basic.rb +0 -21
- data/examples/nested.rb +0 -30
- data/examples/rule_ast.rb +0 -33
- data/lib/dry/validation/error.rb +0 -43
- data/lib/dry/validation/error_compiler.rb +0 -116
- data/lib/dry/validation/messages.rb +0 -71
- data/lib/dry/validation/predicate.rb +0 -39
- data/lib/dry/validation/predicate_set.rb +0 -22
- data/lib/dry/validation/predicates.rb +0 -88
- data/lib/dry/validation/rule_compiler.rb +0 -57
- data/lib/dry/validation/schema/definition.rb +0 -15
- data/lib/dry/validation/schema/key.rb +0 -39
- data/lib/dry/validation/schema/rule.rb +0 -28
- data/lib/dry/validation/schema/value.rb +0 -31
- data/lib/dry/validation/schema.rb +0 -74
- data/rakelib/rubocop.rake +0 -18
- data/spec/fixtures/errors.yml +0 -4
- data/spec/integration/custom_error_messages_spec.rb +0 -35
- data/spec/integration/custom_predicates_spec.rb +0 -57
- data/spec/integration/validation_spec.rb +0 -118
- data/spec/shared/predicates.rb +0 -31
- data/spec/spec_helper.rb +0 -18
- data/spec/unit/error_compiler_spec.rb +0 -165
- data/spec/unit/predicate_spec.rb +0 -37
- data/spec/unit/predicates/empty_spec.rb +0 -38
- data/spec/unit/predicates/eql_spec.rb +0 -21
- data/spec/unit/predicates/exclusion_spec.rb +0 -35
- data/spec/unit/predicates/filled_spec.rb +0 -38
- data/spec/unit/predicates/format_spec.rb +0 -21
- data/spec/unit/predicates/gt_spec.rb +0 -40
- data/spec/unit/predicates/gteq_spec.rb +0 -40
- data/spec/unit/predicates/inclusion_spec.rb +0 -35
- data/spec/unit/predicates/int_spec.rb +0 -34
- data/spec/unit/predicates/key_spec.rb +0 -29
- data/spec/unit/predicates/lt_spec.rb +0 -40
- data/spec/unit/predicates/lteq_spec.rb +0 -40
- data/spec/unit/predicates/max_size_spec.rb +0 -49
- data/spec/unit/predicates/min_size_spec.rb +0 -49
- data/spec/unit/predicates/nil_spec.rb +0 -28
- data/spec/unit/predicates/size_spec.rb +0 -49
- data/spec/unit/predicates/str_spec.rb +0 -32
- data/spec/unit/rule/each_spec.rb +0 -20
- data/spec/unit/rule/key_spec.rb +0 -27
- data/spec/unit/rule/set_spec.rb +0 -32
- data/spec/unit/rule/value_spec.rb +0 -42
- data/spec/unit/rule_compiler_spec.rb +0 -86
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,296 +1,29 @@
|
|
1
|
-
|
1
|
+
<!--- this file is synced from dry-rb/template-gem project -->
|
2
|
+
[gem]: https://rubygems.org/gems/dry-validation
|
3
|
+
[actions]: https://github.com/dry-rb/dry-validation/actions
|
4
|
+
[codacy]: https://www.codacy.com/gh/dry-rb/dry-validation
|
5
|
+
[chat]: https://dry-rb.zulipchat.com
|
6
|
+
[inchpages]: http://inch-ci.org/github/dry-rb/dry-validation
|
2
7
|
|
3
|
-
|
4
|
-
<a href="https://travis-ci.org/dryrb/dry-validation" target="_blank">![Build Status](https://travis-ci.org/dryrb/dry-validation.svg?branch=master)</a>
|
5
|
-
<a href="https://gemnasium.com/dryrb/dry-validation" target="_blank">![Dependency Status](https://gemnasium.com/dryrb/dry-validation.svg)</a>
|
6
|
-
<a href="https://codeclimate.com/github/dryrb/dry-validation" target="_blank">![Code Climate](https://codeclimate.com/github/dryrb/dry-validation/badges/gpa.svg)</a>
|
7
|
-
<a href="http://inch-ci.org/github/dryrb/dry-validation" target="_blank">![Documentation Status](http://inch-ci.org/github/dryrb/dry-validation.svg?branch=master&style=flat)</a>
|
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]
|
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=master)][inchpages]
|
10
15
|
|
11
|
-
##
|
16
|
+
## Links
|
12
17
|
|
13
|
-
|
14
|
-
|
15
|
-
of validation logic. It is designed to work with any data input, whether it's a
|
16
|
-
simple hash, an array or a complex object with deeply nested data.
|
18
|
+
* [User documentation](https://dry-rb.org/gems/dry-validation)
|
19
|
+
* [API documentation](http://rubydoc.info/gems/dry-validation)
|
17
20
|
|
18
|
-
|
19
|
-
stateless predicate, that receives some input and returns either `true` or `false`.
|
21
|
+
## Supported Ruby versions
|
20
22
|
|
21
|
-
|
22
|
-
`predicate logic`. This means you can use the common logic operators to build up
|
23
|
-
a validation `schema`.
|
23
|
+
This library officially supports the following Ruby versions:
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
Validations can be described with great precision, `dry-validation` eliminates
|
28
|
-
ambigious concepts like `presence` validation where we can't really say whether
|
29
|
-
some attribute or key is *missing* or it's just that the value is `nil`.
|
30
|
-
|
31
|
-
There's also the concept of type-safety, completely missing in other validation
|
32
|
-
libraries, which is quite important and useful. It means you can compose a validation
|
33
|
-
that does rely on the type of a given value. In example it makes no sense to validate
|
34
|
-
each element of an array when it turns out to be an empty string.
|
35
|
-
|
36
|
-
## The DSL
|
37
|
-
|
38
|
-
The core of `dry-validation` is rules composition and predicate logic. The DSL
|
39
|
-
is a simple front-end for that. It only allows you to define the rules by using
|
40
|
-
predicate identifiers. There are no magical options, conditionals and custom
|
41
|
-
validation blocks known from other libraries. The focus is on pure validation
|
42
|
-
logic.
|
43
|
-
|
44
|
-
## Examples
|
45
|
-
|
46
|
-
### Basic
|
47
|
-
|
48
|
-
Here's a basic example where we validate following things:
|
49
|
-
|
50
|
-
* The input *must have a key* called `:email`
|
51
|
-
* Provided the email key is present, its value *must be filled*
|
52
|
-
* The input *must have a key* called `:age`
|
53
|
-
* Provided the age key is present, its value *must be an integer* and it *must be greater than 18*
|
54
|
-
|
55
|
-
This can be easily expressed through the DSL:
|
56
|
-
|
57
|
-
``` ruby
|
58
|
-
require 'dry-validation'
|
59
|
-
|
60
|
-
class Schema < Dry::Validation::Schema
|
61
|
-
key(:email) { |email| email.filled? }
|
62
|
-
|
63
|
-
key(:age) do |age|
|
64
|
-
age.int? & age.gt?(18)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
schema = Schema.new
|
69
|
-
|
70
|
-
errors = schema.messages(email: 'jane@doe.org', age: 19)
|
71
|
-
|
72
|
-
puts errors.inspect
|
73
|
-
# []
|
74
|
-
|
75
|
-
errors = schema.messages(email: nil, age: 19)
|
76
|
-
|
77
|
-
puts errors.inspect
|
78
|
-
# [[:email, ["email must be filled"]]]
|
79
|
-
```
|
80
|
-
|
81
|
-
A couple of remarks:
|
82
|
-
|
83
|
-
* `key` assumes that we want to use the `:key?` predicate to check the existance of that key
|
84
|
-
* `age.gt?(18)` translates to calling a predicate like this: `schema[:gt?].(18, age)`
|
85
|
-
* `age.int? & age.gt?(18)` is a conjunction, so we don't bother about `gt?` unless `int?` returns `true`
|
86
|
-
* You can also use `|` for disjunction
|
87
|
-
* Schema object does not carry the input as its state, nor does it know how to access the input values, we
|
88
|
-
pass the input to `call` and get error set as the response
|
89
|
-
|
90
|
-
### Nested Hash
|
91
|
-
|
92
|
-
We are free to define validations for anything, including deeply nested structures:
|
93
|
-
|
94
|
-
``` ruby
|
95
|
-
require 'dry-validation'
|
96
|
-
|
97
|
-
class Schema < Dry::Validation::Schema
|
98
|
-
key(:address) do |address|
|
99
|
-
address.key(:city) do |city|
|
100
|
-
city.min_size?(3)
|
101
|
-
end
|
102
|
-
|
103
|
-
address.key(:street) do |street|
|
104
|
-
street.filled?
|
105
|
-
end
|
106
|
-
|
107
|
-
address.key(:country) do |country|
|
108
|
-
country.key(:name, &:filled?)
|
109
|
-
country.key(:code, &:filled?)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
schema = Schema.new
|
115
|
-
|
116
|
-
errors = schema.messages({})
|
117
|
-
|
118
|
-
puts errors.inspect
|
119
|
-
# [[:address, ["address is missing"]]]
|
120
|
-
|
121
|
-
errors = schema.messages(address: { city: 'NYC' })
|
122
|
-
|
123
|
-
puts errors.inspect
|
124
|
-
# [[:address, [[:street, ["street is missing"]], [:country, ["country is missing"]]]]]
|
125
|
-
```
|
126
|
-
|
127
|
-
### Defining Custom Predicates
|
128
|
-
|
129
|
-
You can simply define predicate methods on your schema object:
|
130
|
-
|
131
|
-
``` ruby
|
132
|
-
class Schema < Dry::Validation::Schema
|
133
|
-
key(:email) { |value| value.str? & value.email? }
|
134
|
-
|
135
|
-
def email?(value)
|
136
|
-
! /magical-regex-that-matches-emails/.match(value).nil?
|
137
|
-
end
|
138
|
-
end
|
139
|
-
```
|
140
|
-
|
141
|
-
You can also re-use a predicate container across multiple schemas:
|
142
|
-
|
143
|
-
``` ruby
|
144
|
-
module MyPredicates
|
145
|
-
include Dry::Validation::Predicates
|
146
|
-
|
147
|
-
predicate(:email?) do |input|
|
148
|
-
! /magical-regex-that-matches-emails/.match(value).nil?
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
class Schema < Dry::Validation::Schema
|
153
|
-
configure do |config|
|
154
|
-
config.predicates = MyPredicates
|
155
|
-
end
|
156
|
-
|
157
|
-
key(:email) { |value| value.str? & value.email? }
|
158
|
-
end
|
159
|
-
```
|
160
|
-
|
161
|
-
## List of Built-In Predicates
|
162
|
-
|
163
|
-
* `empty?`
|
164
|
-
* `eql?`
|
165
|
-
* `exclusion?`
|
166
|
-
* `filled?`
|
167
|
-
* `format?`
|
168
|
-
* `gt?`
|
169
|
-
* `gteq?`
|
170
|
-
* `inclusion?`
|
171
|
-
* `int?`
|
172
|
-
* `key?`
|
173
|
-
* `lt?`
|
174
|
-
* `lteq?`
|
175
|
-
* `max_size?`
|
176
|
-
* `min_size?`
|
177
|
-
* `nil?`
|
178
|
-
* `size?`
|
179
|
-
* `str?`
|
180
|
-
|
181
|
-
## Error Messages
|
182
|
-
|
183
|
-
By default `dry-validation` comes with a set of pre-defined error messages for
|
184
|
-
every built-in predicate. They are defined in [a yaml file](https://github.com/dryrb/dry-validation/blob/master/config/errors.yml)
|
185
|
-
which is shipped with the gem.
|
186
|
-
|
187
|
-
You can provide your own messages and configure your schemas to use it like that:
|
188
|
-
|
189
|
-
``` ruby
|
190
|
-
class Schema < Dry::Validation::Schema
|
191
|
-
configure { |config| config.messages_file = '/path/to/my/errors.yml' }
|
192
|
-
end
|
193
|
-
```
|
194
|
-
|
195
|
-
You can also provide a namespace per-schema that will be used by default:
|
196
|
-
|
197
|
-
``` ruby
|
198
|
-
class Schema < Dry::Validation::Schema
|
199
|
-
configure { |config| config.namespace = :user }
|
200
|
-
end
|
201
|
-
```
|
202
|
-
|
203
|
-
Lookup rules:
|
204
|
-
|
205
|
-
``` yaml
|
206
|
-
filled?: "%{name} must be filled"
|
207
|
-
|
208
|
-
attributes:
|
209
|
-
email:
|
210
|
-
filled?: "the email is missing"
|
211
|
-
|
212
|
-
user:
|
213
|
-
filled?: "%{name} name cannot be blank"
|
214
|
-
|
215
|
-
attributes:
|
216
|
-
address:
|
217
|
-
filled?: "You gotta tell us where you live"
|
218
|
-
```
|
219
|
-
|
220
|
-
Given the yaml file above, messages lookup works as follows:
|
221
|
-
|
222
|
-
``` ruby
|
223
|
-
messages = Dry::Validation::Messages.load('/path/to/our/errors.yml')
|
224
|
-
|
225
|
-
messages.lookup(:filled?, :age) # => "age must be filled"
|
226
|
-
messages.lookup(:filled?, :address) # => "address must be filled"
|
227
|
-
messages.lookup(:filled?, :email) # => "the email is missing"
|
228
|
-
|
229
|
-
# with namespaced messages
|
230
|
-
user_messages = messages.namespaced(:user)
|
231
|
-
|
232
|
-
user_messages.lookup(:filled?, :age) # "age cannot be blank"
|
233
|
-
user_messages.lookup(:filled?, :address) # "You gotta tell us where you live"
|
234
|
-
```
|
235
|
-
|
236
|
-
By configuring `messages_file` and/or `namespace` in a schema, default messages
|
237
|
-
are going to be automatically merged with your overrides and/or namespaced.
|
238
|
-
|
239
|
-
## I18n Integration
|
240
|
-
|
241
|
-
Coming (very) soon...
|
242
|
-
|
243
|
-
## Rule AST
|
244
|
-
|
245
|
-
Internally, `dry-validation` uses a simple AST representation of rules and errors
|
246
|
-
to produce rule objects and error messages. If you would like to programatically
|
247
|
-
generate rules, it is a very simple process:
|
248
|
-
|
249
|
-
``` ruby
|
250
|
-
ast = [
|
251
|
-
[
|
252
|
-
:and,
|
253
|
-
[
|
254
|
-
[:key, [:age, [:predicate, [:key?, []]]]],
|
255
|
-
[
|
256
|
-
:and,
|
257
|
-
[
|
258
|
-
[:val, [:age, [:predicate, [:filled?, []]]]],
|
259
|
-
[:val, [:age, [:predicate, [:gt?, [18]]]]]
|
260
|
-
]
|
261
|
-
]
|
262
|
-
]
|
263
|
-
]
|
264
|
-
]
|
265
|
-
|
266
|
-
compiler = Dry::Validation::RuleCompiler.new(Dry::Validation::Predicates)
|
267
|
-
|
268
|
-
# compile an array of rule objects
|
269
|
-
rules = compiler.call(ast)
|
270
|
-
|
271
|
-
puts rules.inspect
|
272
|
-
# [
|
273
|
-
# #<Dry::Validation::Rule::Conjunction
|
274
|
-
# left=#<Dry::Validation::Rule::Key name=:age predicate=#<Dry::Validation::Predicate id=:key?>>
|
275
|
-
# right=#<Dry::Validation::Rule::Conjunction
|
276
|
-
# left=#<Dry::Validation::Rule::Value name=:age predicate=#<Dry::Validation::Predicate id=:filled?>>
|
277
|
-
# right=#<Dry::Validation::Rule::Value name=:age predicate=#<Dry::Validation::Predicate id=:gt?>>>>
|
278
|
-
# ]
|
279
|
-
|
280
|
-
# dump it back to ast
|
281
|
-
puts rules.map(&:to_ary).inspect
|
282
|
-
# [[:and, [:key, [:age, [:predicate, [:key?, [:age]]]]], [[:and, [:val, [:age, [:predicate, [:filled?, []]]]], [[:val, [:age, [:predicate, [:gt?, [18]]]]]]]]]]
|
283
|
-
```
|
284
|
-
|
285
|
-
Complete docs for the AST format are coming soon, for now please refer to
|
286
|
-
[this spec](https://github.com/dryrb/dry-validation/blob/master/spec/unit/rule_compiler_spec.rb).
|
287
|
-
|
288
|
-
## Status and Roadmap
|
289
|
-
|
290
|
-
This library is in a very early stage of development but you are encauraged to
|
291
|
-
try it out and provide feedback.
|
292
|
-
|
293
|
-
For planned features check out [the issues](https://github.com/dryrb/dry-validation/labels/feature).
|
25
|
+
* MRI `>= 2.7.0`
|
26
|
+
* jruby `>= 9.3` (postponed until 2.7 is supported)
|
294
27
|
|
295
28
|
## License
|
296
29
|
|
data/config/errors.yml
CHANGED
@@ -1,35 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
eql?: "%{name} must be equal to %{eql_value}"
|
6
|
-
|
7
|
-
filled?: "%{name} must be filled"
|
8
|
-
|
9
|
-
format?: "%{name} is in invalid format"
|
10
|
-
|
11
|
-
gt?: "%{name} must be greater than %{num} (%{value} was given)"
|
12
|
-
|
13
|
-
gteq?: "%{name} must be greater than or equal to %{num}"
|
14
|
-
|
15
|
-
inclusion?: "%{name} must be one of: %{list}"
|
16
|
-
|
17
|
-
int?: "%{name} must be an integer"
|
18
|
-
|
19
|
-
key?: "%{name} is missing"
|
20
|
-
|
21
|
-
lt?: "%{name} must be less than %{num} (%{value} was given)"
|
22
|
-
|
23
|
-
lteq?: "%{name} must be less than or equal to %{num}"
|
24
|
-
|
25
|
-
max_size?: "%{name} size cannot be greater than %{num}"
|
26
|
-
|
27
|
-
min_size?: "%{name} size cannot be less than %{num}"
|
28
|
-
|
29
|
-
nil?: "%{name} cannot be nil"
|
30
|
-
|
31
|
-
size?:
|
32
|
-
range: "%{name} size must be within %{left} - %{right}"
|
33
|
-
default: "%{name} size must be %{num}"
|
34
|
-
|
35
|
-
str?: "%{name} must be a string"
|
1
|
+
en:
|
2
|
+
dry_validation:
|
3
|
+
errors:
|
4
|
+
acceptance: "must accept %{key}"
|
data/dry-validation.gemspec
CHANGED
@@ -1,25 +1,41 @@
|
|
1
|
-
#
|
2
|
-
|
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"
|
3
8
|
|
4
9
|
Gem::Specification.new do |spec|
|
5
|
-
spec.name =
|
6
|
-
spec.
|
7
|
-
spec.
|
8
|
-
spec.
|
9
|
-
spec.
|
10
|
-
|
11
|
-
spec.
|
12
|
-
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
spec.
|
16
|
-
spec.
|
17
|
-
|
18
|
-
|
19
|
-
spec.
|
20
|
-
spec.
|
21
|
-
|
22
|
-
spec.
|
23
|
-
|
24
|
-
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/master/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.9", ">= 1.9.1"
|
37
|
+
|
38
|
+
spec.add_development_dependency "bundler"
|
39
|
+
spec.add_development_dependency "rake"
|
40
|
+
spec.add_development_dependency "rspec"
|
25
41
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema/config"
|
4
|
+
require "dry/validation/macros"
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module Validation
|
8
|
+
# Configuration for contracts
|
9
|
+
#
|
10
|
+
# @see Contract#config
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
class Config < Schema::Config
|
14
|
+
setting :macros, default: Macros::Container.new, constructor: :dup.to_proc
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
def dup
|
18
|
+
config = super
|
19
|
+
config.macros = macros.dup
|
20
|
+
config
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "dry/core/constants"
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module Validation
|
8
|
+
include Dry::Core::Constants
|
9
|
+
|
10
|
+
DOT = "."
|
11
|
+
|
12
|
+
# Root path is used for base errors in hash representation of error messages
|
13
|
+
ROOT_PATH = [nil].freeze
|
14
|
+
|
15
|
+
# Path to the default errors locale file
|
16
|
+
DEFAULT_ERRORS_NAMESPACE = "dry_validation"
|
17
|
+
|
18
|
+
# Path to the default errors locale file
|
19
|
+
DEFAULT_ERRORS_PATH = Pathname(__FILE__).join("../../../../config/errors.yml").realpath.freeze
|
20
|
+
|
21
|
+
# Mapping for block kwarg options used by block_options
|
22
|
+
#
|
23
|
+
# @see Rule#block_options
|
24
|
+
BLOCK_OPTIONS_MAPPINGS = Hash.new { |_, key| key }.update(context: :_context).freeze
|
25
|
+
|
26
|
+
# Error raised when `rule` specifies one or more keys that the schema doesn't specify
|
27
|
+
InvalidKeysError = Class.new(StandardError)
|
28
|
+
|
29
|
+
# Error raised when a localized message was not found
|
30
|
+
MissingMessageError = Class.new(StandardError)
|
31
|
+
|
32
|
+
# Error raised when trying to define a schema in a contract class that already has a schema
|
33
|
+
DuplicateSchemaError = Class.new(StandardError)
|
34
|
+
|
35
|
+
# Error raised during initialization of a contract that has no schema defined
|
36
|
+
SchemaMissingError = Class.new(StandardError) do
|
37
|
+
# @api private
|
38
|
+
def initialize(klass)
|
39
|
+
super("#{klass} cannot be instantiated without a schema defined")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|