@happyvertical/email 0.74.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +34 -0
- package/LICENSE +7 -0
- package/dist/adapters/gmail.d.ts +43 -0
- package/dist/adapters/gmail.d.ts.map +1 -0
- package/dist/adapters/imap.d.ts +114 -0
- package/dist/adapters/imap.d.ts.map +1 -0
- package/dist/adapters/pop3.d.ts +44 -0
- package/dist/adapters/pop3.d.ts.map +1 -0
- package/dist/adapters/smtp.d.ts +64 -0
- package/dist/adapters/smtp.d.ts.map +1 -0
- package/dist/cli/claude-context.d.ts +3 -0
- package/dist/cli/claude-context.d.ts.map +1 -0
- package/dist/cli/claude-context.js +21 -0
- package/dist/cli/claude-context.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2165 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/base.d.ts +41 -0
- package/dist/shared/base.d.ts.map +1 -0
- package/dist/shared/errors.d.ts +46 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/factory.d.ts +43 -0
- package/dist/shared/factory.d.ts.map +1 -0
- package/dist/shared/types.d.ts +242 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/metadata.json +38 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/shared/errors.ts","../src/shared/base.ts","../src/adapters/gmail.ts","../src/adapters/imap.ts","../src/adapters/pop3.ts","../src/adapters/smtp.ts","../src/shared/factory.ts"],"sourcesContent":["/**\n * Error classes for @happyvertical/email package\n */\n\n// ============================================================================\n// Base Error\n// ============================================================================\n\nexport class EmailError extends Error {\n code: string;\n provider?: string;\n cause?: unknown;\n\n constructor(\n message: string,\n code: string,\n provider?: string,\n cause?: unknown,\n ) {\n super(message);\n this.name = 'EmailError';\n this.code = code;\n this.provider = provider;\n this.cause = cause;\n }\n}\n\n// ============================================================================\n// Connection Errors\n// ============================================================================\n\nexport class ConnectionError extends EmailError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'CONNECTION_ERROR', provider, cause);\n this.name = 'ConnectionError';\n }\n}\n\nexport class TimeoutError extends EmailError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'TIMEOUT_ERROR', provider, cause);\n this.name = 'TimeoutError';\n }\n}\n\n// ============================================================================\n// Authentication Errors\n// ============================================================================\n\nexport class AuthenticationError extends EmailError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'AUTHENTICATION_ERROR', provider, cause);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class AuthorizationError extends EmailError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'AUTHORIZATION_ERROR', provider, cause);\n this.name = 'AuthorizationError';\n }\n}\n\n// ============================================================================\n// Message Errors\n// ============================================================================\n\nexport class MessageNotFoundError extends EmailError {\n messageId: string;\n\n constructor(messageId: string, provider?: string) {\n super(`Message not found: ${messageId}`, 'MESSAGE_NOT_FOUND', provider);\n this.name = 'MessageNotFoundError';\n this.messageId = messageId;\n }\n}\n\nexport class InvalidMessageError extends EmailError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'INVALID_MESSAGE', provider, cause);\n this.name = 'InvalidMessageError';\n }\n}\n\n// ============================================================================\n// Folder Errors\n// ============================================================================\n\nexport class FolderNotFoundError extends EmailError {\n folder: string;\n\n constructor(folder: string, provider?: string) {\n super(`Folder not found: ${folder}`, 'FOLDER_NOT_FOUND', provider);\n this.name = 'FolderNotFoundError';\n this.folder = folder;\n }\n}\n\nexport class FolderExistsError extends EmailError {\n folder: string;\n\n constructor(folder: string, provider?: string) {\n super(`Folder already exists: ${folder}`, 'FOLDER_EXISTS', provider);\n this.name = 'FolderExistsError';\n this.folder = folder;\n }\n}\n\n// ============================================================================\n// Send Errors\n// ============================================================================\n\nexport class SendError extends EmailError {\n accepted: string[];\n rejected: string[];\n\n constructor(\n message: string,\n accepted: string[],\n rejected: string[],\n provider?: string,\n cause?: unknown,\n ) {\n super(message, 'SEND_ERROR', provider, cause);\n this.name = 'SendError';\n this.accepted = accepted;\n this.rejected = rejected;\n }\n}\n\n// ============================================================================\n// Attachment Errors\n// ============================================================================\n\nexport class AttachmentError extends EmailError {\n filename?: string;\n\n constructor(\n message: string,\n filename?: string,\n provider?: string,\n cause?: unknown,\n ) {\n super(message, 'ATTACHMENT_ERROR', provider, cause);\n this.name = 'AttachmentError';\n this.filename = filename;\n }\n}\n","/**\n * Base email client adapter class\n */\n\nimport { createLogger, type Logger } from '@happyvertical/logger';\nimport { EmailError, InvalidMessageError } from './errors';\nimport type {\n AdapterType,\n EmailAddress,\n EmailClient,\n EmailClientCapabilities,\n EmailClientConfig,\n EmailMessage,\n FetchOptions,\n Folder,\n FolderInfo,\n SearchCriteria,\n SendOptions,\n SendResult,\n} from './types';\n\n/**\n * Base adapter class providing shared functionality\n *\n * All adapter implementations should extend this class.\n * This is a protocol-only base class - no database persistence.\n * For database sync and AI features, use @happyvertical/smrt-messages.\n */\nexport abstract class BaseEmailClient implements EmailClient {\n protected config: EmailClientConfig;\n protected logger: Logger;\n protected connected = false;\n\n constructor(config: EmailClientConfig) {\n this.config = this.validateConfig(config);\n this.logger = config.logger || createLogger({ level: 'info' });\n }\n\n // ========================================================================\n // Abstract methods that adapters must implement\n // ========================================================================\n\n abstract send(\n message: EmailMessage,\n options?: SendOptions,\n ): Promise<SendResult>;\n\n abstract fetch(options?: FetchOptions): Promise<EmailMessage[]>;\n\n abstract getMessage(messageId: string): Promise<EmailMessage>;\n\n abstract listFolders(): Promise<Folder[]>;\n\n abstract selectFolder(name: string): Promise<FolderInfo>;\n\n abstract createFolder(name: string): Promise<void>;\n\n abstract deleteFolder(name: string): Promise<void>;\n\n abstract markRead(messageId: string | string[]): Promise<void>;\n\n abstract markUnread(messageId: string | string[]): Promise<void>;\n\n abstract move(messageId: string | string[], folder: string): Promise<void>;\n\n abstract copy(messageId: string | string[], folder: string): Promise<void>;\n\n abstract delete(messageId: string | string[]): Promise<void>;\n\n abstract search(criteria: SearchCriteria): Promise<EmailMessage[]>;\n\n abstract connect(): Promise<void>;\n\n abstract disconnect(): Promise<void>;\n\n abstract getCapabilities(): Promise<EmailClientCapabilities>;\n\n abstract getAdapter(): AdapterType;\n\n // ========================================================================\n // Connection management\n // ========================================================================\n\n isConnected(): boolean {\n return this.connected;\n }\n\n // ========================================================================\n // Validation helpers\n // ========================================================================\n\n protected validateConfig(config: EmailClientConfig): EmailClientConfig {\n if (!config.type) {\n throw new EmailError('Email client type is required', 'INVALID_CONFIG');\n }\n\n return config;\n }\n\n protected validateEmail(email: EmailAddress): void {\n if (!email.address) {\n throw new InvalidMessageError(\n 'Email address is required',\n this.getAdapter(),\n );\n }\n\n // Basic email format validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email.address)) {\n throw new InvalidMessageError(\n `Invalid email address: ${email.address}`,\n this.getAdapter(),\n );\n }\n }\n\n protected validateMessage(message: EmailMessage): void {\n // Validate sender\n if (!message.from) {\n throw new InvalidMessageError(\n 'Message must have a sender (from)',\n this.getAdapter(),\n );\n }\n this.validateEmail(message.from);\n\n // Validate recipients\n if (!message.to || message.to.length === 0) {\n throw new InvalidMessageError(\n 'Message must have at least one recipient (to)',\n this.getAdapter(),\n );\n }\n for (const recipient of message.to) {\n this.validateEmail(recipient);\n }\n\n // Validate CC recipients\n if (message.cc) {\n for (const recipient of message.cc) {\n this.validateEmail(recipient);\n }\n }\n\n // Validate BCC recipients\n if (message.bcc) {\n for (const recipient of message.bcc) {\n this.validateEmail(recipient);\n }\n }\n\n // Validate subject\n if (!message.subject) {\n throw new InvalidMessageError(\n 'Message must have a subject',\n this.getAdapter(),\n );\n }\n\n // Validate content\n if (!message.text && !message.html) {\n throw new InvalidMessageError(\n 'Message must have either text or HTML content',\n this.getAdapter(),\n );\n }\n }\n\n // ========================================================================\n // Error mapping\n // ========================================================================\n\n protected mapError(error: unknown): EmailError {\n if (error instanceof EmailError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new EmailError(\n error.message,\n 'UNKNOWN_ERROR',\n this.getAdapter(),\n error,\n );\n }\n\n return new EmailError(String(error), 'UNKNOWN_ERROR', this.getAdapter());\n }\n\n // ========================================================================\n // Utility methods\n // ========================================================================\n\n protected normalizeMessageIds(messageId: string | string[]): string[] {\n return Array.isArray(messageId) ? messageId : [messageId];\n }\n\n protected debug(message: string, data?: unknown): void {\n if (this.config.debug) {\n this.logger.debug(message, data as Record<string, unknown> | undefined);\n }\n }\n}\n","/**\n * Gmail adapter using Gmail API with OAuth2\n */\n\nimport type { OAuth2Client } from 'google-auth-library';\nimport type { gmail_v1 } from 'googleapis';\nimport { google } from 'googleapis';\nimport { simpleParser } from 'mailparser';\nimport { BaseEmailClient } from '../shared/base';\nimport {\n AuthenticationError,\n ConnectionError,\n EmailError,\n FolderExistsError,\n FolderNotFoundError,\n MessageNotFoundError,\n SendError,\n TimeoutError,\n} from '../shared/errors';\nimport type {\n AdapterType,\n EmailClientCapabilities,\n EmailMessage,\n FetchOptions,\n Folder,\n FolderInfo,\n GmailOptions,\n SearchCriteria,\n SendOptions,\n SendResult,\n} from '../shared/types';\n\n/**\n * Gmail adapter implementation using Gmail API\n *\n * Requires OAuth2 credentials with appropriate scopes:\n * - gmail.readonly: Read emails and settings\n * - gmail.send: Send emails\n * - gmail.modify: Modify emails (mark read, delete, move)\n * - gmail.labels: Manage labels\n */\nexport class GmailAdapter extends BaseEmailClient {\n private gmail: gmail_v1.Gmail | null = null;\n private options: GmailOptions;\n private auth: OAuth2Client | null = null;\n\n constructor(options: GmailOptions) {\n super({\n type: 'gmail',\n debug: options.debug,\n });\n this.options = options;\n }\n\n // ========================================================================\n // Connection management\n // ========================================================================\n\n async connect(): Promise<void> {\n try {\n // Create OAuth2 client\n const auth = new google.auth.OAuth2(\n this.options.auth.clientId,\n this.options.auth.clientSecret,\n );\n auth.setCredentials({\n refresh_token: this.options.auth.refreshToken,\n access_token: this.options.auth.accessToken,\n });\n\n this.auth = auth as unknown as OAuth2Client;\n\n // Create Gmail API client\n this.gmail = google.gmail({ version: 'v1', auth });\n\n // Test connection by getting profile\n await this.gmail.users.getProfile({ userId: this.getUserId() });\n\n this.connected = true;\n this.debug('Connected to Gmail API');\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n async disconnect(): Promise<void> {\n this.gmail = null;\n this.auth = null;\n this.connected = false;\n this.debug('Disconnected from Gmail API');\n }\n\n // ========================================================================\n // Send operations\n // ========================================================================\n\n async send(\n message: EmailMessage,\n options?: SendOptions,\n ): Promise<SendResult> {\n this.ensureConnected();\n this.validateMessage(message);\n\n try {\n // Build RFC 2822 formatted email\n const email = this.buildRFC2822Message(message, options);\n\n // Encode email in base64url format\n const encodedEmail = Buffer.from(email)\n .toString('base64')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n\n // Send message\n const response = await this.gmail?.users.messages.send({\n userId: this.getUserId(),\n requestBody: {\n raw: encodedEmail,\n },\n });\n\n if (!response) {\n throw new SendError('Failed to send message', [], [], 'gmail');\n }\n\n return {\n messageId: response.data.id || '',\n accepted: message.to.map((addr) => addr.address),\n rejected: [],\n response: `Message sent: ${response.data.id}`,\n };\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n // ========================================================================\n // Receive operations\n // ========================================================================\n\n async fetch(options?: FetchOptions): Promise<EmailMessage[]> {\n this.ensureConnected();\n\n try {\n // Build query\n const query = this.buildGmailQuery(options);\n\n // Handle folder option - convert to labelIds\n let labelIds = options?.labelIds;\n if (options?.folder && !labelIds) {\n // If folder is provided, use it as labelId\n labelIds = [options.folder];\n }\n\n // List messages\n let listResponse;\n try {\n listResponse = await this.gmail?.users.messages.list({\n userId: this.getUserId(),\n q: query,\n labelIds,\n maxResults: options?.maxResults || options?.limit || 100,\n });\n } catch (error) {\n // Gmail throws error for invalid labels - return empty array instead\n if (error instanceof Error && error.message.includes('Invalid label')) {\n return [];\n }\n throw error;\n }\n\n if (!listResponse) {\n return [];\n }\n\n const messageIds = listResponse.data.messages || [];\n\n if (messageIds.length === 0) {\n return [];\n }\n\n // Fetch full message details\n const messages: EmailMessage[] = [];\n for (const msgId of messageIds) {\n if (!msgId.id) continue;\n\n try {\n const message = await this.getMessage(msgId.id);\n messages.push(message);\n\n // Apply limit\n if (options?.limit && messages.length >= options.limit) {\n break;\n }\n } catch (error) {\n this.logger.error(`Failed to fetch message ${msgId.id}:`, {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return messages;\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n async getMessage(messageId: string): Promise<EmailMessage> {\n this.ensureConnected();\n\n try {\n const response = await this.gmail?.users.messages.get({\n userId: this.getUserId(),\n id: messageId,\n format: 'raw',\n });\n\n if (!response || !response.data.raw) {\n throw new MessageNotFoundError(messageId, 'gmail');\n }\n\n // Decode raw message\n const rawMessage = Buffer.from(response.data.raw, 'base64').toString(\n 'utf-8',\n );\n\n // Parse message\n const parsed = await simpleParser(rawMessage);\n\n // Get labels\n const labels = response.data.labelIds || [];\n\n // Helper to extract addresses from AddressObject\n const extractAddresses = (\n addressObj:\n | import('mailparser').AddressObject\n | import('mailparser').AddressObject[]\n | undefined,\n ) => {\n if (!addressObj) return [];\n // Handle array of AddressObjects\n const addressArray = Array.isArray(addressObj)\n ? addressObj\n : [addressObj];\n const addresses = addressArray.flatMap((obj) =>\n Array.isArray(obj.value) ? obj.value : [obj.value],\n );\n return addresses.map((addr: { address?: string; name?: string }) => ({\n address: addr.address || '',\n name: addr.name,\n }));\n };\n\n const fromAddresses = extractAddresses(parsed.from);\n const toAddresses = extractAddresses(parsed.to);\n const ccAddresses = extractAddresses(parsed.cc);\n const bccAddresses = extractAddresses(parsed.bcc);\n const replyToAddresses = extractAddresses(parsed.replyTo);\n\n return {\n id: response.data.id || undefined,\n messageId: parsed.messageId || response.data.id || undefined,\n threadId: response.data.threadId || undefined,\n inReplyTo: parsed.inReplyTo,\n references: parsed.references\n ? Array.isArray(parsed.references)\n ? parsed.references\n : [parsed.references]\n : undefined,\n from: fromAddresses[0] || { address: '', name: undefined },\n to: toAddresses,\n cc: ccAddresses.length > 0 ? ccAddresses : undefined,\n bcc: bccAddresses.length > 0 ? bccAddresses : undefined,\n replyTo: replyToAddresses[0],\n subject: parsed.subject || '',\n date: parsed.date,\n text: parsed.text,\n html: parsed.html ? parsed.html.toString() : undefined,\n attachments: parsed.attachments?.map((att) => ({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content: att.content,\n contentId: att.contentId,\n contentDisposition: att.contentDisposition as 'attachment' | 'inline',\n })),\n labels,\n headers: parsed.headers as unknown as Record<string, string | string[]>,\n size: Number(response.data.sizeEstimate),\n raw: rawMessage,\n };\n } catch (error) {\n if (error instanceof MessageNotFoundError) {\n throw error;\n }\n throw this.mapGmailError(error);\n }\n }\n\n // ========================================================================\n // Label operations (Gmail uses labels instead of folders)\n // ========================================================================\n\n async listFolders(): Promise<Folder[]> {\n this.ensureConnected();\n\n try {\n const response = await this.gmail?.users.labels.list({\n userId: this.getUserId(),\n });\n\n if (!response) {\n return [];\n }\n\n const labels = response.data.labels || [];\n\n return labels.map((label) => ({\n name: label.name || '',\n path: label.id || '',\n delimiter: '/',\n specialUse: this.mapGmailLabelToSpecialUse(label.type),\n messageCount: label.messagesTotal || undefined,\n unreadCount: label.messagesUnread || undefined,\n }));\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n async selectFolder(name: string): Promise<FolderInfo> {\n this.ensureConnected();\n\n try {\n // Find label by name or ID\n const labels = await this.listFolders();\n const label = labels.find((l) => l.name === name || l.path === name);\n\n if (!label) {\n throw new FolderNotFoundError(name, 'gmail');\n }\n\n return {\n name: label.name,\n exists: label.messageCount || 0,\n recent: 0,\n unseen: label.unreadCount || 0,\n uidValidity: 0,\n uidNext: 0,\n flags: [],\n permanentFlags: [],\n };\n } catch (error) {\n if (error instanceof FolderNotFoundError) {\n throw error;\n }\n throw this.mapGmailError(error);\n }\n }\n\n async createFolder(name: string): Promise<void> {\n this.ensureConnected();\n\n try {\n // Check if label already exists\n const labels = await this.listFolders();\n if (labels.some((l) => l.name === name)) {\n throw new FolderExistsError(name, 'gmail');\n }\n\n await this.gmail?.users.labels.create({\n userId: this.getUserId(),\n requestBody: {\n name,\n labelListVisibility: 'labelShow',\n messageListVisibility: 'show',\n },\n });\n } catch (error) {\n if (error instanceof FolderExistsError) {\n throw error;\n }\n throw this.mapGmailError(error);\n }\n }\n\n async deleteFolder(name: string): Promise<void> {\n this.ensureConnected();\n\n try {\n // Find label by name\n const labels = await this.listFolders();\n const label = labels.find((l) => l.name === name);\n\n if (!label) {\n throw new FolderNotFoundError(name, 'gmail');\n }\n\n // Can't delete system labels\n if (label.specialUse) {\n throw new EmailError(\n `Cannot delete system label: ${name}`,\n 'INVALID_OPERATION',\n 'gmail',\n );\n }\n\n await this.gmail?.users.labels.delete({\n userId: this.getUserId(),\n id: label.path,\n });\n } catch (error) {\n if (error instanceof FolderNotFoundError || error instanceof EmailError) {\n throw error;\n }\n throw this.mapGmailError(error);\n }\n }\n\n // ========================================================================\n // Message operations\n // ========================================================================\n\n async markRead(messageId: string | string[]): Promise<void> {\n this.ensureConnected();\n\n const ids = this.normalizeMessageIds(messageId);\n\n try {\n for (const id of ids) {\n await this.gmail?.users.messages.modify({\n userId: this.getUserId(),\n id,\n requestBody: {\n removeLabelIds: ['UNREAD'],\n },\n });\n }\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n async markUnread(messageId: string | string[]): Promise<void> {\n this.ensureConnected();\n\n const ids = this.normalizeMessageIds(messageId);\n\n try {\n for (const id of ids) {\n await this.gmail?.users.messages.modify({\n userId: this.getUserId(),\n id,\n requestBody: {\n addLabelIds: ['UNREAD'],\n },\n });\n }\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n async move(messageId: string | string[], folder: string): Promise<void> {\n this.ensureConnected();\n\n const ids = this.normalizeMessageIds(messageId);\n\n try {\n // Find label ID\n const labels = await this.listFolders();\n const label = labels.find((l) => l.name === folder || l.path === folder);\n\n if (!label) {\n throw new FolderNotFoundError(folder, 'gmail');\n }\n\n for (const id of ids) {\n await this.gmail?.users.messages.modify({\n userId: this.getUserId(),\n id,\n requestBody: {\n addLabelIds: [label.path],\n },\n });\n }\n } catch (error) {\n if (error instanceof FolderNotFoundError) {\n throw error;\n }\n throw this.mapGmailError(error);\n }\n }\n\n async copy(messageId: string | string[], folder: string): Promise<void> {\n // Gmail doesn't support copying messages directly\n // Move is more appropriate since messages can have multiple labels\n await this.move(messageId, folder);\n }\n\n async delete(messageId: string | string[]): Promise<void> {\n this.ensureConnected();\n\n const ids = this.normalizeMessageIds(messageId);\n\n try {\n for (const id of ids) {\n // Move to trash instead of permanent delete\n await this.gmail?.users.messages.trash({\n userId: this.getUserId(),\n id,\n });\n }\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n // ========================================================================\n // Search\n // ========================================================================\n\n async search(criteria: SearchCriteria): Promise<EmailMessage[]> {\n this.ensureConnected();\n\n try {\n // Use Gmail's search query if provided\n if (criteria.q) {\n return await this.fetch({ q: criteria.q });\n }\n\n // Build Gmail query from criteria\n const queryParts: string[] = [];\n\n if (criteria.from) queryParts.push(`from:${criteria.from}`);\n if (criteria.to) queryParts.push(`to:${criteria.to}`);\n if (criteria.subject) queryParts.push(`subject:${criteria.subject}`);\n if (criteria.body) queryParts.push(criteria.body);\n\n if (criteria.since) {\n queryParts.push(`after:${this.formatGmailDate(criteria.since)}`);\n }\n if (criteria.before) {\n queryParts.push(`before:${this.formatGmailDate(criteria.before)}`);\n }\n\n if (criteria.unread === true) queryParts.push('is:unread');\n if (criteria.unread === false) queryParts.push('is:read');\n if (criteria.flagged) queryParts.push('is:starred');\n\n if (criteria.larger) queryParts.push(`larger:${criteria.larger}`);\n if (criteria.smaller) queryParts.push(`smaller:${criteria.smaller}`);\n\n const query = queryParts.join(' ');\n\n return await this.fetch({ q: query });\n } catch (error) {\n throw this.mapGmailError(error);\n }\n }\n\n // ========================================================================\n // Adapter info\n // ========================================================================\n\n async getCapabilities(): Promise<EmailClientCapabilities> {\n return {\n send: true,\n receive: true,\n folders: true,\n search: true,\n markRead: true,\n move: true,\n delete: true,\n threads: true,\n oauth: true,\n };\n }\n\n getAdapter(): AdapterType {\n return 'gmail';\n }\n\n // ========================================================================\n // Private helper methods\n // ========================================================================\n\n private ensureConnected(): void {\n if (!this.connected || !this.gmail) {\n throw new ConnectionError(\n 'Not connected to Gmail. Call connect() first.',\n 'gmail',\n );\n }\n }\n\n private getUserId(): string {\n return this.options.userId || 'me';\n }\n\n private buildRFC2822Message(\n message: EmailMessage,\n options?: SendOptions,\n ): string {\n const lines: string[] = [];\n const hasAttachments =\n message.attachments && message.attachments.length > 0;\n\n // Headers\n lines.push(`From: ${this.formatEmailAddress(message.from)}`);\n lines.push(\n `To: ${message.to.map((a) => this.formatEmailAddress(a)).join(', ')}`,\n );\n\n if (message.cc && message.cc.length > 0) {\n lines.push(\n `Cc: ${message.cc.map((a) => this.formatEmailAddress(a)).join(', ')}`,\n );\n }\n\n if (message.replyTo) {\n lines.push(`Reply-To: ${this.formatEmailAddress(message.replyTo)}`);\n }\n\n lines.push(`Subject: ${message.subject}`);\n lines.push(\n `Date: ${options?.date?.toUTCString() || new Date().toUTCString()}`,\n );\n\n if (options?.messageId) {\n lines.push(`Message-ID: <${options.messageId}>`);\n }\n\n lines.push('MIME-Version: 1.0');\n\n // If there are attachments, use multipart/mixed\n if (hasAttachments) {\n lines.push('Content-Type: multipart/mixed; boundary=\"mixed-boundary\"');\n lines.push('');\n lines.push('--mixed-boundary');\n\n // Message body (text/html alternative)\n if (message.html) {\n lines.push(\n 'Content-Type: multipart/alternative; boundary=\"alt-boundary\"',\n );\n lines.push('');\n lines.push('--alt-boundary');\n lines.push('Content-Type: text/plain; charset=\"UTF-8\"');\n lines.push('Content-Transfer-Encoding: 7bit');\n lines.push('');\n lines.push(message.text || '');\n lines.push('');\n lines.push('--alt-boundary');\n lines.push('Content-Type: text/html; charset=\"UTF-8\"');\n lines.push('Content-Transfer-Encoding: 7bit');\n lines.push('');\n lines.push(message.html);\n lines.push('');\n lines.push('--alt-boundary--');\n } else {\n lines.push('Content-Type: text/plain; charset=\"UTF-8\"');\n lines.push('Content-Transfer-Encoding: 7bit');\n lines.push('');\n lines.push(message.text || '');\n }\n\n // Attachments\n if (message.attachments) {\n for (const attachment of message.attachments) {\n lines.push('');\n lines.push('--mixed-boundary');\n lines.push(\n `Content-Type: ${attachment.contentType}; name=\"${attachment.filename}\"`,\n );\n lines.push('Content-Transfer-Encoding: base64');\n lines.push(\n `Content-Disposition: ${attachment.contentDisposition || 'attachment'}; filename=\"${attachment.filename}\"`,\n );\n if (attachment.contentId) {\n lines.push(`Content-ID: <${attachment.contentId}>`);\n }\n lines.push('');\n\n // Encode attachment content as base64\n const content = attachment.content || Buffer.from('');\n const base64Content = content.toString('base64');\n\n // Split base64 into 76-character lines (RFC 2045)\n const base64Lines = base64Content.match(/.{1,76}/g) || [];\n lines.push(...base64Lines);\n }\n }\n\n lines.push('');\n lines.push('--mixed-boundary--');\n } else {\n // No attachments - simple message\n if (message.html) {\n lines.push(\n 'Content-Type: multipart/alternative; boundary=\"alt-boundary\"',\n );\n lines.push('');\n lines.push('--alt-boundary');\n lines.push('Content-Type: text/plain; charset=\"UTF-8\"');\n lines.push('Content-Transfer-Encoding: 7bit');\n lines.push('');\n lines.push(message.text || '');\n lines.push('');\n lines.push('--alt-boundary');\n lines.push('Content-Type: text/html; charset=\"UTF-8\"');\n lines.push('Content-Transfer-Encoding: 7bit');\n lines.push('');\n lines.push(message.html);\n lines.push('');\n lines.push('--alt-boundary--');\n } else {\n lines.push('Content-Type: text/plain; charset=\"UTF-8\"');\n lines.push('Content-Transfer-Encoding: 7bit');\n lines.push('');\n lines.push(message.text || '');\n }\n }\n\n return lines.join('\\r\\n');\n }\n\n private formatEmailAddress(addr: { address: string; name?: string }): string {\n if (addr.name) {\n return `${addr.name} <${addr.address}>`;\n }\n return addr.address;\n }\n\n private buildGmailQuery(options?: FetchOptions): string {\n const queryParts: string[] = [];\n\n // Use provided query if available\n if (options?.q) {\n return options.q;\n }\n\n // Date filters\n if (options?.since) {\n queryParts.push(`after:${this.formatGmailDate(options.since)}`);\n }\n if (options?.before) {\n queryParts.push(`before:${this.formatGmailDate(options.before)}`);\n }\n\n // Unread filter\n if (options?.unreadOnly) {\n queryParts.push('is:unread');\n }\n\n return queryParts.join(' ');\n }\n\n private formatGmailDate(date: Date): string {\n // Format: YYYY/MM/DD\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}/${month}/${day}`;\n }\n\n private mapGmailLabelToSpecialUse(\n type?: string | null,\n ):\n | '\\\\Inbox'\n | '\\\\Sent'\n | '\\\\Drafts'\n | '\\\\Trash'\n | '\\\\Junk'\n | '\\\\Archive'\n | '\\\\All'\n | undefined {\n switch (type) {\n case 'system':\n return '\\\\Inbox';\n default:\n return undefined;\n }\n }\n\n private mapGmailError(error: unknown): EmailError {\n if (error instanceof EmailError) {\n return error;\n }\n\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const errorObj = error as unknown as Record<string, unknown>;\n\n // Timeout errors\n if (\n message.includes('timeout') ||\n errorObj.code === 'ETIMEDOUT' ||\n errorObj.code === 'ESOCKETTIMEDOUT'\n ) {\n return new TimeoutError(error.message, 'gmail', error);\n }\n\n // Connection errors\n if (\n message.includes('network') ||\n message.includes('connect') ||\n errorObj.code === 'ECONNREFUSED' ||\n errorObj.code === 'ENOTFOUND' ||\n errorObj.code === 'ECONNRESET'\n ) {\n return new ConnectionError(error.message, 'gmail', error);\n }\n\n // Authentication errors\n if (\n message.includes('auth') ||\n message.includes('invalid_grant') ||\n message.includes('unauthorized') ||\n errorObj.code === 401\n ) {\n return new AuthenticationError(error.message, 'gmail', error);\n }\n\n // Send errors\n if (message.includes('recipient') || message.includes('invalid email')) {\n return new SendError(error.message, [], [], 'gmail', error);\n }\n\n return new EmailError(error.message, 'GMAIL_ERROR', 'gmail', error);\n }\n\n return new EmailError(String(error), 'GMAIL_ERROR', 'gmail');\n }\n}\n","/**\n * IMAP adapter implementation using ImapFlow\n */\n\nimport type { ImapFlowOptions } from 'imapflow';\nimport { ImapFlow } from 'imapflow';\nimport { simpleParser } from 'mailparser';\nimport { BaseEmailClient } from '../shared/base';\nimport {\n AuthenticationError,\n ConnectionError,\n EmailError,\n FolderExistsError,\n FolderNotFoundError,\n MessageNotFoundError,\n TimeoutError,\n} from '../shared/errors';\nimport type {\n AdapterType,\n EmailClientCapabilities,\n EmailMessage,\n FetchOptions,\n Folder,\n FolderInfo,\n IMAPOptions,\n SearchCriteria,\n SendOptions,\n SendResult,\n} from '../shared/types';\n\n/**\n * IMAP adapter for receiving email via IMAP protocol\n *\n * Uses ImapFlow for robust IMAP operations including:\n * - Fetch messages with various filters\n * - Folder management (list, create, delete, rename)\n * - Message operations (mark read, move, copy, delete)\n * - Search functionality\n * - OAuth2 authentication\n * - IDLE push notifications (optional)\n */\nexport class IMAPAdapter extends BaseEmailClient {\n private client: ImapFlow | null = null;\n private options: IMAPOptions;\n private currentFolder: string | null = null;\n\n constructor(options: IMAPOptions) {\n super({\n type: 'imap',\n debug: options.debug,\n });\n\n this.options = options;\n }\n\n /**\n * Create ImapFlow client\n */\n private createClient(): ImapFlow {\n const config: ImapFlowOptions = {\n host: this.options.host,\n port: this.options.port,\n secure: this.options.secure ?? true,\n auth: this.options.auth,\n tls: this.options.tls as ImapFlowOptions['tls'],\n logger: this.options.debug\n ? {\n debug: (msg: string) => this.debug(msg),\n info: (msg: string) => this.debug(msg),\n warn: (msg: string) => this.debug(`WARN: ${msg}`),\n error: (msg: string) => this.debug(`ERROR: ${msg}`),\n }\n : false,\n };\n\n return new ImapFlow(config);\n }\n\n getAdapter(): AdapterType {\n return 'imap';\n }\n\n /**\n * Helper to convert search results to array\n */\n private searchResultToArray(result: false | number[] | undefined): number[] {\n if (!result || !Array.isArray(result)) {\n return [];\n }\n return result;\n }\n\n /**\n * Connect to IMAP server\n */\n async connect(): Promise<void> {\n try {\n this.debug('Connecting to IMAP server', { host: this.options.host });\n this.client = this.createClient();\n await this.client.connect();\n this.connected = true;\n this.debug('IMAP connection established');\n } catch (error) {\n this.connected = false;\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Disconnect from IMAP server\n */\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.logout();\n this.client = null;\n this.connected = false;\n this.currentFolder = null;\n this.debug('IMAP connection closed');\n }\n }\n\n /**\n * Fetch messages with filters\n */\n async fetch(options?: FetchOptions): Promise<EmailMessage[]> {\n this.ensureConnected();\n\n const folder = options?.folder || 'INBOX';\n await this.selectFolder(folder);\n\n try {\n // Build IMAP search criteria\n const searchQuery = this.buildSearchQuery(options);\n\n this.debug('Fetching messages', { folder, query: searchQuery });\n\n // Search for message UIDs\n const searchResult = await this.client!.search(searchQuery, {\n uid: true,\n });\n\n // Handle false or empty results\n const uids = this.searchResultToArray(searchResult);\n\n // Apply limit/offset\n let targetUids = uids;\n if (options?.offset || options?.limit) {\n const start = options.offset || 0;\n const end = options.limit ? start + options.limit : undefined;\n targetUids = uids.slice(start, end);\n }\n\n if (targetUids.length === 0) {\n return [];\n }\n\n // Fetch message data\n const messages: EmailMessage[] = [];\n for await (const msg of this.client!.fetch(targetUids, {\n source: true,\n flags: true,\n uid: true,\n envelope: true,\n bodyStructure: true,\n })) {\n try {\n if (!msg.source) {\n this.debug('Message has no source', { uid: msg.uid });\n continue;\n }\n const parsed = await simpleParser(msg.source);\n const email = this.parseMessage(parsed, msg);\n messages.push(email);\n\n // Mark as seen if requested\n if (options?.markSeen) {\n await this.client!.messageFlagsAdd(msg.uid, ['\\\\Seen'], {\n uid: true,\n });\n }\n } catch (parseError) {\n this.debug('Failed to parse message', { uid: msg.uid, parseError });\n }\n }\n\n return messages;\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Get a specific message by ID\n */\n async getMessage(messageId: string): Promise<EmailMessage> {\n this.ensureConnected();\n\n try {\n // Search for message by Message-ID header\n // biome-ignore lint/suspicious/noExplicitAny: ImapFlow search types don't match exactly\n const searchResult = await this.client!.search(\n { header: ['message-id', messageId] } as any,\n { uid: true },\n );\n\n // Handle false or empty results\n const uids = this.searchResultToArray(searchResult);\n\n if (uids.length === 0) {\n throw new MessageNotFoundError(messageId, 'imap');\n }\n\n // Fetch the message\n const messages: EmailMessage[] = [];\n for await (const msg of this.client!.fetch(uids[0], {\n source: true,\n flags: true,\n uid: true,\n })) {\n if (!msg.source) {\n continue;\n }\n const parsed = await simpleParser(msg.source);\n messages.push(this.parseMessage(parsed, msg));\n }\n\n if (messages.length === 0) {\n throw new MessageNotFoundError(messageId, 'imap');\n }\n\n return messages[0];\n } catch (error) {\n if (error instanceof EmailError) {\n throw error;\n }\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * List all folders\n */\n async listFolders(): Promise<Folder[]> {\n this.ensureConnected();\n\n try {\n const list = await this.client?.list();\n\n if (!list) {\n return [];\n }\n\n return list.map((folder) => ({\n name: folder.name,\n path: folder.path,\n delimiter: folder.delimiter,\n specialUse: folder.specialUse as Folder['specialUse'],\n subscribed: folder.subscribed,\n }));\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Select a folder\n */\n async selectFolder(name: string): Promise<FolderInfo> {\n this.ensureConnected();\n\n try {\n const mailbox = await this.client?.mailboxOpen(name);\n this.currentFolder = name;\n\n if (!mailbox) {\n throw new FolderNotFoundError(name, 'imap');\n }\n\n return {\n name,\n exists: Number(mailbox.exists),\n recent: 0, // ImapFlow doesn't provide this\n unseen: 0, // Would need separate STATUS command\n uidValidity: Number(mailbox.uidValidity),\n uidNext: Number(mailbox.uidNext),\n flags: Array.from(mailbox.flags || []),\n permanentFlags: Array.from(mailbox.permanentFlags || []),\n };\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.toLowerCase().includes('does not exist')\n ) {\n throw new FolderNotFoundError(name, 'imap');\n }\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Create a new folder\n */\n async createFolder(name: string): Promise<void> {\n this.ensureConnected();\n\n try {\n await this.client?.mailboxCreate(name);\n this.debug('Folder created', { name });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.toLowerCase().includes('already exists')\n ) {\n throw new FolderExistsError(name, 'imap');\n }\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Delete a folder\n */\n async deleteFolder(name: string): Promise<void> {\n this.ensureConnected();\n\n try {\n await this.client?.mailboxDelete(name);\n this.debug('Folder deleted', { name });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.toLowerCase().includes('does not exist')\n ) {\n throw new FolderNotFoundError(name, 'imap');\n }\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Mark message(s) as read\n */\n async markRead(messageId: string | string[]): Promise<void> {\n this.ensureConnected();\n\n const ids = Array.isArray(messageId) ? messageId : [messageId];\n\n try {\n for (const id of ids) {\n // biome-ignore lint/suspicious/noExplicitAny: ImapFlow search types don't match exactly\n const searchResult = await this.client?.search(\n { header: ['message-id', id] } as any,\n { uid: true },\n );\n const uids = this.searchResultToArray(searchResult);\n if (uids.length > 0) {\n await this.client?.messageFlagsAdd(uids[0], ['\\\\Seen'], {\n uid: true,\n });\n }\n }\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Mark message(s) as unread\n */\n async markUnread(messageId: string | string[]): Promise<void> {\n this.ensureConnected();\n\n const ids = Array.isArray(messageId) ? messageId : [messageId];\n\n try {\n for (const id of ids) {\n // biome-ignore lint/suspicious/noExplicitAny: ImapFlow search types don't match exactly\n const searchResult = await this.client?.search(\n { header: ['message-id', id] } as any,\n { uid: true },\n );\n const uids = this.searchResultToArray(searchResult);\n if (uids.length > 0) {\n await this.client?.messageFlagsRemove(uids[0], ['\\\\Seen'], {\n uid: true,\n });\n }\n }\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Move message(s) to another folder\n */\n async move(messageId: string | string[], folder: string): Promise<void> {\n this.ensureConnected();\n\n const ids = Array.isArray(messageId) ? messageId : [messageId];\n\n try {\n for (const id of ids) {\n // biome-ignore lint/suspicious/noExplicitAny: ImapFlow search types don't match exactly\n const searchResult = await this.client?.search(\n { header: ['message-id', id] } as any,\n { uid: true },\n );\n const uids = this.searchResultToArray(searchResult);\n if (uids.length > 0) {\n await this.client?.messageMove(uids[0], folder, { uid: true });\n }\n }\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Copy message(s) to another folder\n */\n async copy(messageId: string | string[], folder: string): Promise<void> {\n this.ensureConnected();\n\n const ids = Array.isArray(messageId) ? messageId : [messageId];\n\n try {\n for (const id of ids) {\n // biome-ignore lint/suspicious/noExplicitAny: ImapFlow search types don't match exactly\n const searchResult = await this.client?.search(\n { header: ['message-id', id] } as any,\n { uid: true },\n );\n const uids = this.searchResultToArray(searchResult);\n if (uids.length > 0) {\n await this.client?.messageCopy(uids[0], folder, { uid: true });\n }\n }\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Delete message(s)\n */\n async delete(messageId: string | string[]): Promise<void> {\n this.ensureConnected();\n\n const ids = Array.isArray(messageId) ? messageId : [messageId];\n\n try {\n for (const id of ids) {\n // biome-ignore lint/suspicious/noExplicitAny: ImapFlow search types don't match exactly\n const searchResult = await this.client?.search(\n { header: ['message-id', id] } as any,\n { uid: true },\n );\n const uids = this.searchResultToArray(searchResult);\n if (uids.length > 0) {\n await this.client?.messageFlagsAdd(uids[0], ['\\\\Deleted'], {\n uid: true,\n });\n }\n }\n // Note: expunge() is not available in ImapFlow - messages are deleted when flags are set\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Search messages\n */\n async search(criteria: SearchCriteria): Promise<EmailMessage[]> {\n this.ensureConnected();\n\n try {\n const query = this.buildSearchCriteria(criteria);\n const searchResult = await this.client!.search(query, { uid: true });\n const uids = this.searchResultToArray(searchResult);\n\n if (uids.length === 0) {\n return [];\n }\n\n // Fetch matching messages\n const messages: EmailMessage[] = [];\n for await (const msg of this.client!.fetch(uids, {\n source: true,\n flags: true,\n uid: true,\n })) {\n if (!msg.source) {\n continue;\n }\n const parsed = await simpleParser(msg.source);\n messages.push(this.parseMessage(parsed, msg));\n }\n\n return messages;\n } catch (error) {\n throw this.mapIMAPError(error);\n }\n }\n\n /**\n * Get adapter capabilities\n */\n async getCapabilities(): Promise<EmailClientCapabilities> {\n return {\n send: false, // IMAP is receive-only\n receive: true,\n folders: true,\n search: true,\n markRead: true,\n move: true,\n delete: true,\n threads: false, // Thread support not implemented yet\n oauth: this.isOAuth2(),\n };\n }\n\n /**\n * Check if using OAuth2 authentication\n */\n private isOAuth2(): boolean {\n return (\n this.options.auth !== undefined &&\n 'type' in this.options.auth &&\n this.options.auth.type === 'OAuth2'\n );\n }\n\n // ========================================================================\n // Unsupported operations (IMAP is receive-only)\n // ========================================================================\n\n async send(\n _message: EmailMessage,\n _options?: SendOptions,\n ): Promise<SendResult> {\n throw new EmailError(\n 'IMAP does not support sending messages. Use SMTP adapter.',\n 'UNSUPPORTED_OPERATION',\n 'imap',\n );\n }\n\n // ========================================================================\n // Helper methods\n // ========================================================================\n\n /**\n * Ensure client is connected\n */\n private ensureConnected(): void {\n if (!this.client || !this.connected) {\n throw new ConnectionError(\n 'Not connected to IMAP server. Call connect() first.',\n 'imap',\n );\n }\n }\n\n /**\n * Build IMAP search query from FetchOptions\n */\n private buildSearchQuery(options?: FetchOptions): Record<string, unknown> {\n const query: Record<string, unknown> = {};\n\n if (options?.unreadOnly) {\n query.unseen = true;\n }\n\n if (options?.since) {\n query.since = options.since;\n }\n\n if (options?.before) {\n query.before = options.before;\n }\n\n // If no criteria, return all messages\n if (Object.keys(query).length === 0) {\n query.all = true;\n }\n\n return query;\n }\n\n /**\n * Build IMAP search criteria from SearchCriteria\n */\n private buildSearchCriteria(\n criteria: SearchCriteria,\n ): Record<string, unknown> {\n const query: Record<string, unknown> = {};\n\n if (criteria.from) {\n query.from = criteria.from;\n }\n\n if (criteria.to) {\n query.to = criteria.to;\n }\n\n if (criteria.subject) {\n query.subject = criteria.subject;\n }\n\n if (criteria.body) {\n query.body = criteria.body;\n }\n\n if (criteria.since) {\n query.since = criteria.since;\n }\n\n if (criteria.before) {\n query.before = criteria.before;\n }\n\n if (criteria.unread) {\n query.unseen = true;\n }\n\n if (criteria.flagged) {\n query.flagged = true;\n }\n\n if (criteria.answered) {\n query.answered = true;\n }\n\n if (criteria.draft) {\n query.draft = true;\n }\n\n if (criteria.deleted) {\n query.deleted = true;\n }\n\n if (criteria.larger) {\n query.larger = criteria.larger;\n }\n\n if (criteria.smaller) {\n query.smaller = criteria.smaller;\n }\n\n if (criteria.header) {\n query.header = Object.entries(criteria.header).map(([key, value]) => [\n key,\n value,\n ]);\n }\n\n // If no criteria, return all messages\n if (Object.keys(query).length === 0) {\n query.all = true;\n }\n\n return query;\n }\n\n /**\n * Parse mailparser output to EmailMessage\n */\n private parseMessage(\n parsed: Awaited<ReturnType<typeof simpleParser>>,\n msg: { uid: number; flags?: Set<string> },\n ): EmailMessage {\n // Helper to extract addresses from AddressObject\n const extractAddresses = (\n addressObj:\n | import('mailparser').AddressObject\n | import('mailparser').AddressObject[]\n | undefined,\n ) => {\n if (!addressObj) return [];\n // Handle array of AddressObjects\n const addressArray = Array.isArray(addressObj)\n ? addressObj\n : [addressObj];\n const addresses = addressArray.flatMap((obj) =>\n Array.isArray(obj.value) ? obj.value : [obj.value],\n );\n return addresses.map((addr: { address?: string; name?: string }) => ({\n address: addr.address || '',\n name: addr.name,\n }));\n };\n\n const fromAddresses = extractAddresses(parsed.from);\n const toAddresses = extractAddresses(parsed.to);\n const ccAddresses = extractAddresses(parsed.cc);\n const bccAddresses = extractAddresses(parsed.bcc);\n const replyToAddresses = extractAddresses(parsed.replyTo);\n\n return {\n id: String(msg.uid),\n messageId: parsed.messageId || undefined,\n from: fromAddresses[0] || { address: '', name: undefined },\n to: toAddresses,\n cc: ccAddresses.length > 0 ? ccAddresses : undefined,\n bcc: bccAddresses.length > 0 ? bccAddresses : undefined,\n replyTo: replyToAddresses[0],\n subject: parsed.subject || '',\n date: parsed.date,\n text: parsed.text,\n html: parsed.html ? String(parsed.html) : undefined,\n attachments: parsed.attachments?.map((att) => ({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content: att.content,\n contentId: att.contentId,\n contentDisposition: att.contentDisposition as 'attachment' | 'inline',\n })),\n flags: msg.flags\n ? (Array.from(msg.flags) as EmailMessage['flags'])\n : undefined,\n inReplyTo: parsed.inReplyTo,\n references: Array.isArray(parsed.references)\n ? parsed.references\n : parsed.references\n ? [parsed.references]\n : undefined,\n headers: parsed.headers\n ? (Object.fromEntries(\n Array.from(parsed.headers.entries()).map(([key, value]) => [\n key,\n Array.isArray(value) ? value : String(value),\n ]),\n ) as Record<string, string | string[]>)\n : undefined,\n };\n }\n\n /**\n * Map ImapFlow errors to standard error types\n */\n private mapIMAPError(error: unknown): EmailError {\n if (error instanceof EmailError) {\n return error;\n }\n\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n\n // Authentication errors\n if (\n message.includes('authentication') ||\n message.includes('auth') ||\n message.includes('login') ||\n message.includes('invalid credentials')\n ) {\n return new AuthenticationError(error.message, 'imap', error);\n }\n\n // Timeout errors\n if (message.includes('timeout') || message.includes('etimedout')) {\n return new TimeoutError(error.message, 'imap', error);\n }\n\n // Connection errors\n if (\n message.includes('econnrefused') ||\n message.includes('enotfound') ||\n message.includes('connection') ||\n message.includes('ehostunreach') ||\n message.includes('network')\n ) {\n return new ConnectionError(error.message, 'imap', error);\n }\n\n return new EmailError(error.message, 'IMAP_ERROR', 'imap', error);\n }\n\n return new EmailError(String(error), 'UNKNOWN_ERROR', 'imap');\n }\n}\n","/**\n * POP3 adapter for receiving email\n */\n\nimport { simpleParser } from 'mailparser';\nimport Pop3Command from 'node-pop3';\nimport { BaseEmailClient } from '../shared/base';\nimport {\n AuthenticationError,\n ConnectionError,\n EmailError,\n MessageNotFoundError,\n TimeoutError,\n} from '../shared/errors';\nimport type {\n AdapterType,\n EmailClientCapabilities,\n EmailMessage,\n FetchOptions,\n Folder,\n FolderInfo,\n POP3Options,\n SearchCriteria,\n SendOptions,\n SendResult,\n} from '../shared/types';\n\n/**\n * POP3 adapter implementation\n *\n * POP3 is a simple protocol for retrieving email. It does not support:\n * - Folders (POP3 has no folder concept)\n * - Marking messages as read/unread\n * - Moving or copying messages\n * - Server-side search\n *\n * By default, POP3 deletes messages from the server after retrieval.\n * Use leaveOnServer: true to keep messages on the server.\n */\nexport class POP3Adapter extends BaseEmailClient {\n private client: Pop3Command | null = null;\n private options: POP3Options;\n private messageCache: Map<string, string> = new Map(); // msgNum -> UID\n\n constructor(options: POP3Options) {\n super({\n type: 'pop3',\n debug: options.debug,\n });\n this.options = options;\n }\n\n // ========================================================================\n // Connection management\n // ========================================================================\n\n async connect(): Promise<void> {\n try {\n this.client = new Pop3Command({\n user: this.options.auth.user,\n password: this.options.auth.pass,\n host: this.options.host,\n port: this.options.port,\n tls: this.options.secure ?? this.options.port === 995,\n timeout: this.options.connectionTimeout,\n tlsOptions: this.options.tls,\n });\n\n await this.client.connect();\n this.connected = true;\n this.debug('Connected to POP3 server');\n } catch (error) {\n throw this.mapPOP3Error(error);\n }\n }\n\n async disconnect(): Promise<void> {\n if (!this.client) {\n return;\n }\n\n try {\n await this.client.QUIT();\n this.client = null;\n this.connected = false;\n this.messageCache.clear();\n this.debug('Disconnected from POP3 server');\n } catch (error) {\n this.client = null;\n this.connected = false;\n this.messageCache.clear();\n throw this.mapPOP3Error(error);\n }\n }\n\n // ========================================================================\n // Message operations\n // ========================================================================\n\n async fetch(options?: FetchOptions): Promise<EmailMessage[]> {\n this.ensureConnected();\n\n try {\n // Get list of message UIDs\n const uidlResponse = await this.client?.UIDL();\n if (!uidlResponse || !uidlResponse[0]) {\n return [];\n }\n const uidList = this.parseUidlResponse(\n Array.isArray(uidlResponse[0])\n ? uidlResponse[0].join('\\n')\n : uidlResponse[0],\n );\n\n if (uidList.length === 0) {\n return [];\n }\n\n // Update message cache\n this.messageCache.clear();\n for (const { msgNum, uid } of uidList) {\n this.messageCache.set(msgNum, uid);\n }\n\n // Apply limit and offset\n let messageNums = uidList.map((item) => item.msgNum);\n if (options?.offset) {\n messageNums = messageNums.slice(options.offset);\n }\n if (options?.limit) {\n messageNums = messageNums.slice(0, options.limit);\n }\n\n // Fetch messages\n const messages: EmailMessage[] = [];\n for (const msgNum of messageNums) {\n try {\n const message = await this.fetchMessage(msgNum);\n\n // Apply filters\n if (this.shouldIncludeMessage(message, options)) {\n messages.push(message);\n\n // Delete from server if not leaving on server\n if (!this.options.leaveOnServer) {\n await this.deleteMessageByNum(msgNum);\n }\n }\n } catch (error) {\n this.logger.error(`Failed to fetch message ${msgNum}:`, {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return messages;\n } catch (error) {\n throw this.mapPOP3Error(error);\n }\n }\n\n async getMessage(messageId: string): Promise<EmailMessage> {\n this.ensureConnected();\n\n try {\n // First try to find by UID in cache\n let msgNum: string | null = null;\n for (const [num, uid] of this.messageCache.entries()) {\n if (uid === messageId) {\n msgNum = num;\n break;\n }\n }\n\n // If not in cache, refresh UIDL\n if (!msgNum) {\n const uidlResponse = await this.client?.UIDL();\n if (!uidlResponse || !uidlResponse[0]) {\n throw new MessageNotFoundError(messageId, 'pop3');\n }\n const uidList = this.parseUidlResponse(\n Array.isArray(uidlResponse[0])\n ? uidlResponse[0].join('\\n')\n : uidlResponse[0],\n );\n\n this.messageCache.clear();\n for (const { msgNum: num, uid } of uidList) {\n this.messageCache.set(num, uid);\n if (uid === messageId) {\n msgNum = num;\n }\n }\n }\n\n if (!msgNum) {\n throw new MessageNotFoundError(messageId, 'pop3');\n }\n\n return await this.fetchMessage(msgNum);\n } catch (error) {\n if (error instanceof MessageNotFoundError) {\n throw error;\n }\n throw this.mapPOP3Error(error);\n }\n }\n\n async delete(messageId: string | string[]): Promise<void> {\n this.ensureConnected();\n\n const ids = this.normalizeMessageIds(messageId);\n\n for (const id of ids) {\n try {\n // Find message number by UID\n let msgNum: string | null = null;\n for (const [num, uid] of this.messageCache.entries()) {\n if (uid === id) {\n msgNum = num;\n break;\n }\n }\n\n if (!msgNum) {\n // Refresh UIDL\n const uidlResponse = await this.client?.UIDL();\n if (!uidlResponse || !uidlResponse[0]) {\n throw new MessageNotFoundError(id, 'pop3');\n }\n const uidList = this.parseUidlResponse(\n Array.isArray(uidlResponse[0])\n ? uidlResponse[0].join('\\n')\n : uidlResponse[0],\n );\n\n for (const { msgNum: num, uid } of uidList) {\n if (uid === id) {\n msgNum = num;\n break;\n }\n }\n }\n\n if (!msgNum) {\n throw new MessageNotFoundError(id, 'pop3');\n }\n\n await this.deleteMessageByNum(msgNum);\n } catch (error) {\n throw this.mapPOP3Error(error);\n }\n }\n }\n\n // ========================================================================\n // Unsupported operations (POP3 limitations)\n // ========================================================================\n\n async send(\n _message: EmailMessage,\n _options?: SendOptions,\n ): Promise<SendResult> {\n throw new EmailError(\n 'POP3 does not support sending email. Use SMTP instead.',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async listFolders(): Promise<Folder[]> {\n throw new EmailError(\n 'POP3 does not support folders',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async selectFolder(_name: string): Promise<FolderInfo> {\n throw new EmailError(\n 'POP3 does not support folders',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async createFolder(_name: string): Promise<void> {\n throw new EmailError(\n 'POP3 does not support folders',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async deleteFolder(_name: string): Promise<void> {\n throw new EmailError(\n 'POP3 does not support folders',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async markRead(_messageId: string | string[]): Promise<void> {\n throw new EmailError(\n 'POP3 does not support marking messages as read',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async markUnread(_messageId: string | string[]): Promise<void> {\n throw new EmailError(\n 'POP3 does not support marking messages as unread',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async move(_messageId: string | string[], _folder: string): Promise<void> {\n throw new EmailError(\n 'POP3 does not support moving messages',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async copy(_messageId: string | string[], _folder: string): Promise<void> {\n throw new EmailError(\n 'POP3 does not support copying messages',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n async search(_criteria: SearchCriteria): Promise<EmailMessage[]> {\n throw new EmailError(\n 'POP3 does not support server-side search. Use fetch() with filters instead.',\n 'UNSUPPORTED_OPERATION',\n 'pop3',\n );\n }\n\n // ========================================================================\n // Adapter info\n // ========================================================================\n\n async getCapabilities(): Promise<EmailClientCapabilities> {\n return {\n send: false,\n receive: true,\n folders: false,\n search: false,\n markRead: false,\n move: false,\n delete: true,\n threads: false,\n oauth: false,\n };\n }\n\n getAdapter(): AdapterType {\n return 'pop3';\n }\n\n // ========================================================================\n // Private helper methods\n // ========================================================================\n\n private ensureConnected(): void {\n if (!this.connected || !this.client) {\n throw new ConnectionError(\n 'Not connected to POP3 server. Call connect() first.',\n 'pop3',\n );\n }\n }\n\n private async fetchMessage(msgNum: string): Promise<EmailMessage> {\n try {\n // Retrieve full message (convert string to number for RETR)\n const response = await this.client?.RETR(Number(msgNum));\n if (!response || !response[0]) {\n throw new Error(`Failed to retrieve message ${msgNum}`);\n }\n const messageData = response[0];\n\n // Parse message\n const parsed = await simpleParser(messageData);\n\n // Get UID\n const uid = this.messageCache.get(msgNum);\n\n // Helper to extract addresses from AddressObject\n const extractAddresses = (\n addressObj:\n | import('mailparser').AddressObject\n | import('mailparser').AddressObject[]\n | undefined,\n ) => {\n if (!addressObj) return [];\n // Handle array of AddressObjects\n const addressArray = Array.isArray(addressObj)\n ? addressObj\n : [addressObj];\n const addresses = addressArray.flatMap((obj) =>\n Array.isArray(obj.value) ? obj.value : [obj.value],\n );\n return addresses.map((addr: { address?: string; name?: string }) => ({\n address: addr.address || '',\n name: addr.name,\n }));\n };\n\n const fromAddresses = extractAddresses(parsed.from);\n const toAddresses = extractAddresses(parsed.to);\n const ccAddresses = extractAddresses(parsed.cc);\n const bccAddresses = extractAddresses(parsed.bcc);\n const replyToAddresses = extractAddresses(parsed.replyTo);\n\n return {\n id: uid || msgNum,\n messageId: parsed.messageId || uid || msgNum,\n from: fromAddresses[0] || { address: '', name: undefined },\n to: toAddresses,\n cc: ccAddresses.length > 0 ? ccAddresses : undefined,\n bcc: bccAddresses.length > 0 ? bccAddresses : undefined,\n replyTo: replyToAddresses[0],\n subject: parsed.subject || '',\n date: parsed.date,\n text: parsed.text,\n html: parsed.html ? parsed.html.toString() : undefined,\n attachments: parsed.attachments?.map((att) => ({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content: att.content,\n contentId: att.contentId,\n contentDisposition: att.contentDisposition as 'attachment' | 'inline',\n })),\n headers: parsed.headers as unknown as Record<string, string | string[]>,\n size: messageData.length,\n raw: messageData,\n };\n } catch (error) {\n throw this.mapPOP3Error(error);\n }\n }\n\n private async deleteMessageByNum(msgNum: string): Promise<void> {\n try {\n await this.client?.command(`DELE ${msgNum}`);\n this.messageCache.delete(msgNum);\n this.debug(`Deleted message ${msgNum}`);\n } catch (error) {\n throw this.mapPOP3Error(error);\n }\n }\n\n private parseUidlResponse(\n response: string,\n ): Array<{ msgNum: string; uid: string }> {\n const lines = response.split('\\n');\n const result: Array<{ msgNum: string; uid: string }> = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed === '.' || trimmed.startsWith('+OK')) {\n continue;\n }\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n result.push({\n msgNum: parts[0],\n uid: parts[1],\n });\n }\n }\n\n return result;\n }\n\n private shouldIncludeMessage(\n message: EmailMessage,\n options?: FetchOptions,\n ): boolean {\n // Date filters\n if (options?.since && message.date) {\n if (message.date < options.since) {\n return false;\n }\n }\n\n if (options?.before && message.date) {\n if (message.date >= options.before) {\n return false;\n }\n }\n\n // Note: POP3 doesn't support unreadOnly filter since it can't track read status\n\n return true;\n }\n\n private mapPOP3Error(error: unknown): EmailError {\n if (error instanceof EmailError) {\n return error;\n }\n\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const errorObj = error as unknown as Record<string, unknown>;\n\n // Timeout errors\n if (\n message.includes('timeout') ||\n errorObj.eventName === 'timeout' ||\n errorObj.code === 'ETIMEDOUT'\n ) {\n return new TimeoutError(error.message, 'pop3', error);\n }\n\n // Connection errors\n if (\n message.includes('connect') ||\n message.includes('econnrefused') ||\n message.includes('enotfound') ||\n message.includes('ehostunreach') ||\n errorObj.eventName === 'error' ||\n errorObj.eventName === 'close' ||\n errorObj.code === 'ECONNREFUSED' ||\n errorObj.code === 'ENOTFOUND'\n ) {\n return new ConnectionError(error.message, 'pop3', error);\n }\n\n // Authentication errors\n if (\n message.includes('auth') ||\n message.includes('login') ||\n message.includes('password') ||\n message.includes('user') ||\n message.includes('-err')\n ) {\n return new AuthenticationError(error.message, 'pop3', error);\n }\n\n return new EmailError(error.message, 'POP3_ERROR', 'pop3', error);\n }\n\n return new EmailError(String(error), 'POP3_ERROR', 'pop3');\n }\n}\n","/**\n * SMTP adapter implementation using Nodemailer\n */\n\nimport type { Transporter } from 'nodemailer';\nimport nodemailer from 'nodemailer';\nimport { BaseEmailClient } from '../shared/base';\nimport {\n AuthenticationError,\n ConnectionError,\n EmailError,\n SendError,\n TimeoutError,\n} from '../shared/errors';\nimport type {\n AdapterType,\n EmailClientCapabilities,\n EmailMessage,\n FetchOptions,\n Folder,\n FolderInfo,\n SearchCriteria,\n SendOptions,\n SendResult,\n SMTPOptions,\n} from '../shared/types';\n\n/**\n * SMTP adapter for sending email via SMTP protocol\n *\n * Uses Nodemailer for robust SMTP operations including:\n * - Plain text and HTML email\n * - Attachments (files and inline images)\n * - Multiple recipients (To, CC, BCC)\n * - Connection pooling\n * - OAuth2 authentication\n * - TLS/SSL support\n */\nexport class SMTPAdapter extends BaseEmailClient {\n private transporter: Transporter;\n private options: SMTPOptions;\n\n constructor(options: SMTPOptions) {\n super({\n type: 'smtp',\n debug: options.debug,\n });\n\n this.options = options;\n this.transporter = this.createTransporter();\n }\n\n /**\n * Create Nodemailer transporter with configuration\n */\n private createTransporter(): Transporter {\n // Cast to any to bypass nodemailer's complex overload types\n // biome-ignore lint/suspicious/noExplicitAny: nodemailer transport config has complex overloads\n const config: any = {\n host: this.options.host,\n port: this.options.port,\n secure: this.options.secure ?? false,\n auth: this.options.auth,\n tls: this.options.tls,\n connectionTimeout: this.options.connectionTimeout,\n greetingTimeout: this.options.greetingTimeout,\n socketTimeout: this.options.socketTimeout,\n pool: this.options.pool,\n maxConnections: this.options.maxConnections,\n maxMessages: this.options.maxMessages,\n debug: this.options.debug,\n };\n\n return nodemailer.createTransport(config);\n }\n\n getAdapter(): AdapterType {\n return 'smtp';\n }\n\n /**\n * Send an email message\n */\n async send(\n message: EmailMessage,\n options?: SendOptions,\n ): Promise<SendResult> {\n // Validate message before sending\n this.validateMessage(message);\n\n try {\n // Build mail options - cast to any due to nodemailer's incomplete type definitions\n // biome-ignore lint/suspicious/noExplicitAny: nodemailer SendMailOptions doesn't include all properties we use\n const mailOptions: any = {\n from: this.formatEmailAddress(message.from),\n to: message.to.map((addr) => this.formatEmailAddress(addr)),\n cc: message.cc?.map((addr) => this.formatEmailAddress(addr)),\n bcc: message.bcc?.map((addr) => this.formatEmailAddress(addr)),\n subject: message.subject,\n text: message.text,\n html: message.html,\n replyTo: message.replyTo\n ? this.formatEmailAddress(message.replyTo)\n : undefined,\n inReplyTo: message.inReplyTo,\n references: message.references,\n attachments: message.attachments?.map((att) => ({\n filename: att.filename,\n content: att.content,\n path: att.path,\n contentType: att.contentType,\n cid: att.contentId,\n contentDisposition: att.contentDisposition,\n })),\n headers: message.headers,\n messageId: message.messageId || options?.messageId,\n date: message.date || options?.date,\n encoding: options?.encoding,\n textEncoding: options?.textEncoding,\n envelope: options?.envelope,\n priority: options?.priority,\n dsn: options?.dsn,\n };\n\n // Send email\n this.debug('Sending email', {\n to: mailOptions.to,\n subject: message.subject,\n });\n const info = await this.transporter.sendMail(mailOptions);\n\n // Type assertion for nodemailer SentMessageInfo which has accepted/rejected\n const sendInfo = info as unknown as {\n messageId: string;\n accepted: string[];\n rejected: string[];\n response: string;\n };\n\n return {\n messageId: sendInfo.messageId,\n accepted: sendInfo.accepted,\n rejected: sendInfo.rejected,\n response: sendInfo.response,\n };\n } catch (error) {\n throw this.mapSMTPError(error);\n }\n }\n\n /**\n * Format email address for Nodemailer\n */\n private formatEmailAddress(addr: { address: string; name?: string }): string {\n if (addr.name) {\n // Escape quotes in name\n const name = addr.name.replace(/\"/g, '\\\\\"');\n return `\"${name}\" <${addr.address}>`;\n }\n return addr.address;\n }\n\n /**\n * Map Nodemailer/SMTP errors to standard error types\n */\n private mapSMTPError(error: unknown): EmailError {\n if (error instanceof EmailError) {\n return error;\n }\n\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n\n // Authentication errors\n if (\n message.includes('authentication') ||\n message.includes('invalid login') ||\n message.includes('535')\n ) {\n return new AuthenticationError(error.message, 'smtp', error);\n }\n\n // Timeout errors (check before connection errors as timeout messages may contain \"connection\")\n if (message.includes('timeout') || message.includes('etimedout')) {\n return new TimeoutError(error.message, 'smtp', error);\n }\n\n // Connection errors\n if (\n message.includes('econnrefused') ||\n message.includes('enotfound') ||\n message.includes('connection') ||\n message.includes('ehostunreach')\n ) {\n return new ConnectionError(error.message, 'smtp', error);\n }\n\n // Send errors (with recipient info if available)\n if ('accepted' in error && 'rejected' in error) {\n const errorWithRecipients = error as unknown as {\n accepted?: string[];\n rejected?: string[];\n };\n return new SendError(\n error.message,\n errorWithRecipients.accepted || [],\n errorWithRecipients.rejected || [],\n 'smtp',\n error,\n );\n }\n\n return new EmailError(error.message, 'SMTP_ERROR', 'smtp', error);\n }\n\n return new EmailError(String(error), 'UNKNOWN_ERROR', 'smtp');\n }\n\n /**\n * Connect to SMTP server (verify connection)\n */\n async connect(): Promise<void> {\n try {\n this.debug('Verifying SMTP connection', { host: this.options.host });\n await this.transporter.verify();\n this.connected = true;\n this.debug('SMTP connection verified');\n } catch (error) {\n this.connected = false;\n throw this.mapSMTPError(error);\n }\n }\n\n /**\n * Disconnect from SMTP server\n */\n async disconnect(): Promise<void> {\n this.transporter.close();\n this.connected = false;\n this.debug('SMTP connection closed');\n }\n\n /**\n * Get adapter capabilities\n */\n async getCapabilities(): Promise<EmailClientCapabilities> {\n return {\n send: true,\n receive: false, // SMTP is send-only\n folders: false,\n search: false,\n markRead: false,\n move: false,\n delete: false,\n threads: false,\n oauth: this.isOAuth2(),\n };\n }\n\n /**\n * Check if using OAuth2 authentication\n */\n private isOAuth2(): boolean {\n return (\n this.options.auth !== undefined &&\n 'type' in this.options.auth &&\n this.options.auth.type === 'OAuth2'\n );\n }\n\n // ========================================================================\n // Unsupported operations (SMTP is send-only)\n // ========================================================================\n\n async fetch(_options?: FetchOptions): Promise<EmailMessage[]> {\n throw new EmailError(\n 'SMTP does not support receiving messages. Use IMAP or POP3 adapter.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async getMessage(_messageId: string): Promise<EmailMessage> {\n throw new EmailError(\n 'SMTP does not support receiving messages. Use IMAP or POP3 adapter.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async listFolders(): Promise<Folder[]> {\n throw new EmailError(\n 'SMTP does not support folder operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async selectFolder(_name: string): Promise<FolderInfo> {\n throw new EmailError(\n 'SMTP does not support folder operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async createFolder(_name: string): Promise<void> {\n throw new EmailError(\n 'SMTP does not support folder operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async deleteFolder(_name: string): Promise<void> {\n throw new EmailError(\n 'SMTP does not support folder operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async markRead(_messageId: string | string[]): Promise<void> {\n throw new EmailError(\n 'SMTP does not support message operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async markUnread(_messageId: string | string[]): Promise<void> {\n throw new EmailError(\n 'SMTP does not support message operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async move(_messageId: string | string[], _folder: string): Promise<void> {\n throw new EmailError(\n 'SMTP does not support message operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async copy(_messageId: string | string[], _folder: string): Promise<void> {\n throw new EmailError(\n 'SMTP does not support message operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async delete(_messageId: string | string[]): Promise<void> {\n throw new EmailError(\n 'SMTP does not support message operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n\n async search(_criteria: SearchCriteria): Promise<EmailMessage[]> {\n throw new EmailError(\n 'SMTP does not support search operations.',\n 'UNSUPPORTED_OPERATION',\n 'smtp',\n );\n }\n}\n","/**\n * Factory function and type guards for @happyvertical/email package\n */\n\nimport type {\n AdapterType,\n EmailClient,\n GetEmailClientOptions,\n GmailOptions,\n IMAPOptions,\n POP3Options,\n SMTPOptions,\n} from './types';\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport function isSMTPOptions(\n opts: GetEmailClientOptions,\n): opts is SMTPOptions {\n return opts.type === 'smtp';\n}\n\nexport function isIMAPOptions(\n opts: GetEmailClientOptions,\n): opts is IMAPOptions {\n return opts.type === 'imap';\n}\n\nexport function isPOP3Options(\n opts: GetEmailClientOptions,\n): opts is POP3Options {\n return opts.type === 'pop3';\n}\n\nexport function isGmailOptions(\n opts: GetEmailClientOptions,\n): opts is GmailOptions {\n return opts.type === 'gmail';\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create an email client adapter instance\n *\n * @param options - Configuration options for the email client adapter\n * @returns Promise resolving to an EmailClient instance\n *\n * @example\n * ```typescript\n * // SMTP adapter\n * const smtp = await getEmailClient({\n * type: 'smtp',\n * host: 'smtp.gmail.com',\n * port: 587,\n * auth: { user: 'user@gmail.com', pass: 'password' }\n * });\n *\n * // IMAP adapter\n * const imap = await getEmailClient({\n * type: 'imap',\n * host: 'imap.gmail.com',\n * port: 993,\n * secure: true,\n * auth: { user: 'user@gmail.com', pass: 'password' }\n * });\n *\n * // Gmail adapter\n * const gmail = await getEmailClient({\n * type: 'gmail',\n * auth: {\n * clientId: 'CLIENT_ID',\n * clientSecret: 'CLIENT_SECRET',\n * refreshToken: 'REFRESH_TOKEN'\n * }\n * });\n * ```\n */\nexport async function getEmailClient(\n options: GetEmailClientOptions,\n): Promise<EmailClient> {\n // Load environment variables if not provided\n const opts = await loadEnvironmentConfig(options);\n\n // Create adapter based on type\n if (isSMTPOptions(opts)) {\n const { SMTPAdapter } = await import('../adapters/smtp.js');\n return new SMTPAdapter(opts);\n }\n\n if (isIMAPOptions(opts)) {\n const { IMAPAdapter } = await import('../adapters/imap.js');\n return new IMAPAdapter(opts);\n }\n\n if (isPOP3Options(opts)) {\n const { POP3Adapter } = await import('../adapters/pop3.js');\n return new POP3Adapter(opts);\n }\n\n if (isGmailOptions(opts)) {\n const { GmailAdapter } = await import('../adapters/gmail.js');\n return new GmailAdapter(opts);\n }\n\n throw new Error(\n `Unknown email client type: ${(opts as { type: string }).type}`,\n );\n}\n\n// ============================================================================\n// Environment Configuration\n// ============================================================================\n\n/**\n * Load configuration from environment variables\n *\n * Environment variables follow the pattern: HAVE_EMAIL_*\n *\n * Common variables:\n * - HAVE_EMAIL_TYPE: Adapter type (smtp, imap, pop3, gmail)\n * - HAVE_EMAIL_HOST: Server host\n * - HAVE_EMAIL_PORT: Server port\n * - HAVE_EMAIL_SECURE: Use TLS/SSL (true/false)\n * - HAVE_EMAIL_USER: Username/email\n * - HAVE_EMAIL_PASSWORD: Password\n * - HAVE_EMAIL_DEBUG: Enable debug logging (true/false)\n *\n * SMTP-specific:\n * - HAVE_EMAIL_SMTP_HOST\n * - HAVE_EMAIL_SMTP_PORT\n * - HAVE_EMAIL_SMTP_SECURE\n *\n * IMAP-specific:\n * - HAVE_EMAIL_IMAP_HOST\n * - HAVE_EMAIL_IMAP_PORT\n * - HAVE_EMAIL_IMAP_SECURE\n *\n * Gmail-specific:\n * - HAVE_EMAIL_GMAIL_CLIENT_ID\n * - HAVE_EMAIL_GMAIL_CLIENT_SECRET\n * - HAVE_EMAIL_GMAIL_REFRESH_TOKEN\n */\nasync function loadEnvironmentConfig(\n options: GetEmailClientOptions,\n): Promise<GetEmailClientOptions> {\n // If type is not provided, try to load from environment\n if (!options.type && process.env.HAVE_EMAIL_TYPE) {\n options = {\n ...(options as object),\n type: process.env.HAVE_EMAIL_TYPE as AdapterType,\n } as GetEmailClientOptions;\n }\n\n // Load type-specific environment variables\n if (options.type === 'smtp') {\n return loadSMTPEnvironmentConfig(options as SMTPOptions);\n }\n\n if (options.type === 'imap') {\n return loadIMAPEnvironmentConfig(options as IMAPOptions);\n }\n\n if (options.type === 'pop3') {\n return loadPOP3EnvironmentConfig(options as POP3Options);\n }\n\n if (options.type === 'gmail') {\n return loadGmailEnvironmentConfig(options as GmailOptions);\n }\n\n return options;\n}\n\nfunction loadSMTPEnvironmentConfig(options: SMTPOptions): SMTPOptions {\n return {\n ...options,\n host:\n options.host ||\n process.env.HAVE_EMAIL_SMTP_HOST ||\n process.env.HAVE_EMAIL_HOST ||\n '',\n port:\n options.port ||\n Number.parseInt(\n process.env.HAVE_EMAIL_SMTP_PORT ||\n process.env.HAVE_EMAIL_PORT ||\n '587',\n 10,\n ),\n secure:\n options.secure ??\n (process.env.HAVE_EMAIL_SMTP_SECURE || process.env.HAVE_EMAIL_SECURE) ===\n 'true',\n auth:\n options.auth ||\n ({\n user: process.env.HAVE_EMAIL_USER || process.env.HAVE_EMAIL_SMTP_USER,\n pass:\n process.env.HAVE_EMAIL_PASSWORD ||\n process.env.HAVE_EMAIL_SMTP_PASSWORD,\n } as SMTPOptions['auth']),\n debug: options.debug ?? process.env.HAVE_EMAIL_DEBUG === 'true',\n };\n}\n\nfunction loadIMAPEnvironmentConfig(options: IMAPOptions): IMAPOptions {\n return {\n ...options,\n host:\n options.host ||\n process.env.HAVE_EMAIL_IMAP_HOST ||\n process.env.HAVE_EMAIL_HOST ||\n '',\n port:\n options.port ||\n Number.parseInt(\n process.env.HAVE_EMAIL_IMAP_PORT ||\n process.env.HAVE_EMAIL_PORT ||\n '993',\n 10,\n ),\n secure:\n options.secure ??\n (process.env.HAVE_EMAIL_IMAP_SECURE || process.env.HAVE_EMAIL_SECURE) ===\n 'true',\n auth: options.auth || {\n user: process.env.HAVE_EMAIL_USER || process.env.HAVE_EMAIL_IMAP_USER,\n pass:\n process.env.HAVE_EMAIL_PASSWORD || process.env.HAVE_EMAIL_IMAP_PASSWORD,\n },\n debug: options.debug ?? process.env.HAVE_EMAIL_DEBUG === 'true',\n };\n}\n\nfunction loadPOP3EnvironmentConfig(options: POP3Options): POP3Options {\n return {\n ...options,\n host:\n options.host ||\n process.env.HAVE_EMAIL_POP3_HOST ||\n process.env.HAVE_EMAIL_HOST ||\n '',\n port:\n options.port ||\n Number.parseInt(\n process.env.HAVE_EMAIL_POP3_PORT ||\n process.env.HAVE_EMAIL_PORT ||\n '995',\n 10,\n ),\n secure:\n options.secure ??\n (process.env.HAVE_EMAIL_POP3_SECURE || process.env.HAVE_EMAIL_SECURE) ===\n 'true',\n auth: options.auth || {\n user: process.env.HAVE_EMAIL_USER || process.env.HAVE_EMAIL_POP3_USER,\n pass:\n process.env.HAVE_EMAIL_PASSWORD || process.env.HAVE_EMAIL_POP3_PASSWORD,\n },\n debug: options.debug ?? process.env.HAVE_EMAIL_DEBUG === 'true',\n };\n}\n\nfunction loadGmailEnvironmentConfig(options: GmailOptions): GmailOptions {\n return {\n ...options,\n auth: options.auth || {\n clientId: process.env.HAVE_EMAIL_GMAIL_CLIENT_ID || '',\n clientSecret: process.env.HAVE_EMAIL_GMAIL_CLIENT_SECRET || '',\n refreshToken: process.env.HAVE_EMAIL_GMAIL_REFRESH_TOKEN || '',\n accessToken: process.env.HAVE_EMAIL_GMAIL_ACCESS_TOKEN,\n },\n userId: options.userId || process.env.HAVE_EMAIL_GMAIL_USER_ID || 'me',\n debug: options.debug ?? process.env.HAVE_EMAIL_DEBUG === 'true',\n };\n}\n"],"names":["SMTPAdapter","IMAPAdapter","POP3Adapter","GmailAdapter"],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Logger } from '@happyvertical/logger';
|
|
2
|
+
import { EmailError } from './errors';
|
|
3
|
+
import { AdapterType, EmailAddress, EmailClient, EmailClientCapabilities, EmailClientConfig, EmailMessage, FetchOptions, Folder, FolderInfo, SearchCriteria, SendOptions, SendResult } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Base adapter class providing shared functionality
|
|
6
|
+
*
|
|
7
|
+
* All adapter implementations should extend this class.
|
|
8
|
+
* This is a protocol-only base class - no database persistence.
|
|
9
|
+
* For database sync and AI features, use @happyvertical/smrt-messages.
|
|
10
|
+
*/
|
|
11
|
+
export declare abstract class BaseEmailClient implements EmailClient {
|
|
12
|
+
protected config: EmailClientConfig;
|
|
13
|
+
protected logger: Logger;
|
|
14
|
+
protected connected: boolean;
|
|
15
|
+
constructor(config: EmailClientConfig);
|
|
16
|
+
abstract send(message: EmailMessage, options?: SendOptions): Promise<SendResult>;
|
|
17
|
+
abstract fetch(options?: FetchOptions): Promise<EmailMessage[]>;
|
|
18
|
+
abstract getMessage(messageId: string): Promise<EmailMessage>;
|
|
19
|
+
abstract listFolders(): Promise<Folder[]>;
|
|
20
|
+
abstract selectFolder(name: string): Promise<FolderInfo>;
|
|
21
|
+
abstract createFolder(name: string): Promise<void>;
|
|
22
|
+
abstract deleteFolder(name: string): Promise<void>;
|
|
23
|
+
abstract markRead(messageId: string | string[]): Promise<void>;
|
|
24
|
+
abstract markUnread(messageId: string | string[]): Promise<void>;
|
|
25
|
+
abstract move(messageId: string | string[], folder: string): Promise<void>;
|
|
26
|
+
abstract copy(messageId: string | string[], folder: string): Promise<void>;
|
|
27
|
+
abstract delete(messageId: string | string[]): Promise<void>;
|
|
28
|
+
abstract search(criteria: SearchCriteria): Promise<EmailMessage[]>;
|
|
29
|
+
abstract connect(): Promise<void>;
|
|
30
|
+
abstract disconnect(): Promise<void>;
|
|
31
|
+
abstract getCapabilities(): Promise<EmailClientCapabilities>;
|
|
32
|
+
abstract getAdapter(): AdapterType;
|
|
33
|
+
isConnected(): boolean;
|
|
34
|
+
protected validateConfig(config: EmailClientConfig): EmailClientConfig;
|
|
35
|
+
protected validateEmail(email: EmailAddress): void;
|
|
36
|
+
protected validateMessage(message: EmailMessage): void;
|
|
37
|
+
protected mapError(error: unknown): EmailError;
|
|
38
|
+
protected normalizeMessageIds(messageId: string | string[]): string[];
|
|
39
|
+
protected debug(message: string, data?: unknown): void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/shared/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAuB,MAAM,UAAU,CAAC;AAC3D,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,UAAU,EACV,cAAc,EACd,WAAW,EACX,UAAU,EACX,MAAM,SAAS,CAAC;AAEjB;;;;;;GAMG;AACH,8BAAsB,eAAgB,YAAW,WAAW;IAC1D,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACpC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,SAAS,UAAS;gBAEhB,MAAM,EAAE,iBAAiB;IASrC,QAAQ,CAAC,IAAI,CACX,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,UAAU,CAAC;IAEtB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAE/D,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAE7D,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAEzC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAExD,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAElD,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAElD,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAE9D,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAEhE,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1E,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1E,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAE5D,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAElE,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAEjC,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAEpC,QAAQ,CAAC,eAAe,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAE5D,QAAQ,CAAC,UAAU,IAAI,WAAW;IAMlC,WAAW,IAAI,OAAO;IAQtB,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB;IAQtE,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAkBlD,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAwDtD,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU;IAqB9C,SAAS,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE;IAIrE,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;CAKvD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for @happyvertical/email package
|
|
3
|
+
*/
|
|
4
|
+
export declare class EmailError extends Error {
|
|
5
|
+
code: string;
|
|
6
|
+
provider?: string;
|
|
7
|
+
cause?: unknown;
|
|
8
|
+
constructor(message: string, code: string, provider?: string, cause?: unknown);
|
|
9
|
+
}
|
|
10
|
+
export declare class ConnectionError extends EmailError {
|
|
11
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
12
|
+
}
|
|
13
|
+
export declare class TimeoutError extends EmailError {
|
|
14
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
15
|
+
}
|
|
16
|
+
export declare class AuthenticationError extends EmailError {
|
|
17
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
18
|
+
}
|
|
19
|
+
export declare class AuthorizationError extends EmailError {
|
|
20
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
21
|
+
}
|
|
22
|
+
export declare class MessageNotFoundError extends EmailError {
|
|
23
|
+
messageId: string;
|
|
24
|
+
constructor(messageId: string, provider?: string);
|
|
25
|
+
}
|
|
26
|
+
export declare class InvalidMessageError extends EmailError {
|
|
27
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
28
|
+
}
|
|
29
|
+
export declare class FolderNotFoundError extends EmailError {
|
|
30
|
+
folder: string;
|
|
31
|
+
constructor(folder: string, provider?: string);
|
|
32
|
+
}
|
|
33
|
+
export declare class FolderExistsError extends EmailError {
|
|
34
|
+
folder: string;
|
|
35
|
+
constructor(folder: string, provider?: string);
|
|
36
|
+
}
|
|
37
|
+
export declare class SendError extends EmailError {
|
|
38
|
+
accepted: string[];
|
|
39
|
+
rejected: string[];
|
|
40
|
+
constructor(message: string, accepted: string[], rejected: string[], provider?: string, cause?: unknown);
|
|
41
|
+
}
|
|
42
|
+
export declare class AttachmentError extends EmailError {
|
|
43
|
+
filename?: string;
|
|
44
|
+
constructor(message: string, filename?: string, provider?: string, cause?: unknown);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/shared/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,qBAAa,UAAW,SAAQ,KAAK;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAGd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO;CAQlB;AAMD,qBAAa,eAAgB,SAAQ,UAAU;gBACjC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAED,qBAAa,YAAa,SAAQ,UAAU;gBAC9B,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAMD,qBAAa,mBAAoB,SAAQ,UAAU;gBACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAED,qBAAa,kBAAmB,SAAQ,UAAU;gBACpC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAMD,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,SAAS,EAAE,MAAM,CAAC;gBAEN,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;CAKjD;AAED,qBAAa,mBAAoB,SAAQ,UAAU;gBACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAMD,qBAAa,mBAAoB,SAAQ,UAAU;IACjD,MAAM,EAAE,MAAM,CAAC;gBAEH,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;CAK9C;AAED,qBAAa,iBAAkB,SAAQ,UAAU;IAC/C,MAAM,EAAE,MAAM,CAAC;gBAEH,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;CAK9C;AAMD,qBAAa,SAAU,SAAQ,UAAU;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;gBAGjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO;CAOlB;AAMD,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;gBAGhB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO;CAMlB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { EmailClient, GetEmailClientOptions, GmailOptions, IMAPOptions, POP3Options, SMTPOptions } from './types';
|
|
2
|
+
export declare function isSMTPOptions(opts: GetEmailClientOptions): opts is SMTPOptions;
|
|
3
|
+
export declare function isIMAPOptions(opts: GetEmailClientOptions): opts is IMAPOptions;
|
|
4
|
+
export declare function isPOP3Options(opts: GetEmailClientOptions): opts is POP3Options;
|
|
5
|
+
export declare function isGmailOptions(opts: GetEmailClientOptions): opts is GmailOptions;
|
|
6
|
+
/**
|
|
7
|
+
* Create an email client adapter instance
|
|
8
|
+
*
|
|
9
|
+
* @param options - Configuration options for the email client adapter
|
|
10
|
+
* @returns Promise resolving to an EmailClient instance
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // SMTP adapter
|
|
15
|
+
* const smtp = await getEmailClient({
|
|
16
|
+
* type: 'smtp',
|
|
17
|
+
* host: 'smtp.gmail.com',
|
|
18
|
+
* port: 587,
|
|
19
|
+
* auth: { user: 'user@gmail.com', pass: 'password' }
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // IMAP adapter
|
|
23
|
+
* const imap = await getEmailClient({
|
|
24
|
+
* type: 'imap',
|
|
25
|
+
* host: 'imap.gmail.com',
|
|
26
|
+
* port: 993,
|
|
27
|
+
* secure: true,
|
|
28
|
+
* auth: { user: 'user@gmail.com', pass: 'password' }
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Gmail adapter
|
|
32
|
+
* const gmail = await getEmailClient({
|
|
33
|
+
* type: 'gmail',
|
|
34
|
+
* auth: {
|
|
35
|
+
* clientId: 'CLIENT_ID',
|
|
36
|
+
* clientSecret: 'CLIENT_SECRET',
|
|
37
|
+
* refreshToken: 'REFRESH_TOKEN'
|
|
38
|
+
* }
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function getEmailClient(options: GetEmailClientOptions): Promise<EmailClient>;
|
|
43
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/shared/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAEV,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACZ,MAAM,SAAS,CAAC;AAMjB,wBAAgB,aAAa,CAC3B,IAAI,EAAE,qBAAqB,GAC1B,IAAI,IAAI,WAAW,CAErB;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,qBAAqB,GAC1B,IAAI,IAAI,WAAW,CAErB;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,qBAAqB,GAC1B,IAAI,IAAI,WAAW,CAErB;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,qBAAqB,GAC1B,IAAI,IAAI,YAAY,CAEtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,WAAW,CAAC,CA4BtB"}
|