nxt_schema 0.1.2 → 1.0.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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +32 -29
- data/README.md +186 -116
- data/lib/nxt_schema.rb +56 -49
- data/lib/nxt_schema/{node.rb → application.rb} +1 -1
- data/lib/nxt_schema/application/any_of.rb +40 -0
- data/lib/nxt_schema/application/base.rb +116 -0
- data/lib/nxt_schema/application/collection.rb +57 -0
- data/lib/nxt_schema/application/error_store.rb +57 -0
- data/lib/nxt_schema/application/errors/schema_error.rb +15 -0
- data/lib/nxt_schema/application/errors/validation_error.rb +15 -0
- data/lib/nxt_schema/application/leaf.rb +15 -0
- data/lib/nxt_schema/application/schema.rb +114 -0
- data/lib/nxt_schema/callable.rb +21 -55
- data/lib/nxt_schema/dsl.rb +41 -31
- data/lib/nxt_schema/error.rb +4 -0
- data/lib/nxt_schema/errors/invalid.rb +16 -0
- data/lib/nxt_schema/errors/{error.rb → invalid_options.rb} +1 -2
- data/lib/nxt_schema/missing_input.rb +9 -0
- data/lib/nxt_schema/node/any_of.rb +51 -0
- data/lib/nxt_schema/node/base.rb +135 -233
- data/lib/nxt_schema/node/collection.rb +10 -65
- data/lib/nxt_schema/node/has_sub_nodes.rb +81 -0
- data/lib/nxt_schema/node/leaf.rb +1 -31
- data/lib/nxt_schema/node/maybe_evaluator.rb +15 -10
- data/lib/nxt_schema/node/on_evaluator.rb +25 -0
- data/lib/nxt_schema/node/schema.rb +8 -134
- data/lib/nxt_schema/node/sub_nodes.rb +22 -0
- data/lib/nxt_schema/node/type_system_resolver.rb +22 -0
- data/lib/nxt_schema/types.rb +1 -1
- data/lib/nxt_schema/validators/attribute.rb +3 -3
- data/lib/nxt_schema/validators/{equality.rb → equal_to.rb} +5 -5
- data/lib/nxt_schema/validators/error_messages.rb +42 -0
- data/lib/nxt_schema/{error_messages → validators/error_messages}/en.yaml +3 -3
- data/lib/nxt_schema/validators/{excluded.rb → excluded_in.rb} +4 -4
- data/lib/nxt_schema/validators/excludes.rb +3 -3
- data/lib/nxt_schema/validators/greater_than.rb +3 -3
- data/lib/nxt_schema/validators/greater_than_or_equal.rb +3 -3
- data/lib/nxt_schema/validators/{included.rb → included_in.rb} +4 -4
- data/lib/nxt_schema/validators/includes.rb +3 -3
- data/lib/nxt_schema/validators/less_than.rb +3 -3
- data/lib/nxt_schema/validators/less_than_or_equal.rb +3 -3
- data/lib/nxt_schema/validators/optional_node.rb +13 -8
- data/lib/nxt_schema/validators/pattern.rb +3 -3
- data/lib/nxt_schema/validators/query.rb +4 -4
- data/lib/nxt_schema/validators/registry.rb +1 -7
- data/lib/nxt_schema/{node → validators}/validate_with_proxy.rb +8 -8
- data/lib/nxt_schema/validators/validator.rb +2 -2
- data/lib/nxt_schema/version.rb +1 -1
- data/nxt_schema.gemspec +1 -0
- metadata +42 -22
- data/lib/nxt_schema/callable_or_value.rb +0 -72
- data/lib/nxt_schema/error_messages.rb +0 -40
- data/lib/nxt_schema/errors.rb +0 -4
- data/lib/nxt_schema/errors/invalid_options_error.rb +0 -5
- data/lib/nxt_schema/errors/schema_not_applied_error.rb +0 -5
- data/lib/nxt_schema/node/constructor.rb +0 -9
- data/lib/nxt_schema/node/default_value_evaluator.rb +0 -20
- data/lib/nxt_schema/node/error.rb +0 -13
- data/lib/nxt_schema/node/has_subnodes.rb +0 -97
- data/lib/nxt_schema/node/template_store.rb +0 -15
- data/lib/nxt_schema/registry.rb +0 -85
- data/lib/nxt_schema/undefined.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36a741174bf1669b013e32f2b3693c99cae2b4e479378cb1494069dd66f1af44
|
4
|
+
data.tar.gz: 2984ab8830a495bf1a694cd369216dee00e0dc5cc2cf1c87c173dd5c1e984963
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1924005010c80140b9d545fb307ef373cb237a31e166195d6e959af56b41208d49db1d48ff3ab68c77ad45bdee3941821e9c2584cfe50cd2da47134a15a1eac
|
7
|
+
data.tar.gz: '001459e22044cfef5aded2ade7d9b8b0fe15c944c4bb886a992578a82886777c2a92e5ce1711919414b79910577b68671249b8bdc74526a89ee0c1437ba4c421'
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,35 +1,36 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nxt_schema (0.
|
4
|
+
nxt_schema (1.0.0)
|
5
5
|
activesupport
|
6
6
|
dry-types
|
7
|
+
nxt_init
|
7
8
|
nxt_registry
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
|
-
activesupport (6.0.
|
13
|
+
activesupport (6.0.3.4)
|
13
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
15
|
i18n (>= 0.7, < 2)
|
15
16
|
minitest (~> 5.1)
|
16
17
|
tzinfo (~> 1.1)
|
17
|
-
zeitwerk (~> 2.2)
|
18
|
-
coderay (1.1.
|
19
|
-
concurrent-ruby (1.1.
|
20
|
-
diff-lcs (1.
|
21
|
-
dry-configurable (0.11.
|
18
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
19
|
+
coderay (1.1.3)
|
20
|
+
concurrent-ruby (1.1.7)
|
21
|
+
diff-lcs (1.4.4)
|
22
|
+
dry-configurable (0.11.6)
|
22
23
|
concurrent-ruby (~> 1.0)
|
23
24
|
dry-core (~> 0.4, >= 0.4.7)
|
24
25
|
dry-equalizer (~> 0.2)
|
25
26
|
dry-container (0.7.2)
|
26
27
|
concurrent-ruby (~> 1.0)
|
27
28
|
dry-configurable (~> 0.1, >= 0.1.3)
|
28
|
-
dry-core (0.4.
|
29
|
+
dry-core (0.4.10)
|
29
30
|
concurrent-ruby (~> 1.0)
|
30
31
|
dry-equalizer (0.3.0)
|
31
32
|
dry-inflector (0.2.0)
|
32
|
-
dry-logic (1.0.
|
33
|
+
dry-logic (1.0.8)
|
33
34
|
concurrent-ruby (~> 1.0)
|
34
35
|
dry-core (~> 0.2)
|
35
36
|
dry-equalizer (~> 0.2)
|
@@ -41,35 +42,37 @@ GEM
|
|
41
42
|
dry-inflector (~> 0.1, >= 0.1.2)
|
42
43
|
dry-logic (~> 1.0, >= 1.0.2)
|
43
44
|
hirb (0.7.3)
|
44
|
-
i18n (1.8.
|
45
|
+
i18n (1.8.5)
|
45
46
|
concurrent-ruby (~> 1.0)
|
46
47
|
method_profiler (2.0.1)
|
47
48
|
hirb (>= 0.6.0)
|
48
|
-
method_source (0.
|
49
|
-
minitest (5.14.
|
50
|
-
|
49
|
+
method_source (1.0.0)
|
50
|
+
minitest (5.14.2)
|
51
|
+
nxt_init (0.1.5)
|
51
52
|
activesupport
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
nxt_registry (0.3.2)
|
54
|
+
activesupport
|
55
|
+
pry (0.13.1)
|
56
|
+
coderay (~> 1.1)
|
57
|
+
method_source (~> 1.0)
|
55
58
|
rake (12.3.3)
|
56
|
-
rspec (3.
|
57
|
-
rspec-core (~> 3.
|
58
|
-
rspec-expectations (~> 3.
|
59
|
-
rspec-mocks (~> 3.
|
60
|
-
rspec-core (3.
|
61
|
-
rspec-support (~> 3.
|
62
|
-
rspec-expectations (3.
|
59
|
+
rspec (3.10.0)
|
60
|
+
rspec-core (~> 3.10.0)
|
61
|
+
rspec-expectations (~> 3.10.0)
|
62
|
+
rspec-mocks (~> 3.10.0)
|
63
|
+
rspec-core (3.10.0)
|
64
|
+
rspec-support (~> 3.10.0)
|
65
|
+
rspec-expectations (3.10.0)
|
63
66
|
diff-lcs (>= 1.2.0, < 2.0)
|
64
|
-
rspec-support (~> 3.
|
65
|
-
rspec-mocks (3.
|
67
|
+
rspec-support (~> 3.10.0)
|
68
|
+
rspec-mocks (3.10.0)
|
66
69
|
diff-lcs (>= 1.2.0, < 2.0)
|
67
|
-
rspec-support (~> 3.
|
68
|
-
rspec-support (3.
|
70
|
+
rspec-support (~> 3.10.0)
|
71
|
+
rspec-support (3.10.0)
|
69
72
|
thread_safe (0.3.6)
|
70
|
-
tzinfo (1.2.
|
73
|
+
tzinfo (1.2.8)
|
71
74
|
thread_safe (~> 0.1)
|
72
|
-
zeitwerk (2.
|
75
|
+
zeitwerk (2.4.1)
|
73
76
|
|
74
77
|
PLATFORMS
|
75
78
|
ruby
|
data/README.md
CHANGED
@@ -16,138 +16,185 @@ Or install it yourself as:
|
|
16
16
|
|
17
17
|
$ gem install nxt_schema
|
18
18
|
|
19
|
-
##
|
19
|
+
## What it is for?
|
20
|
+
|
21
|
+
NxtSchema is a type casting and validation framework that allows you to validate and type cast arbitrary nested
|
22
|
+
structures of data.
|
23
|
+
|
24
|
+
### Usage
|
20
25
|
|
21
26
|
```ruby
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
schema(:address) do
|
29
|
-
requires(:street, :String)
|
30
|
-
requires(:street_number, :Integer)
|
31
|
-
end
|
27
|
+
PERSON = NxtSchema.schema(:person) do
|
28
|
+
node(:first_name, :String)
|
29
|
+
node(:last_name, :String)
|
30
|
+
node(:email, :String, optional: true).validate(:includes, '@')
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
input = {
|
34
|
+
first_name: 'Andy',
|
35
|
+
last_name: 'Robecke',
|
36
|
+
email: 'andreas@robecke.de'
|
37
|
+
}
|
38
38
|
|
39
|
-
|
40
|
-
nodes(:employees) do
|
41
|
-
hash(:employee) do
|
42
|
-
POSITIONS = %w[senior junior intern]
|
39
|
+
result = PERSON.apply(input: input)
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
requires(:position, NxtSchema::Types::Enums[*POSITIONS])
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Schema with array root
|
53
|
-
schema = NxtSchema.roots(:companies) do
|
54
|
-
schema(:company) do
|
55
|
-
requires(:name, :String)
|
56
|
-
requires(:value, :Integer).maybe(nil)
|
57
|
-
end
|
58
|
-
end
|
41
|
+
result.valid? # => true
|
42
|
+
result.output # => input
|
43
|
+
```
|
59
44
|
|
60
|
-
|
61
|
-
|
45
|
+
### Nodes
|
46
|
+
|
47
|
+
A schema consists of a number of nodes. Every node has a name and an associated type for casting it's input when the
|
48
|
+
schema is applied. Schemas can consist of 4 different kinds of nodes:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
NxtSchema::Node::Schema # => Hash of values
|
52
|
+
NxtSchema::Node::Collection # => Array of values
|
53
|
+
NxtSchema::Node::AnyOf # => Any of the defined schemas
|
54
|
+
NxtSchema::Node::Leaf # => Node without sub nodes
|
62
55
|
```
|
63
56
|
|
64
|
-
|
57
|
+
The kind of node dictates how the schema is applied to the input. On the root level the following methods are available
|
58
|
+
to create schemas:
|
65
59
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
60
|
+
```ruby
|
61
|
+
NxtSchema.schema { ... } # => Create a schema node
|
62
|
+
NxtSchema.collection { ... } # => Create an array of nodes
|
63
|
+
NxtSchema.any_of { ... } # => Create a collection of allowed schemas
|
64
|
+
```
|
70
65
|
|
71
|
-
####
|
66
|
+
#### Node predicate aliases
|
67
|
+
|
68
|
+
Of course these nodes can be combined and nested in arbitrary manner. When defining nodes within a schema, nodes are
|
69
|
+
always required per default. You can create nodes with the node method or several useful helper methods.
|
72
70
|
|
73
71
|
```ruby
|
74
|
-
NxtSchema.
|
75
|
-
node(:first_name, :String)
|
76
|
-
|
77
|
-
|
72
|
+
NxtSchema.schema(:person) do
|
73
|
+
required(:first_name, :String) # => same as node(:first_name, :String)
|
74
|
+
optional(:last_name, :String) # => same as node(:first_name, :String, optional: true)
|
75
|
+
omnipresent(:email, :String) # => same as node(:first_name, :String, omnipresent: true)
|
78
76
|
end
|
79
77
|
```
|
80
78
|
|
81
|
-
|
82
|
-
(omni)present nodes.
|
79
|
+
**NOTE: The methods above only apply to the keys of your schema and do not make any assumptions about values!**
|
83
80
|
|
84
|
-
|
81
|
+
In other word this means that making a node optional only makes your node optional. When your input contains the key but
|
82
|
+
the value is nil, you will still get an error in case there is no default or maybe expression that applies. Omnipresent
|
83
|
+
node also only inject the node into the schema but do not inject a default value. In order to inject a key with value
|
84
|
+
into a schema you also have to combine the node predicates with default value method described below. For clarification
|
85
|
+
check out the examples below:
|
85
86
|
|
86
87
|
```ruby
|
87
|
-
NxtSchema.
|
88
|
-
|
89
|
-
optional(:last_name, :String)
|
90
|
-
present(:email, :String)
|
88
|
+
schema = NxtSchema.schema(:person) do
|
89
|
+
optional(:email, :String)
|
91
90
|
end
|
91
|
+
|
92
|
+
result = schema.apply(input: { email: nil })
|
93
|
+
result.errors # => {"person.email"=>["nil violates constraints (type?(String, nil) failed)"]}
|
94
|
+
result.output # => {:email=>nil}
|
95
|
+
|
96
|
+
result = schema.apply(input: {})
|
97
|
+
result.errors # => {}
|
98
|
+
result.output # => {}
|
92
99
|
```
|
93
100
|
|
94
|
-
|
101
|
+
```ruby
|
102
|
+
schema = NxtSchema.schema(:person) do
|
103
|
+
optional(:email, :String).default('andreas@robecke.de')
|
104
|
+
end
|
95
105
|
|
96
|
-
|
106
|
+
result = schema.apply(input: { email: nil })
|
107
|
+
result.errors # => {}
|
97
108
|
|
98
|
-
|
109
|
+
result = schema.apply(input: {})
|
110
|
+
result.errors # => {}
|
111
|
+
result.output # => {:email=>"andreas@robecke.de"}
|
112
|
+
```
|
99
113
|
|
100
114
|
```ruby
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
hash(:test) do ... end
|
105
|
-
```
|
115
|
+
schema = NxtSchema.schema(:person) do
|
116
|
+
omnipresent(:email, :String)
|
117
|
+
end
|
106
118
|
|
107
|
-
|
119
|
+
result = schema.apply(input: {})
|
120
|
+
result.errors # => {}
|
121
|
+
result.output # => {:email=>NxtSchema::MissingInput}
|
122
|
+
```
|
108
123
|
|
109
124
|
```ruby
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
nodes(:test) do
|
114
|
-
# For type checking of array items you can simply add a node with the expected type.
|
115
|
-
# As always you need to give it a name. This would result in an array of string items
|
116
|
-
required(:item, :String)
|
125
|
+
schema = NxtSchema.schema(:person) do
|
126
|
+
# make sure a node is always present and at least nil even though the type is String
|
127
|
+
omnipresent(:email, :String).default(nil).maybe(:nil?)
|
117
128
|
end
|
118
129
|
|
119
|
-
|
130
|
+
result = schema.apply(input: {})
|
131
|
+
result.errors # => {}
|
132
|
+
result.output # => {:email=>nil}
|
133
|
+
|
134
|
+
result = schema.apply(input: { email: 'andreas@robecke.de' })
|
135
|
+
result.errors # => {}
|
136
|
+
result.output # => {:email=>"andreas@robecke.de"}
|
120
137
|
```
|
121
138
|
|
122
|
-
|
139
|
+
##### Conditionally optional nodes
|
140
|
+
|
141
|
+
You can also pass a proc as the optional option. This will add a validator to the parent node that makes sure thar the
|
142
|
+
key is present if the optional condition does not apply.
|
123
143
|
|
124
144
|
```ruby
|
125
|
-
|
126
|
-
required(:
|
127
|
-
|
145
|
+
schema = NxtSchema.schema(:contact) do
|
146
|
+
required(:first_name, :String)
|
147
|
+
required(:last_name, :String)
|
148
|
+
node(:email, :String, optional: ->(node) { node.up[:last_name].input == 'Robecke' })
|
149
|
+
end
|
150
|
+
|
151
|
+
result = schema.apply(input: { first_name: 'Andy', last_name: 'Other' })
|
152
|
+
result.errors # => {"contact"=>["Required key :email is missing"]}
|
153
|
+
|
154
|
+
result = schema.apply(input: { first_name: 'Andy', last_name: 'Robecke' })
|
155
|
+
result.errors # => {}
|
156
|
+
```
|
157
|
+
|
158
|
+
#### Combining Schemas
|
128
159
|
|
129
|
-
|
160
|
+
You can also simply reuse a schema by passing it to the node method as the type of a node. When doing so the schema
|
161
|
+
will be cloned with the same options and configuration as the schema passed in.
|
130
162
|
|
131
163
|
```ruby
|
132
|
-
|
133
|
-
|
164
|
+
ADDRESS = NxtSchema.schema(:address) do
|
165
|
+
required(:street, :String)
|
166
|
+
required(:town, :String)
|
167
|
+
required(:zip_code, :String)
|
168
|
+
end
|
169
|
+
|
170
|
+
PERSON = NxtSchema.schema(:person) do
|
171
|
+
required(:first_name, :String)
|
172
|
+
required(:last_name, :String)
|
173
|
+
optional(:address, ADDRESS)
|
174
|
+
end
|
134
175
|
```
|
135
176
|
|
136
177
|
### Types
|
137
178
|
|
138
|
-
The type system is built with dry-types from the amazing https://dry-rb.org
|
179
|
+
The type system is built with dry-types from the amazing https://dry-rb.org eco system. Even though dry-types also
|
139
180
|
offers features such as default values for types as well as maybe types, these features are built directly into
|
140
|
-
NxtSchema.
|
141
|
-
|
142
|
-
|
143
|
-
|
181
|
+
NxtSchema.
|
182
|
+
|
183
|
+
Please note that Dry.rb also has a gem for schemas: https://dry-rb.org/gems/dry-schema and another one dedicated to
|
184
|
+
validations explicitly https://dry-rb.org/gems/dry-validation. You should probably go and check those out! NxtSchema
|
185
|
+
is trying to implement a simpler solution that is easy to understand yet powerful enough for most tasks.
|
186
|
+
|
187
|
+
In NxtSchema every node has a type and you can either provide a symbol that will be resolved
|
188
|
+
through the type system of the schema or you can directly provide an instance of dry type and thus use your
|
189
|
+
custom types. This means you can basically build any kind of objects such as structs and models from your data and
|
190
|
+
you are not limited to just hashes arrays and primitives.
|
144
191
|
|
145
192
|
#### Default type system
|
146
193
|
|
147
194
|
You can tell your schema which default type system it should use. Dry-Types comes with a few built in type systems.
|
148
195
|
Per default NxtSchema will use nominal types if not specified otherwise. If the type cannot be resolved from the default
|
149
|
-
type system that was specified
|
150
|
-
a separate type system per node if that's what you
|
196
|
+
type system that was specified NxtSchema will always fallback to nominal types. In theory you can provide
|
197
|
+
a separate type system per node if that's what you need.
|
151
198
|
|
152
199
|
```ruby
|
153
200
|
NxtSchema.root do
|
@@ -188,7 +235,7 @@ NxtSchema.register_type(
|
|
188
235
|
# once registered you can use the type in your schema
|
189
236
|
|
190
237
|
NxtSchema.root(:company) do
|
191
|
-
required(:name,
|
238
|
+
required(:name, :MyCustomStrippedString)
|
192
239
|
end
|
193
240
|
```
|
194
241
|
|
@@ -198,34 +245,41 @@ end
|
|
198
245
|
|
199
246
|
```ruby
|
200
247
|
# Define default values as options or with the default method
|
201
|
-
required(:test, :
|
202
|
-
required(:test, :String, default:
|
248
|
+
required(:test, :DateTime).default(-> { Time.current })
|
249
|
+
required(:test, :String, default: 'Andy')
|
203
250
|
```
|
204
251
|
|
205
252
|
#### Maybe values
|
206
253
|
|
207
|
-
|
254
|
+
With maybe you can allow your values to be of a certain type and halt conversion. **Note: This means that your output
|
255
|
+
will simply be set to the input without coercing the value!**
|
208
256
|
|
209
257
|
```ruby
|
210
258
|
# Define maybe values (values that do not match the type)
|
211
|
-
required(:test, :String).maybe(
|
212
|
-
|
259
|
+
required(:test, :String).maybe(:nil?)
|
260
|
+
|
261
|
+
nodes(:tests).maybe(:empty?) do # will allow the collection to be empty
|
262
|
+
required(:test, :String)
|
263
|
+
end
|
264
|
+
|
213
265
|
```
|
214
266
|
|
215
267
|
### Validations
|
216
268
|
|
217
269
|
NxtSchema comes with a simple validation system and ships with a small set of useful validators. Every node in a schema
|
218
270
|
implements the `:validate` method. Similar to ActiveModel::Validations it allows you to simply add errors to a node
|
219
|
-
based on some condition.
|
271
|
+
based on some condition. When the node is yielded to your validation proc you have access to the nodes input with
|
272
|
+
`node.input` and `node.index` when the node is within a collection of nodes as well as `node.name`. Furthermore you have
|
273
|
+
access to the context that was passed in when defining the schema or passed to the apply method later.
|
220
274
|
|
221
275
|
```ruby
|
222
|
-
# Simple validation
|
223
|
-
required(:test, :String).validate
|
276
|
+
# Simple custom validation
|
277
|
+
required(:test, :String).validate(-> (node) { node.add_error("#{node.input} is not valid") if node.input == 'not allowed' })
|
224
278
|
# Built in validations
|
225
279
|
required(:test, :String).validate(:attribute, :size, ->(s) { s < 7 })
|
226
|
-
required(:test, :String).validate(:
|
227
|
-
required(:test, :String).validate(:
|
228
|
-
required(:test, :String).validate(:
|
280
|
+
required(:test, :String).validate(:equal_to, 'same')
|
281
|
+
required(:test, :String).validate(:excluded_in, %w[not_allowed]) # excluded in the target: %w[not_allowed]
|
282
|
+
required(:test, :String).validate(:included_in, %w[allowed]) # included in the target: %w[allowed]
|
229
283
|
required(:test, :Array).validate(:excludes, 'excluded') # array value itself must exclude 'excluded'
|
230
284
|
required(:test, :Array).validate(:includes, 'included') # array value itself must include 'included'
|
231
285
|
required(:test, :Integer).validate(:greater_than, 1)
|
@@ -323,7 +377,7 @@ schema = NxtSchema.root(additional_keys: :allow) do
|
|
323
377
|
required(:test, :String)
|
324
378
|
end
|
325
379
|
|
326
|
-
schema.apply(test: 'getsafe', other: 'Heidelberg')
|
380
|
+
schema.apply(input: {test: 'getsafe', other: 'Heidelberg'})
|
327
381
|
schema.valid? # => true
|
328
382
|
schema.value # => { test: 'getsafe', other: 'Heidelberg' }
|
329
383
|
```
|
@@ -334,12 +388,12 @@ You may want to transform the keys from your input. Therefore specify the transf
|
|
334
388
|
when you want your schema to return only symbolized keys for example.
|
335
389
|
|
336
390
|
```ruby
|
337
|
-
schema = NxtSchema.root(transform_keys:
|
391
|
+
schema = NxtSchema.root(transform_keys: ->(key) { key.to_sym}) do
|
338
392
|
required(:test, :String)
|
339
393
|
end
|
340
394
|
|
341
|
-
schema.apply('test' => 'getsafe') # => {:test=>"getsafe"}
|
342
|
-
schema.apply(test: 'getsafe') # => {:test=>"getsafe"}
|
395
|
+
schema.apply(input: { 'test' => 'getsafe' }) # => {:test=>"getsafe"}
|
396
|
+
schema.apply(input: { test: 'getsafe' }) # => {:test=>"getsafe"}
|
343
397
|
```
|
344
398
|
|
345
399
|
#### Adding meta data to nodes
|
@@ -356,10 +410,18 @@ schema = NxtSchema.root do
|
|
356
410
|
required(:test, :String).meta(ERROR_MESSAGES).validate ->(node) { node.add_error(node.meta.fetch(node.name)) }
|
357
411
|
end
|
358
412
|
|
359
|
-
schema.apply(test: 'getsafe')
|
413
|
+
schema.apply(input: { test: 'getsafe' })
|
360
414
|
schema.error # {"root.test"=>["This is always broken"]}
|
361
415
|
```
|
362
416
|
|
417
|
+
#### Contexts
|
418
|
+
|
419
|
+
# TODO
|
420
|
+
|
421
|
+
##### Build time
|
422
|
+
|
423
|
+
##### Apply time
|
424
|
+
|
363
425
|
## Development
|
364
426
|
|
365
427
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -368,22 +430,30 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
368
430
|
|
369
431
|
## Contributing
|
370
432
|
|
371
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
433
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/getand.
|
372
434
|
|
373
435
|
## License
|
374
436
|
|
375
437
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
376
438
|
|
377
|
-
|
378
|
-
|
379
|
-
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
439
|
+
## TODO:
|
440
|
+
|
441
|
+
- Allow to disable validation when applying
|
442
|
+
--> Are there attributes that should be moved to apply time?
|
443
|
+
- Should we have a global and a local registry for validators?
|
444
|
+
--> Would be cool to register things for the schema only
|
445
|
+
--> Would be cool if this was extendable
|
446
|
+
- Do we need all off in order to combine multiple schemas?
|
447
|
+
- Think about a good implementation of params framework for controllers
|
448
|
+
|
449
|
+
```ruby
|
450
|
+
PARAMS = NxtRegistry::Registry.new do
|
451
|
+
register(:create) do
|
452
|
+
NxtSchema.params do
|
453
|
+
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
PARAMS.resolve(:create).apply(input: params)
|
459
|
+
```
|