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
JavaScript
"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