JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 9
  • Score
    100M100P100Q49480F
  • License CC-BY-4.0

Advanced validation library with multiple API styles including JSON templates, inline rules, builder pattern, and functional composition. Features 50+ built-in validators, dot notation for nested objects, field reference resolution, and internationalization support. Zero dependencies, fully synchronous, and designed for maximum developer experience with extensible custom rule system.

Package Exports

  • @teonord/validator

Readme

@teonord/validator

Advanced validator package inspired by Laravel validation, built with TypeScript. Supports multiple validation APIs including JSON templates, inline rules, builder pattern, and functional composition.

Features

  • 🎯 Multiple Validation APIs: JSON templates, inline rules, builder pattern, functional composition
  • 🏷️ TypeScript First: Full type safety and intelligent autocomplete
  • 🌍 Internationalization: Multi-language error messages
  • 🔧 Extensible: Custom rules and validators
  • 🧪 Comprehensive Rule Set: 50+ built-in validation rules
  • 🚀 Lightweight: Zero dependencies, tree-shakable

📚 Table of Contents

Installation

npm install @teonord/validator

Examples

Quick Start

import { Validator } from '@teonord/validator';

const data = {
  name: 'John Doe',
  email: 'john@example.com',
  age: 25
};

const validator = new Validator(data);
const result = validator.validateRules({
  name: [{ rule: 'required' }, { rule: 'minLength', value: 2 }],
  email: [{ rule: 'required' }, { rule: 'email' }],
  age: [{ rule: 'required' }, { rule: 'numeric' }, { rule: 'min', value: 18 }]
});

console.log(result.isValid); // true
console.log(result.errors); // []

JSON Template Validation

const template = [
  {
    type: 'input',
    name: 'username',
    validation: [
      {
        rule: 'required',
        message: {
          en: 'Username is required',
          fr: 'Nom d\'utilisateur est requis'
        }
      },
      {
        rule: 'minLength',
        value: 3,
        message: {
          en: 'Username must be at least 3 characters',
          fr: 'Le nom d\'utilisateur doit contenir au moins 3 caractères'
        }
      }
    ]
  }
];

const result = validator.validateTemplate(template);

Validation APIs

JSON Template API

Structured validation with field definitions and custom messages:

const template = [
  {
    type: 'input',
    name: 'email',
    validation: [
      {
        rule: 'required',
        message: { en: 'Email is required', es: 'El email es requerido' }
      },
      {
        rule: 'email',
        message: { en: 'Invalid email format', es: 'Formato de email inválido' }
      }
    ]
  },
  {
    type: 'input',
    name: 'password',
    validation: [
      {
        rule: 'required',
        message: { en: 'Password is required', es: 'La contraseña es requerida' }
      },
      {
        rule: 'minLength',
        value: 8,
        message: { en: 'Password must be 8+ characters', es: 'La contraseña debe tener 8+ caracteres' }
      }
    ]
  }
];

const result = validator.validateTemplate(template);

Inline Rules API

import { parseInlineRules } from '@teonord/validator';

const rules = {
  username: parseInlineRules('required|minLength:3|maxLength:20|alphaDash'),
  email: parseInlineRules('required|email'),
  age: parseInlineRules('required|numeric|min:18|max:100'),
  tags: parseInlineRules('array|minItems:1|maxItems:5'),
  website: parseInlineRules('url')
};

const result = validator.validateRules(rules);

Builder Pattern API

Fluent interface for building validation rules:

import { ValidatorBuilder } from '@teonord/validator';

const result = new ValidatorBuilder()
  .setData({ username: 'john_doe', email: 'john@example.com' })
  .addField('username', [
    { rule: 'required' },
    { rule: 'minLength', value: 3 },
    { rule: 'alphaDash' }
  ])
  .addField('email', [
    { rule: 'required' },
    { rule: 'email' }
  ])
  .setLanguage('en')
  .validate();

Functional Composition API

Composable validation pipelines:

import { createPipe, pipe, transformData, mapErrors } from '@teonord/validator';

const userPipe = createPipe({
  name: [{ rule: 'required' }, { rule: 'minLength', value: 2 }],
  email: [{ rule: 'required' }, { rule: 'email' }]
});

const trimmedPipe = transformData(userPipe, data => ({
  ...data,
  name: data.name?.trim(),
  email: data.email?.trim()
}));

const validationPipe = pipe(
  trimmedPipe,
  mapErrors(result => result.errors.map(error => ({
    ...error,
    field: error.field.toUpperCase()
  })))
);

const result = validationPipe({
  name: '  John  ',
  email: 'JOHN@EXAMPLE.COM  '
});

Rule Reference

String Rules

  • required
  • minLength:value
  • maxLength:value
  • length:value
  • email
  • url
  • ip
  • uuid
  • alpha
  • alphaNumeric
  • alphaDash
  • regex:pattern
  • startsWith:value
  • endsWith:value
  • contains:value
  • notContains:value
  • in:value1,value2,...
  • notIn:value1,value2,...

Number Rules

  • numeric
  • integer
  • float
  • min:value
  • max:value
  • between:min,max
  • positive
  • negative
  • multipleOf:value

Array Rules

  • array
  • minItems:value
  • maxItems:value
  • lengthItems:value
  • includes:value
  • excludes:value
  • unique

Date Rules

  • date
  • before:date
  • after:date
  • betweenDates:start,end

File Rules

  • file
  • mime:type1,type2,...
  • maxSize:bytes
  • minSize:bytes

Boolean Rules

  • boolean
  • accepted

Conditional Rules

  • requiredIf:field,value
  • requiredUnless:field,value
  • requiredWith:field
  • requiredWithAll:field1,field2,...
  • requiredWithout:field
  • requiredWithoutAll:field1,field2,...
  • same:field
  • different:field
  • gt:field
  • gte:field
  • lt:field
  • lte:field
  • when:condition
  • unless:condition

Error Handling

const result = validator.validateRules({
  email: [{ rule: 'required' }, { rule: 'email' }]
});

if (!result.isValid) {
  result.errors.forEach(error => {
    console.log(`Field: ${error.field}`);
    console.log(`Rule: ${error.rule}`);
    console.log(`Message: ${error.message}`);
    console.log(`Value: ${error.value}`);
  });

  const apiErrors = result.errors.map(error => ({
    field: error.field,
    message: error.message,
    code: error.rule
  }));
}

Internationalization

const validator = new Validator(data, {
  language: 'fr',
  customMessages: {
    'email.required': {
      en: 'Email address is required',
      fr: 'L\'adresse email est requise',
      es: 'La dirección de correo electrónico es obligatoria'
    },
    'email.email': {
      en: 'Must be a valid email address',
      fr: 'Doit être une adresse email valide',
      es: 'Debe ser una dirección de correo electrónico válida'
    }
  }
});

Custom Rules

const customRule = (value: any, params: any[], data: Record<string, any>) => {
  if (value === 'custom') {
    return true;
  }
  return 'Value must be "custom"';
};

validator.addCustomRule('customRule', customRule);

const result = validator.validateRules({
  field: [{ rule: 'customRule' }]
});

API Reference

Validator Class

Constructor

new Validator(data: Record<string, any>, options?: ValidatorOptions)

Methods

  • validateTemplate(template: any[]): ValidationResult
  • validateRules(rules: Record<string, ValidationRuleConfig[]>): ValidationResult
  • addCustomRule(name: string, rule: CustomRule): void

ValidatorBuilder Class

Methods

  • setData(data: Record<string, any>): this
  • addField(field: string, rules: ValidationRuleConfig[]): this
  • setOptions(options: ValidatorOptions): this
  • setLanguage(language: string): this
  • build(): Validator
  • validate(): ValidationResult

Functional API

  • createPipe(rules, options): ValidationPipe
  • createTemplatePipe(template, options): ValidationPipe
  • pipe(...pipes): ValidationPipe
  • mapErrors(pipe, mapper): ValidationPipe
  • transformData(pipe, transformer): ValidationPipe
  • conditional(condition, truePipe, falsePipe?): ValidationPipe
  • mergePipes(...pipes): ValidationPipe