89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import multer from 'multer';
|
|
import { Request, RequestHandler } from 'express';
|
|
|
|
// Configure multer for memory storage (we'll process files in memory)
|
|
const storage = multer.memoryStorage();
|
|
|
|
// File filter for image types only
|
|
const fileFilter = (_req: Request, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
|
|
const allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp'];
|
|
|
|
if (allowedTypes.includes(file.mimetype)) {
|
|
console.log(
|
|
`[${new Date().toISOString()}] Accepted file: ${file.originalname} (${file.mimetype})`,
|
|
);
|
|
cb(null, true);
|
|
} else {
|
|
console.log(
|
|
`[${new Date().toISOString()}] Rejected file: ${file.originalname} (${file.mimetype})`,
|
|
);
|
|
cb(new Error(`Unsupported file type: ${file.mimetype}. Allowed: PNG, JPEG, WebP`));
|
|
}
|
|
};
|
|
|
|
// Configuration constants
|
|
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
|
const MAX_FILES = 3;
|
|
|
|
// Configure multer with limits and file filtering
|
|
export const upload = multer({
|
|
storage,
|
|
limits: {
|
|
fileSize: MAX_FILE_SIZE, // 5MB per file
|
|
files: MAX_FILES, // Maximum 3 files
|
|
},
|
|
fileFilter,
|
|
});
|
|
|
|
// Middleware for handling reference images
|
|
export const uploadReferenceImages: RequestHandler = upload.array('referenceImages', MAX_FILES);
|
|
|
|
// Error handler for multer errors
|
|
export const handleUploadErrors = (error: any, _req: Request, res: any, next: any) => {
|
|
if (error instanceof multer.MulterError) {
|
|
const timestamp = new Date().toISOString();
|
|
console.error(`[${timestamp}] Multer error:`, error.message);
|
|
|
|
switch (error.code) {
|
|
case 'LIMIT_FILE_SIZE':
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: `File too large. Maximum size: ${MAX_FILE_SIZE / (1024 * 1024)}MB`,
|
|
message: 'File upload failed',
|
|
});
|
|
|
|
case 'LIMIT_FILE_COUNT':
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: `Too many files. Maximum: ${MAX_FILES} files`,
|
|
message: 'File upload failed',
|
|
});
|
|
|
|
case 'LIMIT_UNEXPECTED_FILE':
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Unexpected file field. Use "referenceImages" for image uploads',
|
|
message: 'File upload failed',
|
|
});
|
|
|
|
default:
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: error.message,
|
|
message: 'File upload failed',
|
|
});
|
|
}
|
|
}
|
|
|
|
if (error.message.includes('Unsupported file type')) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: error.message,
|
|
message: 'File validation failed',
|
|
});
|
|
}
|
|
|
|
// Pass other errors to the next error handler
|
|
next(error);
|
|
};
|