/** * Compatibility wrapper — makes NativeImapClient look like the old ImapClient API. * This allows mailx-imap to switch to the native client without rewriting all call sites. * Each method opens the mailbox, does the operation, and returns. No persistent state. */ import { type NativeFolder } from "./imap-native.js"; import { FetchedMessage } from "./fetched-message.js"; import type { ImapClientConfig } from "./types.js"; import type { TransportFactory } from "./transport.js"; import type * as proto from "./imap-protocol.js"; /** Special folder detection result */ export interface SpecialFolders { inbox?: string; sent?: string; trash?: string; drafts?: string; spam?: string; junk?: string; archive?: string; } /** * Compatibility IMAP client — wraps NativeImapClient with the old ImapClient API. * Each method creates its own select/operation/close cycle. */ export declare class CompatImapClient { private native; constructor(config: ImapClientConfig, transportFactory: TransportFactory); /** Connect and authenticate */ connect(): Promise; /** * Ensure connected (lazy connect). Checks both the native client's connected * flag AND the transport's connected state. The transport flag catches cases * where the socket died without a close/error event reaching NativeImapClient * (common on Android where the bridge may not relay all TCP events). */ private ensureConnected; logout(): Promise; /** Get folder list */ getFolderList(): Promise; /** Extract special folders from folder list */ getSpecialFolders(folders: NativeFolder[]): SpecialFolders; /** Fetch messages since a UID in a mailbox */ fetchMessagesSinceUid(mailbox: string, sinceUid: number, options?: { source?: boolean; }): Promise; /** Batch-fetch bodies for many UIDs in one folder on one connection. Streams * each body through `onBody` as it arrives. No per-message round trips — * one SELECT, one UID FETCH, streaming response. Required by mailx-imap's * batch prefetch path. */ fetchBodiesBatch(mailbox: string, uids: number[], onBody: (uid: number, source: string) => void): Promise; /** Fetch messages by date range. Optional onChunk callback for incremental processing. */ fetchMessageByDate(mailbox: string, start: Date, end?: Date, options?: { source?: boolean; }, onChunk?: (msgs: FetchedMessage[]) => void): Promise; /** Fetch the most recent N messages by sequence number — sidesteps * SEARCH SINCE which can take minutes on cold Dovecot mailboxes. Used * by mailx-imap's first-sync path so the user sees something fast even * on a wide folder tree. The 30-day backfill is a follow-up step. */ fetchLatestN(mailbox: string, n: number, options?: { source?: boolean; }, onChunk?: (msgs: FetchedMessage[]) => void): Promise; /** Fetch a single message by UID */ fetchMessageByUid(mailbox: string, uid: number, options?: { source?: boolean; }): Promise; /** Get message count via STATUS (does not require SELECT) */ getMessagesCount(mailbox: string): Promise; /** Mailbox size in octets + message count. STATUS=SIZE when the server has it, else a * size-only UID FETCH. See NativeImapClient.getFolderSize. (2026-09-16, Claude Code) */ getFolderSize(mailbox: string): Promise<{ messages: number; bytes: number; method: "status" | "fetch"; }>; /** Get all UIDs in a mailbox */ getUids(mailbox: string): Promise; /** Get UIDs whose INTERNALDATE is on/after `since`. Bounded version of * getUids — returns only the date window the caller cares about * instead of the entire folder. Lets set-diff reconciliation scope * itself to "messages from the last N days" rather than enumerating * every UID in a 134k-message folder. */ getUidsSince(mailbox: string, since: Date): Promise; /** Fetch messages — supports two calling conventions for compatibility: * * New: fetchMessages(mailbox, "100:200") — UID range string * Old: fetchMessages(mailbox, endSeq, count) — sequence-number range (iflow compat) * * The old form computes UID range "start:end" from (end - count + 1) : end, * matching the legacy iflow/imapflow fetchMessages(mailbox, end, count) API * used by the puller. */ fetchMessages(mailbox: string, uidRange: string, options?: { source?: boolean; }): Promise; fetchMessages(mailbox: string, end: number, count: number, options?: { source?: boolean; }): Promise; /** Search messages in a mailbox. * Criteria: from/to/cc/subject/body/text (string or string[], each key * repeats and ANDs), since/before (Date), seen/unseen/flagged/answered/ * draft (boolean flags), `not` (criteria object or array — each becomes * a NOT'd key group), `or` (array of ≥2 criteria objects — compiled to * IMAP's binary prefix OR chain). */ searchMessages(mailbox: string, criteria: any): Promise; /** Search by header value — returns matching UIDs */ searchByHeader(mailbox: string, headerName: string, headerValue: string): Promise; /** Delete a message by UID */ deleteMessageByUid(mailbox: string, uid: number): Promise; /** Delete many messages by UID in one mailbox — chunked STORE + one * EXPUNGE (see ImapNative.deleteMessages). 2026-09-16 Claude Code. */ deleteMessagesByUid(mailbox: string, uids: number[]): Promise; /** Move a message between mailboxes (same server) */ moveMessage(msg: any, fromMailbox: string, toMailbox: string): Promise; /** Add flags to a message */ addFlags(mailbox: string, uid: number, flags: string[]): Promise; /** Remove flags from a message */ removeFlags(mailbox: string, uid: number, flags: string[]): Promise; /** Create a mailbox */ createmailbox(name: string): Promise; /** Append a message to a mailbox */ appendMessage(mailbox: string, message: string | Uint8Array, flags?: string[]): Promise; /** Cached CAPABILITY set parsed at connect/login. Callers gate * optional features (NOTIFY, QRESYNC, MOVE, ...) on this. */ getCapabilities(): Set; /** Snapshot of the most recently SELECTed mailbox's info. Callers use this * to read `highestModSeq` after any operation that did a SELECT — useful * for seeding the QRESYNC modSeq watermark on the very first sync of a * folder (before the QRESYNC path is eligible). */ getCurrentMailboxInfo(): { uidValidity: number; uidNext: number; exists: number; highestModSeq?: number; }; /** RFC 5161 ENABLE — activates an IMAP extension for the remainder of * the session. QRESYNC must be enabled before any SELECT for * `* VANISHED` responses + automatic `MODSEQ` to start flowing. * Returns the set of extensions the server confirmed are active. */ enable(extensions: string[]): Promise>; /** Convenience: enable QRESYNC if the server advertises it. Returns * true if QRESYNC is active on the session afterwards. Idempotent — * safe to call once per connection at connect time. */ enableQresync(): Promise; /** Fast resync of a mailbox via RFC 7162 QRESYNC. Caller supplies the * `uidValidity` and last-seen `modSeq` from its prior visit; the * server replies with `* VANISHED` for UIDs expunged since then and * unsolicited `* FETCH` for state changes (flag updates etc.) since * then, plus the current `HIGHESTMODSEQ` for the caller to persist * as its new watermark. * * Returns: * - `uidValidityChanged`: server's UIDVALIDITY no longer matches; the * caller's UID set is stale and MUST be full-resynced. * - `vanishedUids`: authoritative deletion list. No client-side diff. * - `changedMessages`: state-change FETCH responses since the prior * modSeq — each carries `uid`, `flags`, and `modSeq` (and possibly * other FETCH items the caller asked for). * - `newHighestModSeq`: persist this for the next resync. * * Pre-requisite: `enableQresync()` returned true once on the session. * If the server doesn't support QRESYNC, fall back to the older * `fetchMessagesSinceUid` / set-diff path. */ resyncFolder(mailbox: string, uidValidity: number, modSeq: number): Promise<{ uidValidityChanged: boolean; vanishedUids: number[]; changedMessages: FetchedMessage[]; newHighestModSeq: number | undefined; exists: number; uidNext: number; }>; /** Watch a mailbox for new messages (IDLE). Optionally engage RFC 5465 * NOTIFY so the server also pushes STATUS responses for non-selected * mailboxes named in `opts.notifySpec` — `opts.onMailboxStatus` fires * for each. Capability check is the caller's responsibility; pass * notifySpec only when `getCapabilities().has("NOTIFY")`. */ watchMailbox(mailbox: string, onNew: (count: number) => void, opts?: { notifySpec?: string; onMailboxStatus?: (mailbox: string, data: proto.StatusData) => void; onExpunge?: () => void; /** A flag changed on a message in the watched mailbox — another * client starred, read or unread something. */ onFlagChange?: (seq: number, flags: string[]) => void; }): Promise<() => Promise>; /** Copy a message to another server (cross-account) */ moveMessageToServer(msg: any, fromMailbox: string, targetClient: CompatImapClient, toMailbox: string): Promise; /** Rename a mailbox (via native access) */ renameMailbox(from: string, to: string): Promise; /** Delete a mailbox */ deleteMailbox(name: string): Promise; /** Get flags for a UID — returns string[] for compatibility with old client */ getFlags(mailbox: string, uid: number): Promise; } export declare function buildSearchString(criteria: any): string; //# sourceMappingURL=imap-compat.d.ts.map