const http = require("http"); const { markdownToHtml, htmlToPdf } = require("./convert"); const PORT = process.env.PORT || 3000; const UPLOAD_PAGE = ` Markdown Converter

Markdown Converter

Convert Markdown to styled HTML or PDF with TOC and Mermaid diagrams

Drag & drop a .md file here, or click to browse

`; function parseBody(req) { return new Promise((resolve, reject) => { const chunks = []; let size = 0; const limit = 10 * 1024 * 1024; // 10MB req.on("data", (chunk) => { size += chunk.length; if (size > limit) { reject(new Error("Request body too large")); req.destroy(); return; } chunks.push(chunk); }); req.on("end", () => resolve(Buffer.concat(chunks).toString())); req.on("error", reject); }); } const server = http.createServer(async (req, res) => { if (req.method === "GET" && (req.url === "/" || req.url === "")) { res.writeHead(200, { "Content-Type": "text/html" }); res.end(UPLOAD_PAGE); return; } if (req.method === "POST" && req.url === "/convert") { try { const body = JSON.parse(await parseBody(req)); const { markdown, format } = body; if (!markdown) { res.writeHead(400, { "Content-Type": "text/plain" }); res.end("Missing 'markdown' field"); return; } const html = markdownToHtml(markdown); if (format === "pdf") { const pdfBuffer = await htmlToPdf(html); res.writeHead(200, { "Content-Type": "application/pdf", "Content-Disposition": "attachment; filename=output.pdf", }); res.end(pdfBuffer); } else { res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); res.end(html); } } catch (err) { console.error("Convert error:", err); res.writeHead(500, { "Content-Type": "text/plain" }); res.end("Conversion failed: " + err.message); } return; } // curl-friendly API: accepts raw markdown body, format via query param or Accept header // Usage: // curl -X POST --data-binary @file.md https://host/api/convert > output.html // curl -X POST --data-binary @file.md https://host/api/convert?format=pdf -o output.pdf if (req.method === "POST" && req.url.startsWith("/api/convert")) { try { const url = new URL(req.url, `http://${req.headers.host}`); const formatParam = url.searchParams.get("format") || "html"; const markdown = await parseBody(req); if (!markdown.trim()) { res.writeHead(400, { "Content-Type": "text/plain" }); res.end("Empty body — POST raw markdown text"); return; } const html = markdownToHtml(markdown); if (formatParam === "pdf") { const pdfBuffer = await htmlToPdf(html); res.writeHead(200, { "Content-Type": "application/pdf", "Content-Disposition": "attachment; filename=output.pdf", }); res.end(pdfBuffer); } else { res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); res.end(html); } } catch (err) { console.error("API convert error:", err); res.writeHead(500, { "Content-Type": "text/plain" }); res.end("Conversion failed: " + err.message); } return; } if (req.method === "GET" && req.url === "/health") { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ status: "ok" })); return; } res.writeHead(404, { "Content-Type": "text/plain" }); res.end("Not found"); }); server.listen(PORT, () => { console.log(`md2html server listening on http://0.0.0.0:${PORT}`); });