Validate objects against predefined rules (node.js).

rules (node.js)

A tiny rules framework that can be used to validate any value, either by you creating a rules/schema object or applying validations to a single value. In both cases a fluent interface is used.

You create an object to declare the rules/invariants you want to apply (something akin to a schema). A fluent interface makes it easy to specify the invariants for each property:

var nameRules = {
    first  : mustBe().populated().string({ minLength: 5, maxLength: 20}), [1]
    second : mustBe().populated().string({ minLength: 5, maxLength: 20}),
var personRules = {
    name:        nameRules,
    weight:      mustBe().populated().numeric({min : 0, max: 130}),
    dateOfBirthfunction() { 
        this.populated().date({ before: now.subtract("years", 1) }); 
    } [2]

As shown you can access this fluent interface using two approaches:

  • [1] mustBe() - Acts as the entry point to the fluent interface.
  • [2] function - 'this' inside the function being the entry point to the fluent interface.

The function based approach is designed primarily for use with CoffeeScript:

# This schema is not showing how to validate a real address, it just shows a few validators 
addressRules = {
  streetOne: mustBe().populated()
  streetTwo: -> @.populated().string( minLength: 10maxLength : 50 ) 
  streetThree: -> @.populated().string( minLength : 10maxLength: 50) 
  town: -> @.populated()
  postCode: -> @.populated().matchFor(/.../)

The same validators are available for use validating individual values:

var doSomeStuff = function(nameage) {
    ensure(age, "age").integer();

You trigger validation using:

result = rules.apply(person, personRules)

The returned object has the per-property details of any validation failures, e.g.:

    name: { 
        first: { 
            message: 'The value must be populated.',
            type: 'not_populated',
            value: '' 
        second: { 
            message: 'The value must be populated.',
            type: 'not_populated',
            value: undefined } 
    weight: { 
        message: 'The value must be populated.',
        type: 'not_populated',
        value: undefined 

Note in this case both the first name (e.g. and second name ( needed to be populated, along with the weight.

The framework comes with several validators, to understand them further you may want to run the examples.

  • populated - Checks the value is not null, undefined, "", or an empty array.
  • array
  • numeric - Optionally you can also pass in object with min and/or max values
  • integer
  • matchFor - You can pass in an object with pattern and optionally flags, alternatively you can pass in the RegExp object to use.
  • date - Optionally you can specify that the date must be before and/or after specified dates. To make this easier you use now.add or now.subtract to specify the dates to use for before/after.
  • string - Optionally you can pass in minLength and/or maxLength.

The project comes with examples in the examples directory.

mocha -R spec spec/testFixture spec/ --recursive
  • Numeric validators - >, <, >=, <=
  • Date validator - Support now()
  • boolean validator
  • enum style validator - valueIn(list), valueNotIn(list).
  • Potentially UMD support
  • Trying to apply multiple of same validator, multiple type validators (integer and string, numeric and boolean), regex with anything other than string
  • Ensure interface e.g. ensure(5).populate().numeric(), allowing direct validation of single values
  • API for throwing
  • Cyclical rules objects warning
  • Numeric validator - failing if passed "15.5"