/** * Outbound attachment resolver, shared by every tool that can send a file: * outlook-mail-reply, outlook-mail-send, outlook-draft, and outlook-draft-edit. * Mirrors the email plugin's account-scope check (realpath under the account * directory, regular file, size cap), then classifies each file by how it must * reach the draft: * * - `inline` — at or under Graph's ~3 MB fileAttachment limit; sent as a * single base64 `POST /messages/{id}/attachments`. * - `session` — above the inline limit and up to the 25 MB account cap; sent * through a Graph upload session (see `upload-session.ts`). * * The account cap (25 MB) matches the email plugin's outbound cap, so an * Outlook message and the equivalent IMAP message carry the same maximum. * * Resolution reads no bytes — it returns per-file metadata (path, size, mode) * so the caller can choose the path. Path validation happens before any Graph * write, so a bad path leaves no orphan draft; bytes are read at send time by * `toInlineAttachment` (inline) or the upload session (session). * * This module stays pure node:fs on purpose — the Graph-side attach loop lives * in `attach.ts` so this boundary carries no client, no network, and no I/O * beyond the filesystem. */ /** Graph fileAttachment inline limit for POST /messages/{id}/attachments. */ export declare const OUTLOOK_ATTACHMENT_INLINE_MAX_BYTES: number; /** Per-file account cap; parity with the email plugin's outbound cap. */ export declare const OUTLOOK_ATTACHMENT_MAX_BYTES: number; export interface GraphFileAttachment { "@odata.type": "#microsoft.graph.fileAttachment"; name: string; contentType: string; contentBytes: string; } /** Why a single path was refused. Carried as a field so callers classify a * refusal on a field, never by parsing its message. */ /** * `bad-path` / `oversize` are outbound path validation (attach). `not-on-draft` * / `ambiguous-name` are removal resolution (detach). All four are carried as a * field so callers classify on `reason` and never parse the message. */ export type RefusalReason = "bad-path" | "oversize" | "not-on-draft" | "ambiguous-name"; /** * A per-path refusal, raised before any Graph write. Carries the fields the * `op: "refuse"` log line names. * * Account-context failures (ACCOUNT_DIR unset, account directory unreadable) * are NOT refusals: they name no file and no per-file cause, so they stay plain * Errors and emit no refuse line. */ export declare class AttachmentRefusedError extends Error { readonly reason: RefusalReason; readonly file: string; readonly bytes?: number | undefined; readonly cap?: number | undefined; constructor(message: string, reason: RefusalReason, file: string, bytes?: number | undefined, cap?: number | undefined); } /** A validated, account-scoped file and the Graph path it must take. */ export interface OutboundAttachment { /** realpath, verified under the account directory. */ path: string; name: string; contentType: string; size: number; mode: "inline" | "session"; } /** ACCOUNT_DIR (spawn-set) wins; else derive from PLATFORM_ROOT + accountId, * matching the email plugin's resolver. Null when neither resolves. */ export declare function resolveAccountDir(accountId: string): string | null; /** * Validate agent-supplied paths and classify each as inline or session. Each * path must realpath to a regular file under the account directory and be within * the 25 MB account cap. Any violation throws a precise error naming the * offending path, so the caller sends nothing rather than a reply that silently * drops the file. Absent/empty input returns [] (a text-only reply). */ export declare function resolveOutboundAttachments(accountId: string, paths: string[] | undefined): OutboundAttachment[]; /** * Read an inline attachment's bytes and base64-encode them into the Graph * fileAttachment shape a reply draft accepts. Only called for `mode: "inline"` * files; larger files go through the upload session instead. */ export declare function toInlineAttachment(att: OutboundAttachment): GraphFileAttachment; /** The " with N attachment(s): a, b" suffix for a reply success message. */ export declare function attachNote(names: string[]): string; //# sourceMappingURL=outbound-attachments.d.ts.map