Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jsen

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsen

JSON-Schema validator built for speed

  • 0.3.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
23K
decreased by-18.69%
Maintainers
1
Weekly downloads
 
Created
Source

JSEN

Build Coverage Downloads

NPM

jsen (JSON Sentinel) validates your JSON objects using JSON-Schema.

Table of Contents

Getting Started

Install through NPM in node.

$ npm install jsen --save
var jsen = require('jsen');
var validate = jsen({ type: 'string' });
var valid = validate('some value');             // true

Install through Bower in your HTML page.

$ bower install jsen
<script src="bower_components/jsen/dist/jsen.min.js"></script>
<script>
    var validate = jsen({ type: 'string' });    // under window.jsen
    var valid = validate('some value');         // true
</script>

Validation works by passing a JSON schema to build a validator function that can be used to validate a JSON object.

The validator builder function (jsen) throws an error if the first parameter is not a schema object:

try {
    // cannot use this string as a schema
    jsen('not a valid schema');
}
catch (e) {
    console.log(e);
}

jsen will not throw an error if the provided schema is not compatible with the JSON-schema version 4 spec. In this case, as per the spec, validation will always succeed for every schema keyword that is incorrectly defined.


// this will not throw, but validation will be incorrect
var validate = jsen({ type: 'object', properties: ['string', 'number'] });

// validation erroneously passes, because keyword `properties` is ignored
var valid = validate({});   // true

If you need to validate your schema object, you can use a reference to the JSON meta schema. Internally, jsen will recognize and validate against the metaschema.

var validateSchema = jsen({"$ref": "http://json-schema.org/draft-04/schema#"});
var isSchemaValid = validateSchema({ type: 'object' }); // true

isSchemaValid = validateSchema({ 
    type: 'object', 
    properties: ['string', 'number'] 
});
// false, because properties is not in correct format

Performance & Benchmarks

JSEN uses dynamic code generation to produce a validator function that the V8 engine can optimize for performance. Following is a set of benchmarks where JSEN is compared to other JSON Schema validators for node.

More on V8 optimization: Performance Tips for JavaScript in V8

JSON Schema

To get started with JSON Schema, check out the JSEN schema guide.

For further reading, check out this excellent guide to JSON Schema by Michael Droettboom, et al.

JSEN fully implements draft 4 of the JSON Schema specification.

Format Validation

JSEN supports a few built-in formats, as defined by the JSON Schema spec:

  • date-time
  • uri
  • email
  • ipv4
  • ipv6
  • hostname

These formats are validated against string values only. As per the spec, format validation passes successfully for any non-string value.

var schema = { format: 'uri' },
    validate = jsen(schema);

validate('invalid/uri');    // false - format validation kicks in for strings
validate({});               // true - does not kick in for non-strings

Custom Formats

JSEN additionally supports custom format validation. Custom formats are passed in options.formats as a second argument to the jsen validator builder function.

var schema = { format: 'uuid' },
    uuidRegex = '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$',
    validate = jsen(schema, {
        formats: {
            uuid: uuidRegex
        }
    });

validate('fad2b4f5-bc3c-44ca-8e17-6d30cf62bdb1');   // true
validate('not-a-valid-UUID');                       // false

A custom format validator can be specified as:

  • a regular expression string
  • a regular expression object
  • a function (value, schema) that must return a truthy value if validation passes

Unlike built-in format validators, custom format validators passed in the options are run for all data types, not only strings. This allows implementing custom validation behavior for arrays and objects in scenarios, where it is not possible or practical to use only JSON Schema keywords for validation rules.

Custom format validation runs after all built-in keyword validators. This means that an error in any previous keyword validator will stop execution and any custom format validators won't run.

Errors

The validator function (the one called with the object to validate) provides an errors array containing all reported errors in a single validation run.

var validate = jsen({ type: 'string' });

validate(123);      // false
console.log(validate.errors)
// Output: [{ path: '', keyword: 'type' }]

// path - deep (dot-delimited) path to the property that failed validation
// keyword - the JSON schema keyword that failed validation

validate('abc');    // true
// Output: []

The errors array may contain multiple errors from a single run.

var validate = jsen({
    anyOf: [
        {
            type: 'object',
            properties: {
                tags: { type: 'array' }
            }
        },
        {
            type: 'object',
            properties: {
                comment: { minLength: 1 }
            }
        }
    ]
});

validate({ tags: null, comment: '' });

console.log(validate.errors);
/* Output:
[ { path: 'tags', keyword: 'type' },
  { path: 'comment', keyword: 'minLength' },
  { path: '', keyword: 'anyOf' } ]
*/

The errors array is replaced on every call of the validator function. You can safely modify the array without affecting successive validation runs.

Custom Errors

You can define your custom error messages in the schema object through the invalidMessage and requiredMessage keywords.

var schema = {
        type: 'object',
        properties: {
            username: {
                type: 'string',
                minLength: 5,
                invalidMessage: 'Invalid username',
                requiredMessage: 'Username is required'
            }
        },
        required: ['username']
    };
var validate = jsen(schema);

validate({});
console.log(validate.errors);
/* Output:
[ { path: 'username',
    keyword: 'required',
    message: 'Username is required' } ]
*/

validate({ username: '' });
console.log(validate.errors);
/* Output:
[ { path: 'username',
    keyword: 'minLength',
    message: 'Invalid username' } ]
*/

Custom error messages are assigned to error objects by path, meaning multiple failed JSON schema keywords on the same path will show the same custom error message.

var schema = {
        type: 'object',
        properties: {
            age: {
                type: 'integer',
                minimum: 0,
                maximum: 100,
                invalidMessage: 'Invalid age specified'
            }
        }
    };
var validate = jsen(schema);

validate({ age: 13.3 });
console.log(validate.errors);
/* Output:
[ { path: 'age',
    keyword: 'type',
    message: 'Invalid age specified' } ]
*/

validate({ age: -5 });
console.log(validate.errors);
/* Output:
[ { path: 'age',
    keyword: 'minimum',
    message: 'Invalid age specified' } ]
*/

validate({ age: 120 });
console.log(validate.errors);
/* Output:
[ { path: 'age',
    keyword: 'maximum',
    message: 'Invalid age specified' } ]
*/

The requiredMessage is assigned to errors coming from the required and dependencies keywords. For all other validation keywords, the invalidMessage is used.

Custom Errors for Keywords

You can assign custom error messages to keywords through the messages object in the JSON schema.

var schema = {
    type: 'object',
    messages: {
        type: 'Invalid data type where an object is expected'
    }
}
var validate = jsen(schema);

validate('this is a string, not an object');
console.log(validate.errors);
/* Output:
[ { path: '',
    keyword: 'type',
    message: 'Invalid data type where an object is expected' } ]
*/

NOTE: The following keywords are never assigned to error objects, and thus do not support custom error messages: items, properties, patternProperties, dependecies (when defining a schema dependency) and allOf.

Gathering Default Values

JSEN can collect default values from the schema. The build(initial, options) method in the dynamic validator function recursively walks the schema object and compiles the default values into a single object or array.

var validate = jsen({ type: 'string', default: 'abc' });
console.log(validate.build());      // 'abc'

var validate = jsen({
    default: {},
    properties: {
        foo: { default: 'bar' },
        arr: {
            default: [],
            items: [
                { default: 1 },
                { default: 1 },
                { default: 2 }
            ]
        }
    }
});
console.log(validate.build());      // { foo: 'bar', arr: [1, 2, 3] }

The build function can additionally merge the default values with an initially provided data object.

var validate = jsen({
    properties: {
        rememberMe: {
            default: 'true'
        }
    }
});

var initial = { username: 'John', password: 'P@$$w0rd' };

initial = validate.build(initial);

console.log(initial);
// { username: 'John', password: 'P@$$w0rd', rememberMe: true }

options.copy

By default, the build function creates a copy of the initial data object. You can opt to modify the object in-place by passing { copy: false } as a second argument.

var initial = { username: 'John', password: 'P@$$w0rd' };
var validate = jsen({
    properties: {
        rememberMe: {
            default: 'true'
        }
    }
});

var withDefaults = validate.build(initial);
console.log(withDefaults === initial);      // false (initial is cloned)

withDefaults = validate.build(initial, { copy: false });
console.log(withDefaults === initial);      // true (initial is modified)

options.additionalProperties

The JSON schema spec allows additional properties by default. In many cases, however, this default behavior may be undesirable, forcing developers to specify additionalProperties: false everywhere in their schema objects. JSEN's build function can filter out additional properties by specifying { additionalProperties: false } as a second argument.

var validate = jsen({
    properties: {
        foo: {},
        bar: {}
    }
});

var initial = { foo: 1, bar: 2, baz: 3};

initial = validate.build(initial, { additionalProperties: false });

console.log(initial);   // { foo: 1, bar: 2 }

When both options.additionalProperties and schema.additionalProperties are specified, the latter takes precedence.

var validate = jsen({
    additionalProperties: true,
    properties: {
        foo: {},
        bar: {}
    }
});

var initial = { foo: 1, bar: 2, baz: 3};

initial = validate.build(initial, { additionalProperties: false });

console.log(initial);   // { foo: 1, bar: 2, baz: 3 }

NOTE: When { additionalProperties: false, copy: false } is specified in the build options, any additional properties will be deleted from the initial data object.

In-Browser Usage

Browser-compatible builds of jsen (with the help of browserify) can be found in the dist folder. These are built with the standalone option of browserify, meaning they will work in node, the browser with globals, and AMD loader environments. In the browser, the window.jsen global object will refer to the validator builder function.

Tests

To run mocha tests in node:

$ npm test

To run the same test suite in the browser, serve the test/index.html page in your node web server and navitate to /test/ path from your browser. The example below uses node-static:

[~/github/jsen] $ npm install -g node-static
...
[~/github/jsen] $ static .
serving "." at http://127.0.0.1:8080
# navigate to http://127.0.0.1:8080/test/ in your browser

jsen passes all draft 4 test cases specified by the JSON-Schema-Test-Suite with the exception of:

  • Remote refs
  • Zero-terminated floats
  • Max/min length when using Unicode surrogate pairs

Source code coverage is provided by istanbul and visible on coveralls.io.

Contributing

To contribute to the project, fork the repo, edit and send a Pull Request. Please adhere to the coding guidelines enforced by the jshint and jscs code checkers.

All tests must pass both in node and in the browser.

To build the jsen browser-compatible distribution files, run:

$ npm run build

This will update the files in the /dist folder.

Issues

Please submit issues to the jsen issue tracker in GitHub.

Changelog

v0.3.2

  • Add in-browser support out of the box (#23)
  • Fix broken inlining of regular expressions containing forward slashes when running in the browser (#25)

v0.3.1

  • Add support for IE8

v0.3.0

  • Add support for default value population (#10)
  • Add support for custom messages per keyword (#18)

v0.2.0

  • Add support for custom format validators (#8, #9)
  • Add support for validating javascipt Date objects (#17)

v0.1.2

  • Fix cannot dereference schema when ids change resolution scope (#14)

v0.1.1

  • Fix broken inlining of regular expressions containing slashes (#15)
  • Fix code generation breaks when object properties in schema are not valid identifiers (#16)

v0.1.0

  • Custom error messages defined in the schema
  • Append the required property name to the path in the error object for required and dependencies keywords (#7)
  • Fix protocol-relative URIs are marked invalid (#13)
  • Update JSON-Schema-Test-Suite tests (#12)

v0.0.5

  • Improve generated validation code (#4)
  • Fail fast (#4)
  • Error reporting (#5)
  • Reduce the performance impact of logging validation errors (#4)

v0.0.4

  • Fix multipleOf doesn't validate data for decimal points (#1)

v0.0.3

  • Optimize performance of runtime code generation
  • Optimize performance of generated code

License

MIT

Keywords

FAQs

Package last updated on 10 Jun 2015

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc