npm install valerieSimple javascript object validator
The goal of this project is to provide a simple, intuitive, extensible, independent, and isomorphic javascript object validation library.
* No dependencies
* Very lightweight
* Easy to use both server- and browser-side
* Validation rules are standard functions (keep it simple)
* Supports async/promise-based validation rules
* Custom rules are super easy to make
* Custom error messages for all built-in rules
* Source uses ES6/7 features (transpiled to ES5 for browsers)
* Full tests and linting
Import the function and built-in rules
``js`
import createValidator from 'valerie';
import { number, oneOf } from 'valerie/rules';
import { range, required } from 'valerie/rules/extended';
Compose the validation schema for our object
`js`
const schema = {
id: [required('id is required'), number('id must be a number')],
name: {
first: required('first name is required'),
last: required('last name is required')
},
age: range(0, 123, 'must be a normal human age'),
favoriteColor: oneOf(['blue', 'red', 'yellow'], 'must be a primary color')
};
Create the object validator, which is a function taking a single object parameter, and returns a Promise which resolves to an array containing errors. The array will be empty if there are no errors.
`js`
const validate = createValidator(schema);
Validate
`js
const input = {
id: 10,
name: {
first: 'foo'
},
age: 99,
favoriteColor: 'potato'
};
// ES7
const errors = await validate(input);
// ES6
validate(input).then(errors => {
// tell the user about the errors!
})
// ES5
validate(input).then(function(errors) {
// tell the user about the errors!
});
/*
[
{
property: 'name.last',
message: 'last name is required'
},
{
property: 'favoriteColor',
message: 'must be a primary color'
}
]
*/
// or just get the first error
const errors = await validate(input, 1);
/*
[
{
property: 'name.last',
message: 'last name is required'
}
]
*/
`
Validation rules are just simple functions that take a single input, the value to validate, and return undefined if valid, or an error message if not.
The built-in rule objects exported from valerie/rules are functions that take a set of options and return the rule function itself.
Example:
`js
import { is } from 'valerie/rules';
const isTrue = is(true, 'value must be true');
isTrue(false); // 'value must be true';
isTrue(true); // undefined
`
The simple rules are largely based on the fundamental javascript operations.
#### is(target, [message = "is"])
Tests if a value is strictly equal (===) to a target value.
- target: what the validated value should equalmessage
- : optional custom error message
`js
const isBar = equalTo('bar', 'foo must be bar');
const validate = createValidator({ foo: isBar });
const errors = await validate({ foo: 'bar' });
`
#### equalTo(target, [message = "equalTo"])
Tests if a value is loosely equal (==) to a target value.
- target: what the validated value should equalmessage
- : optional custom error message
`js
const isBar = equalTo('bar', 'foo must be bar');
const validate = createValidator({ foo: isBar });
const errors = await validate({ foo: new String('bar') });
`
#### number([message = "number"])
Tests if a value is a number (!isNaN).
- message: optional custom error message
`js
const isNumber = number(foo 'must be a number');
const validate = createValidator({ foo: isNumber });
const errors = await validate({ foo: Math.PI });
`
#### greaterThan(target, [message = "greaterThan"])
Tests if a value is greater than (>) a target value.
- target: what the validated value should be greater thanmessage
- : optional custom error message
`js
const isPositive = greaterThan(0, 'foo must be positive');
const validate = createValidator({ foo: isPositive });
const errors = await validate({ foo: 1 });
`
#### lessThan(target, [message = "lessThan"])
Tests if a value is less than (<) a target value.
- target: what the validated value should be less thanmessage
- : optional custom error message
`js
const isNegative = lessThan(0, 'foo must be negative');
const validate = createValidator({ foo: isNegative });
const errors = await validate({ foo: -1 });
`
#### array([message = "array"])
Tests if a value is an array (Array.isArray).
- message: optional custom error message
`js
const isArray = array('foo must be an array');
const validate = createValidator({ foo: isArray });
const errors = await validate({ foo: ['bar', 'baz'] });
`
#### contains(item, [message = "contains"])
Tests if a value contains (indexOf) an item.
- item: item that value should containmessage
- : optional custom error message
`js
const containsBar = contains('bar', 'foo must contain bar');
const validate = createValidator({ foo: containsBar });
const errors = await validate({ foo: ['bar'] });
`
#### oneOf(options, [message = "oneOf"])
Tests if a value is equal to (===) an item in an Array.
- options: array of items to check againstmessage
- : optional custom error message
`js
const isPrimaryColor = oneOf(['red', 'blue', 'yellow'], 'foo must be a primary color');
const validate = createValidator({ foo: isPrimaryColor });
const errors = await validate({ foo: 'blue' });
`
#### isInstanceOf(type, [message = "isInstanceOf"])
Tests if a value is an instance of a class (instanceof).
- type: what the validated value should be an instance ofmessage
- : optional custom error message
`js
const isBar = isInstanceOf(Bar, 'foo must be bar');
const validate = createValidator({ foo: isBar });
const errors = await validate({ foo: new Bar() });
`
#### isTypeOf(type, [message = "isTypeOf"])
Tests if a value is of a given type (typeof).
- type: what the validated value should be a type ofmessage
- : optional custom error message
`js
const isString = isTypeOf(Bar, 'foo must be a string');
const validate = createValidator({ foo: isString });
const errors = await validate({ foo: 'bar' });
`
#### hasProperty(property, [message = "hasProperty"])
Tests if an object has a child property (hasOwnProperty).
- property: name of the propertymessage
- : optional custom error message
`js
const hasBar = hasProperty('bar', 'foo must have bar property');
const validate = createValidator({ foo: hasBar });
const errors = await validate({
foo: {
bar: true
}
});
`
These rules take one or more rules as input and return new, compoud rule.
#### async and(rules, [message = "and"])
Tests if a value is valid against all rules within an Array.
- rules: array of rules to validate againstmessage
- : optional custom error message
`js
const isArrayContainingBar = and([array(), contains('bar')], 'foo must be an array containing "bar"');
const validate = createValidator({ foo: isArrayContainingBar });
const errors = await validate({ foo: ['bar', 'baz', 'qux'] );
`
#### async or(rules, [message = "or"])
Tests if a value is is valid against at least one rule within an Array of rules.
- rules: array of rules to validate againstmessage
- : optional custom error message
`js
const isNumberOrX = or([number(), equals('x')], 'foo must be a number or the letter "x"');
const validate = createValidator({ foo: isNumberOrX });
const errors = await validate({ foo: 'x' );
`
#### async not(rule, [message = "not"])
Tests if a value is _not_ valid against rule.
- rule: rule to validate againstmessage
- : optional custom error message
`js
const isNotNumber = not(number(), 'foo must not be a number');
const validate = createValidator({ foo: isNotNumber });
const errors = await validate({ foo: 'bar' );
`
#### regex(pattern, [message = "regex"])
Tests if a value matches a regex (.match)
- pattern: regexp (RegExp or /pattern/)message
- : optional custom error message
`js
const isEMail = regex(/^\S+@\S+$/, 'foo must be an email address');
const validate = createValidator({ foo: isEMail });
const errors = await validate({ foo: 'bar@baz.com' });
`
Extended rules use the simple rules to form more complex logic
Tests if a value is between two values. Generally want to use with number. Depends on and, or, greaterThan, lessThan, and equalTo.
- min: minimum value, inclusivemax
- : maximum value, inclusivemessage
- : optional custom error message
`js
const isNumber = number('foo must be a number');
const isHumanAge = range(0, 123, 'foo must be a human age');
const validate = createValidator({ foo: [isNumber, isHumanAge] });
const errors = await validate({ foo: 100 });
`
#### async required([message = "required"])
Tests if a value exists (not undefined, not an empty string, not an empty array). Depends on and, defined, and notEmpty.
- message: optional custom error message
`js
const isRequired = required('foo is required');
const validate = createValidator({ foo: isRequired });
const errors = await validate({ foo: 'bar' );
`
Custom rules are easy to implement. They're simply functions that take a single value and return an error message for failure, and undefined for passing.
`js
const isEven = value => {
if (value % 2 !== 0) return 'value must be even';
};
isEven(4); // undefined
isEven(5); // value must be even
const validate = createValidator({
foo: isEven
});
const errors = await validate({
foo: 5
});
/*
[
{
property: 'foo',
message: 'value must be even'
}
]
*/
`
Built-in rules use currying to allow options and custom error messages to be set. You can follow this technique like so:
`js
const divisibleBy = (divisor, message = 'divisibleBy') => {
return value => {
if (value % divisor !== 0) return message;
}
};
const isDivisibleBy3 = divisibleBy(3, 'value must divisibly by 3');
`
Check out the other rules for more examples.
* Rules
* email`
* Examples of client- and server-side usage
* Example of promise rule
* Compare to other libs
* https://github.com/hapijs/joi (large)
* https://github.com/molnarg/js-schema (no custom messages)
* https://github.com/ansman/validate.js