const express = require("express"); const cors = require("cors"); const puppeteer = require("puppeteer"); const app = express(); const PORT = process.env.PORT || 7860; // Hugging Face uses port 7860 // Middleware app.use(cors()); app.use(express.json({ limit: "5mb" })); // Root endpoint - Health check app.get("/", (_req, res) => { res.json({ status: "ok", message: "HTML to PDF API is running", version: "1.0.0", endpoints: { health: "GET / or GET /health", convert: "POST /api/html-to-pdf" }, usage: { method: "POST", url: "/api/html-to-pdf", body: { html_code: "Your HTML content here (with inline styles and complete structure)", pdf_options: { format: "A4", printBackground: true, margin: { top: "0mm", right: "0mm", bottom: "0mm", left: "0mm" } } }, notes: [ "HTML should include all styles inline or in ${htmlContent} `, { waitUntil: ["load", "domcontentloaded", "networkidle0"], timeout: 30000 } ); // Wait for fonts and images to load await page.evaluateHandle('document.fonts.ready'); // Wait for any dynamic content (charts, images, etc.) await new Promise(resolve => setTimeout(resolve, 1500)); // Generate PDF with optimized options const defaultPdfOptions = { format: "A4", printBackground: true, margin: { top: "0mm", right: "0mm", bottom: "0mm", left: "0mm" }, preferCSSPageSize: true }; const pdfBuffer = await page.pdf({ ...defaultPdfOptions, ...(pdfOptions || {}), encoding: 'binary' }); await browser.close(); browser = null; const processingTime = Date.now() - startTime; console.log(`[${new Date().toISOString()}] PDF generated successfully in ${processingTime}ms`); // Convert Buffer to base64 properly const pdfBase64 = Buffer.from(pdfBuffer).toString('base64'); res.json({ pdf_base64: pdfBase64, success: true, processing_time_ms: processingTime, pdf_size_bytes: pdfBuffer.length }); } catch (err) { console.error(`[${new Date().toISOString()}] PDF Generation Error:`, err); if (browser) { try { await browser.close(); } catch (closeErr) { console.error("Browser close error:", closeErr); } } res.status(500).json({ error: "Failed to generate PDF", details: err.message, success: false }); } }); // 404 handler app.use((_req, res) => { res.status(404).json({ error: "Endpoint not found", available_endpoints: [ "GET /", "GET /health", "POST /api/html-to-pdf" ] }); }); // Start server app.listen(PORT, "0.0.0.0", () => { console.log(` ╔════════════════════════════════════════╗ ║ HTML to PDF API Server ║ ║ Status: Running ✅ ║ ║ Port: ${PORT} ║ ║ URL: http://0.0.0.0:${PORT} ║ ╚════════════════════════════════════════╝ `); }); // Graceful shutdown process.on('SIGTERM', () => { console.log('SIGTERM signal received: closing HTTP server'); process.exit(0); }); process.on('SIGINT', () => { console.log('SIGINT signal received: closing HTTP server'); process.exit(0); });