60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
const path = require('path');
|
|
const fs = require('fs');
|
|
const crypto = require('crypto');
|
|
|
|
const UPLOADS_DIR = path.join(__dirname, '..', 'public', 'uploads', 'herramientas');
|
|
|
|
// Asegurar existencia del directorio de uploads
|
|
if (!fs.existsSync(UPLOADS_DIR)) {
|
|
fs.mkdirSync(UPLOADS_DIR, { recursive: true });
|
|
}
|
|
|
|
const ALLOWED_MIME_TYPES = [
|
|
'image/jpeg',
|
|
'image/png',
|
|
'image/webp',
|
|
'image/gif'
|
|
];
|
|
|
|
const ALLOWED_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.webp', '.gif'];
|
|
|
|
/**
|
|
* Guarda una imagen subida mediante express-fileupload en public/uploads/herramientas/
|
|
* @param {Object} fileObj - Objeto de archivo de req.files
|
|
* @param {string} prefix - Prefijo descriptivo del archivo (ej: 'herramienta', 'kit', 'entrega', 'devolucion')
|
|
* @returns {Promise<string|null>} - Ruta pública (/uploads/herramientas/...) o null si no se proporcionó archivo
|
|
*/
|
|
async function guardarFoto(fileObj, prefix = 'herramienta') {
|
|
if (!fileObj || !fileObj.name || !fileObj.data) {
|
|
return null;
|
|
}
|
|
|
|
const ext = path.extname(fileObj.name).toLowerCase();
|
|
if (!ALLOWED_EXTENSIONS.includes(ext) || !ALLOWED_MIME_TYPES.includes(fileObj.mimetype)) {
|
|
throw new Error('Formato de imagen no soportado. Formatos válidos: JPG, PNG, WEBP, GIF.');
|
|
}
|
|
|
|
// Límite de 8 MB
|
|
if (fileObj.size > 8 * 1024 * 1024) {
|
|
throw new Error('La imagen excede el límite máximo de 8MB.');
|
|
}
|
|
|
|
const randomSuffix = crypto.randomBytes(6).toString('hex');
|
|
const safeFilename = `${prefix}_${Date.now()}_${randomSuffix}${ext}`;
|
|
const targetPath = path.join(UPLOADS_DIR, safeFilename);
|
|
|
|
await new Promise((resolve, reject) => {
|
|
fileObj.mv(targetPath, (err) => {
|
|
if (err) return reject(err);
|
|
resolve();
|
|
});
|
|
});
|
|
|
|
return `/uploads/herramientas/${safeFilename}`;
|
|
}
|
|
|
|
module.exports = {
|
|
guardarFoto,
|
|
UPLOADS_DIR
|
|
};
|