1.1.0 • Published 5 months ago
smart-data-validator v1.1.0
Smart Data Validator
A powerful, flexible, and easy-to-use data validation library for TypeScript/JavaScript. Built to be more intuitive than Zod or Yup while maintaining full type safety and excellent developer experience.
Features
- 🚀 Fluent, chainable API that's easier to use than alternatives
- 🎯 Full TypeScript support with excellent type inference
- ⚡ First-class async validation support
- 🔄 Powerful value transformation
- 🌳 Deep nested object validation
- 📝 Detailed error messages
- 🎨 Customizable validation rules
- 🔒 Type-safe by default
- 🎁 Rich set of built-in validators
- 🌟 Zero dependencies (except validator.js)
- 📦 Lightweight and tree-shakeable
Installation
npm install smart-data-validator
Why Smart Data Validator?
- More Intuitive API: Building schemas is more natural and readable
- Better Type Inference: Get full TypeScript type hints and autocompletion
- Flexible Validation: Mix and match sync and async validations easily
- Powerful Transformations: Transform data during validation
- Rich Error Messages: Get detailed, contextual error messages
Basic Usage
import { v, SmartValidator } from 'smart-data-validator';
// Define a schema
const userSchema = {
username: v.string()
.required()
.add(rules.minLength(3))
.add(rules.maxLength(20))
.build(),
email: v.string()
.required()
.add(rules.email())
.build(),
age: v.number()
.transform(value => typeof value === 'string' ? parseInt(value) : value)
.add(rules.min(18))
.build()
};
// Create validator
const validator = new SmartValidator(userSchema);
// Validate data
const result = await validator.validate({
username: 'john_doe',
email: 'john@example.com',
age: '25' // Will be transformed to number
});
if (result.isValid) {
console.log('Valid data:', result.data);
} else {
console.log('Validation errors:', result.errors);
}
Advanced Features
1. Custom Validation Rules
Create your own validation rules for complex scenarios:
const passwordSchema = {
password: v.string()
.required()
.add(rules.minLength(8))
.add(rules.custom(
(value) => {
const hasUpper = /[A-Z]/.test(value);
const hasLower = /[a-z]/.test(value);
const hasNumber = /\d/.test(value);
const hasSpecial = /[!@#$%^&*]/.test(value);
return hasUpper && hasLower && hasNumber && hasSpecial;
},
'Password must include uppercase, lowercase, numbers, and special characters'
))
.build()
};
2. Async Validation with External APIs
const registrationSchema = {
username: v.string()
.required()
.add(rules.custom(
async (value) => {
const response = await fetch(`/api/check-username/${value}`);
return response.ok;
},
'Username already taken',
true // mark as async
))
.build()
};
3. Nested Object Validation
const productSchema = {
product: v.object({
details: v.object({
name: v.string().required().build(),
price: v.number()
.transform(value => typeof value === 'string' ? parseFloat(value) : value)
.add(rules.min(0))
.build(),
variants: v.array()
.add(rules.minLength(1))
.add(rules.unique())
.build()
}).build(),
metadata: v.object({
tags: v.array()
.transform(tags => [...new Set(tags)])
.build()
}).build()
}).build()
};
4. Conditional Validation
const paymentSchema = {
method: v.string()
.add(rules.enum(['credit_card', 'paypal']))
.required()
.build(),
cardDetails: v.object({
number: v.string()
.add(rules.custom(
(value, context) => {
if (context.data.method === 'credit_card') {
return /^\d{16}$/.test(value);
}
return true;
},
'Invalid card number'
))
.build(),
cvv: v.string()
.add(rules.matches(/^\d{3,4}$/))
.build()
}).build()
};
5. Value Transformation
const formSchema = {
date: v.date()
.transform(value => new Date(value))
.build(),
tags: v.array()
.transform(value => typeof value === 'string' ? value.split(',') : value)
.add(rules.unique())
.build(),
price: v.number()
.transform(value => {
if (typeof value === 'string') {
return parseFloat(value.replace(/[$,]/g, ''));
}
return value;
})
.add(rules.min(0))
.build()
};
Built-in Validators
String Validators
required()
- Makes field requiredemail()
- Validates email formaturl()
- Validates URL formatminLength(n)
- Minimum string lengthmaxLength(n)
- Maximum string lengthmatches(regex)
- Regular expression matchinguuid([version])
- UUID validation
Number Validators
min(n)
- Minimum valuemax(n)
- Maximum valueinteger()
- Integer validationpositive()
- Positive number validationnegative()
- Negative number validation
Array Validators
minLength(n)
- Minimum array lengthmaxLength(n)
- Maximum array lengthunique()
- Unique values in arrayenum(values)
- Array values from enum
Common Features
optional()
- Makes field optionaldefault(value)
- Set default valuetransform(fn)
- Transform value before validationcustom(fn)
- Custom validation logic
Error Handling
The validator returns detailed error information:
{
isValid: boolean;
errors: Array<{
field: string; // Field path (includes nested paths)
message: string; // Error message
value?: any; // Invalid value
}>;
data: T; // Validated and transformed data
}
Best Practices
- Type Safety: Use TypeScript for better type inference
- Reusable Schemas: Create reusable schema components
- Transform Early: Transform data before validation
- Clear Messages: Provide clear error messages
- Async Validation: Use async validation for external checks
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Support
If you find this library helpful, please consider giving it a star on GitHub!