import express from 'express'; import cors from 'cors'; import { tmpdir } from 'os'; import { join } from 'path'; import { promises as fs } from 'fs'; import { v4 as uuidV4 } from 'uuid'; import Epub from 'epub-gen'; const app = express(); const PORT = process.env.PORT || 4000; const ORIGIN = process.env.CLIENT_ORIGIN || 'http://localhost:5173'; app.use(cors({ origin: ORIGIN, credentials: true })); app.use(express.json({ limit: '10mb' })); const sanitizeHtml = (text = '') => text .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, ''') .replace(/\n/g, '
'); app.post('/generate-epub', async (req, res) => { const { text, meta } = req.body || {}; if (!text || !text.trim()) { return res.status(400).json({ message: 'text is required' }); } const title = meta?.title || 'imgPub OCR Export'; const author = meta?.author || 'imgPub'; const filename = meta?.filename || `imgpub${Date.now()}.epub`; const content = [ { title, data: `
${sanitizeHtml(text)}
`, }, ]; const outputPath = join(tmpdir(), `imgpub-${uuidV4()}.epub`); try { const epub = new Epub({ title, author, content }, outputPath); await epub.promise; const buffer = await fs.readFile(outputPath); await fs.unlink(outputPath).catch(() => {}); res.json({ filename, data: buffer.toString('base64') }); } catch (error) { console.error('EPUB generation failed:', error); res.status(500).json({ message: 'EPUB generation failed' }); } }); app.get('/', (_, res) => { res.json({ status: 'ok' }); }); app.listen(PORT, () => { console.log(`imgPub EPUB server listening on port ${PORT}`); });