JSPM

  • Created
  • Published
  • Downloads 3990
  • Score
    100M100P100Q117326F

Second generation object or request validator for node.js

Package Exports

  • better-validator

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (better-validator) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

better-validator

better-validator is my second generation object or request validator for node.js.

The aim of this validator is to

  • be simple to use
  • support a number of usage patterns including a fluent interface
  • support re-use of validator parts
  • support deep object and array validation
  • be able to customise the output structure
  • be able to customise failure messages
  • support i18n
  • use the well known validator library for string validation
  • be easily used with both express.js and koa.js

Basic usage

const Validator = require('better-validator');
const validator = new Validator();

validator(123).isNumber();
const errors = validator.run(); // => []
const validator = new Validator();

validator('not number').isNumber();
const errors = validator.run(); // => [{path: [], value: 'not number', failed: 'isNumber'}]

Validate multiple objects at once:

const validator = new Validator();

const query = {};
const body = null;

validator(query).display('query').required();
validator(body).display('body').required();
const errors = validator.run(); // => [{path: ['body'], value: null, failed: 'required'}]

Validate children of an object:

const validator = new Validator();

const query = {count: 5, hint: 32};

validator(query).required().isObject((obj) => {
  obj('count').required().isNumber().integer(); // pass
  obj('hint').isString(); // fail
});
const errors = validator.run(); // => [{path: ['hint'], value: 32, failed: 'isString'}]

Validate children of an array:

const validator = new Validator();

const array = [{count: 5, hint: 32}];

validator(array).required().isArrayOf((child) => {
  child('count').required().isNumber().integer(); // pass
  child('hint').isString(); // fail
});
const errors = validator.run(); // => [{path: [0, 'hint'], value: 32, failed: 'isString'}]

Re-usable validation parts:

const validator = new Validator();

const rule = (item) => {
  item.isNumber().integer().isPositive();
};

const errors = validator(123, rule); // => []
const validator = new Validator();

const query = {count: 5, hint: '32'};

const rule = (item) => item.isNumber().integer().isPositive();

validator(query).required().isObject((child) => {
  child('count').check(rule).lte(10); // pass
  child('hint').check(rule); // fail
});
const errors = validator.run(); // => [{path: ['hint'], value: '32', failed: 'isNumber'}]

Using with express.js

const Formatter = require('better-validator/format/response/wrapperFormatter');
const check = Validator.expressMiddleware({responseFormatter: new Formatter()});
const queryRule = (query) => {
  query('email').isEmail();
  query('date').isISO8601();
};
const bodyRule = (body) => {
  body('count').required().isNumber().integer();
  body('hint').isString();
  body().strict(); // make sure there aren't any expected properties in the body
};
app.post('/', [check.query(queryRule), check.body(bodyRule), function(req, res) {
  // ...
}

Using with koa.js

const Formatter = require('better-validator/format/response/wrapperFormatter');
const check = Validator.koaMiddleware({responseFormatter: new Formatter()});
const queryRule = (query) => {
  query('email').isEmail();
  query('date').isISO8601();
};
const bodyRule = (body) => {
  body('count').required().isNumber().integer();
  body('hint').isString();
  body().strict(); // make sure there aren't any expected properties in the body
};
route.post('/', check.query(queryRule), check.body(bodyRule), otherFunction);

If the body content does not pass the given validation check, the validator will return.

400 Bad Request

{
    "type": "ValidationError"
    "failures": [
        {
            "parameter": "children[0].prop",
            "value": "zxzx",
            "failed": "required"
        }
    ]
}

Installation

$ npm install better-validator

Included Validators

Following are the build-in validators. You may also use your own, see section below.

required

The various type validators will accept the specified type or null or undefined. To modify the check to not accept null or undefined, add the required() constraint.

validator(value).required();
validator(value).isString().required();
validator(value).required().isString();

All Types

validator(value).isEqual(7);
validator(value).notEqual('test');

isObject

Used to validate that the value under test is an object, and to check it's properties.

validator(value).isObject((obj) => {
  obj('count').required().isNumber().integer();
  obj('hint').isString();
});

To ensure that the object has only the expected properties, the strict() constraint is added.

validator(value).isObject((obj) => {
  obj('count').required().isNumber().integer();
  obj('hint').isString();
}).strict();

isString

Makes sure the value is of type string.

validator(value).isString();
validator(value).isString().isEmail();

isString Checks

Checks from the library validator are included. Please see the link for more details. All checks that start with is are mounted into the isString() module along with their inverse not

  • isAfter(date), notAfter(date)
  • isAlpha(locale), notAlpha(locale)
  • isAlphanumeric(locale), notAlphanumeric(locale)
  • isAscii(), notAscii()
  • isBase64(), notBase64()
  • isBefore(date), notBefore(date)
  • isBoolean(), notBoolean()
  • isByteLength(options), notByteLength(options)
  • isCreditCard(), notCreditCard()
  • isCurrency(options), notCurrency(options)
  • isDataURI(), notDataURI()
  • isDate(), notDate()
  • isDecimal(), notDecimal()
  • isDivisibleBy(number), notDivisibleBy(number)
  • isEmail(options), notEmail(options)
  • isEmpty(), notEmpty()
  • isFQDN(options), notFQDN(options)
  • isFloat(options), notFloat(options)
  • isFullWidth(), notFullWidth()
  • isHalfWidth(), notHalfWidth()
  • isHexColor(), notHexColor()
  • isHexadecimal(), notHexadecimal()
  • isIP(version), notIP(version)
  • isISBN(version), notISBN(version)
  • isISSN(options), notISSN(options)
  • isISIN(), notISIN()
  • isISO8601(), notISO8601()
  • isIn(values), notIn(values)
  • isInt(options), notInt(options)
  • isJSON(), notJSON()
  • isLength(options), notLength(options)
  • isLowercase(), notLowercase()
  • isMACAddress(), notMACAddress()
  • isMD5(), notMD5()
  • isMobilePhone(locale), notMobilePhone(locale)
  • isMongoId(), notMongoId()
  • isMultibyte(), notMultibyte()
  • isNumeric(), notNumeric()
  • isSurrogatePair(), notSurrogatePair()
  • isURL(options), notURL(options)
  • isUUID(version), notUUID(version)
  • isUppercase(), notUppercase()
  • isVariableWidth(), notVariableWidth()
  • isWhitelisted(chars), notWhitelisted(chars)

Also regular expression checks can be performed with isMatch(regex) and notMatch(regex)

Like all other constraints, these amy be chained together:

validator(value).isAlphanumeric().isLowercase();

isNumber

Makes sure the value is a number.

validator(value).isNumber();
validator(value).isNumber().integer();

isNumber Checks

  • integer()
  • isInRange(lower, upper), notInRange(lower, upper)
  • gt(threshold)
  • gte(threshold)
  • lt(threshold)
  • lte(threshold)
  • isPositive(), notPositive()
  • isNegative(), notNegative()
  • isZero(), notZero()

isArrayOf

Makes sure that the item is of type array, and validates the items. Also can specify minimum and maximum length of the array.

validator(value).isArrayOf((item) => {
  item('foo').isString();
  item('bar').isString().required();
  item().strict();
}).length(2);
validator(value).isArrayOf((item) => {
  // ...
}).lengthInRange(4, 8); // 4 to 8 inclusive
validator(value).isArrayOf((item) => {
  // ...
}).lengthInRange(undefined, 8); // less than or equal to 8
validator(value).isArrayOf((item) => {
  // ...
}).lengthInRange(1); // one or more

Your Own Validators

TODO

Formatting Result / Errors

TODO

i18n

TODO

License

(The MIT License)

Copyright (c) 2013

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.