JSON schema validator for JavaScript with comprehensive validation capabilities and support for both synchronous and asynchronous validation modes
Custom format registration system and built-in format validators for common data types. z-schema includes comprehensive format validators and allows registration of custom format validation functions.
Register a custom format validator function.
/**
* Register a custom format validator
* @param formatName - Name of the custom format
* @param validatorFunction - Function that validates the format
*/
static registerFormat(
formatName: string,
validatorFunction: (value: any, callback?: (result: boolean) => void) => boolean
): void;Usage Examples:
const ZSchema = require("z-schema");
// Synchronous custom format
ZSchema.registerFormat("xstring", function(str) {
return str === "xxx";
});
// Asynchronous custom format
ZSchema.registerFormat("async-email", function(email, callback) {
// Simulate async validation (e.g., checking against database)
setTimeout(function() {
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
callback(isValid);
}, 100);
});
// Custom format with complex validation
ZSchema.registerFormat("credit-card", function(cardNumber) {
if (typeof cardNumber !== "string") return false;
// Remove spaces and dashes
const cleaned = cardNumber.replace(/[\s-]/g, "");
// Check if all digits
if (!/^\d+$/.test(cleaned)) return false;
// Simple Luhn algorithm check
let sum = 0;
let shouldDouble = false;
for (let i = cleaned.length - 1; i >= 0; i--) {
let digit = parseInt(cleaned.charAt(i), 10);
if (shouldDouble) {
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
shouldDouble = !shouldDouble;
}
return sum % 10 === 0;
});
// Use custom format in schema
const validator = new ZSchema();
const schema = {
type: "object",
properties: {
cardNumber: {
type: "string",
format: "credit-card"
}
}
};
const valid = validator.validate(
{ cardNumber: "4532-1234-5678-9012" },
schema
);Remove a registered format validator.
/**
* Remove a registered format validator
* @param formatName - Name of the format to remove
*/
static unregisterFormat(formatName: string): void;Usage Examples:
// Remove a custom format
ZSchema.unregisterFormat("xstring");
// Remove built-in format (not recommended)
ZSchema.unregisterFormat("email");Get a list of all registered format names.
/**
* Get array of all registered format names
* @returns Array of format names (built-in and custom)
*/
static getRegisteredFormats(): string[];Usage Examples:
const formats = ZSchema.getRegisteredFormats();
console.log("Available formats:", formats);
// Output: ["date", "date-time", "email", "hostname", "ipv4", "ipv6", "uri", ...]
// Check if a format is registered
if (formats.includes("credit-card")) {
console.log("Credit card format is available");
}Use format validators to prefill default values into objects during validation.
/**
* Format validator that modifies the object being validated
* Can be used to set default values or transform data
*/
// Example format that sets default values
ZSchema.registerFormat("fillDefaults", function(obj) {
if (typeof obj === "object" && obj !== null) {
if (!obj.hasOwnProperty("timestamp")) {
obj.timestamp = new Date().toISOString();
}
if (!obj.hasOwnProperty("version")) {
obj.version = "1.0.0";
}
}
return true;
});Usage Examples:
ZSchema.registerFormat("fillHello", function(obj) {
obj.hello = "world";
return true;
});
const validator = new ZSchema();
const schema = {
type: "object",
format: "fillHello"
};
const data = {};
validator.validate(data, schema);
console.log(data); // { hello: "world" }z-schema includes comprehensive built-in format validators:
// Built-in date/time format validators
interface DateTimeFormats {
/** RFC3339 date format (YYYY-MM-DD) */
"date": (value: string) => boolean;
/** RFC3339 date-time format */
"date-time": (value: string) => boolean;
}Usage Examples:
const schema = {
type: "object",
properties: {
birthDate: { type: "string", format: "date" },
createdAt: { type: "string", format: "date-time" }
}
};
// Valid data
const valid = validator.validate({
birthDate: "1990-05-15",
createdAt: "2023-10-15T14:30:00Z"
}, schema);// Built-in network format validators
interface NetworkFormats {
/** Email address format */
"email": (value: string) => boolean;
/** RFC1034 hostname format */
"hostname": (value: string) => boolean;
/** Alias for hostname */
"host-name": (value: string) => boolean;
/** IPv4 address format */
"ipv4": (value: string) => boolean;
/** IPv6 address format */
"ipv6": (value: string) => boolean;
/** URI format (RFC3986) */
"uri": (value: string) => boolean;
/** Strict absolute URI format */
"strict-uri": (value: string) => boolean;
}Usage Examples:
const schema = {
type: "object",
properties: {
email: { type: "string", format: "email" },
website: { type: "string", format: "uri" },
serverIP: { type: "string", format: "ipv4" },
hostname: { type: "string", format: "hostname" }
}
};
// Valid data
const valid = validator.validate({
email: "user@example.com",
website: "https://example.com/path",
serverIP: "192.168.1.1",
hostname: "api.example.com"
}, schema);// Built-in regex format validator
interface RegexFormat {
/** Validates regular expression syntax */
"regex": (value: string) => boolean;
}Usage Examples:
const schema = {
type: "object",
properties: {
pattern: { type: "string", format: "regex" }
}
};
// Valid regex patterns
const valid1 = validator.validate({
pattern: "^[a-zA-Z0-9]+$"
}, schema); // true
const valid2 = validator.validate({
pattern: "[invalid regex("
}, schema); // falseControl URI format validation strictness through validator options.
interface FormatOptions {
/** Require fully RFC3986 compliant URIs (default: false) */
strictUris?: boolean;
/** Don't report unknown formats as errors (default: false) */
ignoreUnknownFormats?: boolean;
}Usage Examples:
// Strict URI validation
const strictValidator = new ZSchema({
strictUris: true
});
const schema = { type: "string", format: "uri" };
// With strictUris: false (default)
validator.validate("relative/path", schema); // true
// With strictUris: true
strictValidator.validate("relative/path", schema); // false
strictValidator.validate("https://example.com", schema); // true
// Ignore unknown formats
const lenientValidator = new ZSchema({
ignoreUnknownFormats: true
});
const schemaWithUnknownFormat = {
type: "string",
format: "unknown-format"
};
// With ignoreUnknownFormats: false (default)
validator.validate("test", schemaWithUnknownFormat); // false (error)
// With ignoreUnknownFormats: true
lenientValidator.validate("test", schemaWithUnknownFormat); // true (ignored)Format validation errors are reported with specific error codes and detailed information.
interface FormatValidationError {
code: "INVALID_FORMAT" | "UNKNOWN_FORMAT";
message: string;
params: [string, any]; // [formatName, value]
path: string;
}Usage Examples:
const validator = new ZSchema();
const schema = {
type: "object",
properties: {
email: { type: "string", format: "email" }
}
};
const valid = validator.validate({
email: "invalid-email"
}, schema);
if (!valid) {
const errors = validator.getLastErrors();
errors.forEach(error => {
if (error.code === "INVALID_FORMAT") {
console.log(`Format validation failed for ${error.params[0]}: ${error.params[1]}`);
// Output: Format validation failed for email: invalid-email
}
});
}Install with Tessl CLI
npx tessl i tessl/npm-z-schema