@th3hero/request-validator
v1.1.9
Published
π Lightweight, fast & flexible request validation library for Node.js/Express/Next.js with TypeScript support. Features 20+ validation rules, database integration, file upload validation, and zero external dependencies. Perfect for API validation, form v
Maintainers
Keywords
Readme
@th3hero/request-validator
π The Ultimate Request Validation Library for Node.js - Lightweight, fast, and feature-rich validation with TypeScript support. Perfect for Express, Next.js, Fastify, and any Node.js framework.
Why choose @th3hero/request-validator?
β Zero External Dependencies - No bloat, just pure validation power
β 20+ Built-in Rules - From basic validation to complex database checks
β TypeScript First - Full type safety and IntelliSense support
β Framework Agnostic - Works with Express, Next.js, Fastify, Koa, and more
β Database Integration - Built-in MySQL support for unique/exists validation
β File Upload Validation - Secure file validation with MIME type checking
β Async Support - Handle complex validation scenarios
β High Performance - Optimized for speed and efficiency
π Table of Contents
- Features
- Installation
- Quick Start
- Validation Rules
- Database Integration
- File Upload Validation
- Custom Validation Rules
- Error Handling
- TypeScript Support
- Best Practices
- Contributing
- Testing
- License
β¨ Features
- π Simple Function-Based API: Easy to use with a clean, intuitive interface
- π Comprehensive Validation Rules: Over 20 built-in validation rules
- π― Database Integration: Built-in support for unique/exists validations with MySQL
- π File Upload Validation: Support for file uploads with MIME type checking
- π§ͺ Extensive Test Coverage: Thoroughly tested with Jest (90%+ coverage)
- β‘οΈ High Performance: Optimized for speed and efficiency
- π Secure by Default: Built-in security features
- π TypeScript Support: Full TypeScript support with type definitions
- π Async Validation: Support for asynchronous validation rules
- π¨ Customizable: Easy to extend with custom validation rules
- π οΈ Zero External Validation Dependencies: Custom-built validation functions
- π Framework Agnostic: Works with Express, Next.js, Fastify, Koa, and more
π Installation
# Using npm
npm install @th3hero/request-validator
# Using yarn
yarn add @th3hero/request-validator
# Using pnpm
pnpm add @th3hero/request-validatorπ¦ Dependencies
This library has the following dependencies:
Core Dependencies
express(^4.18.2) - For request handling and types
Optional Dependencies
mysql(^2.18.1) - For database validations (only required if using database validation rules)
Development Dependencies
- TypeScript and related type definitions
- Jest for testing
- Various type definitions for better TypeScript support
Note: While the library has these dependencies, they are only required if you use the specific features that need them. For example:
- MySQL is only required if you use database validation rules (unique/exists)
- Express is only required if you're using it in an Express.js application
β‘ Quick Start
Basic Usage
import { validateInput } from '@th3hero/request-validator';
import { Request } from 'express';
// Define validation rules
const rules = {
username: 'required|min:3|max:15',
email: 'required|email|unique:users,email',
password: 'required|min:8',
age: 'integer|min:18',
status: 'in:active,inactive,pending'
};
// Validate request
app.post('/users', async (req: Request, res) => {
const result = await validateInput(req, rules);
if (result.failed) {
return res.status(400).json({ errors: result.errors });
}
// Process valid request...
});With File Upload
π Why Choose @th3hero/request-validator?
| Feature | @th3hero/request-validator | Joi | Yup | express-validator | |---------|---------------------------|-----|-----|-------------------| | Bundle Size | π’ ~15KB | π‘ ~200KB | π‘ ~150KB | π‘ ~100KB | | Zero Dependencies | β Yes | β No | β No | β No | | TypeScript Support | β First-class | β Good | β Good | β Limited | | Database Integration | β Built-in | β No | β No | β No | | File Upload Validation | β Built-in | β No | β No | β Yes | | Async Validation | β Yes | β Yes | β Yes | β Yes | | Custom Validators | β Easy | β Complex | β Complex | β Complex | | Framework Agnostic | β Yes | β Yes | β Yes | β Express only | | Learning Curve | π’ Simple | π‘ Medium | π‘ Medium | π‘ Medium | | Performance | π’ Fast | π‘ Good | π‘ Good | π‘ Good |
Key Advantages:
- π Zero External Dependencies: No bloat, just pure validation power
- π¦ Lightweight: Only ~15KB vs 100-200KB for alternatives
- π§ Database Ready: Built-in MySQL support for unique/exists validation
- π File Upload Support: Secure file validation with MIME type checking
- π― Framework Agnostic: Works with Express, Next.js, Fastify, Koa, and more
- β‘ High Performance: Optimized for speed and efficiency
- π‘οΈ Security First: Built-in security features and sanitization
π Validation Rules
Basic Rules
| Rule | Description | Example | Error Message |
|------|-------------|---------|---------------|
| required | Field must be present and not empty | username: 'required' | "username is required" |
| nullable | Field can be null or undefined | middle_name: 'nullable' | - |
| not-empty | Field cannot be empty | description: 'not-empty' | "description cannot be empty" |
| numeric | Field must be a number | age: 'numeric' | "age must be a number" |
| confirmed | Field must have a matching confirmation field | password: 'confirmed' | "password must be confirmed" |
| digits:length | Field must contain exactly the specified number of digits | phone: 'digits:10' | "phone must be exactly 10 digits" |
String Rules
| Rule | Description | Example | Error Message |
|------|-------------|---------|---------------|
| min:length | Minimum string length | username: 'min:3' | "username must be at least 3 characters long" |
| max:length | Maximum string length | username: 'max:15' | "username must not exceed 15 characters" |
| string | Must be a string | note: 'string' | "note must be a string" |
| alpha | Must contain only letters | name: 'alpha' | "name must contain only letters" |
| alphanumeric | Must contain only letters and numbers | username: 'alphanumeric' | "username must contain only letters and numbers" |
| regex:/pattern/ | Must match the regular expression | username: 'regex:/^[a-z0-9-]+$/' | "username format is invalid" |
Type Rules
| Rule | Description | Example | Error Message |
|------|-------------|---------|---------------|
| email | Valid email address | email: 'email' | "Invalid email address for email" |
| integer | Must be an integer | age: 'integer' | "age must be an integer" |
| boolean | Must be a boolean | active: 'boolean' | "active must be a boolean" |
| date:format | Valid date with format | birth_date: 'date:YYYY-MM-DD' | "birth_date must be a valid date with format YYYY-MM-DD" |
| url | Must be a valid URL | website: 'url' | "website must be a valid URL" |
| array | Must be an array | tags: 'array' | "tags must be an array" |
| object | Must be an object | settings: 'object' | "settings must be an object" |
File Rules
| Rule | Description | Example | Error Message |
|------|-------------|---------|---------------|
| file | Must be a file upload | profile_picture: 'file' | "profile_picture is required" |
| mimetype:types | Valid MIME types | avatar: 'mimetype:image/jpeg,image/png' | "Invalid file format for avatar. Supported media types are image/jpeg, image/png" |
| max_size:size | File size must not exceed the specified size | avatar: 'max_size:2048' | "avatar file size must not exceed 2048 bytes" |
Database Rules
| Rule | Description | Example | Error Message |
|------|-------------|---------|---------------|
| unique:table,column | Must be unique in database | email: 'unique:users,email' | "email already exists" |
| exists:table,column | Must exist in database | user_id: 'exists:users,id' | "user_id does not exist" |
Enum Rules
| Rule | Description | Example | Error Message |
|------|-------------|---------|---------------|
| in:values | Must be one of the values | status: 'in:active,inactive,pending' | "status must be one of the following values: active, inactive, pending" |
Conditional Rules
| Rule | Description | Example | Error Message |
|------|-------------|---------|---------------|
| required_if:field,value | Required if field equals value | spouse_name: 'required_if:marital_status,married' | "spouse_name is required when marital_status is married" |
Database Integration
The library provides optional database validation rules that require MySQL. To use these features:
- Install MySQL:
npm install mysql- Set up the database connection:
import { setDatabase } from '@th3hero/request-validator';
import mysql from 'mysql';
const pool = mysql.createPool({
host: 'localhost',
user: 'your_username',
password: 'your_password',
database: 'your_database'
});
setDatabase(pool);If you try to use database validation rules without setting up the database connection, the library will throw an error with a helpful message.
File Upload Validation
Basic File Upload
const rules = {
avatar: 'file|mimetype:image/jpeg,image/png'
};
app.post('/upload', async (req: Request, res) => {
const result = await validateInput(req, rules);
if (result.failed) {
return res.status(400).json({ errors: result.errors });
}
// Process valid file upload...
});Multiple Files
const rules = {
documents: 'file|mimetype:application/pdf'
};
app.post('/upload-documents', async (req: Request, res) => {
const result = await validateInput(req, rules);
if (result.failed) {
return res.status(400).json({ errors: result.errors });
}
// Process valid file uploads...
});Custom Validation Rules
Define Custom Validator
const customValidators = {
isFortyTwo: (value: any) => value === 42 || 'Value must be 42',
isAdult: (value: any) => {
const age = parseInt(value);
return age >= 18 || 'Must be at least 18 years old';
}
};
const req = {
body: { value: 42, age: 20 },
customValidators
};Use Custom Validator
const rules = {
value: 'isFortyTwo',
age: 'isAdult'
};
app.post('/validate', async (req: Request, res) => {
const result = await validateInput(req, rules);
if (result.failed) {
return res.status(400).json({ errors: result.errors });
}
// Process valid request...
});Error Handling
Basic Error Handling
const result = await validateInput(req, rules);
if (result.failed) {
return res.status(400).json({ errors: result.errors });
}Custom Error Handling
try {
const result = await validateInput(req, rules);
if (result.failed) {
// Log validation errors
console.error('Validation failed:', result.errors);
// Return custom error response
return res.status(400).json({
success: false,
message: 'Validation failed',
errors: result.errors
});
}
// Process valid request...
} catch (error) {
// Handle unexpected errors
console.error('Validation error:', error);
return res.status(500).json({
success: false,
message: 'Internal server error'
});
}TypeScript Support
Type Definitions
import { Request } from 'express';
import { ValidationRules, ValidationResult } from '@th3hero/request-validator';
interface UserRequest extends Request {
body: {
username: string;
email: string;
password: string;
};
files?: {
avatar?: Express.Multer.File[];
};
}
const rules: ValidationRules = {
username: 'required|min:3',
email: 'required|email',
password: 'required|min:8',
avatar: 'file|mimetype:image/jpeg,image/png'
};
app.post('/users', async (req: UserRequest, res) => {
const result: ValidationResult = await validateInput(req, rules);
if (result.failed) {
return res.status(400).json({ errors: result.errors });
}
// Process valid request...
});π― Best Practices
Always Validate Input
// Good app.post('/users', async (req, res) => { const result = await validateInput(req, rules); if (result.failed) return res.status(400).json({ errors: result.errors }); // Process request... }); // Bad app.post('/users', async (req, res) => { // Process request without validation... });Use Specific Rules
// Good const rules = { email: 'required|email|unique:users,email', password: 'required|min:8|max:20' }; // Bad const rules = { email: 'required', password: 'required' };Handle File Uploads Properly
// Good const rules = { avatar: 'file|mimetype:image/jpeg,image/png' }; // Bad const rules = { avatar: 'file' };Use Custom Validators for Complex Rules
// Good const customValidators = { isAdult: (value) => parseInt(value) >= 18 || 'Must be at least 18 years old' }; // Bad const rules = { age: 'integer|min:18' // Less flexible };
π€ Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
π§ͺ Testing
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watchπ License
This project is licensed under the MIT License - see the LICENSE file for details.
β Support the Project
If you find this library helpful, please consider:
- β Star the repository on GitHub
- π¦ Use it in your projects and spread the word
- π Report bugs or suggest features
- π‘ Contribute code or documentation
- β Buy me a coffee if you want to support development
Made with β€οΈ by Alok Kumar
