CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-z-schema

JSON schema validator for JavaScript with comprehensive validation capabilities and support for both synchronous and asynchronous validation modes

Overview
Eval results
Files

format-validation.mddocs/

Format Validation

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.

Capabilities

Register Custom Format

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
);

Unregister Format

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 Registered Formats

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");
}

Prefill Default Values

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" }

Built-in Format Validators

z-schema includes comprehensive built-in format validators:

Date and Time Formats

// 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);

Network Formats

// 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);

Regular Expression Format

// 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); // false

Format Validation Options

Strict URI Validation

Control 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 Error Handling

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

docs

error-handling.md

format-validation.md

index.md

schema-management.md

validation.md

tile.json