UNPKG

@th3hero/request-validator

Version:

๐Ÿš€ 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

486 lines (375 loc) โ€ข 16.4 kB
# @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. [![npm version](https://img.shields.io/npm/v/@th3hero/request-validator.svg)](https://www.npmjs.com/package/@th3hero/request-validator) [![npm downloads](https://img.shields.io/npm/dm/@th3hero/request-validator.svg)](https://www.npmjs.com/package/@th3hero/request-validator) [![GitHub stars](https://img.shields.io/github/stars/th3hero/request-validator.svg)](https://github.com/th3hero/request-validator) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![Node.js](https://img.shields.io/badge/Node.js-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/) [![Test Coverage](https://img.shields.io/badge/coverage-90%25-brightgreen)](https://github.com/th3hero/request-validator) > **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](#features) - [Installation](#installation) - [Quick Start](#quick-start) - [Validation Rules](#validation-rules) - [Database Integration](#database-integration) - [File Upload Validation](#file-upload-validation) - [Custom Validation Rules](#custom-validation-rules) - [Error Handling](#error-handling) - [TypeScript Support](#typescript-support) - [Best Practices](#best-practices) - [Contributing](#contributing) - [Testing](#testing) - [License](#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 ```bash # 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 ```typescript 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: 1. Install MySQL: ```bash npm install mysql ``` 2. 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 ```typescript 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 ```typescript 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 ```typescript 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 ```typescript const result = await validateInput(req, rules); if (result.failed) { return res.status(400).json({ errors: result.errors }); } ``` ### Custom Error Handling ```typescript 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 ```typescript 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 1. **Always Validate Input** ```typescript // 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... }); ``` 2. **Use Specific Rules** ```typescript // Good const rules = { email: 'required|email|unique:users,email', password: 'required|min:8|max:20' }; // Bad const rules = { email: 'required', password: 'required' }; ``` 3. **Handle File Uploads Properly** ```typescript // Good const rules = { avatar: 'file|mimetype:image/jpeg,image/png' }; // Bad const rules = { avatar: 'file' }; ``` 4. **Use Custom Validators for Complex Rules** ```typescript // 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](CONTRIBUTING.md) for details. 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## ๐Ÿงช Testing ```bash # 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](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](https://github.com/th3hero)** [![GitHub Sponsors](https://img.shields.io/badge/Sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/th3hero) [![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/th3hero) [![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://linkedin.com/in/th3hero)