import { Router } from "express"; import path from 'path'; import multer from 'multer'; import fs from 'fs/promises'; import sharp from 'sharp'; import crypto from 'crypto'; import { fileTypeFromBuffer } from 'file-type'; import { createNewOffer, getOfferById, deleteOffer, getAllOffers, getOffersByUserId, editOffer } from "../functions/offerFunctions.js"; const router = Router(); const storage = multer.memoryStorage(); const fileFilter = (req, file, cb) => { if (file.mimetype.startsWith('image/')) { cb(null, true); } else { cb(new Error('Solo se permiten imágenes'), false); } }; const upload = multer({ storage: storage, fileFilter: fileFilter, limits: { fileSize: 5 * 1024 * 1024 // 5MB limit } }); async function processImage(file) { const imagePath = path.join(process.cwd(), 'uploads'); const buffer = file.buffer; const hash = crypto.createHash('sha256').update(buffer).digest('hex'); const mime = await fileTypeFromBuffer(buffer).then(type => type?.mime); // Validate MIME type if (!mime || !['image/jpeg', 'image/png', 'image/gif', 'image/webp'].includes(mime)) { throw new Error('Unsupported image format'); } // File save name and path if not GIF let filename; if (mime === 'image/gif') { filename = `${hash}.gif`; await fs.writeFile(path.join(imagePath, filename), buffer); } else { filename = `${hash}.webp`; await sharp(buffer) .resize({ width: 800, height: 800, fit: 'inside', withoutEnlargement: true }) .rotate() .normalise() .withMetadata() .toFormat('webp', { quality: 80 }) .toFile(path.join(imagePath, filename)); } return filename; } const processUploadedImage = async (req, res, next) => { try { if (req.file) { const filename = await processImage(req.file); req.processedFilename = filename; } next(); } catch (error) { console.error('Error processing image:', error); res.status(400).json({ error: 'Error al procesar la imagen: ' + error.message }); } }; // Validate create offer payload const validateOfferPayload = (req, res, next) => { const { nombre, descripcion, precio, id_usuario } = req.body; if (!nombre || !descripcion || !precio || !id_usuario) { return res.status(400).json({ error: 'nombre, descripcion, precio and id_usuario are required' }); } next(); }; router.post('/', upload.single('imagen'), validateOfferPayload, processUploadedImage, createNewOffer); router.get('/', getAllOffers); router.get('/:id_oferta', getOfferById); router.put('/:id_oferta', upload.single('imagen'), validateOfferPayload, processUploadedImage, editOffer); router.delete('/:id_oferta', deleteOffer); router.get('/user/:id_usuario', getOffersByUserId); export default router;