npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vvlad1973/data-validator

v2.0.0

Published

TypeScript library for loading and validating JSON/YAML schemas using AJV with optional logging support

Downloads

70

Readme

@vvlad1973/data-validator

TypeScript library for loading and validating JSON/YAML schemas using AJV with optional pino-logger-tree integration.

Features

  • Loads all .json, .jsonc, .yaml, .yml schemas from a directory
  • Supports $ref links between schemas
  • Validates data by schema key
  • Supports comments (jsonc) and YAML format
  • Optional multi-level logging (trace, debug, info, warn, error)
  • Optional integration with @vvlad1973/pino-logger-tree for structured logging
  • Automatic method tracing via decorators (when pino-logger-tree is installed)
  • Three logging modes: no logging, direct logger, auto-binding
  • Pure ESM package
  • Comprehensive JSDoc documentation

Installation

npm install @vvlad1973/data-validator

Optional: Install pino-logger-tree for advanced logging

npm install @vvlad1973/pino-logger-tree

Quick Start

Basic Usage

import DataValidator from '@vvlad1973/data-validator';

const validator = new DataValidator({
  schemasDir: './schemas'
});

await validator.isReady();

await validator.validate('user.schema.json', {
  name: 'John Doe',
  email: '[email protected]'
});

Legacy Constructor (Backward Compatible)

import DataValidator from '@vvlad1973/data-validator';

const validator = new DataValidator('./schemas');
await validator.isReady();

With pino-logger-tree (Direct Logger)

import DataValidator from '@vvlad1973/data-validator';
import { LoggerTree } from '@vvlad1973/pino-logger-tree';

// Create logger tree
const tree = new LoggerTree({ level: 'debug' });
const logger = tree.createLogger('app.validator');

// Create validator with logger
const validator = new DataValidator({
  schemasDir: './schemas',
  logger
});

// Validator will log all operations with structured logging
await validator.validate('user.schema.json', userData);

With pino-logger-tree (Auto-binding)

import DataValidator from '@vvlad1973/data-validator';
import { LoggerTree } from '@vvlad1973/pino-logger-tree';

// Create logger tree
const tree = new LoggerTree({ level: 'debug' });

// Create validator with auto-binding
const validator = new DataValidator({
  schemasDir: './schemas',
  loggerTree: tree,
  loggerPath: 'app.validator'
});

// Logger automatically created and bound
await validator.validate('user.schema.json', userData);

// Cleanup when done
validator.destroy();

With Custom Logger

import DataValidator, { ILogger } from '@vvlad1973/data-validator';

const customLogger: ILogger = {
  trace: (msg, ...args) => console.log('[TRACE]', msg, ...args),
  debug: (msg, ...args) => console.log('[DEBUG]', msg, ...args),
  info: (msg, ...args) => console.log('[INFO]', msg, ...args),
  warn: (msg, ...args) => console.warn('[WARN]', msg, ...args),
  error: (msg, ...args) => console.error('[ERROR]', msg, ...args),
};

const validator = new DataValidator({
  schemasDir: './schemas',
  logger: customLogger
});

API Reference

Constructor

new DataValidator(options?: string | DataValidatorOptions)

Parameters:

  • options - Schema directory path (string) or configuration object

DataValidatorOptions:

interface DataValidatorOptions {
  schemasDir?: string;    // Directory containing schema files
  logger?: ILogger;       // Optional logger instance (direct mode)
  loggerTree?: LoggerTree; // Optional LoggerTree for auto-binding
  loggerPath?: string;    // Path in LoggerTree hierarchy
}

Logging Modes

The validator supports three logging modes:

  1. No logging - Don't provide any logger-related options
  2. Direct logger - Provide logger instance
  3. Auto-binding - Provide both loggerTree and loggerPath for automatic logger creation

Methods

isReady(): Promise<boolean>

Checks if schemas are loaded and validator is ready.

const ready = await validator.isReady();
if (ready) {
  // Validator is ready to use
}

loadSchemasFromDirectory(schemaDir: string): Promise<boolean>

Loads schemas from a directory. Supports .json, .jsonc, .yaml, .yml formats.

await validator.loadSchemasFromDirectory('./custom-schemas');

addSchema(schema: object, key: string): void

Adds a schema programmatically.

validator.addSchema({
  type: 'object',
  properties: {
    name: { type: 'string' }
  },
  required: ['name']
}, 'user');

validate(schemaKey: string, data: unknown): Promise<void>

Validates data against a schema. Throws error if validation fails.

try {
  await validator.validate('user.schema.json', userData);
  console.log('Valid!');
} catch (error) {
  console.error('Invalid:', error.message);
}

destroy(): void

Cleans up resources and removes logger from tree if auto-bound. Call this when the validator is no longer needed, especially when using auto-binding mode.

const validator = new DataValidator({
  schemasDir: './schemas',
  loggerTree: tree,
  loggerPath: 'app.validator'
});

// Use validator...
await validator.validate('schema.json', data);

// Cleanup
validator.destroy();

Types

import { DataValidator, DataValidatorOptions, ILogger } from '@vvlad1973/data-validator';

ILogger Interface:

interface ILogger {
  // Pino-style: structured logging with context object
  trace(obj: object, msg?: string, ...args: unknown[]): void;
  debug(obj: object, msg?: string, ...args: unknown[]): void;
  info(obj: object, msg?: string, ...args: unknown[]): void;
  warn(obj: object, msg?: string, ...args: unknown[]): void;
  error(obj: object, msg?: string, ...args: unknown[]): void;

  // Simple style: console-like logging
  trace(msg: string, ...args: unknown[]): void;
  debug(msg: string, ...args: unknown[]): void;
  info(msg: string, ...args: unknown[]): void;
  warn(msg: string, ...args: unknown[]): void;
  error(msg: string, ...args: unknown[]): void;
}

The interface supports both Pino-style structured logging and simple console-style logging.

Schema Structure

Schemas should be placed in a directory. The package includes example schemas to demonstrate functionality:

schemas/
├── user.schema.json       # User validation schema
├── product.schema.yaml    # Product schema (YAML format)
├── order.schema.json      # Order schema with $ref examples
└── config.schema.jsonc    # Config schema (JSON with comments)

All matching files (.json, .jsonc, .yaml, .yml) are automatically loaded on initialization. Each schema is registered with its filename (including extension) as the key.

Example Schemas

The package includes example schemas that demonstrate:

  • user.schema.json - Basic validation with formats (email, uuid), patterns, and enums
  • product.schema.yaml - YAML format support with arrays and nested objects
  • order.schema.json - Schema references using $ref for reusable definitions
  • config.schema.jsonc - JSONC format with comments for documentation

Logging Levels

When a logger is provided, the validator logs operations at different levels:

  • trace - Method tracing (via decorators when pino-logger-tree is installed), very detailed info (file parsing, skipped files)
  • debug - Operation details (loading schemas, validation start/end)
  • info - Major operations (schema loading completed) - uses template strings without context object
  • warn - Non-critical issues (validation failed with details)
  • error - Critical errors (schema not found, parsing errors)

With pino-logger-tree

When pino-logger-tree is installed, all public methods are automatically traced at TRACE level via decorators:

import { LoggerTree } from '@vvlad1973/pino-logger-tree';

const tree = new LoggerTree({ level: 'trace' });

const validator = new DataValidator({
  schemasDir: './schemas',
  loggerTree: tree,
  loggerPath: 'app.validator'
});

// Method calls are automatically logged with parameters
await validator.validate('user.schema.json', userData);

Example pino log output (JSON format):

{"level":20,"time":1234567890,"name":"app.validator","msg":"Initializing DataValidator","schemasDir":"./schemas"}
{"level":10,"time":1234567890,"name":"app.validator","msg":"loadSchemasFromDirectory() called","schemaDir":"./schemas"}
{"level":20,"time":1234567890,"name":"app.validator","msg":"Schema loaded successfully","file":"user.schema.json","key":"user.schema.json"}
{"level":30,"time":1234567890,"name":"app.validator","msg":"Schema loading completed: loaded 3 of 3 files"}
{"level":10,"time":1234567890,"name":"app.validator","msg":"validate() called","schemaKey":"user.schema.json"}
{"level":20,"time":1234567890,"name":"app.validator","msg":"Validation succeeded","schemaKey":"user.schema.json"}

Without pino-logger-tree

When pino-logger-tree is not installed, decorators become no-ops and only explicit logger calls are made:

[DEBUG] Initializing DataValidator { schemasDir: './schemas' }
[DEBUG] Schema loaded successfully { file: 'user.schema.json', key: 'user.schema.json' }
[INFO] Schema loading completed: loaded 3 of 3 files
[DEBUG] Starting validation { schemaKey: 'user.schema.json' }
[DEBUG] Validation succeeded { schemaKey: 'user.schema.json' }

Development

Testing

This project uses Vitest with comprehensive test coverage (96%+).

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch

# Run tests with UI
npm run test:ui

Test Coverage:

  • Overall: 96.42%
  • Statements: 96.42%
  • Branches: 91.48%
  • Functions: 100%
  • Lines: 96.87%

Linting

# Check code quality
npm run lint

# Auto-fix issues
npm run lint:fix

Building

# Build the project
npm run build

Examples

Complete Example

import DataValidator from '@vvlad1973/data-validator';
import { LoggerTree } from '@vvlad1973/pino-logger-tree';

// Setup logger tree
const loggerTree = new LoggerTree();
const rootLogger = loggerTree.root();

// Configure logger level
rootLogger.updateParam({ level: 'debug' });

// Create validator with auto-binding
const validator = new DataValidator({
  schemasDir: './schemas',
  loggerTree: loggerTree,
  loggerPath: 'app.validator'
});

// Wait for schemas to load
await validator.isReady();

// Add custom schema
validator.addSchema({
  type: 'object',
  properties: {
    id: { type: 'string', format: 'uuid' },
    email: { type: 'string', format: 'email' },
    age: { type: 'number', minimum: 0 }
  },
  required: ['id', 'email']
}, 'custom-user');

// Validate data
try {
  await validator.validate('custom-user', {
    id: '123e4567-e89b-12d3-a456-426614174000',
    email: '[email protected]',
    age: 25
  });
  console.log('Data is valid!');
} catch (error) {
  console.error('Validation error:', error.message);
}

Error Handling

async function validateUserData(userData: unknown) {
  const validator = new DataValidator({ schemasDir: './schemas' });
  await validator.isReady();

  try {
    await validator.validate('user.schema.json', userData);
    return { valid: true };
  } catch (error) {
    if (error instanceof Error) {
      return {
        valid: false,
        errors: error.message.split('\n')
      };
    }
    throw error;
  }
}

TypeScript Support

This package is written in TypeScript and provides full type definitions.

import DataValidator, {
  DataValidatorOptions,
  ILogger
} from '@vvlad1973/data-validator';

// Type-safe options
const options: DataValidatorOptions = {
  schemasDir: './schemas',
  logger: myLogger
};

const validator = new DataValidator(options);

Build System

The package uses a pure ESM build system:

  • ESM output in dist/src/
  • Post-build scripts to clean test files from distribution

Compatibility

  • Node.js: 20.x or higher
  • TypeScript: 5.x or higher
  • Module System: ES Modules only
  • Logger: Compatible with TreeLogger from @vvlad1973/pino-logger-tree and console-like loggers
  • Optional Integration: @vvlad1973/pino-logger-tree ^1.1.0 (optional peer dependency)

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: npm test
  5. Run linter: npm run lint
  6. Submit a pull request

Changelog

See CHANGELOG.md for version history.

License

MIT License with Commercial Use