import { PdfObject } from '../core/objects/pdf-object.js'; import { PdfSecurityHandler } from '../security/handlers/base.js'; import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js'; import { PdfComment } from '../core/objects/pdf-comment.js'; import { PdfToken } from '../core/tokens/token.js'; import { PdfDictionary } from '../core/objects/pdf-dictionary.js'; import { IPdfObjectResolver, PdfObjectReference } from '../core/objects/pdf-object-reference.js'; import { PdfXrefLookup } from './pdf-xref-lookup.js'; import { PdfRevision } from './pdf-revision.js'; import { PdfEncryptionDictionaryObject } from '../security/types.js'; import { PdfTrailerEntries } from '../core/objects/pdf-trailer.js'; import { ByteArray } from '../types.js'; import { PdfDocumentVerificationResult, PdfSigner } from '../signing/signer.js'; import { PdfAcroForm } from '../acroform/pdf-acro-form.js'; import { PdfPages } from './pdf-pages.js'; /** * Represents a PDF document with support for reading, writing, and modifying PDF files. * Handles document structure, revisions, encryption, and digital signatures. * * @example * ```typescript * // Create a new document * const document = new PdfDocument() * * // Read from bytes * const document = await PdfDocument.fromBytes(fileBytes) * * // Add objects and commit * document.add(pdfObject) * await document.commit() * ``` */ export declare class PdfDocument extends PdfObject implements IPdfObjectResolver { /** List of document revisions for incremental updates */ revisions: PdfRevision[]; /** Signer instance for digital signature operations */ signer: PdfSigner; /** Security handler for encryption/decryption operations */ securityHandler?: PdfSecurityHandler; /** Whether the document is currently in incremental mode (appending changes as a new revision) */ private incremental; private originalSecurityHandler?; private hasEncryptionDictionary?; private _resolvedCache; private _objStreamCache; private _committing; private _updating; private _finalized; private _signed; /** * Creates a new PDF document instance. * * @param options - Configuration options for the document * @param options.revisions - Pre-existing revisions for the document * @param options.version - PDF version string (e.g., '1.7', '2.0') or version comment * @param options.password - User password for encryption * @param options.ownerPassword - Owner password for encryption * @param options.securityHandler - Custom security handler for encryption * @param options.signer - Custom signer for digital signatures */ constructor(options?: { revisions?: PdfRevision[]; version?: string | PdfComment; password?: string; ownerPassword?: string; securityHandler?: PdfSecurityHandler; signer?: PdfSigner; }); resolve(objectNumber: number, generationNumber: number): PdfIndirectObject; get acroform(): PdfAcroForm | null; get pages(): PdfPages; get header(): PdfComment | undefined; set header(comment: PdfComment | undefined); /** * Creates a PdfDocument from an array of PDF objects. * Parses objects into revisions based on EOF comments. * * @param objects - Array of PDF objects to construct the document from * @returns A new PdfDocument instance */ static fromObjects(objects: PdfObject[]): PdfDocument; /** * Starts a new revision for incremental updates. * Creates a new revision linked to the previous one. * * @returns The document instance for method chaining */ startNewRevision(): PdfDocument; hasObjectInLatestRevision(obj: PdfObject): boolean; /** * Adds objects to the document's latest revision. * Automatically starts a new revision if the current one is locked. * * @param objects - PDF objects to add to the document */ add(...objects: PdfObject[]): void; /** * Packs non-stream indirect objects into compressed ObjStm containers. * Objects that already have an object number are left unchanged. * Appearance streams and other PdfStream objects must NOT be passed here — * only non-stream indirect objects (dictionaries, arrays, etc.) are eligible. * * @param objects - Non-stream indirect objects to compress into ObjStm * @param batchSize - Maximum objects per ObjStm container (default 100) */ addObjectsAsStream(objects: PdfIndirectObject[], batchSize?: number): void; /** * Gets the latest (most recent) revision of the document. * * @returns The latest PdfRevision * @throws Error if the revision for the last StartXRef cannot be found */ get latestRevision(): PdfRevision; /** * Gets the cross-reference lookup table for the latest revision. * * @returns The PdfXrefLookup for the latest revision */ get xrefLookup(): PdfXrefLookup; /** * Gets the trailer dictionary from the cross-reference lookup. * * @returns The trailer dictionary containing document metadata references */ get trailerDict(): PdfDictionary; /** * Gets all objects across all revisions in the document. * * @returns A readonly array of all PDF objects */ get objects(): ReadonlyArray; /** * Gets the encryption dictionary from the document if present. * * @returns The encryption dictionary object or undefined if not encrypted * @throws Error if the encryption dictionary reference points to a non-dictionary object */ get encryptionDictionary(): PdfEncryptionDictionaryObject | undefined; get rootReference(): PdfObjectReference; /** * Gets the document catalog (root) dictionary, or creates one if it doesn't exist. * * @returns The root dictionary * @throws Error if the Root reference points to a non-dictionary object */ get root(): PdfIndirectObject; /** * Gets the reference to the metadata stream from the document catalog. * * @returns The metadata stream reference or undefined if not present */ get metadataStreamReference(): PdfObjectReference | undefined; resetSecurityHandler(): void; private getSecurityHandler; private initSecurityHandler; /** * Sets the user password for document encryption. * * @param password - The user password to set * @throws Error if the security handler doesn't support password setting */ setPassword(password: string): void; /** * Sets the owner password for document encryption. * * @param ownerPassword - The owner password to set * @throws Error if the security handler doesn't support password setting */ setOwnerPassword(ownerPassword: string): void; /** * Checks if a PDF object exists in the document. * * @param obj - The PDF object to check * @returns True if the object exists in the document */ hasObject(obj: PdfObject): boolean; private isObjectEncryptable; commitIncrementalUpdates(): void; /** * Decrypts all encrypted object data in-place without removing * the encryption infrastructure. Useful in incremental mode where * the original (encrypted) bytes are preserved via cached tokens * but the live object data needs to be readable. */ decryptObjects(): Promise; /** * Re-encrypts all objects and updates the document structure. * No-op if the document has no security handler (unencrypted document). */ finalize(): Promise; /** * Decrypts all encrypted objects in the document. * Removes the security handler and encryption dictionary after decryption. */ decrypt(): Promise; /** * Encrypts all encryptable objects using the security handler. * Re-uses the existing encryption dictionary or creates one if needed, * propagating it to all revisions. */ encrypt(): Promise; /** * Finds a compressed object by its object number within an object stream. * * @param options - Object identifier with objectNumber and optional generationNumber * @returns The found indirect object or undefined if not found * @throws Error if the object cannot be found in the expected object stream */ findCompressedObject(options: { objectNumber: number; generationNumber?: number; } | PdfObjectReference): PdfIndirectObject | undefined; /** * Finds an uncompressed indirect object by its object number. * * @param options - Object identifier with objectNumber and optional generationNumber * @returns The found indirect object or undefined if not found * @throws FoundCompressedObjectError if the object is compressed (in an object stream) */ findUncompressedObject(options: { objectNumber: number; generationNumber?: number; } | PdfObjectReference): PdfIndirectObject | undefined; /** * Reads and optionally decrypts an object by its object number. * Handles both compressed and uncompressed objects. * * @param options - Object lookup options * @param options.objectNumber - The object number to find * @param options.generationNumber - Optional generation number filter * @param options.allowUnindexed - If true, searches unindexed objects as fallback * @returns A cloned and decrypted copy of the object, or undefined if not found */ readObject(options: { objectNumber: number; generationNumber?: number; allowUnindexed?: boolean; cloned?: boolean; }): PdfIndirectObject | undefined; /** * Finds the revision that contains a given PDF object. * Useful for determining the origin of an object across multiple revisions. * @param obj - The PDF object to find the revision for * @returns The PdfRevision that contains the object, or undefined if not found in any revision */ findRevisionForObject(obj: PdfObject): PdfRevision | undefined; /** * Deletes an object from all revisions in the document. * * @param obj - The PDF object to delete */ deleteObject(obj: PdfObject | undefined): void; /** * Sets the PDF version for the document. * * @param version - The PDF version string (e.g., '1.7', '2.0') * @throws Error if attempting to change version after objects have been added in incremental mode */ setVersion(version: string): void; /** * Sets whether the document should use incremental updates. * When true, locks all existing revisions to preserve original content. * * @param value - True to enable incremental mode, false to disable. Defaults to true. */ setIncremental(value?: boolean): void; /** * Checks if the document is in incremental mode. * * @returns True if all revisions are locked for incremental updates */ isIncremental(): boolean; /** * Returns tokens paired with their source objects. * Useful for debugging and analysis of document structure. * * @returns Array of token-object pairs */ tokensWithObjects(): { token: PdfToken; object: PdfObject | undefined; }[]; protected tokenize(): PdfToken[]; private wireResolvers; private collectMissingReferences; private linkRevisions; private linkOffsets; private calculateOffsets; private updateRevisions; /** * Performs a full update cycle to ensure all revisions are consistent and offsets are correct. */ private update; /** * Walks all objects in the document and registers any newly created * PdfIndirectObjects that are referenced but not yet part of the document * (e.g. appearance streams created by generateAppearance). */ private registerNewReferences; private flushResolvedCache; sign(): Promise; /** * Serializes the document to a byte array. * * @returns The PDF document as a Uint8Array */ toBytes(): ByteArray; /** * Creates a deep copy of the document. * * @returns A cloned PdfDocument instance */ cloneImpl(): this; toJSON(): { type: string; revisions: { type: string; objects: object[]; }[]; }; /** * Creates a PdfDocument from a byte stream. * * @param input - Async or sync iterable of byte arrays * @returns A promise that resolves to the parsed PdfDocument */ static fromBytes(input: AsyncIterable | Iterable, options?: { password?: string; ownerPassword?: string; incremental?: boolean; }): Promise; isModified(): boolean; /** * Verifies all digital signatures in the document. * * @returns A promise that resolves to the verification result */ verifySignatures(): Promise; }