feat: add best-effort PDF source converters (txt, html, docx)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 09:12:43 +02:00
co-authored by Claude Sonnet 5
parent 16b4f28b42
commit 05ff96b8b3
2 changed files with 106 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import fs from 'node:fs/promises';
import path from 'node:path';
import os from 'node:os';
import { PDFDocument, StandardFonts } from 'pdf-lib';
import { registerDocumentConverters } from '../../src/converters/document.js';
import { resolve } from '../../src/converters/registry.js';
let tmpDir;
let pdfFixturePath;
beforeAll(async () => {
registerDocumentConverters();
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'converter-document-from-pdf-'));
const pdfDoc = await PDFDocument.create();
const page = pdfDoc.addPage([600, 400]);
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
page.drawText('Extractable fixture text', { x: 50, y: 350, size: 24, font });
const bytes = await pdfDoc.save();
pdfFixturePath = path.join(tmpDir, 'fixture.pdf');
await fs.writeFile(pdfFixturePath, bytes);
});
afterAll(async () => {
await fs.rm(tmpDir, { recursive: true, force: true });
});
describe('PDF source document converters', () => {
it('extracts text from PDF to TXT', async () => {
const outputPath = path.join(tmpDir, 'output.txt');
const entry = resolve('pdf', 'txt');
await entry.convert(pdfFixturePath, outputPath);
const text = await fs.readFile(outputPath, 'utf8');
expect(text).toContain('Extractable fixture text');
});
it('extracts text from PDF to HTML', async () => {
const outputPath = path.join(tmpDir, 'output.html');
const entry = resolve('pdf', 'html');
await entry.convert(pdfFixturePath, outputPath);
const html = await fs.readFile(outputPath, 'utf8');
expect(html).toContain('Extractable fixture text');
expect(html).toContain('<p>');
});
it('reconstructs PDF text into a DOCX (best-effort)', async () => {
const outputPath = path.join(tmpDir, 'output.docx');
const entry = resolve('pdf', 'docx');
await entry.convert(pdfFixturePath, outputPath);
const stat = await fs.stat(outputPath);
expect(stat.size).toBeGreaterThan(0);
const mammoth = await import('mammoth');
const result = await mammoth.default.convertToHtml({ path: outputPath });
expect(result.value).toContain('Extractable fixture text');
});
});