A simple input validation system designed for apis or form inputs. Supports custom validators and actually readable outputs.
Use Yarn to add APIExpect to your project:
yarn add api-expect
APIExpect exports a singleton by default. Import the module and start creating templates!
const expect = require('api-expect')
const template = { myField: 'string:3:50' }
const compiledTemplate = expect.compile(template)
var data = { myField: 'someStuff', _otherMetaField: 42 }
var result = expect.exec(compiledTemplate, data)
// result.error = false
// result.output = { myField: 'someStuff' }
APIExpect has a built-in ExpressJS middleware creator. It automatically compiles templates, then executes them for all data incoming data in its route. Usage:
expect.middleware(template, source, options)
Where template
is an uncompile template object, source
is property of req
that has the data, and options
is an optional object of configuration.
Example:
const express = require('express')
const expect = require('api-expect')
var router = express.Router()
router.post('/signup',
expect.middleware({ name: 'string:3', password: 'string:6' }, 'body')),
(req, res, next) => {
// req.data will have all validated data
}
)
Convenience functions are provided for the common data sources:
expect.body(template) // same as expect.middleware(template, 'body')
expect.query(template) // same as expect.middleware(template, 'query')
expect.params(template) // same as expect.middleware(template, 'params')
All three functions also support options
as a second parameter.
Field | Meaning | Default |
---|---|---|
destination | The field in req where the output should be placed. |
'data' |
dest | Alias of destination |
null |
inPlace | When true, the output will replace the input data | false |
APIExpect was designed to limit tedium and make it easy to create validation templates on the fly. It supports 3 main style of templates: short-hand, array short-hand, and long-form. As you may have guessed, both short-hand forms are just convinence functions that expand to the long-form internally. The short-hand forms can only pass static arguments to the validators, so in circumstances where you must pass a variable or externally-defined constant, the long form is required. Below is a brief overview of the three forms.
This is the most common form and is very handy for simple validation. The basic format is:
{
field: 'validator:arg1:arg2:arg3:...'
}
See the Validators section for more information on the arguments.
Example:
{
name: 'string:5'
}
In words, this template translates to: "The name
field must be a string of at least 5 characters".
Similar to the short-hand form, this form combines the Array validator with any other validator for the values of the array. The format is:
{
field: ['validator:arg1:arg2:...', minLength, maxLength]
}
The minLength
is optional and defaults to 0; maxLength
is also optional and defaults to infinity. See the Validators section for more information on the arguments.
Example:
{
favouriteColours: ['string:3:20', 0, 5]
}
This template translates to: "The favouriteColours
field must be an array of strings whose lengths are between 3 and 20 characters; the array must have between 0 and 5 elements".
And when the convient methods fail to deliver, we resort to verbose measures. The long format is:
{
field: { 'validator': [arg1, arg2, arg3, ...] }
}
See the Validators section for more information on the arguments.
Example:
const STATUSES = [ 'Active', 'Inactive', 'Disabled' ]
{
status: { 'index': [STATUSES] }
}
This template translates to: "The status
field must be a number who value is greater than or equal to 0, and less the length of the array STATUSES (in this case 3)".
When a required field is invalid, the whole input is rejected and error messages are returned. When an optional field is invalid, its value is ignored. Most validators have a 'default' field which will be returned in the final output when the optional field is either empty or invalid.
By default, all fields are required. You can change by setting the value defaultOptional
.
Example:
const expect = require('api-expect')
// Make all fields optional by default
expect.defaultOptional = true
// Make all fields required by default
expect.defaultOptional = false
NOTE: If you change defaultOptional
to be true, the short-hand behaviour changes! (See When Optional By Defaul)
To make a specific field optional, insert the '~' field in a short-hand validator, or a boolean value for required
as the first parameter for the array in an array-short-hand or long-form entry.
Example:
const STATUSES = [ 'Active', 'Inactive', 'Disabled' ]
{
status: { 'index', [false, STATUSES] },
colour: '~string:3:50:black'
}
Translation: "The status
field should be a number >= 0 and < STATUSES.length
but default to 0; and colour
should be a string whose length is between 3 and 50, but default to 'black'".
When defaultOptional
is true
, all fields are optional by default. To make a specific field required, preappend an *
(asterisk), as such:
{
name: '*string:3',
colour: 'string:3:50:black'
}
Translation: "The name
field must be a string of at least 3 characters; and the colour
field should be a string whose length is between 3 and 50, but default to 'black'".
There are a wealth of default validators that exist. All validators' first argument is required
(omitted for breivity).
Validator Name | Arg1 | Arg2 | Arg 3 |
---|---|---|---|
object | Uncompiled Template | ||
array | Validator | minLength | maxLength |
string | minLength | maxLength | defaultValue |
html | minLength | maxLength | defaultValue |
defaultValue | |||
url | defaultValue | ||
bool | defaultValue | ||
number | min | max | defaultValue |
index | array | min | defaultValue |
date | min | max | defaultValue |
Note: the html
validator strips all tags except <b>, <blockquote>, <code>, <del>, <dd>, <dl>, <dt>, <em>, <h1>, <h2>, <h3>, <i>, <li>, <ol>, <p>, <pre>, <s>, <sup>, <sub>, <strong>, <strike>, <ul>, <br>, and <hr>, and removes all styling.
Copyright © 2017 Mesbah Mowlavi. Released under the MIT Licence.