export interface PDFOptions { format?: string; landscape?: boolean; margin?: { top: number; right: number; bottom: number; left: number }; printBackground?: boolean; headerTemplate?: string; footerTemplate?: string; } const DOC_WORKER_URL = (process.env.DOC_WORKER_URL || "http://document-worker:3000").replace(/\/+$/, ""); function getTimeout(): number { const env = process.env.DOC_WORKER_TIMEOUT_MS; return env ? parseInt(env, 10) : 30000; } /** * Конвертирует HTML в PDF через внешний document-worker сервис. * Возвращает Buffer или null при ошибке. */ export async function convertHtmlToPdf(html: string, options: PDFOptions = {}): Promise { try { const response = await fetch(`${DOC_WORKER_URL}/convert/pdf`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ html, options }), signal: AbortSignal.timeout(getTimeout()), }); if (!response.ok) { const text = await response.text().catch(() => ""); console.error("[doc-worker] PDF conversion HTTP error:", response.status, text); return null; } const data = await response.json(); if (!data.success || !data.pdf) { console.error("[doc-worker] PDF conversion failed:", data.error || "unknown"); return null; } return Buffer.from(data.pdf, "base64"); } catch (err) { console.error("[doc-worker] PDF conversion request failed:", err); return null; } } /** * Конвертирует DOCX (Buffer) в PDF через внешний document-worker сервис. * Возвращает Buffer или null при ошибке. */ export async function convertDocxToPdf(docxBuffer: Buffer): Promise { try { const response = await fetch(`${DOC_WORKER_URL}/convert/docx-to-pdf`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ docxBase64: docxBuffer.toString("base64") }), signal: AbortSignal.timeout(getTimeout()), }); if (!response.ok) { const text = await response.text().catch(() => ""); console.error("[doc-worker] DOCX→PDF conversion HTTP error:", response.status, text); return null; } const data = await response.json(); if (!data.success || !data.pdf) { console.error("[doc-worker] DOCX→PDF conversion failed:", data.error || "unknown"); return null; } return Buffer.from(data.pdf, "base64"); } catch (err) { console.error("[doc-worker] DOCX→PDF conversion request failed:", err); return null; } } /** * Конвертирует EMF/WMF (Buffer) в PNG через внешний document-worker сервис. * Возвращает Buffer или null при ошибке. */ export async function convertEmfToPng(emfBuffer: Buffer): Promise { try { const response = await fetch(`${DOC_WORKER_URL}/convert/emf-to-png`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ emfBase64: emfBuffer.toString("base64") }), signal: AbortSignal.timeout(getTimeout()), }); if (!response.ok) { const text = await response.text().catch(() => ""); console.error("[doc-worker] EMF→PNG conversion HTTP error:", response.status, text); return null; } const data = await response.json(); if (!data.success || !data.png) { console.error("[doc-worker] EMF→PNG conversion failed:", data.error || "unknown"); return null; } return Buffer.from(data.png, "base64"); } catch (err) { console.error("[doc-worker] EMF→PNG conversion request failed:", err); return null; } } /** * Проверяет доступность document-worker сервиса. */ export async function checkDocumentWorkerHealth(): Promise<{ ok: boolean; error?: string }> { try { const response = await fetch(`${DOC_WORKER_URL}/health`, { signal: AbortSignal.timeout(5000), }); if (!response.ok) { return { ok: false, error: `HTTP ${response.status}` }; } return { ok: true }; } catch (err) { return { ok: false, error: err instanceof Error ? err.message : String(err) }; } }