CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jsoneditor

A web-based tool to view, edit, format, and validate JSON with multiple editing modes including tree, code, text, and preview

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

schema-validation.mddocs/

Schema Validation

JSON schema validation system with comprehensive error reporting, custom validation support, and real-time validation feedback powered by the Ajv library.

Capabilities

Set JSON Schema

Configure JSON schema for automatic validation of editor content.

/**
 * Set a JSON schema for validation of the JSON object
 * @param schema - JSON schema object, or null to remove validation
 * @param schemaRefs - Optional referenced schemas for $ref properties
 */
setSchema(schema: object | null, schemaRefs?: { [key: string]: object }): void;

Usage Example:

// Define a schema
const userSchema = {
  type: "object",
  properties: {
    name: { 
      type: "string", 
      minLength: 1 
    },
    email: { 
      type: "string", 
      format: "email" 
    },
    age: { 
      type: "number", 
      minimum: 0, 
      maximum: 150 
    },
    active: { 
      type: "boolean" 
    }
  },
  required: ["name", "email"],
  additionalProperties: false
};

// Set the schema
editor.setSchema(userSchema);

// Remove schema validation
editor.setSchema(null);

Schema with References

Use referenced schemas for complex validation scenarios.

// Example with schema references
const mainSchema = {
  type: "object",
  properties: {
    user: { $ref: "#/definitions/User" },
    company: { $ref: "company.json" }
  }
};

const schemaRefs = {
  "#/definitions/User": {
    type: "object",
    properties: {
      name: { type: "string" },
      email: { type: "string", format: "email" }
    }
  },
  "company.json": {
    type: "object", 
    properties: {
      name: { type: "string" },
      industry: { type: "string" }
    }
  }
};

editor.setSchema(mainSchema, schemaRefs);

Validate Content

Manually trigger validation and retrieve validation errors.

/**
 * Validate current JSON object against the configured JSON schema
 * @returns Promise resolving to array of validation errors
 */
validate(): Promise<ValidationError[]>;

Usage Example:

// Trigger validation manually
const errors = await editor.validate();

if (errors.length > 0) {
  console.log("Validation errors found:");
  errors.forEach(error => {
    console.log(`- ${error.message} at path: ${error.path.join('.')}`);
  });
} else {
  console.log("Validation passed!");
}

Validation Error Structure

Structure of validation error objects returned by the validation system.

interface ValidationError {
  /** Type of validation error */
  type: "validation" | "customValidation" | "error";
  
  /** Path to the invalid data as an array */
  path: (string | number)[];
  
  /** Human-readable error message */
  message: string;
  
  /** Original error object (for type: "error") */
  error?: Error;
  
  /** Schema keyword that failed (for type: "validation") */
  keyword?: string;
  
  /** Schema path where validation failed */
  schemaPath?: string;
  
  /** Additional error data from Ajv */
  data?: any;
}

Custom Validation Function

Implement custom validation logic beyond JSON schema capabilities.

/**
 * Custom validation function in editor options
 */
interface ValidationOptions {
  onValidate?: (json: any) => ValidationError[] | Promise<ValidationError[]> | null;
}

Usage Example:

const options = {
  mode: "tree",
  onValidate: (json) => {
    const errors = [];
    
    // Custom business logic validation
    if (json.users && Array.isArray(json.users)) {
      json.users.forEach((user, index) => {
        if (user.email && user.email.endsWith('@tempmail.com')) {
          errors.push({
            type: "customValidation",
            path: ['users', index, 'email'],
            message: "Temporary email addresses are not allowed"
          });
        }
      });
    }
    
    // Async validation example
    if (json.username) {
      return fetch(`/api/validate-username/${json.username}`)
        .then(response => response.json())
        .then(result => {
          if (!result.available) {
            return [{
              type: "customValidation", 
              path: ['username'],
              message: "Username is already taken"
            }];
          }
          return [];
        });
    }
    
    return errors;
  }
};

const editor = new JSONEditor(container, options);

Validation Error Callback

Handle validation errors with a dedicated callback function.

/**
 * Validation error callback in editor options
 */
interface ValidationOptions {
  onValidationError?: (errors: ValidationError[]) => void;
}

Usage Example:

const options = {
  mode: "tree",
  schema: userSchema,
  onValidationError: (errors) => {
    const errorContainer = document.getElementById('validation-errors');
    
    if (errors.length > 0) {
      const errorList = errors.map(error => {
        const pathStr = error.path.length > 0 ? ` at ${error.path.join('.')}` : '';
        return `<li>${error.message}${pathStr}</li>`;
      }).join('');
      
      errorContainer.innerHTML = `<ul class="errors">${errorList}</ul>`;
      errorContainer.style.display = 'block';
    } else {
      errorContainer.style.display = 'none';
    }
  }
};

Custom Ajv Instance

Provide a custom Ajv instance with specific configuration.

/**
 * Custom Ajv configuration in editor options
 */
interface ValidationOptions {
  ajv?: any; // Ajv instance
}

Usage Example:

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

// Create custom Ajv instance
const ajv = new Ajv({
  allErrors: true,
  verbose: true,
  $data: true,
  strictSchema: false
});

// Add format validation
addFormats(ajv);

// Add custom keyword
ajv.addKeyword({
  keyword: 'isEven',
  type: 'number',
  schemaType: 'boolean',
  validate: (schemaValue, data) => {
    return schemaValue ? data % 2 === 0 : data % 2 !== 0;
  }
});

const options = {
  mode: "tree",
  ajv: ajv,
  schema: {
    type: "object",
    properties: {
      evenNumber: {
        type: "number",
        isEven: true
      }
    }
  }
};

const editor = new JSONEditor(container, options);

Schema-based Autocomplete

Enable autocomplete suggestions based on JSON schema properties and enums.

/**
 * Schema autocomplete configuration in editor options
 */
interface ValidationOptions {
  allowSchemaSuggestions?: boolean;
}

Usage Example:

const schemaWithEnums = {
  type: "object",
  properties: {
    status: {
      type: "string",
      enum: ["draft", "published", "archived"],
      examples: ["draft"]
    },
    category: {
      type: "string",
      enum: ["tech", "business", "lifestyle"]
    }
  }
};

const options = {
  mode: "code", // Only works in code mode
  schema: schemaWithEnums,
  allowSchemaSuggestions: true
};

const editor = new JSONEditor(container, options);

Real-time Validation

JSONEditor automatically validates content in real-time as users edit:

  • Tree/View/Form modes: Invalid nodes are highlighted with error styling
  • Code/Text modes: Error annotations appear in the editor gutter
  • All modes: Error table can be displayed showing all validation issues
  • Debounced: Validation is debounced (150ms default) to avoid excessive validation calls

Validation Error Display

Control how validation errors are displayed to users:

const options = {
  mode: "tree",
  schema: userSchema,
  
  // Show error table for specific modes
  showErrorTable: true, // boolean
  // or
  showErrorTable: ["text", "code"], // array of modes
  
  // Custom error handling
  onValidationError: (errors) => {
    // Custom error display logic
    displayCustomErrorUI(errors);
  }
};

Validation Best Practices

Schema Design

// Good: Comprehensive schema with clear constraints
const goodSchema = {
  type: "object",
  properties: {
    id: { type: "string", pattern: "^[a-zA-Z0-9_-]+$" },
    name: { type: "string", minLength: 1, maxLength: 100 },
    email: { type: "string", format: "email" },
    age: { type: "integer", minimum: 0, maximum: 150 },
    tags: {
      type: "array",
      items: { type: "string" },
      maxItems: 10
    }
  },
  required: ["id", "name"],
  additionalProperties: false
};

Error Handling

// Handle validation errors gracefully
const options = {
  onValidationError: (errors) => {
    // Group errors by type
    const schemaErrors = errors.filter(e => e.type === 'validation');
    const customErrors = errors.filter(e => e.type === 'customValidation');
    const parseErrors = errors.filter(e => e.type === 'error');
    
    // Display appropriate user feedback
    if (parseErrors.length > 0) {
      showMessage("Invalid JSON format", "error");
    } else if (schemaErrors.length > 0 || customErrors.length > 0) {
      showMessage(`${errors.length} validation error(s) found`, "warning");
    }
  }
};

Performance Optimization

// For large schemas or frequent validation
const ajv = new Ajv({
  allErrors: false, // Stop on first error for better performance
  verbose: false,   // Reduce error object size
  validateSchema: false // Skip schema validation if schema is trusted
});

docs

configuration.md

editor-core.md

index.md

mode-management.md

preview-mode.md

schema-validation.md

text-operations.md

transform-operations.md

tree-operations.md

tile.json