Nine Pomeranian Monsters
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    z-schemapublic

    z-schema validator

    npm version bower version build status coverage status

    Greenkeeper badge dependencies Status devDependencies Status optionalDependencies Status

    NPM

    • version 3.0 runs also in the browsers now, run tests yourself here

    Topics

    Usage

    Validator will try to perform sync validation when possible for speed, but supports async callbacks when they are necessary.

    Development:

    These repository has several submodules and should be cloned as follows:

    git clone --recursive https://github.com/zaggino/z-schema.git

    CLI:

    npm install --global z-schema
    z-schema --help
    z-schema mySchema.json
    z-schema mySchema.json myJson.json
    z-schema --strictMode mySchema.json myJson.json
    

    NodeJS:

    var ZSchema = require("z-schema");
    var options = ... // see below for possible option values
    var validator = new ZSchema(options);

    Sync mode:

    var valid = validator.validate(json, schema);
    // this will return a native error object with name and message
    var error = validator.getLastError();
    // this will return an array of validation errors encountered
    var errors = validator.getLastErrors();
    ...

    Async mode:

    validator.validate(json, schema, function (err, valid) {
        ...
    });

    Browser:

    <script type="text/javascript" src="../dist/ZSchema-browser-min.js"></script>
    <script type="text/javascript">
        var validator = new ZSchema();
        var valid = validator.validate("string", { "type": "string" });
        console.log(valid);
    </script> 

    Remote references and schemas:

    In case you have some remote references in your schemas, you have to download those schemas before using validator. Otherwise you'll get UNRESOLVABLE_REFERENCE error when trying to compile a schema.

    var validator = new ZSchema();
    var json = {};
    var schema = { "$ref": "http://json-schema.org/draft-04/schema#" };
     
    var valid = validator.validate(json, schema);
    var errors = validator.getLastErrors();
    // valid === false
    // errors.length === 1
    // errors[0].code === "UNRESOLVABLE_REFERENCE"
     
    var requiredUrl = "http://json-schema.org/draft-04/schema";
    request(requiredUrl, function (error, response, body) {
     
        validator.setRemoteReference(requiredUrl, JSON.parse(body));
     
        var valid = validator.validate(json, schema);
        var errors = validator.getLastErrors();
        // valid === true
        // errors === undefined
     
    }

    If you're able to load schemas synchronously, you can use ZSchema.setSchemaReader feature:

    ZSchema.setSchemaReader(function (uri) {
        var someFilename = path.resolve(__dirname, "..", "schemas", uri + ".json");
        return JSON.parse(fs.readFileSync(someFilename, "utf8"));
    });

    Features

    Validate against subschema

    In case you don't want to split your schema into multiple schemas using reference for any reason, you can use option schemaPath when validating:

    var valid = validator.validate(cars, schema, { schemaPath: "definitions.car.definitions.cars" });

    See more details in the test.

    Compile arrays of schemas and use references between them

    You can use validator to compile an array of schemas that have references between them and then validate against one of those schemas:

    var schemas = [
        {
            id: "personDetails",
            type: "object",
            properties: {
                firstName: { type: "string" },
                lastName: { type: "string" }
            },
            required: ["firstName", "lastName"]
        },
        {
            id: "addressDetails",
            type: "object",
            properties: {
                street: { type: "string" },
                city: { type: "string" }
            },
            required: ["street", "city"]
        },
        {
            id: "personWithAddress",
            allOf: [
                { $ref: "personDetails" },
                { $ref: "addressDetails" }
            ]
        }
    ];
     
    var data = {
        firstName: "Martin",
        lastName: "Zagora",
        street: "George St",
        city: "Sydney"
    };
     
    var validator = new ZSchema();
     
    // compile & validate schemas first, z-schema will automatically handle array
    var allSchemasValid = validator.validateSchema(schemas);
    // allSchemasValid === true
     
    // now validate our data against the last schema
    var valid = validator.validate(data, schemas[2]);
    // valid === true

    Register a custom format

    You can register any format of your own. Your sync validator function should always respond with a boolean:

    ZSchema.registerFormat("xstring", function (str) {
        return str === "xxx";
    });

    Async format validators are also supported, they should accept two arguments, value and a callback to which they need to respond:

    ZSchema.registerFormat("xstring", function (str, callback) {
        setTimeout(function () {
            callback(str === "xxx");
        }, 1);
    });

    Helper method to check the formats that have been registered

    var registeredFormats = ZSchema.getRegisteredFormats();
    //registeredFormats will now contain an array of all formats that have been registered with z-schema

    Automatic downloading of remote schemas

    Automatic downloading of remote schemas was removed from version 3.x but is still possible with a bit of extra code, see this test for more information on this.

    Prefill default values to object using format

    Using format, you can pre-fill values of your choosing into the objects like this:

    ZSchema.registerFormat("fillHello", function (obj) {
        obj.hello = "world";
        return true;
    });
     
    var data = {};
     
    var schema = {
        "type": "object",
        "format": "fillHello"
    };
     
    validator.validate(data, schema);
    // data.hello === "world"

    Options

    asyncTimeout

    Defines a time limit, which should be used when waiting for async tasks like async format validators to perform their validation, before the validation fails with an ASYNC_TIMEOUT error.

    var validator = new ZSchema({
        asyncTimeout: 2000
    });

    noEmptyArrays

    When true, validator will assume that minimum count of items in any array is 1, except when minItems: 0 is explicitly defined.

    var validator = new ZSchema({
        noEmptyArrays: true
    });

    noEmptyStrings

    When true, validator will assume that minimum length of any string to pass type string validation is 1, except when minLength: 0 is explicitly defined.

    var validator = new ZSchema({
        noEmptyStrings: true
    });

    noTypeless

    When true, validator will fail validation for schemas that don't specify a type of object that they expect.

    var validator = new ZSchema({
        noTypeless: true
    });

    noExtraKeywords

    When true, validator will fail for schemas that use keywords not defined in JSON Schema specification and doesn't provide a parent schema in $schema property to validate the schema.

    var validator = new ZSchema({
        noExtraKeywords: true
    });

    assumeAdditional

    When true, validator assumes that additionalItems/additionalProperties are defined as false so you don't have to manually fix all your schemas.

    var validator = new ZSchema({
        assumeAdditional: true
    });

    When an array, validator assumes that additionalItems/additionalProperties are defined as false, but allows some properties to pass.

    var validator = new ZSchema({
        assumeAdditional: ["$ref"]
    });

    forceAdditional

    When true, validator doesn't validate schemas where additionalItems/additionalProperties should be defined to either true or false.

    var validator = new ZSchema({
        forceAdditional: true
    });

    forceItems

    When true, validator doesn't validate schemas where items are not defined for array type schemas. This is to avoid passing anything through an array definition.

    var validator = new ZSchema({
        forceItems: true
    });

    forceMinItems

    When true, validator doesn't validate schemas where minItems is not defined for array type schemas. This is to avoid passing zero-length arrays which application doesn't expect to handle.

    var validator = new ZSchema({
        forceMinItems: true
    });

    forceMaxItems

    When true, validator doesn't validate schemas where maxItems is not defined for array type schemas. This is to avoid passing arrays with unlimited count of elements which application doesn't expect to handle.

    var validator = new ZSchema({
        forceMaxItems: true
    });

    forceMinLength

    When true, validator doesn't validate schemas where minLength is not defined for string type schemas. This is to avoid passing zero-length strings which application doesn't expect to handle.

    var validator = new ZSchema({
        forceMinLength: true
    });

    forceMaxLength

    When true, validator doesn't validate schemas where maxLength is not defined for string type schemas. This is to avoid passing extremly large strings which application doesn't expect to handle.

    var validator = new ZSchema({
        forceMaxLength: true
    });

    forceProperties

    When true, validator doesn't validate schemas where properties or patternProperties is not defined for object type schemas. This is to avoid having objects with unexpected properties in application.

    var validator = new ZSchema({
        forceProperties: true
    });

    ignoreUnresolvableReferences

    When true, validator doesn't end with error when a remote reference is unreachable. This setting is not recommended in production outside of testing.

    var validator = new ZSchema({
        ignoreUnresolvableReferences: true
    });

    enumCaseInsensitiveComparison

    When true, validator will return a ENUM_CASE_MISMATCH when the enum values mismatch only in case.

    var validator = new ZSchema({
        enumCaseInsensitiveComparison: true
    });

    strictUris

    When true, all strings of format uri must be an absolute URIs and not only URI references. See more details in this issue.

    var validator = new ZSchema({
        strictUris: true
    });

    strictMode

    Strict mode of z-schema is currently equal to the following:

    if (this.options.strictMode === true) {
        this.options.forceAdditional  = true;
        this.options.forceItems       = true;
        this.options.forceMaxLength   = true;
        this.options.forceProperties  = true;
        this.options.noExtraKeywords  = true;
        this.options.noTypeless       = true;
        this.options.noEmptyStrings   = true;
        this.options.noEmptyArrays    = true;
    }
    var validator = new ZSchema({
        strictMode: true
    });

    breakOnFirstError

    By default, z-schema stops validation after the first error is found. With this you can tell it to continue validating anyway:

    var validator = new ZSchema({
        breakOnFirstError: false
    });

    reportPathAsArray

    Report error paths as an array of path segments instead of a string:

    var validator = new ZSchema({
        reportPathAsArray: true
    });

    ignoreUnknownFormats

    By default, z-schema reports all unknown formats, formats not defined by JSON Schema and not registered using ZSchema.registerFormat, as an error. But the JSON Schema specification says that validator implementations "they SHOULD offer an option to disable validation" for format. That being said, setting this option to true will disable treating unknown formats as errlrs

    var validator = new ZSchema({
        ignoreUnknownFormats: true
    });

    customValidator

    Warning: Use only if know what you are doing. Always consider using custom format before using this option.

    Register function to be called as part of validation process on every subshema encounter during validation.

    Let's make a real-life example with this feature. Imagine you have number of transactions:

    {
        "fromId": 1034834329,
        "toId": 1034834543,
        "amount": 200
    }

    So you write the schema:

    {
        "type": "object",
        "properties": {
            "fromId": {
                "type": "integer"
            },
            "toId": {
                "type": "integer"
            },
            "amount": {
                "type": "number"
            }
        }
    }

    But how to check that fromId and toId are never equal. In JSON Schema Draft4 there is no possibility to do this. Actually, it's easy to just write validation code for such simple payloads. But what if you have to do the same check for many objects in different places of JSON payload. One solution is to add custom keyword uniqueProperties with array of property names as a value. So in our schema we would need to add:

    "uniqueProperties"[
        "fromId",
        "toId"
    ]

    To teach z-schema about this new keyword we need to write handler for it:

    function customValidatorFn(report, schema, json) {
        // check if our custom property is present
        if (Array.isArray(schema.uniqueProperties)) {
            var seenValues = [];
            schema.uniqueProperties.forEach(function (prop) {
                var value = json[prop];
                if (typeof value !== 'undefined') {
                    if (seenValues.indexOf(value) !== -1) {
                        // report error back to z-schema core
                        report.addCustomError("NON_UNIQUE_PROPERTY_VALUE",
                            "Property \"{0}\" has non-unique value: {1}",
                            [prop, value], null, schema.description);
                    }
                    seenValues.push(value)
                }
            });
        }
    }
     
    var validator = new ZSchema({
        // register our custom validator inside z-schema
        customValidator: customValidatorFn
    });

    Let's test it:

    var data = {
        fromId: 1034834346,
        toId: 1034834346,
        amount: 50
    };
     
    validator.validate(data, schema);
    console.log(validator.getLastErrors())
    //[ { code: 'NON_UNIQUE_PROPERTY_VALUE',
    //    params: [ 'toId', 1034834346 ],
    //    message: 'Property "toId" has non-unique value: 1034834346',
    //    path: '#/',
    //    schemaId: undefined } ]

    Note: before creating your own keywords you should consider all compatibility issues.

    Benchmarks

    So how does it compare to version 2.x and others?

    NOTE: these tests are purely orientational, they don't consider extra features any of the validator may support and implement

    rawgithub.com/zaggino/z-schema/master/benchmark/results.html

    Contributors

    Thanks for contributing to:

    and to everyone submitting issues on GitHub

    install

    npm i z-schema

    Downloadsweekly downloads

    350,133

    version

    3.22.0

    license

    MIT

    repository

    githubgithub

    last publish

    collaborators

    • avatar