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
- Quick Start
- JSON Template Validation
- Validation APIs
- Rule Reference
- Error Handling
- Internationalization
- Custom Rules
- API Reference
Installation
npm install @teonord/validatorExamples
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
- 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