/** * MIME structure walking — pure helpers over ImapFlow's bodyStructure. * * No IMAP connection, no MCP dependency — fully unit-testable with plain * fixture objects. Moved verbatim from imap.service.ts so body-part selection * and attachment discovery can be tested without a client. */ import type { AttachmentMeta } from '../types/index.js'; export declare function hasAttachments(bodyStructure: unknown): boolean; export declare function extractAttachments(bodyStructure: unknown): AttachmentMeta[]; /** Find the MIME part number for an attachment by filename. */ export declare function findMimePartByFilename(bodyStructure: unknown, targetFilename: string, partPath?: string): string | undefined; /** A displayable (non-attachment) text part discovered in the MIME tree. */ export interface TextPart { /** IMAP part path, e.g. "1.1" */ path: string; /** Content subtype: "plain" | "html" | … (derived from the full MIME type) */ subtype: string; size: number; /** Content-Type carried `format=flowed`: soft line wraps need undoing. */ flowed?: boolean; /** `format=flowed` with `DelSp=yes`: the space marking a wrap is not content. */ delSp?: boolean; } /** * Split an ImapFlow structure node's Content-Type. * * ImapFlow reports `type` as the complete Content-Type ("text/html") and has * no `subtype` field at all — see MessageStructureObject in imap-flow.d.ts. */ export declare function splitMimeType(type: unknown): { type: string; subtype: string; }; /** * Collect every displayable text/* part in the MIME tree, in document order. * * Excludes attachments — including everything nested under one — and the * contents of embedded message/rfc822 parts. Part paths come from `bs.part` * when the server supplies one, otherwise from the 1-based child index chain * (mirroring the traversal in `findMimePartByFilename`). * * A message whose only text lives inside encapsulated messages — "forward as * attachment" with no covering note, or a mailing-list digest — is retried * with that exclusion lifted, since otherwise there is no body to show at all. */ export declare function collectTextParts(bodyStructure: unknown, partPath?: string): TextPart[]; /** * Choose which text parts to download for an email's body. * * `parts` is in document order and excludes attachments. Both halves of a * multipart/alternative are returned so bodyText and bodyHtml can coexist — * magic-link extraction and calendar scanning each want a specific side — and * every sibling of one subtype comes back together, because multipart/mixed * splits running text across several: Apple Mail puts a note either side of an * inline photo, and a digest carries one part per message. Keeping only the * first silently truncates the body. * * `maxBytes` caps a group's combined size. Two rules can drop a side, and the * order matters: transfer cost is settled first, because an over-cap stream is * drained in full, so pulling 10 MB of HTML to keep 512 KB of it loses even to * a plain part too small to hold the same content. Only among groups that both * fit does the stub rule then suppress a placeholder plain side. */ export declare function selectBodyParts(parts: TextPart[], maxBytes?: number): { plain: TextPart[]; html: TextPart[]; }; /** * Explain a structure that yields no displayable text part, instead of the * bare "(no content)" the tool layer would otherwise show. Encrypted payloads * are not parsed — the label tells the model (and the user) what it is * looking at and what to do about it. */ export declare function describeUndisplayableStructure(bodyStructure: unknown): string | undefined; /** * Find the machine-readable part of a bounce (multipart/report). Its * message/delivery-status part is plain key-value text carrying the Action, * Status, and Diagnostic-Code fields that say what actually failed. */ export declare function findDeliveryStatusPart(bodyStructure: unknown, partPath?: string): string | undefined; /** * Parse an RFC 5322 header block into a lowercase-keyed map. * * Continuation lines (leading space or tab) are unfolded onto the preceding * header, so a long References or Subject split across lines survives intact. */ export declare function parseHeaders(raw: unknown): Record; //# sourceMappingURL=mime-structure.d.ts.map