Skip to content
This repository was archived by the owner on Dec 21, 2017. It is now read-only.

Schema definition

fogine edited this page Jul 22, 2016 · 22 revisions

Please look at the full list of Assertions and their options.

var inspector = require('json-inspector');

Primitive data validation

//validator definition
var validator = inspector.define('stirng-validator', {
    $is: String,
    $hasLengthOf: {min: 1, max: 255}
});

validator.validate('this is valid string');
console.log(validator.success); //true

validator.validate('');
console.log(validator.success); //false
console.log(validator.error); //ValidationError

Hash table (Object) data validation

//validator definition
var validator = inspector.define('user', {
    username: {
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    },
    email: {
        $isEmail: null //if you dont want to pass options object to $isEmail assertion, you can provide null value (even `undefined` would work). In the case, default options will be applied
    },
    address: {
        country_code: {
            $isAlpha: 'en-US'
            $hasLengthOf: {min: 2, max: 2}
        },
        street: {
            $is: String,
            $hasLengthOf: {max: 125}
        },
        zip: {
            $isInt: null, //again, null value means that no options for the $isInt assertion are specified. Default options will be applied
        }
    }
});

validator.validate({
    username: 'happie',
    email: 'test@test.com',
    address: {
        country: 'US',
        street: 'Second',
        zip: 96701
    }
});
console.log(validator.success); //true

Array data validation

//validator definition
var validator = inspector.define('cart', {
    items: {
        $forEach: { // each item of the array must pass following validation rules
            id: {
                $isInt: {min:1}
            },
            name: {
                $is: String
            }
        },
        $hasLengthOf: {max: 5} // `items` collection can have maximum of 5 items, no more
    }
});

validator.validate({
    items: [
        {
            id: 1,
            name: 'Supper-looking T-shirt'
        },
        {
            id: 29,
            name: 'Supper-looking Jumper'
        }
    ]
});
console.log(validator.success); //true

Specifying required properties

By default all properties are optional. That means if you don't provide any data, the validation process will pass.
You can specify which properties are required in validator schema definition or it's possible to change default setting so that all properties are required by default (see Validator options)

null values are treated as any other value by default - they are not threated as "empty" value by default. if a property can have null value, you can specify that either by OR condition or by using $nullable:true option in a schema definition.

//validator definition
var validator = inspector.define('user', {
    username: {
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    },
    email: {
        $isEmail: {allow_display_name: true}
    }
});

validator.validate();
console.log(validator.success); //true - because `username` and `email` properties are not required by default neither is the data object value the `username`, `email` properties are at.

validator.validate({});
console.log(validator.success); //true - because `username` and `email` properties are not required by default

To specify required properties use $required: true option:

//validator definition
var validator = inspector.define('user', {
    $required: true, // all properties within the validated object are set to required (they inherit this special `$required` option)
    username: {
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    },
    email: {
        $isEmail: {allow_display_name: true}
    }
});

validator.validate({});
console.log(validator.success); //false

The above example of pecifying one $required option that other properties inherit is same as defining $required option individualy. This is equivalent schema definition:

{
    username: {
        $required: true, // defining required properties individualy
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    },
    email: {
        $required: true,
        $isEmail: {allow_display_name: true}
    }
}

To futher explain inheritance concept, look at the following example of schema definition:

{
    $required: true,
    username: {
        $required: false, // overwrites inherited `$required: true` option
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    },
    email: {//email property has inherited the `$required: true` option
        $isEmail: {allow_display_name: true}
    }
}

Note: The same inheritance concept applies for the error messages definitions (the $message option).

Error messages

Default error message for all failed assertions is set to: Invalid data for %p, got: "%v". (The value in the message is escaped.)
For assertion specific error messages you can specify an error message via $message keyword in a schema definition:

{
    username: {
        $message: 'The %p must contain only alphanumeric characters in range of 1-32 characters',
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    },
    email: {
        $isEmail: {allow_display_name: true}
    }
}

Note that the $message option if defined, is inherited by nested validator definitions from the parent:

{
    //In case of failture, this error message will be used for both `username` and `email` failed assertions.
    //You can overwrite it be defining specific error message either in `username` or `email` definition scope
    $message: 'The %p is invalid',
    username: {
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    },
    email: {
        $isEmail: {allow_display_name: true}
    }
}

The $message option can has a function value instance of a string message. The function will be given type of failed assertion as first argument and context object with additional information about assertion as second argument. This can be used for generating multi-language error messages or for generating assertion specific messages automaticaly without a need to define them in schema definition.
For more information see Multilanguage error messages.

Conditional data validation

Logical operators Description
$and AND
$nand Negated AND
$or OR
$nor Negated OR

A type of logical operator used between assertions can be controlled with $and & $or & $nand & $nor keywords in schema definition. The default logical operator is set to $and.

An example of conditional validation:

{
    username: {
        $or: {
            $is: null,
            $and: {
                $isAlphanumeric: 'en-US',
                $hasLengthOf: {min:1, max: 32}
            }
        }
    }
}

The above schema definition generates the following condition (pseudo-code):

if(   value === null
   || (isAlphanumeric(value, 'en-US') && hasLengthOf(value, {min: 1, max: 32}))
) { }

All logical operators accept also an array value instead of an object. The following is alternative definition for the above schema definition example:

{
    username: {
        $or: [
            { $is: null },
            {
                $isAlphanumeric: 'en-US',
                $hasLengthOf: {min:1, max: 32}
            }
        ]
    }
}

Just note that you don't need to use "conditional validation" for defining nullable property. Easier solution would be to use the $nullable option instead of $or operator:

{
    username: {
        $nullable: true,
        $isAlphanumeric: 'en-US',
        $hasLengthOf: {min:1, max: 32}
    }
}

Schema definition as a Function

It's possible to provide a Function instead of an Object as schema definition.
The function is expected to return schema definition object.
The advantage of providing a Function is that you have access to other registered validators from within the function via this.getSchemaFor('validator-name').
If json-inspector module is registered in the Express app, you have additional access to the express req object from within the function via this.req.

inspector.define('email', {
    $required: true,
    $isEmail: {allow_display_name: true}
});

inspector.define('user', function() {
    return {
        username: {$is: String},
        email: this.getSchemaFor('email') // you can provide an object schema definition as second argument. The schema will be merged into "email" validator schema definition
    };
});
Clone this wiki locally