@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:
`
typescript 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
```typescript
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