const express = require('express'); const cors = require('cors'); const imageProcessor = require('./image-processing-logic'); const app = express(); const PORT = process.env.PORT || 7860; // Use standard middleware. app.use(cors()); app.use(express.json()); // Health check endpoint. app.get('/ping', (req, res) => { res.status(200).send('pong'); }); /** * Single-image processing endpoint (Stream-based). * This endpoint uses streaming to process a single image from the request body. */ app.post('/api/process-stream', async (req, res) => { try { const { quality, format } = req.query; if (req.is('multipart/form-data')) { // Streaming multipart/form-data is complex without a library like busboy. // For simplicity, this example assumes the client sends the image directly // as the request body with the correct Content-Type header. // This is a more memory-efficient approach for a single image. return res.status(400).json({ error: 'Please send image directly as request body, not as form data.' }); } // Create a sharp instance from the request stream. const processedImageStream = imageProcessor.processImage(req, { quality: quality, format: format }); // Set headers for the response. res.setHeader('Content-Type', `image/${format}`); res.setHeader('Content-Disposition', `attachment; filename=compressed_image.${format}`); // Pipe the processed stream directly to the response stream. processedImageStream.on('error', (error) => { console.error('Error in streaming pipeline:', error); res.status(500).json({ error: 'Image processing failed' }); }); processedImageStream.pipe(res); } catch (error) { console.error('Error in streaming compression route:', error); res.status(500).json({ error: error.message }); } }); // Global error handler middleware. app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ error: err.message }); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });