To define your validation rules, provide a Map
. Keys are field names, values are either a validation rule, or an array of validation rules.
// one rule
const rules = new Map([
['name', required]
])
// multiple rules
const rules = new Map([
['name', [required, longerThanChars(1)]]
])
Validation rules are functions which are given three arguments:
value
- the value of the field being validatedfield
- the name of the field being validatedfields
- an object of all fields, so you can build cross-field validations
The following validation rules are currently provided:
required
- asserts the field is not null/undefinedmustBe(expected)
- asserts the field matchesexpected
eq(expected)
- alias ofmustBe
oneOf(expectations)
- asserts the field is one of theexpectations
(array)shorterThanChars(expectedMaxChars)
- asserts the field is shorter thanexpectedMaxChars
longerThanChars(expectedMinChars)
- asserts the field is longer thanexpectedMinChars
As you can see, some validations are simple functions, others are function factories which allow you to pass through expectations.
We could write a custom rule to assert the field "starts with **
":
// es6
const startsWithStars = value => assert(value.startsWith('**'), 'Must start with "**"')
// es5
function startsWithStars(value) {
return assert(value.indexOf('**') === 0, 'Must start with "**"')
}
Or, we could write a generic "starts with" rule:
// es6
const startsWith = expected => value => assert(value.startsWith(expected), `Must start with "${expected}"`)
// es5
function startsWith(expected) {
return function(value) {
return assert(value.indexOf(expected) === 0, 'Must start with "' + expected + '"')
}
}
Usage:
const rules = new Map([
['name', [startsWithStars, startsWith('**')]] // both rules assert the same thing
])
The validation system is flexible enough to provide cross-field validation rules. For example, you may want to assert that parent
is required
only if age
is less than 18
. We can use the onlyIf
rule, like so:
const rules = new Map([
['parent', [
onlyIf('age', lessThan(18), required)
]]
])
onlyIf
is a more complex function factory which is provided for you.
By default, each rule provides a generic error message when it fails, e.g. Field is required
or Must be less than "18"
etc.
You can provide custom error messages for each rule by specifying it as a two-field array:
const rules = new Map([
['name', [
[required, "You can't be anonymous, sorry!"]
]],
['age', [
[greaterThan(18), "You must be at least 18"]
]]
])
The message can be provided as a string, or if you want more control over the message, you can provide it as a function which will be given two arguments:
value
- the value of the field being validatedfield
- the name of the field being validated
So you could:
const rules = new Map([
['age', [
[greaterThan(18), value => `Sorry you can't be ${value}, you must be at least 18.`]
]]
])
Which if you provided age
as 17
, would provide the error message "Sorry, you can't be 17, you must be at least 18."
.