simple, flexible validations for node and the browser
MIT License
A DOM-independent validation library for Node.js, io.js and the browser.
It supports both sync
It allows you to seamlessly validate full javascript objects, defining custom messages, labels, and validations, with full support for asynchronous validations with promises. It supports conditional validations, and has powerful, consistent error structuring and utility methods for manipulating your errors' output any way you can imagine.
var mainRules = Checkit(rules);
mainRules
.run(obj)
.then(function(validatedFields) {
console.log('The fields: ' + _.keys(validatedFields).join(', ') + ' were validated!');
})
.caught(Checkit.Error, function(err) {
$("#errors").html(err.map(function(val, key) {
return '<li>' + key + ': ' + val.first().message + '</li>';
}).join(''));
});
npm install checkit
The easiest way to use the library is with webpack or browserify
The main Checkit
constructor may be called with or without the new
keyword, taking a hash of fields/rules for these fields to be validated.
Used to specify the default language key for using a particular language file, currently en, es, ru and fr are supported.
Specifies labels for use in error messages for specific keys
Adds specific messages for individual errors
var checkit = new Checkit({
firstName: 'required',
lastName: 'required',
email: ['required', 'email']
});
var body = {
email: '[email protected]',
firstName: 'Tim',
lastName: 'Griesser',
githubUsername: 'tgriesser'
};
checkit.run(body).then(function(validated) {
console.log(validated);
}).catch(Checkit.Error, function(err) {
console.log(err.toJSON());
})
var checkit = new Checkit({
firstName: 'required',
lastName: 'required',
email: ['required', 'email']
});
var body = {
email: '[email protected]',
firstName: 'Tim',
lastName: 'Griesser',
githubUsername: 'tgriesser'
};
var [err, validated] = checkit.validateSync(body)
// ...
Checkit.check('email', email, ['required', 'email'])
.catch(function(err) {
console.log(err.message)
});
// ES6...
var [err, resp] = Checkit.checkSync('email', email, ['required', 'email'])
if (err) {
} else {
// ...
}
Sometimes you may wish to require a given field conditionally, for example require a field only if another field has a greater value than 100. Or you may need two fields to have a given value only when another field is present. Adding these validation rules doesn't have to be a pain. First, create a Checkit
instance with the main rules that never change:
var checkit = new Checkit({
firstName: ['required'],
lastName: ['required'],
email: ['required', 'email']
});
Then use the maybe
method to add additional rules:
The first of the maybe
method is the hash of validation fields / settings, similar to the main Checkit
object. The second argument is a function, evaluated with the object being validated as the first argument and the context passed to run (if any) as a second argument. If it returns explicitly true
or with a promise fulfilling with true
, it will add an additional validator to the Checkit
object.
This method makes building complex conditional validations a snap.
// In this example, the "authorBio" field is only required if there are
// more than 5 books specified in the input object
checkit.maybe({authorBio: ['required', 'max:500']}, function(input) {
return input.books > 5;
});
// In this example, the "authorBio" field is only required if specified by the context
checkit.maybe({authorBio: ['required', 'max:500']}, function(input, context) {
return context.requireBio;
});
checkit.run(someObj, { requireBio: true })
First, and simplest, you can specify a function on the validation array for a property. For example:
{
email: ['email', function(val) {
return knex('accounts').where('email', '=', val).then(function(resp) {
if (resp.length > 0) throw new Error('The email address is already in use.')
})
}]
}
You may also specify an object in one of the validator slots, specifying at the minimum a rule, and optionally params, label, and message.
{
email: {
rule: 'email',
label: 'Email'
},
first_name: [{
rule: 'required',
message: 'You must supply a first name value!!'
}, {
rule: 'minLength:3',
label: 'first name of this application'
}],
arr: {
rule: 'contains',
params: [10] // Number => Different behavior than "contains:10"
}
}
You may also use the context
parameter passed to run
when using a function on the validation array of a property. This can be particularly useful if your validation function needs to execute within a transaction:
{
email: {
rule: function(val, params, context){
var query = knex('users');
if (context && context.transacting){
query.transacting(context.transacting);
}
return query.where('email', '=', val)
.andWhere('id', '<>', this.target.id)
.then(function(resp){
if (resp.length > 0){
throw new Error('The email address is already in use.');
}
});
}
}
}
Second, you may add a custom validator to the Checkit.Validator
object's prototype, returning a boolean value or a promise.
Checkit.Validator.prototype.unused = function(val, table, column) {
return knex(table).where(column, '=', val).andWhere('id', '<>', this._target.id).then(function(resp) {
if (resp.length > 0) {
throw new Error('The ' + table + '.' + column + ' field is already in use.');
}
});
}
{
email: ['email', 'unused:accounts:email']
}
One of the main features of Checkit
is the error handling; By extending the error object with utility methods from underscore, the errors are even easier to work with.
The main Error object, Checkit.Error
is returned from the has several helper methods & properties, as well as a number of utility methods:
The "errors" property of a Checkit.Error
object is a hash of errors for each of the fields which are considered "invalid" in any way by the validation rules. The keys in this hash are the invalid fields, and the values are Checkit.FieldError objects, which in-turn have an errors
attribute, an array containing errors for each failed rule.
The get
method returns the Checkit.FieldError
object for a specific key, or undefined
if one does not exist.
Useful for debugging, the toString
method converts the Checkit
error into a human readable representation of the failed validation. If the flat
argument is passed as a "truthy" value, it will output only the first ValidationError
in the FieldError
; otherwise it will output each validation message in a comma separated string.
Converts the current error object to a json representation of the error, for easy use/refinement elsewhere. For other methods, such as map, reduce, each, see the utility methods section.
A FieldError
is an error that contains all of the sub-errors for the validation of an individual item in the validated hash.
The errors
property of a FieldError
is
A ValidationError
is the result of an individual error in the field rule.
The following methods are underscore methods proxied to the Checkit.Error
and Checkit.FieldError
objects, for easy manipulation of the .errors
object contained in each.
The Checkit.labelTransform
method takes a function that receives the field name and returns a human-readable label for use in error messages.
Promise
instance. Breaking change #69validate
for run
CheckIt
is now renamed Checkit
validations
and target
arguments, so the syntax is now Checkit(validations).run(input)
rather than Checkit(input).run(validations)
, allowing for re-use of the validation objects.Initial release