forked from MikeyPetrillo/Agent402
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpdf.js
More file actions
51 lines (49 loc) · 1.8 KB
/
Copy pathpdf.js
File metadata and controls
51 lines (49 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import { PDFParse } from "pdf-parse";
import { safeFetch } from "./fetch-guard.js";
// Cap on extracted text bytes — a small (within fetch budget) PDF can still
// expand into hundreds of MB of text via heavy compression. Truncate so we
// neither OOM nor return an unsendable response.
const MAX_EXTRACTED_TEXT_BYTES = 8 * 1024 * 1024;
/**
* Fetch a PDF and extract its text content.
*/
export async function pdfToText(rawUrl) {
const { finalUrl, buffer } = await safeFetch(rawUrl, { binary: true, maxBytes: 20 * 1024 * 1024 });
const parser = new PDFParse({ data: buffer });
try {
// The parser's worker cannot handle concurrent calls — keep these sequential.
const textResult = await parser.getText();
let info = {};
try {
info = (await parser.getInfo())?.info ?? {};
} catch {
// Document info is best-effort; some PDFs have metadata the worker can't clone.
}
let text = (textResult.text || "").trim();
let truncated = false;
if (Buffer.byteLength(text, "utf8") > MAX_EXTRACTED_TEXT_BYTES) {
// Byte-truncate (don't slice by chars — multibyte). Drop the last char if
// it landed mid-codepoint by re-decoding.
text = Buffer.from(text, "utf8").subarray(0, MAX_EXTRACTED_TEXT_BYTES).toString("utf8");
truncated = true;
}
return {
url: finalUrl,
pages: textResult.total ?? textResult.pages?.length ?? null,
info: {
title: info.Title || null,
author: info.Author || null,
creationDate: info.CreationDate || null,
},
wordCount: text.split(/\s+/).filter(Boolean).length,
text,
truncated,
};
} catch (e) {
const err = new Error(`Could not parse PDF: ${e.message}`);
err.statusCode = 422;
throw err;
} finally {
await parser.destroy().catch(() => {});
}
}