Skip to content

JSON Schema validator written in JavaScript for NodeJS and Browsers

License

Notifications You must be signed in to change notification settings

zaggino/z-schema

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

615 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

z-schema - a JSON Schema validator

NPM

Coverage Status

Topics

What

What is a JSON Schema? Find here: https://json-schema.org/

Versions

  • v6 - old version which has been around a long time, supports JSON Schema draft-04
  • v7 - modernized version (to ESM module with Typescript) which passes all tests from JSON Schema Test Suite for draft-04
  • v8 - by default assumes all schemas without $schema tag are draft-04, the old behaviour from v7 can be explicitly turned on by specifying validator = ZSchema.create({ version: 'none' });
  • v9 - new api, new ZSchema() replaced by ZSchema.create() for initialization

Getting started

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

ESM and Typescript:

import ZSchema from 'z-schema';
const validator = ZSchema.create();

CommonJs:

const ZSchema = require('z-schema');
const validator = ZSchema.create();

Browser:

<script type="text/javascript" src="z-schema/umd/ZSchema.min.js"></script>
<script type="text/javascript">
  var validator = ZSchema.create();
  try {
    validator.validate('string', { type: 'string' });
    console.log('Validation passed');
  } catch (error) {
    console.log('Validation failed:', error.details);
  }
</script>

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

Usage

Schema Validation

You can pre-validate and compile schemas using the validateSchema method. This is useful for server startup to ensure all schemas are valid and to resolve $ref references between schemas.

const 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' }],
  },
];

try {
  validator.validateSchema(schemas);
  console.log('All schemas are valid and compiled');
} catch (error) {
  console.log('Schema validation failed:', error.details);
}

Sync mode:

The validate method automatically compiles and validates the schema before validating the JSON data against it. For better performance, you can pre-compile schemas using validateSchema during initialization.

try {
  validator.validate(json, schema);
  // validation passed
} catch (error) {
  // this will return a native error object with name and message
  console.log(error.name); // 'z-schema validation error'
  console.log(error.message); // common error message
  // this will return an array of validation errors encountered
  console.log(error.details); // array of detailed errors
}

// Or use validateSafe for object-based result
const result = validator.validateSafe(json, schema);
if (!result.valid) {
  console.log(result.errs); // array of error objects
}

...

Async validation:

ZSchema supports custom format validators that can perform both synchronous and asynchronous validation. This example shows how to validate a person payload with:

  • Async validation: User ID against a database
  • Async validation: Postcode against an external service
  • Sync validation: Phone number format
import ZSchema from 'z-schema';
import db from './db';

// Initialize ZSchema
const validator = ZSchema.create();

// Register async and sync format validators
validator.registerFormat('user-exists', async (input: unknown): Promise<boolean> => {
  if (typeof input !== 'number') return false;
  const user = await db.getUserById(input);
  return user != null;
});
validator.registerFormat('valid-postcode', async (input: unknown): Promise<boolean> => {
  if (typeof input !== 'string') return false;
  const postcode = await db.getPostcode(input);
  return postcode != null;
});
validator.registerFormat('phone-number', (input: unknown): boolean => {
  if (typeof input !== 'string') return false;
  const phoneRegex = /^\+?[1-9]\d{1,14}$/;
  return phoneRegex.test(input);
});

// Define the JSON Schema
const personSchema = {
  $schema: 'http://json-schema.org/draft-04/schema#',
  type: 'object',
  required: ['personId', 'address'],
  properties: {
    personId: {
      type: 'number',
      format: 'user-exists',
    },
    address: {
      type: 'object',
      required: ['postcode', 'phone'],
      properties: {
        postcode: {
          type: 'string',
          format: 'valid-postcode',
        },
        phone: {
          type: 'string',
          format: 'phone-number',
        },
      },
    },
  },
};

// Example payload
const payload = {
  personId: 'user123',
  address: {
    postcode: 'SW1A 1AA',
    phone: '+441234567890',
  },
};

// Validate asynchronously
try {
  const validator = ZSchema.create({ async: true });
  await validator.validate(payload, personSchema);
  console.log('✅ Validation successful!');
} catch (err) {
  console.log('❌ Validation failed:', err);
}

// or validate without try-catch
const validator = ZSchema.create({ async: true, safe: true });
const res = await validator.validate(payload, personSchema);
if (res.valid) {
  console.log('✅ Validation successful!');
} else {
  console.log('❌ Validation failed:', res.err);
}

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 = ZSchema.create();
var json = {};
var schema = { "$ref": "http://json-schema.org/draft-04/schema#" };

try {
  validator.validate(json, schema);
  // This won't reach here due to unresolvable reference
} catch (error) {
  // error.details will contain the validation errors
  console.log(error.details[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));

    try {
      validator.validate(json, schema);
      // validation passed
    } catch (error) {
      // shouldn't happen after setting remote reference
    }

}

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

See FEATURES.md for a full list of features.

Options

See OPTIONS.md for all available options and their descriptions.

Contributing

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

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

Contributors

Big thanks to:

sergey-shandar
Sergey Shandar
IvanGoncharov
Ivan Goncharov
pgonzal
Pete Gonzalez (OLD ALIAS)
simon-p-r
Simon R
TheToolbox
Jason Oettinger
whitlockjc
Jeremy Whitlock
epoberezkin
Evgeny
toofishes
Dan McGee
antialias
Thomas Hallock
kallaspriit
Priit Kallas
santam85
Marco Santarelli
Hirse
Jan Pilzer
geraintluff
Geraint
dgerber
Daniel Gerber
addaleax
Anna Henningsen
mctep
Konstantin Vasilev
barrtender
barrtender
RomanHotsiy
Roman Hotsiy
sauvainr
RenaudS
figadore
Reese
MattiSG
Matti Schneider
sandersky
Matthew Dahl
jfromaniello
José F. Romaniello
KEIII
Ivan Kasenkov
HanOterLin
Tony Lin
domoritz
Dominik Moritz
Semigradsky
Dmitry Semigradsky
countcain
Tao Huang
BuBuaBu
BuBuaBu

and to everyone submitting issues on GitHub

About

JSON Schema validator written in JavaScript for NodeJS and Browsers

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 32