Built-in Specs
import {spec, symbol, valid, conform} from 'js.spec'
and (name, ...specs)
Data must conform to every provided spec. For instance to match an even number greater than 1000:
const big_even = spec.and("big even", spec.number, spec.even, function big(nr) {
return big > 1000;
});
valid(big_even, 1000) // => false
valid(big_even, 1001) // => false
valid(big_even, 1002) // => true
or (name, ...specs)
Data must conform to at least one provided spec. The order in which they are validated is not defined. conform
returns matched branches along with input data.
const big_or_even = spec.or("big or even", {
'even': spec.even,
'big': nr => nr > 1000
})
valid(big_or_even, 999) // => false
valid(big_or_even, 1000) // => true
valid(big_or_even, 1001) // => true
conform(big_or_even, 1000) // => ['even', 1000]
conform(big_or_even, 1001) // => ['big', 1001]
nilable (name, spec)
By default no spec accepts null or undefined as valid input. Wrap your spec in nilable
to change this.
const big = spec.and("big", spec.number, x => x > 1000)
valid(big, null) // => false
valid(big, 1002) // => true
const maybe_big = spec.nilable("maybe big", big)
valid(maybe_big, null) // => true
valid(maybe_big, 1002) // => true
collection(name, spec, options)
Used to define collections with items of the same type. Works with Arrays and Sets. Accepts an option map as optional second parameter.
const {minCount} = symbol
const tag_cloud = spec.collection("tag cloud", spec.string, {
[minCount]: 1
});
valid(tag_cloud, []) // => false
valid(tag_cloud, ['blog']) // => true
valid(tag_cloud, new Set(['blog'])) // => true
valid(tag_cloud, [1, 2, 3]) // => false
valid(tag_cloud, ) // => false, use spec.nilable(spec.collOf(...))
valid(tag_cloud, [null]) // => false, use spec.nilable(spec.string)
Options
symbol.count
: Collection must contain exactlyn
items.symbol.minCount
: Collection must contain at leastn
items.symbol.maxCount
: Collection must contain at mostn
items.
symbol.count
takes precedence over the other options.
tuple (name, ...specs)
Used to define collections with items of possibly different types. Works only with arrays as order is important. Does not accept options.
// team, goals
const team_score = spec.tuple("team score", spec.string, spec.int)
valid(team_score, ['arsenal', 0]) // => true
valid(team_score, [0, 'arsenal']) // => false
// home team, away team
const match_score = spec.tuple("match result", team_score, team_score)
valid(match_score, [
['arsenal', 0],
['manchester city', 1]
]) // => true
map (name, shape)
Used to define the shape of maps. By default all keys are required. Use spec.optional
key to define optional keys.
const {optional} = symbol
const person = spec.map("person", {
email: spec.string,
[optional]: {
name: spec.string
}
})
valid(person, { email: '[email protected]' }) // => true
valid(person, { name: 'hans' }) // => false
valid(person, {
email: '[email protected]',
name: 'hans'
}) // => true
valid(person, { email: false }) // => false
oneOf (name, ...values)
Used to define "one out of these values", like an enum. (It's called oneOf
because enum
is a reserved word in Javascript.)
const state = oneOf("state", "pending", "ready", "cancelled")
valid(state, "pending") // => true
valid(state, "unknown") // => false