Multer Utility
A comprehensive TypeScript wrapper for Multer with enhanced features including memory/disk storage, flexible configuration, and file management utilities.
Features
- 🚀 TypeScript Support - Fully typed with comprehensive interfaces
- 💾 Multiple Storage Options - Memory and disk storage with easy switching
- 🔧 Flexible Configuration - Customizable file validation, naming, and storage options
- 🛡️ Advanced Validation - MIME type and extension validation with custom rules
- 📁 File Management - Built-in utilities for file operations and statistics
- 🎯 Specialized Uploaders - Pre-configured uploaders for images, audio, etc.
- 🔄 Memory & Disk Storage - Switch between storage types effortlessly
Installation
npm install multer-utility
Quick Start
Basic Usage
import { UploadService } from 'multer-utility';
import express from 'express';
const app = express();
const uploader = new UploadService();
// Single file upload
app.post('/upload', uploader.single('file'), (req, res) => {
if (req.file) {
const fileInfo = uploader.getFileInfo(req.file);
res.json({ success: true, file: fileInfo });
}
});
Memory Storage
import { createMemoryUploader } from 'multer-utility';
const memoryUploader = createMemoryUploader({
maxFileSize: 1024 * 1024 * 10, // 10MB
allowedMimeTypes: ['image/jpeg', 'image/png']
});
app.post('/upload-memory', memoryUploader.single('image'), (req, res) => {
if (req.file) {
// File is stored in memory as buffer
const buffer = req.file.buffer;
// Process the buffer as needed
res.json({ success: true, size: buffer.length });
}
});
Custom Disk Storage
import { createDiskUploader } from 'multer-utility';
const diskUploader = createDiskUploader('/custom/upload/path', {
maxFileSize: 1024 * 1024 * 50, // 50MB
useTimestamp: true,
sanitizeFilenames: true
});
Configuration Options
interface UploadConfig {
// Storage configuration
storage?: 'disk' | 'memory';
uploadDir?: string;
// File validation
allowedMimeTypes?: string[];
allowedExtensions?: string[];
maxFileSize?: number; // in bytes
// Naming configuration
useTimestamp?: boolean;
sanitizeFilenames?: boolean;
customNaming?: (file: Express.Multer.File) => string;
// Advanced options
createDirIfNotExists?: boolean;
preserveOriginalName?: boolean;
}
Advanced Usage
Custom Configuration
const uploader = new UploadService({
storage: 'disk',
uploadDir: './uploads/documents',
allowedMimeTypes: ['application/pdf', 'image/jpeg', 'image/png'],
allowedExtensions: ['.pdf', '.jpg', '.jpeg', '.png'],
maxFileSize: 1024 * 1024 * 25, // 25MB
useTimestamp: true,
sanitizeFilenames: true,
customNaming: (file) => `custom-${Date.now()}-${file.originalname}`
});
Multiple File Upload
// Array of files with same field name
app.post('/upload-multiple', uploader.array('files', 5), (req, res) => {
if (req.files && Array.isArray(req.files)) {
const fileInfos = req.files.map(file => uploader.getFileInfo(file));
res.json({ success: true, files: fileInfos });
}
});
// Multiple fields
app.post('/upload-fields', uploader.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]), (req, res) => {
const files = req.files as { [fieldname: string]: Express.Multer.File[] };
res.json({ success: true, files });
});
Pre-configured Uploaders
import { createImageUploader, createAudioUploader } from 'multer-utility';
// Image uploader (JPEG, PNG, GIF, WebP)
const imageUploader = createImageUploader('./uploads/images');
// Audio uploader (MP3, WAV, OGG)
const audioUploader = createAudioUploader('./uploads/audio');
app.post('/upload-image', imageUploader.single('image'), (req, res) => {
// Handle image upload
});
app.post('/upload-audio', audioUploader.single('audio'), (req, res) => {
// Handle audio upload
});
File Management
File Operations
const uploader = new UploadService({ storage: 'disk' });
// Check if file exists
const exists = uploader.fileExists('filename.jpg');
// Get file path
const filePath = uploader.getFilePath('filename.jpg');
// Delete file
const deleted = await uploader.deleteFile('filename.jpg');
// Get upload statistics
const stats = await uploader.getUploadStats();
console.log(stats);
// Output:
// {
// totalFiles: 15,
// totalSize: 2048576,
// files: [
// {
// name: 'file1.jpg',
// size: 102400,
// created: '2023-01-01T00:00:00.000Z',
// modified: '2023-01-01T00:00:00.000Z'
// }
// ]
// }
File Validation
const uploader = new UploadService();
// Validate file manually
const validation = uploader.validateFile(file);
if (!validation.isValid) {
console.error(validation.error);
}
Error Handling
app.post('/upload', uploader.single('file'), (req, res) => {
// Multer errors are automatically handled
// Custom validation errors are thrown as MulterError
});
// Error handling middleware
app.use((error, req, res, next) => {
if (error instanceof MulterError) {
switch (error.code) {
case 'LIMIT_FILE_SIZE':
return res.status(400).json({ error: 'File too large' });
case 'LIMIT_UNEXPECTED_FILE':
return res.status(400).json({ error: 'Invalid file type' });
default:
return res.status(400).json({ error: error.message });
}
}
next(error);
});
Memory vs Disk Storage
Memory Storage
- Files stored in memory as Buffer
- Faster access but limited by available RAM
- Good for small files or temporary processing
- Files don't persist after server restart
const memoryUploader = createMemoryUploader();
// Access via req.file.buffer
Disk Storage
- Files saved to filesystem
- Persistent storage
- Better for large files
- Includes file management utilities
const diskUploader = createDiskUploader('./uploads');
// Access via req.file.path
API Reference
UploadService Class
Methods
single(fieldName: string)
- Handle single file uploadarray(fieldName: string, maxCount?: number)
- Handle multiple files (same field)fields(fields: multer.Field[])
- Handle multiple fieldsany()
- Handle any filesnone()
- No files expectedvalidateFile(file: Express.Multer.File)
- Validate file manuallygetFileInfo(file: Express.Multer.File)
- Get detailed file informationdeleteFile(filename: string)
- Delete file (disk storage only)fileExists(filename: string)
- Check if file exists (disk storage only)getFilePath(filename: string)
- Get file path (disk storage only)getUploadStats()
- Get upload directory statisticsgetConfig()
- Get current configuration
Convenience Functions
createDiskUploader(uploadDir: string, config?: Partial<UploadConfig>)
createMemoryUploader(config?: Partial<UploadConfig>)
createImageUploader(uploadDir?: string)
createAudioUploader(uploadDir?: string)
TypeScript Support
The package is fully typed and exports all necessary interfaces:
import {
UploadService,
UploadConfig,
FileValidationResult,
MulterError
} from 'multer-utility';
Author
[SURAJ] — suraj222615@gmail.com
GitHub: https://github.com/suraj-o
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT © [Suraj]
Made with ❤️ and TypeScript