andy-stack_vaultkeeper-ai/Helpers/DocumentHelper.ts
Andrew Beal a4c65f16c2 Update file attachment messaging and add document file support
Add support for DOCX, PPTX, XLSX, ODT, ODP, and ODS document formats by converting them to plain text. Standardize attachment introduction messages across all AI providers from "Binary data for X follows" to "The contents of the file 'X' are provided below."
2026-03-15 19:48:28 +00:00

48 lines
No EOL
1.9 KiB
TypeScript

import { extractText, getDocumentProxy } from 'unpdf';
import type { IPageText } from '../Types/SearchTypes';
import { Exception } from './Exception';
import OfficeParser from 'officeparser';
// Handles PDF format
export async function readPDF(arrayBuffer: ArrayBuffer): Promise<IPageText[]> {
try {
const pdf = await getDocumentProxy(new Uint8Array(arrayBuffer));
const pages = (await extractText(pdf, { mergePages: false })).text;
const pageTexts: IPageText[] = pages.map((pageText, index) => ({
text: pageText,
pageNumber: index + 1
}));
return pageTexts;
} catch (error) {
/** PDF.js error types (from underlying pdfjs-dist library):
* - InvalidPDFException: Invalid or corrupted PDF structure
* - PasswordException: PDF requires a password
* - FormatError: PDF format error
* - UnexpectedResponseException: Unexpected server response
* - AbortException: Operation was aborted
* - UnknownErrorException: Unknown error occurred **/
if (error instanceof Error && error.name === 'PasswordException') {
return [{ text: "PDF is password protected!", pageNumber: 1 }] as IPageText[];
}
return [{ text: `Failed to read PDF: ${Exception.messageFrom(error)}`, pageNumber: 1 }] as IPageText[];
}
}
// Handles document formats: DOCX, PPTX, XLSX, ODT, ODP, ODS
export async function readDocument(arrayBuffer: ArrayBuffer): Promise<IPageText[]> {
try {
const ast = await OfficeParser.parseOffice(arrayBuffer, {
extractAttachments: true,
ocr: true,
ocrLanguage: "eng+esp"
});
// OfficeParser doesn't currently expose page data (page number etc)
return [{ text: ast.toText(), pageNumber: 1 }] as IPageText[];
} catch (error) {
return [{ text: `Failed to read document: ${Exception.messageFrom(error)}`, pageNumber: 1 }] as IPageText[];
}
}