imapflow
Version:
IMAP Client for Node
1,023 lines (1,003 loc) • 54.1 kB
TypeScript
/// <reference types="node" />
declare module "imapflow" {
import { EventEmitter } from "events";
/**
* IMAP connection options
* @property host - Hostname of the IMAP server.
* @property port - Port number for the IMAP server.
* @property [secure = false] - If `true`, establishes the connection directly over TLS (commonly on port 993).
* If `false`, a plain (unencrypted) connection is used first and, if possible, the connection is upgraded to STARTTLS.
* @property [doSTARTTLS] - Determines whether to upgrade the connection to TLS via STARTTLS:
* - **true**: Start unencrypted and upgrade to TLS using STARTTLS before authentication.
* The connection fails if the server does not support STARTTLS or the upgrade fails.
* Note that `secure=true` combined with `doSTARTTLS=true` is invalid.
* - **false**: Never use STARTTLS, even if the server advertises support.
* This is useful if the server has a broken TLS setup.
* Combined with `secure=false`, this results in a fully unencrypted connection.
* Make sure you warn users about the security risks.
* - **undefined** (default): If `secure=false` (default), attempt to upgrade to TLS via STARTTLS before authentication if the server supports it. If not supported, continue unencrypted. This may expose the connection to a downgrade attack.
* @property [servername] - Server name for SNI or when using an IP address as `host`.
* @property [disableCompression = false] - If `true`, the client does not attempt to use the COMPRESS=DEFLATE extension.
* @property auth - Authentication options. Authentication occurs automatically during {@link connect}.
* @property auth.user - Username for authentication.
* @property [auth.pass] - Password for regular authentication.
* @property [auth.accessToken] - OAuth2 access token, if using OAuth2 authentication.
* @property [auth.loginMethod] - Optional login method for password-based authentication (e.g., "LOGIN", "AUTH=LOGIN", or "AUTH=PLAIN").
* If not set, ImapFlow chooses based on available mechanisms.
* @property [clientInfo] - Client identification info sent to the server (via the ID command).
* @property [disableAutoIdle = false] - If `true`, do not start IDLE automatically. Useful when only specific operations are needed.
* @property [tls] - Additional TLS options. For details, see [Node.js TLS connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
* @property [tls.rejectUnauthorized = true] - If `false`, allows self-signed or expired certificates.
* @property [tls.minVersion = 'TLSv1.2'] - Minimum accepted TLS version (e.g., `'TLSv1.2'`).
* @property [tls.minDHSize = 1024] - Minimum size (in bits) of the DH parameter for TLS connections.
* @property [logger] - Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)`, and `error(obj)` methods.
* If `false`, logging is disabled. If not provided, ImapFlow logs to console in [pino format](https://getpino.io/).
* @property [logRaw = false] - If `true`, logs all raw data (read and written) in base64 encoding. You can pipe such logs to [eerawlog](https://github.com/postalsys/eerawlog) command for readable output.
* @property [emitLogs = false] - If `true`, emits `'log'` events with the same data passed to the logger.
* @property [verifyOnly = false] - If `true`, disconnects after successful authentication without performing other actions.
* @property [proxy] - Proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`).
* @property [qresync = false] - If `true`, enables QRESYNC support so that EXPUNGE notifications include `uid` instead of `seq`.
* @property [maxIdleTime] - If set, breaks and restarts IDLE every `maxIdleTime` milliseconds.
* @property [missingIdleCommand = "NOOP"] - Command to use if the server does not support IDLE.
* @property [disableBinary = false] - If `true`, ignores the BINARY extension for FETCH and APPEND operations.
* @property [disableAutoEnable = false] - If `true`, do not automatically enable supported IMAP extensions.
* @property [connectionTimeout = 90000] - Maximum time (in milliseconds) to wait for the connection to establish. Defaults to 90 seconds.
* @property [greetingTimeout = 16000] - Maximum time (in milliseconds) to wait for the server greeting after a connection is established. Defaults to 16 seconds.
* @property [socketTimeout = 300000] - Maximum period of inactivity (in milliseconds) before terminating the connection. Defaults to 5 minutes.
*/
class ImapFlow extends EventEmitter {
/**
* Current module version as a static class property
* @property version - Module version
*/
version: {
version: string;
};
/**
* Instance ID for logs
*/
id: string;
/**
* Server identification info. Available after successful `connect()`.
* If server does not provide identification info then this value is `null`.
* @example
* await client.connect();
* console.log(client.serverInfo.vendor);
*/
serverInfo: IdInfoObject | null;
/**
* Is the connection currently encrypted or not
*/
secureConnection: boolean;
/**
* Active IMAP capabilities. Value is either `true` for togglabe capabilities (eg. `UIDPLUS`)
* or a number for capabilities with a value (eg. `APPENDLIMIT`)
*/
capabilities: Map<string, boolean | number>;
/**
* Enabled capabilities. Usually `CONDSTORE` and `UTF8=ACCEPT` if server supports these.
*/
enabled: Set<string>;
/**
* Is the connection currently usable or not
*/
usable: boolean;
/**
* Currently authenticated user or `false` if mailbox is not open
* or `true` if connection was authenticated by PREAUTH
*/
authenticated: string | boolean;
/**
* Currently selected mailbox or `false` if mailbox is not open
*/
mailbox: MailboxObject | boolean;
/**
* Is current mailbox idling (`true`) or not (`false`)
*/
idling: boolean;
/**
* Tries to upgrade the connection to TLS using STARTTLS.
* @returns true, if the connection is now protected by TLS, either direct TLS or STARTTLS.
*/
upgradeToSTARTTLS(): boolean;
/**
* Initiates a connection against IMAP server. Throws if anything goes wrong. This is something you have to call before you can run any IMAP commands
* @example
* let client = new ImapFlow({...});
* await client.connect();
*/
connect(): Promise<void>;
/**
* Graceful connection close by sending logout command to server. TCP connection is closed once command is finished.
* @example
* let client = new ImapFlow({...});
* await client.connect();
* ...
* await client.logout();
*/
logout(): Promise<void>;
/**
* Closes TCP connection without notifying the server.
* @example
* let client = new ImapFlow({...});
* await client.connect();
* ...
* client.close();
*/
close(): void;
/**
* Returns current quota
* @example
* let quota = await client.getQuota();
* console.log(quota.storage.used, quota.storage.available)
* @param [path] - Optional mailbox path if you want to check quota for specific folder
* @returns Quota information or `false` if QUTOA extension is not supported or requested path does not exist
*/
getQuota(path?: string): Promise<QuotaResponse | Boolean>;
/**
* Lists available mailboxes as an Array
* @example
* let list = await client.list();
* list.forEach(mailbox=>console.log(mailbox.path));
* @param [options] - defines additional listing options
* @returns An array of ListResponse objects
*/
list(options?: ListOptions): Promise<ListResponse[]>;
/**
* Lists available mailboxes as a tree structured object
* @example
* let tree = await client.listTree();
* tree.folders.forEach(mailbox=>console.log(mailbox.path));
* @param [options] - defines additional listing options
* @returns Tree structured object
*/
listTree(options?: ListOptions): Promise<ListTreeResponse>;
/**
* Performs a no-op call against server
*/
noop(): Promise<void>;
/**
* Creates a new mailbox folder and sets up subscription for the created mailbox. Throws on error.
* @example
* let info = await client.mailboxCreate(['parent', 'child']);
* console.log(info.path);
* // "INBOX.parent.child" // assumes "INBOX." as namespace prefix and "." as delimiter
* @param path - Full mailbox path. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.
* @returns Mailbox info
*/
mailboxCreate(path: string | any[]): Promise<MailboxCreateResponse>;
/**
* Renames a mailbox. Throws on error.
* @example
* let info = await client.mailboxRename('parent.child', 'Important stuff ❗️');
* console.log(info.newPath);
* // "INBOX.Important stuff ❗️" // assumes "INBOX." as namespace prefix
* @param path - Path for the mailbox to rename. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.
* @param newPath - New path for the mailbox
* @returns Mailbox info
*/
mailboxRename(path: string | any[], newPath: string | any[]): Promise<MailboxRenameResponse>;
/**
* Deletes a mailbox. Throws on error.
* @example
* let info = await client.mailboxDelete('Important stuff ❗️');
* console.log(info.path);
* // "INBOX.Important stuff ❗️" // assumes "INBOX." as namespace prefix
* @param path - Path for the mailbox to delete. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.
* @returns Mailbox info
*/
mailboxDelete(path: string | any[]): Promise<MailboxDeleteResponse>;
/**
* Subscribes to a mailbox
* @example
* await client.mailboxSubscribe('Important stuff ❗️');
* @param path - Path for the mailbox to subscribe to. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.
* @returns `true` if subscription operation succeeded, `false` otherwise
*/
mailboxSubscribe(path: string | any[]): Promise<Boolean>;
/**
* Unsubscribes from a mailbox
* @example
* await client.mailboxUnsubscribe('Important stuff ❗️');
* @param path - **Path for the mailbox** to unsubscribe from. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.
* @returns `true` if unsubscription operation succeeded, `false` otherwise
*/
mailboxUnsubscribe(path: string | any[]): Promise<Boolean>;
/**
* Opens a mailbox to access messages. You can perform message operations only against an opened mailbox.
* Using {@link module:imapflow~ImapFlow#getMailboxLock|getMailboxLock()} instead of `mailboxOpen()` is preferred. Both do the same thing
* but next `getMailboxLock()` call is not executed until previous one is released.
* @example
* let mailbox = await client.mailboxOpen('Important stuff ❗️');
* console.log(mailbox.exists);
* // 125
* @param path - **Path for the mailbox** to open
* @param [options] - optional options
* @param [options.readOnly = false] - If `true` then opens mailbox in read-only mode. You can still try to perform write operations but these would probably fail.
* @returns Mailbox info
*/
mailboxOpen(path: string | any[], options?: {
readOnly?: boolean;
}): Promise<MailboxObject>;
/**
* Closes a previously opened mailbox
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* await client.mailboxClose();
* @returns Did the operation succeed or not
*/
mailboxClose(): Promise<Boolean>;
/**
* Requests the status of the indicated mailbox. Only requested status values will be returned.
* @example
* let status = await client.status('INBOX', {unseen: true});
* console.log(status.unseen);
* // 123
* @param path - mailbox path to check for (unicode string)
* @param query - defines requested status items
* @param query.messages - if `true` request count of messages
* @param query.recent - if `true` request count of messages with \\Recent tag
* @param query.uidNext - if `true` request predicted next UID
* @param query.uidValidity - if `true` request mailbox `UIDVALIDITY` value
* @param query.unseen - if `true` request count of unseen messages
* @param query.highestModseq - if `true` request last known modseq value
* @returns status of the indicated mailbox
*/
status(path: string, query: {
messages: boolean;
recent: boolean;
uidNext: boolean;
uidValidity: boolean;
unseen: boolean;
highestModseq: boolean;
}): Promise<StatusObject>;
/**
* Starts listening for new or deleted messages from the currently opened mailbox. Only required if {@link ImapFlow#disableAutoIdle} is set to `true`
* otherwise IDLE is started by default on connection inactivity. NB! If `idle()` is called manually then it does not
* return until IDLE is finished which means you would have to call some other command out of scope.
* @example
* let mailbox = await client.mailboxOpen('INBOX');
*
* await client.idle();
* @returns Did the operation succeed or not
*/
idle(): Promise<Boolean>;
/**
* Sets flags for a message or message range
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // mark all unseen messages as seen (and remove other flags)
* await client.messageFlagsSet({seen: false}, ['\Seen]);
* @param range - Range to filter the messages
* @param Array - of flags to set. Only flags that are permitted to set are used, other flags are ignored
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
* @param [options.unchangedSince] - If set then only messages with a lower or equal `modseq` value are updated. Ignored if server does not support `CONDSTORE` extension.
* @param [options.useLabels = false] - If true then update Gmail labels instead of message flags
* @returns Did the operation succeed or not
*/
messageFlagsSet(range: SequenceString | Number[] | SearchObject, Array: string[], options?: {
uid?: boolean;
unchangedSince?: bigint;
useLabels?: boolean;
}): Promise<Boolean>;
/**
* Adds flags for a message or message range
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // mark all unseen messages as seen (and keep other flags as is)
* await client.messageFlagsAdd({seen: false}, ['\Seen]);
* @param range - Range to filter the messages
* @param Array - of flags to set. Only flags that are permitted to set are used, other flags are ignored
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
* @param [options.unchangedSince] - If set then only messages with a lower or equal `modseq` value are updated. Ignored if server does not support `CONDSTORE` extension.
* @param [options.useLabels = false] - If true then update Gmail labels instead of message flags
* @returns Did the operation succeed or not
*/
messageFlagsAdd(range: SequenceString | Number[] | SearchObject, Array: string[], options?: {
uid?: boolean;
unchangedSince?: bigint;
useLabels?: boolean;
}): Promise<Boolean>;
/**
* Remove specific flags from a message or message range
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // mark all seen messages as unseen by removing \\Seen flag
* await client.messageFlagsRemove({seen: true}, ['\Seen]);
* @param range - Range to filter the messages
* @param Array - of flags to remove. Only flags that are permitted to set are used, other flags are ignored
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
* @param [options.unchangedSince] - If set then only messages with a lower or equal `modseq` value are updated. Ignored if server does not support `CONDSTORE` extension.
* @param [options.useLabels = false] - If true then update Gmail labels instead of message flags
* @returns Did the operation succeed or not
*/
messageFlagsRemove(range: SequenceString | Number[] | SearchObject, Array: string[], options?: {
uid?: boolean;
unchangedSince?: bigint;
useLabels?: boolean;
}): Promise<Boolean>;
/**
* Sets a colored flag for an email. Only supported by mail clients like Apple Mail
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // add a purple flag for all emails
* await client.setFlagColor('1:*', 'Purple');
* @param range - Range to filter the messages
* @param The - color to set. One of 'red', 'orange', 'yellow', 'green', 'blue', 'purple', and 'grey'
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
* @param [options.unchangedSince] - If set then only messages with a lower or equal `modseq` value are updated. Ignored if server does not support `CONDSTORE` extension.
* @returns Did the operation succeed or not
*/
setFlagColor(range: SequenceString | Number[] | SearchObject, The: string, options?: {
uid?: boolean;
unchangedSince?: bigint;
}): Promise<Boolean>;
/**
* Delete messages from the currently opened mailbox. Method does not indicate info about deleted messages,
* instead you should be using {@link ImapFlow#expunge} event for this
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // delete all seen messages
* await client.messageDelete({seen: true});
* @param range - Range to filter the messages
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
* @returns Did the operation succeed or not
*/
messageDelete(range: SequenceString | Number[] | SearchObject, options?: {
uid?: boolean;
}): Promise<Boolean>;
/**
* Appends a new message to a mailbox
* @example
* await client.append('INBOX', rawMessageBuffer, ['\\Seen'], new Date(2000, 1, 1));
* @param path - Mailbox path to upload the message to (unicode string)
* @param content - RFC822 formatted email message
* @param [flags] - an array of flags to be set for the uploaded message
* @param [idate = now] - internal date to be set for the message
* @returns info about uploaded message
*/
append(path: string, content: string | Buffer, flags?: string[], idate?: Date | string): Promise<AppendResponseObject>;
/**
* Copies messages from current mailbox to destination mailbox
* @example
* await client.mailboxOpen('INBOX');
* // copy all messages to a mailbox called "Backup" (must exist)
* let result = await client.messageCopy('1:*', 'Backup');
* console.log('Copied %s messages', result.uidMap.size);
* @param range - Range of messages to copy
* @param destination - Mailbox path to copy the messages to
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
* @returns info about copies messages
*/
messageCopy(range: SequenceString | Number[] | SearchObject, destination: string, options?: {
uid?: boolean;
}): Promise<CopyResponseObject>;
/**
* Moves messages from current mailbox to destination mailbox
* @example
* await client.mailboxOpen('INBOX');
* // move all messages to a mailbox called "Trash" (must exist)
* let result = await client.messageMove('1:*', 'Trash');
* console.log('Moved %s messages', result.uidMap.size);
* @param range - Range of messages to move
* @param destination - Mailbox path to move the messages to
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
* @returns info about moved messages
*/
messageMove(range: SequenceString | Number[] | SearchObject, destination: string, options?: {
uid?: boolean;
}): Promise<CopyResponseObject>;
/**
* Search messages from the currently opened mailbox
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // find all unseen messages
* let list = await client.search({seen: false});
* // use OR modifier (array of 2 or more search queries)
* let list = await client.search({
* seen: false,
* or: [
* {flagged: true},
* {from: 'andris'},
* {subject: 'test'}
* ]});
* @param query - Query to filter the messages
* @param [options.uid] - If `true` then returns UID numbers instead of sequence numbers
* @returns An array of sequence or UID numbers
*/
search(query: SearchObject, options?: {
uid?: boolean;
}): Promise<Number[]>;
/**
* Fetch messages from the currently opened mailbox
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // fetch UID for all messages in a mailbox
* for await (let msg of client.fetch('1:*', {uid: true})){
* console.log(msg.uid);
* // NB! You can not run any IMAP commands in this loop
* // otherwise you will end up in a deadloop
* }
* @param range - Range of messages to fetch
* @param query - Fetch query
* @param [options.uid] - If `true` then uses UID numbers instead of sequence numbers for `range`
* @param [options.changedSince] - If set then only messages with a higher modseq value are returned. Ignored if server does not support `CONDSTORE` extension.
* @param [options.binary = false] - If `true` then requests a binary response if the server supports this
*/
fetch(range: SequenceString | Number[] | SearchObject, query: FetchQueryObject, options?: {
uid?: boolean;
changedSince?: bigint;
binary?: boolean;
}): void;
/**
* Fetch messages from the currently opened mailbox.
*
* This method will fetch all messages before resolving the promise, unlike .fetch(), which
* is an async generator. Do not use large ranges like 1:*, as this might exhaust all available
* memory if the mailbox contains a large number of emails.
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // fetch UID for all messages in a mailbox
* const messages = await client.fetchAll('1:*', {uid: true});
* for (let msg of messages){
* console.log(msg.uid);
* }
* @param range - Range of messages to fetch
* @param query - Fetch query
* @param [options.uid] - If `true` then uses UID numbers instead of sequence numbers for `range`
* @param [options.changedSince] - If set then only messages with a higher modseq value are returned. Ignored if server does not support `CONDSTORE` extension.
* @param [options.binary = false] - If `true` then requests a binary response if the server supports this
* @returns Array of Message data object
*/
fetchAll(range: SequenceString | Number[] | SearchObject, query: FetchQueryObject, options?: {
uid?: boolean;
changedSince?: bigint;
binary?: boolean;
}): Promise<FetchMessageObject[]>;
/**
* Fetch a single message from the currently opened mailbox
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // fetch UID for the last email in the selected mailbox
* let lastMsg = await client.fetchOne('*', {uid: true})
* console.log(lastMsg.uid);
* @param seq - Single UID or sequence number of the message to fetch for
* @param query - Fetch query
* @param [options.uid] - If `true` then uses UID number instead of sequence number for `seq`
* @param [options.binary = false] - If `true` then requests a binary response if the server supports this
* @returns Message data object
*/
fetchOne(seq: SequenceString, query: FetchQueryObject, options?: {
uid?: boolean;
binary?: boolean;
}): Promise<FetchMessageObject>;
/**
* Download either full rfc822 formatted message or a specific bodystructure part as a Stream.
* Bodystructure parts are decoded so the resulting stream is a binary file. Text content
* is automatically converted to UTF-8 charset.
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // download body part nr '1.2' from latest message
* let {meta, content} = await client.download('*', '1.2');
* content.pipe(fs.createWriteStream(meta.filename));
* @param range - UID or sequence number for the message to fetch
* @param [part] - If not set then downloads entire rfc822 formatted message, otherwise downloads specific bodystructure part
* @param [options.uid] - If `true` then uses UID number instead of sequence number for `range`
* @param [options.maxBytes] - If set then limits download size to specified bytes
* @param [options.chunkSize = 65536] - How large content parts to ask from the server
* @returns Download data object
*/
download(range: SequenceString, part?: string, options?: {
uid?: boolean;
maxBytes?: number;
chunkSize?: number;
}): Promise<DownloadObject>;
/**
* Fetch multiple attachments as Buffer values
* @example
* let mailbox = await client.mailboxOpen('INBOX');
* // download body parts '2', and '3' from all messages in the selected mailbox
* let response = await client.downloadMany('*', ['2', '3']);
* process.stdout.write(response[2].content)
* process.stdout.write(response[3].content)
* @param range - UID or sequence number for the message to fetch
* @param parts - A list of bodystructure parts
* @param [options.uid] - If `true` then uses UID number instead of sequence number for `range`
* @returns Download data object
*/
downloadMany(range: SequenceString, parts: string, options?: {
uid?: boolean;
}): Promise<object>;
/**
* Opens a mailbox if not already open and returns a lock. Next call to `getMailboxLock()` is queued
* until previous lock is released. This is suggested over {@link module:imapflow~ImapFlow#mailboxOpen|mailboxOpen()} as
* `getMailboxLock()` gives you a weak transaction while `mailboxOpen()` has no guarantees whatsoever that another
* mailbox is opened while you try to call multiple fetch or store commands.
* @example
* let lock = await client.getMailboxLock('INBOX');
* try {
* // do something in the mailbox
* } finally {
* // use finally{} to make sure lock is released even if exception occurs
* lock.release();
* }
* @param path - **Path for the mailbox** to open
* @param [options] - optional options
* @param [options.readOnly = false] - If `true` then opens mailbox in read-only mode. You can still try to perform write operations but these would probably fail.
* @returns Mailbox lock
*/
getMailboxLock(path: string | any[], options?: {
readOnly?: boolean;
}): Promise<MailboxLockObject>;
/**
* Hostname of the IMAP server.
*/
host: string;
/**
* Port number for the IMAP server.
*/
port: number;
/**
* If `true`, establishes the connection directly over TLS (commonly on port 993).
If `false`, a plain (unencrypted) connection is used first and, if possible, the connection is upgraded to STARTTLS.
*/
secure?: boolean;
/**
* Determines whether to upgrade the connection to TLS via STARTTLS:
- **true**: Start unencrypted and upgrade to TLS using STARTTLS before authentication.
The connection fails if the server does not support STARTTLS or the upgrade fails.
Note that `secure=true` combined with `doSTARTTLS=true` is invalid.
- **false**: Never use STARTTLS, even if the server advertises support.
This is useful if the server has a broken TLS setup.
Combined with `secure=false`, this results in a fully unencrypted connection.
Make sure you warn users about the security risks.
- **undefined** (default): If `secure=false` (default), attempt to upgrade to TLS via STARTTLS before authentication if the server supports it. If not supported, continue unencrypted. This may expose the connection to a downgrade attack.
*/
doSTARTTLS?: boolean;
/**
* Server name for SNI or when using an IP address as `host`.
*/
servername?: string;
/**
* If `true`, the client does not attempt to use the COMPRESS=DEFLATE extension.
*/
disableCompression?: boolean;
/**
* Authentication options. Authentication occurs automatically during {@link connect}.
*/
auth: {
user: string;
pass?: string;
accessToken?: string;
loginMethod?: string;
};
/**
* Client identification info sent to the server (via the ID command).
*/
clientInfo?: IdInfoObject;
/**
* If `true`, do not start IDLE automatically. Useful when only specific operations are needed.
*/
disableAutoIdle?: boolean;
/**
* Additional TLS options. For details, see [Node.js TLS connect](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
*/
tls?: {
rejectUnauthorized?: boolean;
minVersion?: string;
minDHSize?: number;
};
/**
* Custom logger instance with `debug(obj)`, `info(obj)`, `warn(obj)`, and `error(obj)` methods.
If `false`, logging is disabled. If not provided, ImapFlow logs to console in [pino format](https://getpino.io/).
*/
logger?: any | boolean;
/**
* If `true`, logs all raw data (read and written) in base64 encoding. You can pipe such logs to [eerawlog](https://github.com/postalsys/eerawlog) command for readable output.
*/
logRaw?: boolean;
/**
* If `true`, emits `'log'` events with the same data passed to the logger.
*/
emitLogs?: boolean;
/**
* If `true`, disconnects after successful authentication without performing other actions.
*/
verifyOnly?: boolean;
/**
* Proxy URL. Supports HTTP CONNECT (`http://`, `https://`) and SOCKS (`socks://`, `socks4://`, `socks5://`).
*/
proxy?: string;
/**
* If `true`, enables QRESYNC support so that EXPUNGE notifications include `uid` instead of `seq`.
*/
qresync?: boolean;
/**
* If set, breaks and restarts IDLE every `maxIdleTime` milliseconds.
*/
maxIdleTime?: number;
/**
* Command to use if the server does not support IDLE.
*/
missingIdleCommand?: string;
/**
* If `true`, ignores the BINARY extension for FETCH and APPEND operations.
*/
disableBinary?: boolean;
/**
* If `true`, do not automatically enable supported IMAP extensions.
*/
disableAutoEnable?: boolean;
/**
* Maximum time (in milliseconds) to wait for the connection to establish. Defaults to 90 seconds.
*/
connectionTimeout?: number;
/**
* Maximum time (in milliseconds) to wait for the server greeting after a connection is established. Defaults to 16 seconds.
*/
greetingTimeout?: number;
/**
* Maximum period of inactivity (in milliseconds) before terminating the connection. Defaults to 5 minutes.
*/
socketTimeout?: number;
}
}
/**
* @property path - mailbox path
* @property delimiter - mailbox path delimiter, usually "." or "/"
* @property flags - list of flags for this mailbox
* @property [specialUse] - one of special-use flags (if applicable): "\All", "\Archive", "\Drafts", "\Flagged", "\Junk", "\Sent", "\Trash". Additionally INBOX has non-standard "\Inbox" flag set
* @property listed - `true` if mailbox was found from the output of LIST command
* @property subscribed - `true` if mailbox was found from the output of LSUB command
* @property permanentFlags - A Set of flags available to use in this mailbox. If it is not set or includes special flag "\\\*" then any flag can be used.
* @property [mailboxId] - unique mailbox ID if server has `OBJECTID` extension enabled
* @property [highestModseq] - latest known modseq value if server has CONDSTORE or XYMHIGHESTMODSEQ enabled
* @property [noModseq] - if true then the server doesn't support the persistent storage of mod-sequences for the mailbox
* @property uidValidity - Mailbox `UIDVALIDITY` value
* @property uidNext - Next predicted UID
* @property exists - Messages in this folder
*/
declare type MailboxObject = {
path: string;
delimiter: string;
flags: Set<string>;
specialUse?: string;
listed: boolean;
subscribed: boolean;
permanentFlags: Set<string>;
mailboxId?: string;
highestModseq?: bigint;
noModseq?: string;
uidValidity: bigint;
uidNext: number;
exists: number;
};
/**
* @example
* let lock = await client.getMailboxLock('INBOX');
* try {
* // do something in the mailbox
* } finally {
* // use finally{} to make sure lock is released even if exception occurs
* lock.release();
* }
* @property path - mailbox path
* @property release - Release current lock
*/
declare type MailboxLockObject = {
path: string;
release: (...params: any[]) => any;
};
/**
* Client and server identification object, where key is one of RFC2971 defined [data fields](https://tools.ietf.org/html/rfc2971#section-3.3) (but not limited to).
* @property [name] - Name of the program
* @property [version] - Version number of the program
* @property [os] - Name of the operating system
* @property [vendor] - Vendor of the client/server
* @property ['support-url'] - URL to contact for support
* @property [date] - Date program was released
*/
declare type IdInfoObject = {
name?: string;
version?: string;
os?: string;
vendor?: string;
'support-url'?: string;
date?: Date;
};
/**
* @property path - mailbox path this quota applies to
* @property [storage] - Storage quota if provided by server
* @property [storage.used] - used storage in bytes
* @property [storage.limit] - total storage available
* @property [messages] - Message count quota if provided by server
* @property [messages.used] - stored messages
* @property [messages.limit] - maximum messages allowed
*/
declare type QuotaResponse = {
path: string;
storage?: {
used?: number;
limit?: number;
};
messages?: {
used?: number;
limit?: number;
};
};
/**
* @property path - mailbox path (unicode string)
* @property pathAsListed - mailbox path as listed in the LIST/LSUB response
* @property name - mailbox name (last part of path after delimiter)
* @property delimiter - mailbox path delimiter, usually "." or "/"
* @property parent - An array of parent folder names. All names are in unicode
* @property parentPath - Same as `parent`, but as a complete string path (unicode string)
* @property flags - a set of flags for this mailbox
* @property specialUse - one of special-use flags (if applicable): "\All", "\Archive", "\Drafts", "\Flagged", "\Junk", "\Sent", "\Trash". Additionally INBOX has non-standard "\Inbox" flag set
* @property listed - `true` if mailbox was found from the output of LIST command
* @property subscribed - `true` if mailbox was found from the output of LSUB command
* @property [status] - If `statusQuery` was used, then this value includes the status response
*/
declare type ListResponse = {
path: string;
pathAsListed: string;
name: string;
delimiter: string;
parent: String[];
parentPath: string;
flags: Set<string>;
specialUse: string;
listed: boolean;
subscribed: boolean;
status?: StatusObject;
};
/**
* @property [statusQuery] - request status items for every listed entry
* @property [statusQuery.messages] - if `true` request count of messages
* @property [statusQuery.recent] - if `true` request count of messages with \\Recent tag
* @property [statusQuery.uidNext] - if `true` request predicted next UID
* @property [statusQuery.uidValidity] - if `true` request mailbox `UIDVALIDITY` value
* @property [statusQuery.unseen] - if `true` request count of unseen messages
* @property [statusQuery.highestModseq] - if `true` request last known modseq value
* @property [specialUseHints] - set specific paths as special use folders, this would override special use flags provided from the server
* @property [specialUseHints.sent] - Path to "Sent Mail" folder
* @property [specialUseHints.trash] - Path to "Trash" folder
* @property [specialUseHints.junk] - Path to "Junk Mail" folder
* @property [specialUseHints.drafts] - Path to "Drafts" folder
*/
declare type ListOptions = {
statusQuery?: {
messages?: boolean;
recent?: boolean;
uidNext?: boolean;
uidValidity?: boolean;
unseen?: boolean;
highestModseq?: boolean;
};
specialUseHints?: {
sent?: string;
trash?: string;
junk?: string;
drafts?: string;
};
};
/**
* @property root - If `true` then this is root node without any additional properties besides *folders*
* @property path - mailbox path
* @property name - mailbox name (last part of path after delimiter)
* @property delimiter - mailbox path delimiter, usually "." or "/"
* @property flags - list of flags for this mailbox
* @property specialUse - one of special-use flags (if applicable): "\All", "\Archive", "\Drafts", "\Flagged", "\Junk", "\Sent", "\Trash". Additionally INBOX has non-standard "\Inbox" flag set
* @property listed - `true` if mailbox was found from the output of LIST command
* @property subscribed - `true` if mailbox was found from the output of LSUB command
* @property disabled - If `true` then this mailbox can not be selected in the UI
* @property folders - An array of subfolders
*/
declare type ListTreeResponse = {
root: boolean;
path: string;
name: string;
delimiter: string;
flags: String[];
specialUse: string;
listed: boolean;
subscribed: boolean;
disabled: boolean;
folders: ListTreeResponse[];
};
/**
* @property path - full mailbox path
* @property [mailboxId] - unique mailbox ID if server supports `OBJECTID` extension (currently Yahoo and some others)
* @property created - If `true` then mailbox was created otherwise it already existed
*/
declare type MailboxCreateResponse = {
path: string;
mailboxId?: string;
created: boolean;
};
/**
* @property path - full mailbox path that was renamed
* @property newPath - new full mailbox path
*/
declare type MailboxRenameResponse = {
path: string;
newPath: string;
};
/**
* @property path - full mailbox path that was deleted
*/
declare type MailboxDeleteResponse = {
path: string;
};
/**
* @property path - full mailbox path that was checked
* @property [messages] - Count of messages
* @property [recent] - Count of messages with \\Recent tag
* @property [uidNext] - Predicted next UID
* @property [uidValidity] - Mailbox `UIDVALIDITY` value
* @property [unseen] - Count of unseen messages
* @property [highestModseq] - Last known modseq value (if CONDSTORE extension is enabled)
*/
declare type StatusObject = {
path: string;
messages?: number;
recent?: number;
uidNext?: number;
uidValidity?: bigint;
unseen?: number;
highestModseq?: bigint;
};
/**
* Sequence range string. Separate different values with commas, number ranges with colons and use \\* as the placeholder for the newest message in mailbox
* @example
* "1:*" // for all messages
* "1,2,3" // for messages 1, 2 and 3
* "1,2,4:6" // for messages 1,2,4,5,6
* "*" // for the newest message
*/
declare type SequenceString = string;
/**
* IMAP search query options. By default all conditions must match. In case of `or` query term at least one condition must match.
* @property [seq] - message ordering sequence range
* @property [answered] - Messages with (value is `true`) or without (value is `false`) \\Answered flag
* @property [deleted] - Messages with (value is `true`) or without (value is `false`) \\Deleted flag
* @property [draft] - Messages with (value is `true`) or without (value is `false`) \\Draft flag
* @property [flagged] - Messages with (value is `true`) or without (value is `false`) \\Flagged flag
* @property [seen] - Messages with (value is `true`) or without (value is `false`) \\Seen flag
* @property [all] - If `true` matches all messages
* @property [new] - If `true` matches messages that have the \\Recent flag set but not the \\Seen flag
* @property [old] - If `true` matches messages that do not have the \\Recent flag set
* @property [recent] - If `true` matches messages that have the \\Recent flag set
* @property [from] - Matches From: address field
* @property [to] - Matches To: address field
* @property [cc] - Matches Cc: address field
* @property [bcc] - Matches Bcc: address field
* @property [body] - Matches message body
* @property [subject] - Matches message subject
* @property [larger] - Matches messages larger than value
* @property [smaller] - Matches messages smaller than value
* @property [uid] - UID sequence range
* @property [modseq] - Matches messages with modseq higher than value
* @property [emailId] - unique email ID. Only used if server supports `OBJECTID` or `X-GM-EXT-1` extensions
* @property [threadId] - unique thread ID. Only used if server supports `OBJECTID` or `X-GM-EXT-1` extensions
* @property [before] - Matches messages received before date
* @property [on] - Matches messages received on date (ignores time)
* @property [since] - Matches messages received after date
* @property [sentBefore] - Matches messages sent before date
* @property [sentOn] - Matches messages sent on date (ignores time)
* @property [sentSince] - Matches messages sent after date
* @property [keyword] - Matches messages that have the custom flag set
* @property [unKeyword] - Matches messages that do not have the custom flag set
* @property [header] - Matches messages with header key set if value is `true` (**NB!** not supported by all servers) or messages where header partially matches a string value
* @property [not] - A {@link SearchObject} object. It must not match.
* @property [or] - An array of 2 or more {@link SearchObject} objects. At least one of these must match
*/
declare type SearchObject = {
seq?: SequenceString;
answered?: boolean;
deleted?: boolean;
draft?: boolean;
flagged?: boolean;
seen?: boolean;
all?: boolean;
new?: boolean;
old?: boolean;
recent?: boolean;
from?: string;
to?: string;
cc?: string;
bcc?: string;
body?: string;
subject?: string;
larger?: number;
smaller?: number;
uid?: SequenceString;
modseq?: bigint;
emailId?: string;
threadId?: string;
before?: Date | string;
on?: Date | string;
since?: Date | string;
sentBefore?: Date | string;
sentOn?: Date | string;
sentSince?: Date | string;
keyword?: string;
unKeyword?: string;
header?: {
[key: string]: Boolean | String;
};
not?: SearchObject;
or?: SearchObject[];
};
/**
* @property destination - full mailbox path where the message was uploaded to
* @property [uidValidity] - mailbox `UIDVALIDITY` if server has `UIDPLUS` extension enabled
* @property [uid] - UID of the uploaded message if server has `UIDPLUS` extension enabled
* @property [seq] - sequence number of the uploaded message if path is currently selected mailbox
*/
declare type AppendResponseObject = {
destination: string;
uidValidity?: bigint;
uid?: number;
seq?: number;
};
/**
* @property path - path of source mailbox
* @property destination - path of destination mailbox
* @property [uidValidity] - destination mailbox `UIDVALIDITY` if server has `UIDPLUS` extension enabled
* @property [uidMap] - Map of UID values (if server has `UIDPLUS` extension enabled) where key is UID in source mailbox and value is the UID for the same message in destination mailbox
*/
declare type CopyResponseObject = {
path: string;
destination: string;
uidValidity?: bigint;
uidMap?: Map<number, number>;
};
/**
* @property [uid] - if `true` then include UID in the response
* @property [flags] - if `true` then include flags Set in the response. Also adds `flagColor` to the response if the message is flagged.
* @property [bodyStructure] - if `true` then include parsed BODYSTRUCTURE object in the response
* @property [envelope] - if `true` then include parsed ENVELOPE object in the response
* @property [internalDate] - if `true` then include internal date value in the response
* @property [size] - if `true` then include message size in the response
* @property [source] - if `true` then include full message in the response
* @property [source.start] - include full message in the response starting from *start* byte
* @property [source.maxLength] - include full message in the response, up to *maxLength* bytes
* @property [threadId] - if `true` then include thread ID in the response (only if server supports either `OBJECTID` or `X-GM-EXT-1` extensions)
* @property [labels] - if `true` then include GMail labels in the response (only if server supports `X-GM-EXT-1` extension)
* @property [headers] - if `true` then includes full headers of the message in the response. If the value is an array of header keys then includes only headers listed in the array
* @property [bodyParts] - An array of BODYPART identifiers to include in the response
*/
declare type FetchQueryObject = {
uid?: boolean;
flags?: boolean;
bodyStructure?: boolean;
envelope?: boolean;
internalDate?: boolean;
size?: boolean;
source?: {
start?: number;
maxLength?: number;
};
threadId?: string;
labels?: boolean;
headers?: boolean | string[];
bodyParts?: string[];
};
/**
* Parsed email address entry
* @property [name] - name of the address object (unicode)
* @property [address] - email address
*/
declare type MessageAddressObject = {
name?: string;
address?: string;
};
/**
* Parsed IMAP ENVELOPE object
* @property [date] - header date
* @property [subject] - message subject (unicode)
* @property [messageId] - Message ID of the message
* @property [inReplyTo] - Message ID from In-Reply-To header
* @property [from] - Array of addresses from the From: header
* @property [sender] - Array of addresses fr