UNPKG

multer-utility

Version:

A comprehensive TypeScript wrapper for Multer with enhanced features including memory/disk storage, flexible configuration, and file management utilities

378 lines 13.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const path_1 = __importDefault(require("path")); const index_1 = require("../index"); const app = (0, express_1.default)(); const PORT = 3000; // Basic disk uploader const basicUploader = new index_1.UploadService({ storage: 'disk', uploadDir: path_1.default.join(path_1.default.resolve(), 'uploads'), maxFileSize: 1024 * 1024 * 10, // 10MB useTimestamp: true, sanitizeFilenames: true }); // Memory uploader const memoryUploader = (0, index_1.createMemoryUploader)({ maxFileSize: 1024 * 1024 * 5, // 5MB allowedMimeTypes: ['image/jpeg', 'image/png', 'image/gif'] }); // Specialized uploaders const imageUploader = (0, index_1.createImageUploader)(path_1.default.join(path_1.default.resolve(), 'uploads/images')); const audioUploader = (0, index_1.createAudioUploader)(path_1.default.join(path_1.default.resolve(), 'uploads/audio')); // Routes // Single file upload (disk) app.post('/upload/single', basicUploader.single('file'), (req, res) => { try { if (!req.file) { return res.status(400).json({ error: 'No file uploaded' }); } const fileInfo = basicUploader.getFileInfo(req.file); res.json({ success: true, message: 'File uploaded successfully', file: fileInfo }); } catch (error) { res.status(500).json({ error: 'Upload failed' }); } }); // Multiple files upload app.post('/upload/multiple', basicUploader.array('files', 5), (req, res) => { try { if (!req.files || !Array.isArray(req.files) || req.files.length === 0) { return res.status(400).json({ error: 'No files uploaded' }); } const filesInfo = req.files.map(file => basicUploader.getFileInfo(file)); res.json({ success: true, message: `${req.files.length} files uploaded successfully`, files: filesInfo }); } catch (error) { res.status(500).json({ error: 'Upload failed' }); } }); // Memory storage upload app.post('/upload/memory', memoryUploader.single('image'), (req, res) => { try { if (!req.file) { return res.status(400).json({ error: 'No file uploaded' }); } // File is in memory as buffer const fileInfo = memoryUploader.getFileInfo(req.file); res.json({ success: true, message: 'File uploaded to memory successfully', file: { ...fileInfo, bufferSize: req.file.buffer.length, note: 'File stored in memory' } }); } catch (error) { res.status(500).json({ error: 'Upload failed' }); } }); // Image upload app.post('/upload/image', imageUploader.single('image'), (req, res) => { try { if (!req.file) { return res.status(400).json({ error: 'No image uploaded' }); } const fileInfo = imageUploader.getFileInfo(req.file); res.json({ success: true, message: 'Image uploaded successfully', image: fileInfo }); } catch (error) { res.status(500).json({ error: 'Image upload failed' }); } }); // Audio upload app.post('/upload/audio', audioUploader.single('audio'), (req, res) => { try { if (!req.file) { return res.status(400).json({ error: 'No audio file uploaded' }); } const fileInfo = audioUploader.getFileInfo(req.file); res.json({ success: true, message: 'Audio uploaded successfully', audio: fileInfo }); } catch (error) { res.status(500).json({ error: 'Audio upload failed' }); } }); // Multiple fields upload app.post('/upload/fields', basicUploader.fields([ { name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }, { name: 'documents', maxCount: 5 } ]), (req, res) => { try { const files = req.files; if (!files || Object.keys(files).length === 0) { return res.status(400).json({ error: 'No files uploaded' }); } const result = { success: true, message: 'Files uploaded successfully', files: {} }; // Process each field Object.entries(files).forEach(([fieldName, fieldFiles]) => { result.files[fieldName] = fieldFiles.map(file => basicUploader.getFileInfo(file)); }); res.json(result); } catch (error) { res.status(500).json({ error: 'Upload failed' }); } }); // File management endpoints // Get upload statistics app.get('/upload/stats', async (req, res) => { try { const stats = await basicUploader.getUploadStats(); res.json({ success: true, stats }); } catch (error) { res.status(500).json({ error: 'Failed to get stats' }); } }); // Check if file exists app.get('/upload/exists/:filename', (req, res) => { try { const { filename } = req.params; const exists = basicUploader.fileExists(filename); res.json({ success: true, filename, exists }); } catch (error) { res.status(500).json({ error: 'Failed to check file existence' }); } }); // Delete file app.delete('/upload/:filename', async (req, res) => { try { const { filename } = req.params; const deleted = await basicUploader.deleteFile(filename); if (deleted) { res.json({ success: true, message: `File ${filename} deleted successfully` }); } else { res.status(404).json({ success: false, message: `File ${filename} not found or could not be deleted` }); } } catch (error) { res.status(500).json({ error: 'Failed to delete file' }); } }); // Get file path app.get('/upload/path/:filename', (req, res) => { try { const { filename } = req.params; if (!basicUploader.fileExists(filename)) { return res.status(404).json({ error: 'File not found' }); } const filePath = basicUploader.getFilePath(filename); res.json({ success: true, filename, path: filePath }); } catch (error) { res.status(500).json({ error: 'Failed to get file path' }); } }); // Custom validation example app.post('/upload/validate', (req, res) => { const upload = basicUploader.single('file'); upload(req, res, (err) => { if (err) { // Handle multer errors if (err instanceof index_1.MulterError) { switch (err.code) { case 'LIMIT_FILE_SIZE': return res.status(400).json({ error: 'File too large', maxSize: '10MB' }); case 'LIMIT_UNEXPECTED_FILE': return res.status(400).json({ error: 'Invalid file type', message: err.message }); default: return res.status(400).json({ error: err.message }); } } return res.status(500).json({ error: 'Upload failed' }); } if (!req.file) { return res.status(400).json({ error: 'No file uploaded' }); } // Additional custom validation const validation = basicUploader.validateFile(req.file); if (!validation.isValid) { return res.status(400).json({ error: 'File validation failed', details: validation.error }); } const fileInfo = basicUploader.getFileInfo(req.file); res.json({ success: true, message: 'File uploaded and validated successfully', file: fileInfo }); }); }); // Configuration info endpoint app.get('/upload/config', (req, res) => { const config = basicUploader.getConfig(); res.json({ success: true, config: { storage: config.storage, uploadDir: config.uploadDir, maxFileSize: `${Math.round(config.maxFileSize / 1024 / 1024)}MB`, allowedMimeTypes: config.allowedMimeTypes, allowedExtensions: config.allowedExtensions, useTimestamp: config.useTimestamp, sanitizeFilenames: config.sanitizeFilenames } }); }); // Health check app.get('/health', (req, res) => { res.json({ success: true, message: 'Multer Utility Example Server is running', timestamp: new Date().toISOString() }); }); // Error handling middleware app.use((error, req, res, next) => { console.error('Error:', error); if (error instanceof index_1.MulterError) { switch (error.code) { case 'LIMIT_FILE_SIZE': return res.status(400).json({ error: 'File too large', code: error.code }); case 'LIMIT_FILE_COUNT': return res.status(400).json({ error: 'Too many files', code: error.code }); case 'LIMIT_UNEXPECTED_FILE': return res.status(400).json({ error: 'Unexpected file field or invalid file type', code: error.code, message: error.message }); case 'LIMIT_PART_COUNT': return res.status(400).json({ error: 'Too many parts', code: error.code }); case 'LIMIT_FIELD_KEY': return res.status(400).json({ error: 'Field name too long', code: error.code }); case 'LIMIT_FIELD_VALUE': return res.status(400).json({ error: 'Field value too long', code: error.code }); case 'LIMIT_FIELD_COUNT': return res.status(400).json({ error: 'Too many fields', code: error.code }); default: return res.status(400).json({ error: 'Upload error', code: error.code, message: error.message }); } } res.status(500).json({ error: 'Internal server error', message: error.message }); }); // 404 handler app.use('*', (req, res) => { res.status(404).json({ error: 'Route not found', availableRoutes: [ 'POST /upload/single - Single file upload', 'POST /upload/multiple - Multiple files upload', 'POST /upload/memory - Memory storage upload', 'POST /upload/image - Image upload', 'POST /upload/audio - Audio upload', 'POST /upload/fields - Multiple fields upload', 'POST /upload/validate - Upload with validation', 'GET /upload/stats - Upload statistics', 'GET /upload/exists/:filename - Check file existence', 'GET /upload/path/:filename - Get file path', 'GET /upload/config - Get configuration', 'DELETE /upload/:filename - Delete file', 'GET /health - Health check' ] }); }); // Start server app.listen(PORT, () => { console.log(` Multer Utility Example Server running on http://localhost:${PORT}`); console.log('\n Available endpoints:'); console.log(' POST /upload/single - Single file upload (disk)'); console.log(' POST /upload/multiple - Multiple files upload (disk)'); console.log(' POST /upload/memory - Single file upload (memory)'); console.log(' POST /upload/image - Image upload (specialized)'); console.log(' POST /upload/audio - Audio upload (specialized)'); console.log(' POST /upload/fields - Multiple fields upload'); console.log(' POST /upload/validate - Upload with custom validation'); console.log(' GET /upload/stats - Get upload statistics'); console.log(' GET /upload/exists/:filename - Check if file exists'); console.log(' GET /upload/path/:filename - Get file path'); console.log(' GET /upload/config - Get uploader configuration'); console.log(' DELETE /upload/:filename - Delete uploaded file'); console.log(' GET /health - Health check'); console.log('\n Example curl commands:'); console.log(` curl -X POST -F "file=@example.jpg" http://localhost:${PORT}/upload/single`); console.log(` curl -X POST -F "files=@file1.jpg" -F "files=@file2.png" http://localhost:${PORT}/upload/multiple`); console.log(` curl -X GET http://localhost:${PORT}/upload/stats`); }); exports.default = app; //# sourceMappingURL=basic-example.js.map