open-mail-cli 1.0.0
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/LICENSE +21 -0
- package/README.md +313 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15104 -0
- package/dist/index.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/defaults.ts","../src/config/schema.ts","../src/utils/errors.ts","../src/utils/helpers.ts","../src/utils/logger.ts","../src/config/index.ts","../src/imap/client.ts","../src/smtp/client.ts","../src/storage/migrations/001_initial.ts","../src/storage/migrations/002_p0_features.ts","../src/storage/migrations/003_p1_features.ts","../src/storage/migrations/004_p2_features.ts","../src/storage/database.ts","../src/storage/models/account.ts","../src/accounts/manager.ts","../src/cli/commands/account.ts","../src/cli/commands/config.ts","../src/storage/models/contact.ts","../src/storage/models/contact_group.ts","../src/utils/email-parser.ts","../src/contacts/manager.ts","../src/cli/commands/contact.ts","../src/storage/models/email.ts","../src/filters/executor.ts","../src/filters/matcher.ts","../src/storage/models/filter.ts","../src/filters/engine.ts","../src/notifications/manager.ts","../src/spam/rules.ts","../src/storage/models/spam.ts","../src/spam/filter.ts","../src/storage/models/attachment.ts","../src/storage/models/folder.ts","../src/imap/sync.ts","../src/smtp/composer.ts","../src/cli/commands/draft.ts","../src/cli/utils/formatter.ts","../src/cli/commands/folder.ts","../src/cli/commands/forward.ts","../src/import-export/eml.ts","../src/import-export/mbox.ts","../src/import-export/manager.ts","../src/threads/analyzer.ts","../src/threads/builder.ts","../src/cli/commands/thread.ts","../src/storage/models/tag.ts","../src/cli/commands/list.ts","../src/cli/commands/notify.ts","../src/cli/commands/read.ts","../src/cli/commands/reply.ts","../src/storage/models/saved-search.ts","../src/cli/commands/search.ts","../src/storage/models/signature.ts","../src/signatures/manager.ts","../src/cli/commands/send.ts","../src/cli/commands/signature.ts","../src/cli/commands/spam.ts","../src/sync/account-manager.ts","../src/sync/daemon.ts","../src/sync/scheduler.ts","../src/cli/commands/sync.ts","../src/cli/commands/tag.ts","../src/storage/models/template.ts","../src/templates/manager.ts","../src/cli/commands/template.ts","../src/cli/index.ts","../package.json","../src/cli/commands/delete.ts","../src/cli/commands/import-export.ts","../src/cli/commands/mark.ts","../src/cli/commands/trash.ts","../src/index.ts"],"sourcesContent":["import type { AppConfig } from '../types/config';\n\n/**\n * Storage-level runtime options.\n */\nexport interface StorageConfig {\n dataDir: string;\n maxAttachmentSize: number;\n}\n\n/**\n * Sync runtime options.\n */\nexport interface SyncConfig {\n autoSync: boolean;\n syncInterval: number;\n folders: string[];\n enableDaemon: boolean;\n selectiveSyncEnabled: boolean;\n syncSince: string | null;\n concurrentFolders: number;\n retryOnError: boolean;\n maxRetries: number;\n retryDelay: number;\n}\n\n/**\n * Notification filtering options.\n */\nexport interface NotificationFiltersConfig {\n senders: string[];\n tags: string[];\n importantOnly: boolean;\n}\n\n/**\n * Notification runtime options.\n */\nexport interface NotificationsConfig {\n enabled: boolean;\n desktop: boolean;\n sound: boolean;\n filters: NotificationFiltersConfig;\n}\n\n/**\n * Full runtime configuration shape.\n */\nexport interface DefaultConfig extends AppConfig {\n storage: StorageConfig;\n sync: SyncConfig;\n notifications: NotificationsConfig;\n}\n\n/**\n * Default configuration values.\n */\nconst defaults: DefaultConfig = {\n imap: {\n host: '',\n port: 993,\n secure: true,\n user: '',\n password: '',\n },\n smtp: {\n host: '',\n port: 465,\n secure: true,\n user: '',\n password: '',\n },\n storage: {\n dataDir: './data',\n maxAttachmentSize: 10 * 1024 * 1024,\n },\n sync: {\n autoSync: false,\n syncInterval: 300000,\n folders: ['INBOX'],\n enableDaemon: false,\n selectiveSyncEnabled: false,\n syncSince: null,\n concurrentFolders: 3,\n retryOnError: true,\n maxRetries: 3,\n retryDelay: 5000,\n },\n notifications: {\n enabled: false,\n desktop: true,\n sound: true,\n filters: {\n senders: [],\n tags: [],\n importantOnly: false,\n },\n },\n};\n\nexport default defaults;\n","import type { DefaultConfig } from './defaults';\n\n/**\n * Validation output for configuration payloads.\n */\nexport interface ConfigValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Runtime guard for object-like values.\n */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Read a string property from an unknown object.\n */\nfunction getStringField(\n source: Record<string, unknown>,\n key: string\n): string | undefined {\n const value = source[key];\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * Read a number property from an unknown object.\n */\nfunction getNumberField(\n source: Record<string, unknown>,\n key: string\n): number | undefined {\n const value = source[key];\n return typeof value === 'number' ? value : undefined;\n}\n\n/**\n * Configuration schema validation.\n */\nexport function validateConfig(\n config: Partial<DefaultConfig> | unknown\n): ConfigValidationResult {\n const errors: string[] = [];\n\n if (!isRecord(config)) {\n return {\n valid: false,\n errors: ['Config must be an object'],\n };\n }\n\n const imap = isRecord(config.imap) ? config.imap : null;\n const smtp = isRecord(config.smtp) ? config.smtp : null;\n\n if (imap) {\n if (!getStringField(imap, 'host')) {\n errors.push('IMAP host is required');\n }\n if (!getStringField(imap, 'user')) {\n errors.push('IMAP user is required');\n }\n if (!getStringField(imap, 'password')) {\n errors.push('IMAP password is required');\n }\n\n const imapPort = getNumberField(imap, 'port');\n if (imapPort === undefined || imapPort < 1 || imapPort > 65535) {\n errors.push('IMAP port must be between 1 and 65535');\n }\n }\n\n if (smtp) {\n if (!getStringField(smtp, 'host')) {\n errors.push('SMTP host is required');\n }\n if (!getStringField(smtp, 'user')) {\n errors.push('SMTP user is required');\n }\n if (!getStringField(smtp, 'password')) {\n errors.push('SMTP password is required');\n }\n\n const smtpPort = getNumberField(smtp, 'port');\n if (smtpPort === undefined || smtpPort < 1 || smtpPort > 65535) {\n errors.push('SMTP port must be between 1 and 65535');\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * Base class for mail client errors.\n */\nexport class MailClientError extends Error {\n code: string;\n\n /**\n * Create a typed mail client error.\n */\n constructor(message: string, code = 'MAIL_CLIENT_ERROR') {\n super(message);\n this.name = 'MailClientError';\n this.code = code;\n Error.captureStackTrace?.(this, new.target);\n }\n}\n\n/**\n * Configuration-related failure.\n */\nexport class ConfigError extends MailClientError {\n /**\n * Create a config error instance.\n */\n constructor(message: string, code = 'CONFIG_ERROR') {\n super(message, code);\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Network connection failure.\n */\nexport class ConnectionError extends MailClientError {\n /**\n * Create a connection error instance.\n */\n constructor(message: string, code = 'CONNECTION_ERROR') {\n super(message, code);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Authentication failure.\n */\nexport class AuthenticationError extends MailClientError {\n /**\n * Create an authentication error instance.\n */\n constructor(message: string, code = 'AUTH_ERROR') {\n super(message, code);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Synchronization failure.\n */\nexport class SyncError extends MailClientError {\n /**\n * Create a sync error instance.\n */\n constructor(message: string, code = 'SYNC_ERROR') {\n super(message, code);\n this.name = 'SyncError';\n }\n}\n\n/**\n * Storage read/write failure.\n */\nexport class StorageError extends MailClientError {\n /**\n * Create a storage error instance.\n */\n constructor(message: string, code = 'STORAGE_ERROR') {\n super(message, code);\n this.name = 'StorageError';\n }\n}\n\n/**\n * Validation failure.\n */\nexport class ValidationError extends MailClientError {\n /**\n * Create a validation error instance.\n */\n constructor(message: string, code = 'VALIDATION_ERROR') {\n super(message, code);\n this.name = 'ValidationError';\n }\n}\n","import crypto from 'node:crypto';\nimport os from 'node:os';\nimport path from 'node:path';\n\n/**\n * Encrypt a string using AES-256-CBC.\n */\nexport function encrypt(text: string, key: string | null = null): string {\n const encryptionKey = key ?? getEncryptionKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv(\n 'aes-256-cbc',\n Buffer.from(encryptionKey, 'hex'),\n iv\n );\n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n return `${iv.toString('hex')}:${encrypted}`;\n}\n\n/**\n * Decrypt a string encrypted by the encrypt helper.\n */\nexport function decrypt(\n encryptedText: string,\n key: string | null = null\n): string {\n const encryptionKey = key ?? getEncryptionKey();\n const parts = encryptedText.split(':');\n const iv = Buffer.from(parts[0], 'hex');\n const encrypted = parts[1];\n const decipher = crypto.createDecipheriv(\n 'aes-256-cbc',\n Buffer.from(encryptionKey, 'hex'),\n iv\n );\n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n return decrypted;\n}\n\n/**\n * Build a deterministic encryption key from host and user identity.\n */\nexport function getEncryptionKey(): string {\n const machineId = `${os.hostname()}${os.userInfo().username}`;\n return crypto.createHash('sha256').update(machineId).digest('hex');\n}\n\n/**\n * Get platform-specific config directory.\n */\nexport function getConfigDir(): string {\n if (process.platform === 'win32') {\n return path.join(\n process.env.APPDATA ?? path.join(os.homedir(), 'AppData', 'Roaming'),\n 'mail-client'\n );\n }\n\n return path.join(os.homedir(), '.config', 'mail-client');\n}\n\n/**\n * Get platform-specific data directory.\n */\nexport function getDataDir(): string {\n if (process.platform === 'win32') {\n return path.join(\n process.env.LOCALAPPDATA ?? path.join(os.homedir(), 'AppData', 'Local'),\n 'mail-client'\n );\n }\n\n return path.join(os.homedir(), '.local', 'share', 'mail-client');\n}\n\n/**\n * Format date to YYYY-MM-DD.\n */\nexport function formatDate(\n date: string | number | Date | null | undefined\n): string {\n if (!date) {\n return '';\n }\n\n const parsedDate = new Date(date);\n return parsedDate.toISOString().split('T')[0];\n}\n\n/**\n * Truncate a string to max length with ellipsis.\n */\nexport function truncate(\n str: string | null | undefined,\n maxLength = 50\n): string {\n if (!str) {\n return '';\n }\n\n if (str.length <= maxLength) {\n return str;\n }\n\n return `${str.substring(0, maxLength - 3)}...`;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * Log levels supported by the logger.\n */\nexport type LogLevel = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';\n\n/**\n * Simple logger utility that logs to both console and file.\n */\nexport class Logger {\n private logDir: string;\n private logFile: string;\n private levels: Record<LogLevel, number>;\n private currentLevel: number;\n\n /**\n * Create a logger instance.\n */\n constructor(logDir: string | null = null) {\n this.logDir = logDir ?? path.join(process.cwd(), 'data', 'logs');\n this.logFile = path.join(this.logDir, 'mail-client.log');\n this.levels = {\n ERROR: 0,\n WARN: 1,\n INFO: 2,\n DEBUG: 3,\n };\n this.currentLevel = this.levels.INFO;\n this.ensureLogDir();\n }\n\n /**\n * Ensure the target log directory exists.\n */\n private ensureLogDir(): void {\n if (!fs.existsSync(this.logDir)) {\n fs.mkdirSync(this.logDir, { recursive: true });\n }\n }\n\n /**\n * Build a timestamped log line.\n */\n private formatMessage(\n level: LogLevel,\n message: string,\n meta: Record<string, unknown> = {}\n ): string {\n const timestamp = new Date().toISOString();\n const metaStr =\n Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : '';\n return `[${timestamp}] [${level}] ${message}${metaStr}`;\n }\n\n /**\n * Persist a log line to disk.\n */\n private writeToFile(message: string): void {\n try {\n fs.appendFileSync(this.logFile, `${message}\\n`);\n } catch (error) {\n const failureMessage =\n error instanceof Error ? error.message : String(error);\n console.error('Failed to write to log file:', failureMessage);\n }\n }\n\n /**\n * Log a message for a specific level.\n */\n private log(\n level: LogLevel,\n message: string,\n meta: Record<string, unknown> = {}\n ): void {\n if (this.levels[level] <= this.currentLevel) {\n const formattedMessage = this.formatMessage(level, message, meta);\n console.log(formattedMessage);\n this.writeToFile(formattedMessage);\n }\n }\n\n /**\n * Log an error-level message.\n */\n error(message: string, meta: Record<string, unknown> = {}): void {\n this.log('ERROR', message, meta);\n }\n\n /**\n * Log a warn-level message.\n */\n warn(message: string, meta: Record<string, unknown> = {}): void {\n this.log('WARN', message, meta);\n }\n\n /**\n * Log an info-level message.\n */\n info(message: string, meta: Record<string, unknown> = {}): void {\n this.log('INFO', message, meta);\n }\n\n /**\n * Log a debug-level message.\n */\n debug(message: string, meta: Record<string, unknown> = {}): void {\n this.log('DEBUG', message, meta);\n }\n\n /**\n * Update current logging level.\n */\n setLevel(level: LogLevel): void {\n if (this.levels[level] !== undefined) {\n this.currentLevel = this.levels[level];\n }\n }\n}\n\n/**\n * Shared singleton logger instance.\n */\nconst logger = new Logger();\n\n// Keep CommonJS require() callers working during migration.\nexport const error = logger.error.bind(logger);\nexport const warn = logger.warn.bind(logger);\nexport const info = logger.info.bind(logger);\nexport const debug = logger.debug.bind(logger);\nexport const setLevel = logger.setLevel.bind(logger);\n\nexport default logger;\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport defaults, { type DefaultConfig } from './defaults';\nimport { validateConfig, type ConfigValidationResult } from './schema';\nimport { ConfigError } from '../utils/errors';\nimport { decrypt, encrypt, getConfigDir } from '../utils/helpers';\nimport logger from '../utils/logger';\n\n/**\n * Runtime guard for object-like values.\n */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Convert unknown error payload to displayable message.\n */\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Create deep clone for config objects.\n */\nfunction cloneConfig(config: DefaultConfig): DefaultConfig {\n return JSON.parse(JSON.stringify(config)) as DefaultConfig;\n}\n\n/**\n * Merge persisted config with defaults.\n */\nfunction mergeWithDefaults(config: Partial<DefaultConfig>): DefaultConfig {\n return {\n ...defaults,\n ...config,\n imap: {\n ...defaults.imap,\n ...(config.imap ?? {}),\n },\n smtp: {\n ...defaults.smtp,\n ...(config.smtp ?? {}),\n },\n storage: {\n ...defaults.storage,\n ...(config.storage ?? {}),\n },\n sync: {\n ...defaults.sync,\n ...(config.sync ?? {}),\n },\n notifications: {\n ...defaults.notifications,\n ...(config.notifications ?? {}),\n filters: {\n ...defaults.notifications.filters,\n ...(config.notifications?.filters ?? {}),\n },\n },\n };\n}\n\n/**\n * Configuration Manager.\n * Handles loading, saving, and validating configuration.\n */\nexport class ConfigManager {\n private configDir: string;\n private configFile: string;\n private config: DefaultConfig | null;\n\n /**\n * Create config manager.\n */\n constructor(configDir: string | null = null) {\n this.configDir = configDir ?? getConfigDir();\n this.configFile = path.join(this.configDir, 'config.json');\n this.config = null;\n }\n\n /**\n * Ensure config directory exists.\n */\n private ensureConfigDir(): void {\n if (!fs.existsSync(this.configDir)) {\n fs.mkdirSync(this.configDir, { recursive: true });\n logger.info('Created config directory', { path: this.configDir });\n }\n }\n\n /**\n * Load configuration from file.\n */\n load(): DefaultConfig {\n try {\n if (!fs.existsSync(this.configFile)) {\n logger.info('Config file not found, using defaults');\n this.config = cloneConfig(defaults);\n return this.config;\n }\n\n const data = fs.readFileSync(this.configFile, 'utf8');\n const parsedConfig = JSON.parse(data) as Partial<DefaultConfig>;\n const loadedConfig = mergeWithDefaults(parsedConfig);\n\n if (\n typeof loadedConfig.imap.password === 'string' &&\n loadedConfig.imap.password.length > 0\n ) {\n loadedConfig.imap.password = this.decrypt(loadedConfig.imap.password);\n }\n if (\n typeof loadedConfig.smtp.password === 'string' &&\n loadedConfig.smtp.password.length > 0\n ) {\n loadedConfig.smtp.password = this.decrypt(loadedConfig.smtp.password);\n }\n\n this.config = loadedConfig;\n logger.info('Configuration loaded successfully');\n return this.config;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to load configuration', { error: errorMessage });\n throw new ConfigError(`Failed to load configuration: ${errorMessage}`);\n }\n }\n\n /**\n * Save configuration to file.\n */\n save(config: DefaultConfig | null = null): boolean {\n try {\n this.ensureConfigDir();\n\n const configToSave = config ?? this.config;\n if (!configToSave) {\n throw new ConfigError('No configuration to save');\n }\n\n const validation = this.validate(configToSave);\n if (!validation.valid) {\n throw new ConfigError(\n `Invalid configuration: ${validation.errors.join(', ')}`\n );\n }\n\n const encryptedConfig = cloneConfig(configToSave);\n if (encryptedConfig.imap.password) {\n encryptedConfig.imap.password = this.encrypt(\n encryptedConfig.imap.password\n );\n }\n if (encryptedConfig.smtp.password) {\n encryptedConfig.smtp.password = this.encrypt(\n encryptedConfig.smtp.password\n );\n }\n\n fs.writeFileSync(\n this.configFile,\n JSON.stringify(encryptedConfig, null, 2)\n );\n this.config = configToSave;\n logger.info('Configuration saved successfully');\n return true;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to save configuration', { error: errorMessage });\n throw new ConfigError(`Failed to save configuration: ${errorMessage}`);\n }\n }\n\n /**\n * Get configuration value by dot-separated key.\n */\n get<T = unknown>(key: string): T | undefined {\n if (!this.config) {\n this.load();\n }\n\n const keys = key.split('.');\n let value: unknown = this.config;\n\n for (const currentKey of keys) {\n if (!isRecord(value)) {\n return undefined;\n }\n value = value[currentKey];\n }\n\n return value as T;\n }\n\n /**\n * Set configuration value by dot-separated key.\n */\n set(key: string, value: unknown): void {\n if (!this.config) {\n this.load();\n }\n\n if (!this.config) {\n return;\n }\n\n const keys = key.split('.');\n let target: Record<string, unknown> = this.config as unknown as Record<\n string,\n unknown\n >;\n\n for (let index = 0; index < keys.length - 1; index += 1) {\n const segment = keys[index];\n const currentValue = target[segment];\n\n if (!isRecord(currentValue)) {\n target[segment] = {};\n }\n\n target = target[segment] as Record<string, unknown>;\n }\n\n target[keys[keys.length - 1]] = value;\n }\n\n /**\n * Validate configuration.\n */\n validate(config: DefaultConfig | null = null): ConfigValidationResult {\n const configToValidate = config ?? this.config;\n return validateConfig(configToValidate);\n }\n\n /**\n * Encrypt sensitive data.\n */\n encrypt(value: string): string {\n return encrypt(value);\n }\n\n /**\n * Decrypt sensitive data.\n */\n decrypt(value: string): string {\n return decrypt(value);\n }\n\n /**\n * Check if configuration exists on disk.\n */\n exists(): boolean {\n return fs.existsSync(this.configFile);\n }\n}\n\nconst configManager = new ConfigManager();\n\n// Keep CommonJS require() callers working during migration.\nexport function load(): DefaultConfig {\n return configManager.load();\n}\n\nexport function save(config: DefaultConfig | null = null): boolean {\n return configManager.save(config);\n}\n\nexport function get<T = unknown>(key: string): T | undefined {\n return configManager.get<T>(key);\n}\n\nexport function set(key: string, value: unknown): void {\n configManager.set(key, value);\n}\n\nexport function validate(\n config: DefaultConfig | null = null\n): ConfigValidationResult {\n return configManager.validate(config);\n}\n\nexport function encryptValue(value: string): string {\n return configManager.encrypt(value);\n}\n\nexport function decryptValue(value: string): string {\n return configManager.decrypt(value);\n}\n\nexport function exists(): boolean {\n return configManager.exists();\n}\n\nexport default configManager;\n","import { simpleParser, Attachment } from 'mailparser';\nimport Imap from 'node-imap';\n\nimport type {\n ImapConfig,\n ImapMessage,\n ImapFolder,\n ImapMessageAttributes,\n} from '../types/imap';\n\nimport { ConnectionError, AuthenticationError } from '../utils/errors';\nimport logger from '../utils/logger';\n\ninterface FetchOptions {\n batchSize?: number;\n fetchBody?: boolean;\n}\n\ninterface EmailData {\n uid: number | null;\n attributes: ImapMessageAttributes | null;\n body: string;\n headers: string | null;\n}\n\ninterface ParsedEmailResult {\n uid: number;\n messageId?: string;\n from: string;\n to: string;\n cc: string;\n subject: string;\n date: string;\n bodyText: string;\n bodyHtml: string;\n attachments: Attachment[];\n flags: string[];\n}\n\ninterface FetchEmailBodyResult {\n bodyText: string;\n bodyHtml: string;\n attachments: Attachment[];\n}\n\ninterface Boxes {\n [key: string]: Imap.Mailbox;\n}\n\ninterface BoxWithChildren extends Imap.Mailbox {\n children?: Boxes;\n}\n\nclass IMAPClient {\n private config: ImapConfig;\n private imap: Imap | null;\n private connected: boolean;\n\n constructor(config: ImapConfig) {\n this.config = config;\n this.imap = null;\n this.connected = false;\n }\n\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.imap = new Imap({\n user: this.config.user,\n password: this.config.password,\n host: this.config.host,\n port: this.config.port,\n tls: this.config.secure,\n tlsOptions: { rejectUnauthorized: false },\n });\n\n this.imap.once('ready', () => {\n this.connected = true;\n logger.info('IMAP connection established', {\n host: this.config.host,\n });\n resolve();\n });\n\n this.imap.once('error', (err: Error) => {\n logger.error('IMAP connection error', { error: err.message });\n if (err.message.includes('auth')) {\n reject(\n new AuthenticationError(`Authentication failed: ${err.message}`)\n );\n } else {\n reject(new ConnectionError(`Connection failed: ${err.message}`));\n }\n });\n\n this.imap.once('end', () => {\n this.connected = false;\n logger.info('IMAP connection ended');\n });\n\n this.imap.connect();\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to connect to IMAP', { error: err.message });\n reject(new ConnectionError(`Failed to connect: ${err.message}`));\n }\n });\n }\n\n disconnect(): void {\n if (this.imap && this.connected) {\n this.imap.end();\n logger.info('IMAP disconnected');\n }\n }\n\n getImap(): Imap | null {\n return this.imap;\n }\n\n listFolders(): Promise<ImapFolder[]> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.getBoxes((err: Error | null, boxes: Boxes) => {\n if (err) {\n logger.error('Failed to list folders', { error: err.message });\n return reject(\n new ConnectionError(`Failed to list folders: ${err.message}`)\n );\n }\n\n const folders = this._flattenBoxes(boxes);\n logger.debug('Folders listed', { count: folders.length });\n resolve(folders);\n });\n });\n }\n\n openFolder(folderName = 'INBOX', readOnly = true): Promise<Imap.Box> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.openBox(\n folderName,\n readOnly,\n (err: Error | null, box: Imap.Box) => {\n if (err) {\n logger.error('Failed to open folder', {\n folder: folderName,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to open folder: ${err.message}`)\n );\n }\n\n logger.debug('Folder opened', {\n folder: folderName,\n messages: box.messages?.total || 0,\n });\n resolve(box);\n }\n );\n });\n }\n\n fetchEmails(\n criteria: string[] = ['ALL'],\n options: FetchOptions = {}\n ): Promise<ImapMessage[]> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n const searchStartTime = Date.now();\n this.imap!.search(criteria, async (err: Error | null, uids: number[]) => {\n if (err) {\n logger.error('Failed to search emails', { error: err.message });\n return reject(\n new ConnectionError(`Failed to search emails: ${err.message}`)\n );\n }\n\n if (!uids || uids.length === 0) {\n logger.debug('No emails found');\n return resolve([]);\n }\n\n logger.info('[PERF] Email search completed', {\n count: uids.length,\n duration: `${Date.now() - searchStartTime}ms`,\n });\n\n const batchSize = options.batchSize || 100;\n const fetchBody = options.fetchBody || false;\n const allEmails: ImapMessage[] = [];\n\n try {\n for (let i = 0; i < uids.length; i += batchSize) {\n const batchUids = uids.slice(i, i + batchSize);\n const batchNum = Math.floor(i / batchSize) + 1;\n const totalBatches = Math.ceil(uids.length / batchSize);\n\n logger.info('[PERF] Fetching batch', {\n batch: `${batchNum}/${totalBatches}`,\n uids: `${i + 1}-${Math.min(i + batchSize, uids.length)}`,\n count: batchUids.length,\n mode: fetchBody ? 'full' : 'headers-only',\n });\n\n const batchEmails = await this._fetchBatch(batchUids, fetchBody);\n allEmails.push(...batchEmails);\n\n logger.info('[PERF] Batch fetched', {\n batch: `${batchNum}/${totalBatches}`,\n count: batchEmails.length,\n total: allEmails.length,\n });\n }\n\n logger.info('[PERF] All batches fetched', {\n totalCount: allEmails.length,\n duration: `${Date.now() - searchStartTime}ms`,\n });\n\n resolve(allEmails);\n } catch (error) {\n reject(error);\n }\n });\n });\n }\n\n private _fetchBatch(\n uids: number[],\n fetchBody = false\n ): Promise<ImapMessage[]> {\n return new Promise((resolve, reject) => {\n const fetchStartTime = Date.now();\n const emails: ImapMessage[] = [];\n const totalInBatch = uids.length;\n let completedInBatch = 0;\n let totalBytesReceived = 0;\n\n const fetchOptions: Imap.FetchOptions = {\n bodies: fetchBody ? '' : 'HEADER',\n struct: true,\n };\n\n const fetch = this.imap!.fetch(uids, fetchOptions);\n\n fetch.on('message', (msg: Imap.ImapMessage, seqno: number) => {\n const msgStartTime = Date.now();\n const emailData: EmailData = {\n uid: null,\n attributes: null,\n body: '',\n headers: null,\n };\n let bytesReceived = 0;\n\n msg.on(\n 'body',\n (stream: NodeJS.ReadableStream, info: Imap.MessageBodyInfo) => {\n let buffer = '';\n stream.on('data', (chunk: Buffer) => {\n const chunkSize = chunk.length;\n bytesReceived += chunkSize;\n totalBytesReceived += chunkSize;\n buffer += chunk.toString('utf8');\n\n if (\n fetchBody &&\n bytesReceived > 100 * 1024 &&\n bytesReceived % (50 * 1024) < chunkSize\n ) {\n logger.debug('[PERF] Receiving large email', {\n uid: emailData.uid || 'unknown',\n received: `${Math.round(bytesReceived / 1024)}KB`,\n progress: `${completedInBatch + 1}/${totalInBatch}`,\n });\n }\n });\n stream.once('end', () => {\n if (info.which === 'HEADER') {\n emailData.headers = buffer;\n } else {\n emailData.body = buffer;\n }\n });\n }\n );\n\n msg.once('attributes', (attrs: Imap.MessageAttributes) => {\n emailData.uid = attrs.uid;\n emailData.attributes = attrs;\n });\n\n msg.once('end', () => {\n completedInBatch++;\n emails.push({\n uid: emailData.uid!,\n attributes: emailData.attributes!,\n body: emailData.body,\n headers: emailData.headers,\n });\n\n const elapsedTime = Date.now() - fetchStartTime;\n const avgTimePerMsg = elapsedTime / completedInBatch;\n const estimatedRemaining = Math.round(\n (avgTimePerMsg * (totalInBatch - completedInBatch)) / 1000\n );\n\n logger.info('[PERF] Message fetched', {\n uid: emailData.uid,\n progress: `${completedInBatch}/${totalInBatch}`,\n percentage: `${Math.round((completedInBatch / totalInBatch) * 100)}%`,\n size: `${Math.round(bytesReceived / 1024)}KB`,\n duration: `${Date.now() - msgStartTime}ms`,\n totalReceived: `${Math.round(totalBytesReceived / 1024)}KB`,\n estimatedRemaining:\n estimatedRemaining > 0 ? `${estimatedRemaining}s` : 'finishing',\n });\n });\n });\n\n fetch.once('error', (err: Error) => {\n logger.error('Fetch batch error', { error: err.message });\n reject(new ConnectionError(`Fetch batch error: ${err.message}`));\n });\n\n fetch.once('end', () => {\n const totalDuration = Date.now() - fetchStartTime;\n const avgSpeed = totalBytesReceived / (totalDuration / 1000);\n\n logger.info('[PERF] Batch fetch completed', {\n count: emails.length,\n duration: `${totalDuration}ms`,\n totalSize: `${Math.round(totalBytesReceived / 1024)}KB`,\n avgSpeed: `${Math.round(avgSpeed / 1024)}KB/s`,\n avgPerMessage:\n emails.length > 0\n ? `${Math.round(totalDuration / emails.length)}ms`\n : 'N/A',\n });\n resolve(emails);\n });\n });\n }\n\n fetchEmailById(uid: number): Promise<ImapMessage> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n const fetch = this.imap!.fetch([uid], {\n bodies: '',\n struct: true,\n });\n\n const emailData: EmailData = {\n uid: null,\n attributes: null,\n body: '',\n headers: null,\n };\n\n fetch.on('message', (msg: Imap.ImapMessage) => {\n msg.on('body', (stream: NodeJS.ReadableStream) => {\n let buffer = '';\n stream.on('data', (chunk: Buffer) => {\n buffer += chunk.toString('utf8');\n });\n stream.once('end', () => {\n emailData.body = buffer;\n });\n });\n\n msg.once('attributes', (attrs: Imap.MessageAttributes) => {\n emailData.uid = attrs.uid;\n emailData.attributes = attrs;\n });\n });\n\n fetch.once('error', (err: Error) => {\n logger.error('Fetch error', { uid, error: err.message });\n reject(new ConnectionError(`Fetch error: ${err.message}`));\n });\n\n fetch.once('end', () => {\n logger.debug('Email fetched', { uid });\n resolve({\n uid: emailData.uid!,\n attributes: emailData.attributes!,\n body: emailData.body,\n headers: emailData.headers,\n });\n });\n });\n }\n\n async fetchEmailBody(uid: number): Promise<FetchEmailBodyResult> {\n const startTime = Date.now();\n try {\n logger.info('[PERF] Fetching email body on demand', { uid });\n\n const emailData = await this.fetchEmailById(uid);\n const parsed = await this.parseEmail(emailData);\n\n logger.info('[PERF] Email body fetched', {\n uid,\n duration: `${Date.now() - startTime}ms`,\n bodyTextSize: `${Math.round((parsed.bodyText?.length || 0) / 1024)}KB`,\n bodyHtmlSize: `${Math.round((parsed.bodyHtml?.length || 0) / 1024)}KB`,\n });\n\n return {\n bodyText: parsed.bodyText,\n bodyHtml: parsed.bodyHtml,\n attachments: parsed.attachments,\n };\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to fetch email body', { uid, error: err.message });\n throw error;\n }\n }\n\n markAsRead(uid: number): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.addFlags(uid, ['\\\\Seen'], (err: Error | null) => {\n if (err) {\n logger.error('Failed to mark as read', { uid, error: err.message });\n return reject(\n new ConnectionError(`Failed to mark as read: ${err.message}`)\n );\n }\n logger.debug('Email marked as read', { uid });\n resolve();\n });\n });\n }\n\n markAsUnread(uid: number): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.delFlags(uid, ['\\\\Seen'], (err: Error | null) => {\n if (err) {\n logger.error('Failed to mark as unread', { uid, error: err.message });\n return reject(\n new ConnectionError(`Failed to mark as unread: ${err.message}`)\n );\n }\n logger.debug('Email marked as unread', { uid });\n resolve();\n });\n });\n }\n\n moveEmail(uid: number, targetFolder: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.move(uid, targetFolder, (err: Error | null) => {\n if (err) {\n logger.error('Failed to move email', {\n uid,\n targetFolder,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to move email: ${err.message}`)\n );\n }\n logger.debug('Email moved', { uid, targetFolder });\n resolve();\n });\n });\n }\n\n copyEmail(uid: number, targetFolder: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.copy(uid, targetFolder, (err: Error | null) => {\n if (err) {\n logger.error('Failed to copy email', {\n uid,\n targetFolder,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to copy email: ${err.message}`)\n );\n }\n logger.debug('Email copied', { uid, targetFolder });\n resolve();\n });\n });\n }\n\n createFolder(folderName: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.addBox(folderName, (err: Error | null) => {\n if (err) {\n logger.error('Failed to create folder', {\n folderName,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to create folder: ${err.message}`)\n );\n }\n logger.debug('Folder created on server', { folderName });\n resolve();\n });\n });\n }\n\n deleteFolder(folderName: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.delBox(folderName, (err: Error | null) => {\n if (err) {\n logger.error('Failed to delete folder', {\n folderName,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to delete folder: ${err.message}`)\n );\n }\n logger.debug('Folder deleted from server', { folderName });\n resolve();\n });\n });\n }\n\n renameFolder(oldName: string, newName: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n this.imap!.renameBox(oldName, newName, (err: Error | null) => {\n if (err) {\n logger.error('Failed to rename folder', {\n oldName,\n newName,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to rename folder: ${err.message}`)\n );\n }\n logger.debug('Folder renamed on server', { oldName, newName });\n resolve();\n });\n });\n }\n\n batchMoveEmails(uids: number[], targetFolder: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n if (!uids || uids.length === 0) {\n return resolve();\n }\n\n this.imap!.move(uids, targetFolder, (err: Error | null) => {\n if (err) {\n logger.error('Failed to batch move emails', {\n count: uids.length,\n targetFolder,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to batch move emails: ${err.message}`)\n );\n }\n logger.debug('Emails batch moved', {\n count: uids.length,\n targetFolder,\n });\n resolve();\n });\n });\n }\n\n batchCopyEmails(uids: number[], targetFolder: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n if (!uids || uids.length === 0) {\n return resolve();\n }\n\n this.imap!.copy(uids, targetFolder, (err: Error | null) => {\n if (err) {\n logger.error('Failed to batch copy emails', {\n count: uids.length,\n targetFolder,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to batch copy emails: ${err.message}`)\n );\n }\n logger.debug('Emails batch copied', {\n count: uids.length,\n targetFolder,\n });\n resolve();\n });\n });\n }\n\n deleteEmail(uid: number, permanent = false): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n if (permanent) {\n this.imap!.addFlags(uid, ['\\\\Deleted'], (err: Error | null) => {\n if (err) {\n logger.error('Failed to mark email for deletion', {\n uid,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to mark for deletion: ${err.message}`)\n );\n }\n\n this.imap!.expunge((expungeErr: Error | null) => {\n if (expungeErr) {\n logger.error('Failed to expunge email', {\n uid,\n error: expungeErr.message,\n });\n return reject(\n new ConnectionError(`Failed to expunge: ${expungeErr.message}`)\n );\n }\n logger.debug('Email permanently deleted', { uid });\n resolve();\n });\n });\n } else {\n this.moveEmail(uid, 'Trash').then(resolve).catch(reject);\n }\n });\n }\n\n batchDeleteEmails(uids: number[], permanent = false): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.connected) {\n return reject(new ConnectionError('Not connected to IMAP server'));\n }\n\n if (!uids || uids.length === 0) {\n return resolve();\n }\n\n if (permanent) {\n this.imap!.addFlags(uids, ['\\\\Deleted'], (err: Error | null) => {\n if (err) {\n logger.error('Failed to mark emails for deletion', {\n count: uids.length,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to mark for deletion: ${err.message}`)\n );\n }\n\n this.imap!.expunge((expungeErr: Error | null) => {\n if (expungeErr) {\n logger.error('Failed to expunge emails', {\n count: uids.length,\n error: expungeErr.message,\n });\n return reject(\n new ConnectionError(`Failed to expunge: ${expungeErr.message}`)\n );\n }\n logger.debug('Emails permanently deleted', { count: uids.length });\n resolve();\n });\n });\n } else {\n this.imap!.move(uids, 'Trash', (err: Error | null) => {\n if (err) {\n logger.error('Failed to move emails to trash', {\n count: uids.length,\n error: err.message,\n });\n return reject(\n new ConnectionError(`Failed to move to trash: ${err.message}`)\n );\n }\n logger.debug('Emails moved to trash', { count: uids.length });\n resolve();\n });\n }\n });\n }\n\n async parseEmail(emailData: ImapMessage): Promise<ParsedEmailResult> {\n const parseStartTime = Date.now();\n try {\n const contentToParse = emailData.body || emailData.headers || '';\n const parsed = await simpleParser(contentToParse);\n\n const date = parsed.date || new Date();\n const dateString =\n date instanceof Date ? date.toISOString() : String(date);\n\n const result: ParsedEmailResult = {\n uid: emailData.uid,\n messageId: parsed.messageId || undefined,\n from: Array.isArray(parsed.from)\n ? parsed.from.map((f) => f.text).join(', ')\n : parsed.from?.text || '',\n to: Array.isArray(parsed.to)\n ? parsed.to.map((t) => t.text).join(', ')\n : parsed.to?.text || '',\n cc: Array.isArray(parsed.cc)\n ? parsed.cc.map((c) => c.text).join(', ')\n : parsed.cc?.text || '',\n subject: parsed.subject || '',\n date: dateString,\n bodyText: parsed.text || '',\n bodyHtml: parsed.html || '',\n attachments: parsed.attachments || [],\n flags: emailData.attributes?.flags || [],\n };\n\n logger.debug('[PERF] Email parsing completed', {\n uid: emailData.uid,\n duration: `${Date.now() - parseStartTime}ms`,\n mode: emailData.body ? 'full' : 'headers-only',\n bodyTextSize: result.bodyText\n ? `${Math.round(result.bodyText.length / 1024)}KB`\n : '0KB',\n bodyHtmlSize: result.bodyHtml\n ? `${Math.round(result.bodyHtml.length / 1024)}KB`\n : '0KB',\n attachmentCount: result.attachments.length,\n });\n\n return result;\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to parse email', { error: err.message });\n throw error;\n }\n }\n\n private _flattenBoxes(boxes: Boxes, prefix = ''): ImapFolder[] {\n const folders: ImapFolder[] = [];\n for (const [name, box] of Object.entries(boxes)) {\n const fullName = prefix ? `${prefix}${box.delimiter}${name}` : name;\n folders.push({\n name: fullName,\n delimiter: box.delimiter,\n flags: box.attribs || [],\n });\n const boxWithChildren = box as BoxWithChildren;\n if (boxWithChildren.children) {\n folders.push(...this._flattenBoxes(boxWithChildren.children, fullName));\n }\n }\n return folders;\n }\n}\n\nexport default IMAPClient;\n","import nodemailer from 'nodemailer';\n\nimport type { SmtpConfig, EmailSendData } from '../types/smtp';\n\nimport { ConnectionError, AuthenticationError } from '../utils/errors';\nimport logger from '../utils/logger';\n\nclass SMTPClient {\n private config: SmtpConfig;\n private transporter: nodemailer.Transporter | null;\n\n constructor(config: SmtpConfig) {\n this.config = config;\n this.transporter = null;\n }\n\n async connect(): Promise<boolean> {\n try {\n this.transporter = nodemailer.createTransport({\n host: this.config.host,\n port: this.config.port,\n secure: this.config.secure,\n auth: {\n user: this.config.user,\n pass: this.config.password,\n },\n });\n\n await this.transporter.verify();\n logger.info('SMTP connection established', { host: this.config.host });\n return true;\n } catch (error) {\n const err = error as Error;\n logger.error('SMTP connection failed', { error: err.message });\n if (err.message.includes('auth')) {\n throw new AuthenticationError(`Authentication failed: ${err.message}`);\n } else {\n throw new ConnectionError(`Connection failed: ${err.message}`);\n }\n }\n }\n\n async verifyConnection(): Promise<boolean> {\n try {\n if (!this.transporter) {\n await this.connect();\n }\n await this.transporter!.verify();\n return true;\n } catch (error) {\n const err = error as Error;\n logger.error('SMTP verification failed', { error: err.message });\n throw new ConnectionError(`Verification failed: ${err.message}`);\n }\n }\n\n async sendEmail(\n emailData: EmailSendData\n ): Promise<{ success: boolean; messageId: string; response: string }> {\n try {\n if (!this.transporter) {\n await this.connect();\n }\n\n const mailOptions: nodemailer.SendMailOptions = {\n from: emailData.from || this.config.user,\n to: emailData.to,\n cc: emailData.cc,\n bcc: emailData.bcc,\n subject: emailData.subject,\n text: emailData.text,\n html: emailData.html,\n attachments: emailData.attachments,\n inReplyTo: emailData.inReplyTo,\n references: emailData.references,\n };\n\n const info = await this.transporter!.sendMail(mailOptions);\n logger.info('Email sent successfully', {\n messageId: info.messageId,\n to: emailData.to,\n });\n return {\n success: true,\n messageId: info.messageId || '',\n response: info.response || '',\n };\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to send email', { error: err.message });\n throw new ConnectionError(`Failed to send email: ${err.message}`);\n }\n }\n\n disconnect(): void {\n if (this.transporter) {\n this.transporter.close();\n this.transporter = null;\n logger.info('SMTP connection closed');\n }\n }\n}\n\nexport default SMTPClient;\n","import type { SQLiteDatabase } from '../../types/database';\n\n/**\n * Database initialization migration.\n */\nconst createEmailsTable = `\nCREATE TABLE IF NOT EXISTS emails (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n uid INTEGER NOT NULL,\n message_id TEXT UNIQUE,\n folder TEXT NOT NULL,\n from_address TEXT,\n to_address TEXT,\n cc_address TEXT,\n subject TEXT,\n date DATETIME,\n body_text TEXT,\n body_html TEXT,\n has_attachments BOOLEAN DEFAULT 0,\n is_read BOOLEAN DEFAULT 0,\n flags TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP\n);\n`;\n\nconst createAttachmentsTable = `\nCREATE TABLE IF NOT EXISTS attachments (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email_id INTEGER NOT NULL,\n filename TEXT NOT NULL,\n content_type TEXT,\n size INTEGER,\n file_path TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (email_id) REFERENCES emails(id) ON DELETE CASCADE\n);\n`;\n\nconst createFoldersTable = `\nCREATE TABLE IF NOT EXISTS folders (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT UNIQUE NOT NULL,\n delimiter TEXT,\n flags TEXT,\n last_sync DATETIME,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n);\n`;\n\nconst createIndexes = [\n 'CREATE INDEX IF NOT EXISTS idx_emails_uid ON emails(uid);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_folder ON emails(folder);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_date ON emails(date);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_from ON emails(from_address);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_subject ON emails(subject);',\n 'CREATE INDEX IF NOT EXISTS idx_attachments_email_id ON attachments(email_id);',\n];\n\n/**\n * Apply migration.\n */\nexport function up(db: SQLiteDatabase): void {\n db.exec(createEmailsTable);\n db.exec(createAttachmentsTable);\n db.exec(createFoldersTable);\n createIndexes.forEach((indexSql) => db.exec(indexSql));\n}\n\n/**\n * Roll back migration.\n */\nexport function down(db: SQLiteDatabase): void {\n db.exec('DROP TABLE IF EXISTS attachments;');\n db.exec('DROP TABLE IF EXISTS emails;');\n db.exec('DROP TABLE IF EXISTS folders;');\n}\n","import type { SQLiteDatabase } from '../../types/database';\n\n/**\n * Extract readable message from unknown errors.\n */\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * P0 features migration.\n */\nconst alterEmailsTable = [\n 'ALTER TABLE emails ADD COLUMN is_draft BOOLEAN DEFAULT 0;',\n 'ALTER TABLE emails ADD COLUMN is_deleted BOOLEAN DEFAULT 0;',\n 'ALTER TABLE emails ADD COLUMN is_spam BOOLEAN DEFAULT 0;',\n 'ALTER TABLE emails ADD COLUMN in_reply_to TEXT;',\n 'ALTER TABLE emails ADD COLUMN email_references TEXT;',\n 'ALTER TABLE emails ADD COLUMN thread_id TEXT;',\n 'ALTER TABLE emails ADD COLUMN deleted_at DATETIME;',\n];\n\nconst createSignaturesTable = `\nCREATE TABLE IF NOT EXISTS signatures (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n content_text TEXT,\n content_html TEXT,\n is_default BOOLEAN DEFAULT 0,\n account_email TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP\n);\n`;\n\nconst createSpamRulesTable = `\nCREATE TABLE IF NOT EXISTS spam_rules (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n rule_type TEXT NOT NULL,\n pattern TEXT NOT NULL,\n action TEXT NOT NULL,\n is_enabled BOOLEAN DEFAULT 1,\n priority INTEGER DEFAULT 0,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n);\n`;\n\nconst createBlacklistTable = `\nCREATE TABLE IF NOT EXISTS blacklist (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email_address TEXT UNIQUE NOT NULL,\n domain TEXT,\n reason TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n);\n`;\n\nconst createWhitelistTable = `\nCREATE TABLE IF NOT EXISTS whitelist (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email_address TEXT UNIQUE NOT NULL,\n domain TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n);\n`;\n\nconst createIndexes = [\n 'CREATE INDEX IF NOT EXISTS idx_emails_is_draft ON emails(is_draft);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_is_deleted ON emails(is_deleted);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_is_spam ON emails(is_spam);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_thread_id ON emails(thread_id);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_in_reply_to ON emails(in_reply_to);',\n 'CREATE INDEX IF NOT EXISTS idx_signatures_account ON signatures(account_email);',\n 'CREATE INDEX IF NOT EXISTS idx_signatures_is_default ON signatures(is_default);',\n 'CREATE INDEX IF NOT EXISTS idx_spam_rules_type ON spam_rules(rule_type);',\n 'CREATE INDEX IF NOT EXISTS idx_spam_rules_enabled ON spam_rules(is_enabled);',\n 'CREATE INDEX IF NOT EXISTS idx_blacklist_email ON blacklist(email_address);',\n 'CREATE INDEX IF NOT EXISTS idx_blacklist_domain ON blacklist(domain);',\n 'CREATE INDEX IF NOT EXISTS idx_whitelist_email ON whitelist(email_address);',\n 'CREATE INDEX IF NOT EXISTS idx_whitelist_domain ON whitelist(domain);',\n];\n\n/**\n * Apply migration.\n */\nexport function up(db: SQLiteDatabase): void {\n alterEmailsTable.forEach((sql) => {\n try {\n db.exec(sql);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (!errorMessage.includes('duplicate column name')) {\n throw error;\n }\n }\n });\n\n db.exec(createSignaturesTable);\n db.exec(createSpamRulesTable);\n db.exec(createBlacklistTable);\n db.exec(createWhitelistTable);\n\n createIndexes.forEach((indexSql) => db.exec(indexSql));\n\n const insertDefaultRules = db.prepare(`\n INSERT INTO spam_rules (rule_type, pattern, action, priority)\n VALUES (?, ?, ?, ?)\n `);\n\n const defaultRules = [\n {\n type: 'keyword',\n pattern: 'viagra|cialis|lottery|winner|prize',\n action: 'mark_spam',\n priority: 10,\n },\n {\n type: 'keyword',\n pattern: 'click here|act now|limited time',\n action: 'mark_spam',\n priority: 5,\n },\n {\n type: 'header',\n pattern: 'X-Spam-Flag: YES',\n action: 'mark_spam',\n priority: 20,\n },\n ];\n\n defaultRules.forEach((rule) => {\n try {\n insertDefaultRules.run(\n rule.type,\n rule.pattern,\n rule.action,\n rule.priority\n );\n } catch {\n // Ignore duplicate inserts to keep migration idempotent.\n }\n });\n}\n\n/**\n * Roll back migration.\n */\nexport function down(db: SQLiteDatabase): void {\n db.exec('DROP TABLE IF EXISTS whitelist;');\n db.exec('DROP TABLE IF EXISTS blacklist;');\n db.exec('DROP TABLE IF EXISTS spam_rules;');\n db.exec('DROP TABLE IF EXISTS signatures;');\n}\n","import type { SQLiteDatabase } from '../../types/database';\n\n/**\n * Extract readable message from unknown errors.\n */\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nconst createTagsTable = `\nCREATE TABLE IF NOT EXISTS tags (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT UNIQUE NOT NULL,\n color TEXT DEFAULT '#808080',\n description TEXT,\n account_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst createEmailTagsTable = `\nCREATE TABLE IF NOT EXISTS email_tags (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email_id INTEGER NOT NULL,\n tag_id INTEGER NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (email_id) REFERENCES emails(id) ON DELETE CASCADE,\n FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE,\n UNIQUE(email_id, tag_id)\n);\n`;\n\nconst createFiltersTable = `\nCREATE TABLE IF NOT EXISTS filters (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n description TEXT,\n is_enabled BOOLEAN DEFAULT 1,\n priority INTEGER DEFAULT 0,\n match_all BOOLEAN DEFAULT 1,\n account_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst createFilterConditionsTable = `\nCREATE TABLE IF NOT EXISTS filter_conditions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n filter_id INTEGER NOT NULL,\n field TEXT NOT NULL,\n operator TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (filter_id) REFERENCES filters(id) ON DELETE CASCADE\n);\n`;\n\nconst createFilterActionsTable = `\nCREATE TABLE IF NOT EXISTS filter_actions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n filter_id INTEGER NOT NULL,\n action_type TEXT NOT NULL,\n action_value TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (filter_id) REFERENCES filters(id) ON DELETE CASCADE\n);\n`;\n\nconst createContactsTable = `\nCREATE TABLE IF NOT EXISTS contacts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email TEXT UNIQUE NOT NULL,\n display_name TEXT,\n first_name TEXT,\n last_name TEXT,\n nickname TEXT,\n phone TEXT,\n company TEXT,\n job_title TEXT,\n notes TEXT,\n photo_path TEXT,\n is_favorite BOOLEAN DEFAULT 0,\n account_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst createContactGroupsTable = `\nCREATE TABLE IF NOT EXISTS contact_groups (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n description TEXT,\n account_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst createContactGroupMembersTable = `\nCREATE TABLE IF NOT EXISTS contact_group_members (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n group_id INTEGER NOT NULL,\n contact_id INTEGER NOT NULL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (group_id) REFERENCES contact_groups(id) ON DELETE CASCADE,\n FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE CASCADE,\n UNIQUE(group_id, contact_id)\n);\n`;\n\nconst createAccountsTable = `\nCREATE TABLE IF NOT EXISTS accounts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email TEXT UNIQUE NOT NULL,\n display_name TEXT,\n imap_host TEXT NOT NULL,\n imap_port INTEGER NOT NULL,\n imap_secure BOOLEAN DEFAULT 1,\n smtp_host TEXT NOT NULL,\n smtp_port INTEGER NOT NULL,\n smtp_secure BOOLEAN DEFAULT 1,\n username TEXT NOT NULL,\n password TEXT NOT NULL,\n is_default BOOLEAN DEFAULT 0,\n is_enabled BOOLEAN DEFAULT 1,\n sync_interval INTEGER DEFAULT 300,\n last_sync DATETIME,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP\n);\n`;\n\nconst createThreadsTable = `\nCREATE TABLE IF NOT EXISTS threads (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n thread_id TEXT UNIQUE NOT NULL,\n subject TEXT,\n first_message_date DATETIME,\n last_message_date DATETIME,\n message_count INTEGER DEFAULT 0,\n account_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst createSavedSearchesTable = `\nCREATE TABLE IF NOT EXISTS saved_searches (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT UNIQUE NOT NULL,\n query TEXT NOT NULL,\n description TEXT,\n account_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst alterEmailsTable = [\n 'ALTER TABLE emails ADD COLUMN account_id INTEGER;',\n 'ALTER TABLE emails ADD COLUMN is_starred BOOLEAN DEFAULT 0;',\n 'ALTER TABLE emails ADD COLUMN is_important BOOLEAN DEFAULT 0;',\n 'ALTER TABLE emails ADD COLUMN priority INTEGER DEFAULT 0;',\n];\n\nconst alterFoldersTable = [\n 'ALTER TABLE folders ADD COLUMN account_id INTEGER;',\n 'ALTER TABLE folders ADD COLUMN parent_id INTEGER;',\n 'ALTER TABLE folders ADD COLUMN is_favorite BOOLEAN DEFAULT 0;',\n 'ALTER TABLE folders ADD COLUMN sort_order INTEGER DEFAULT 0;',\n 'ALTER TABLE folders ADD COLUMN unread_count INTEGER DEFAULT 0;',\n 'ALTER TABLE folders ADD COLUMN total_count INTEGER DEFAULT 0;',\n];\n\nconst createIndexes = [\n 'CREATE INDEX IF NOT EXISTS idx_tags_name ON tags(name);',\n 'CREATE INDEX IF NOT EXISTS idx_tags_account ON tags(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_email_tags_email ON email_tags(email_id);',\n 'CREATE INDEX IF NOT EXISTS idx_email_tags_tag ON email_tags(tag_id);',\n 'CREATE INDEX IF NOT EXISTS idx_filters_enabled ON filters(is_enabled);',\n 'CREATE INDEX IF NOT EXISTS idx_filters_priority ON filters(priority);',\n 'CREATE INDEX IF NOT EXISTS idx_filters_account ON filters(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_filter_conditions_filter ON filter_conditions(filter_id);',\n 'CREATE INDEX IF NOT EXISTS idx_filter_actions_filter ON filter_actions(filter_id);',\n 'CREATE INDEX IF NOT EXISTS idx_contacts_email ON contacts(email);',\n 'CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(display_name);',\n 'CREATE INDEX IF NOT EXISTS idx_contacts_favorite ON contacts(is_favorite);',\n 'CREATE INDEX IF NOT EXISTS idx_contacts_account ON contacts(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_contact_groups_account ON contact_groups(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_contact_group_members_group ON contact_group_members(group_id);',\n 'CREATE INDEX IF NOT EXISTS idx_contact_group_members_contact ON contact_group_members(contact_id);',\n 'CREATE INDEX IF NOT EXISTS idx_accounts_email ON accounts(email);',\n 'CREATE INDEX IF NOT EXISTS idx_accounts_is_default ON accounts(is_default);',\n 'CREATE INDEX IF NOT EXISTS idx_accounts_is_enabled ON accounts(is_enabled);',\n 'CREATE INDEX IF NOT EXISTS idx_threads_thread_id ON threads(thread_id);',\n 'CREATE INDEX IF NOT EXISTS idx_threads_account ON threads(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_threads_last_message ON threads(last_message_date);',\n 'CREATE INDEX IF NOT EXISTS idx_saved_searches_name ON saved_searches(name);',\n 'CREATE INDEX IF NOT EXISTS idx_saved_searches_account ON saved_searches(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_account ON emails(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_is_starred ON emails(is_starred);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_is_important ON emails(is_important);',\n 'CREATE INDEX IF NOT EXISTS idx_emails_priority ON emails(priority);',\n 'CREATE INDEX IF NOT EXISTS idx_folders_account ON folders(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_folders_parent ON folders(parent_id);',\n 'CREATE INDEX IF NOT EXISTS idx_folders_favorite ON folders(is_favorite);',\n 'CREATE INDEX IF NOT EXISTS idx_folders_sort_order ON folders(sort_order);',\n];\n\n/**\n * Apply migration.\n */\nexport function up(db: SQLiteDatabase): void {\n db.exec(createAccountsTable);\n db.exec(createTagsTable);\n db.exec(createEmailTagsTable);\n db.exec(createFiltersTable);\n db.exec(createFilterConditionsTable);\n db.exec(createFilterActionsTable);\n db.exec(createContactsTable);\n db.exec(createContactGroupsTable);\n db.exec(createContactGroupMembersTable);\n db.exec(createThreadsTable);\n db.exec(createSavedSearchesTable);\n\n alterEmailsTable.forEach((sql) => {\n try {\n db.exec(sql);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (!errorMessage.includes('duplicate column name')) {\n throw error;\n }\n }\n });\n\n alterFoldersTable.forEach((sql) => {\n try {\n db.exec(sql);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (!errorMessage.includes('duplicate column name')) {\n throw error;\n }\n }\n });\n\n createIndexes.forEach((indexSql) => db.exec(indexSql));\n\n const insertDefaultTags = db.prepare(`\n INSERT INTO tags (name, color, description)\n VALUES (?, ?, ?)\n `);\n\n const defaultTags = [\n { name: 'Important', color: '#FF0000', description: 'Important emails' },\n { name: 'Work', color: '#0000FF', description: 'Work-related emails' },\n { name: 'Personal', color: '#00FF00', description: 'Personal emails' },\n {\n name: 'Follow Up',\n color: '#FFA500',\n description: 'Emails requiring follow-up',\n },\n { name: 'To Read', color: '#800080', description: 'Emails to read later' },\n ];\n\n defaultTags.forEach((tag) => {\n try {\n insertDefaultTags.run(tag.name, tag.color, tag.description);\n } catch {\n // Ignore duplicate inserts to keep migration idempotent.\n }\n });\n}\n\n/**\n * Roll back migration.\n */\nexport function down(db: SQLiteDatabase): void {\n db.exec('DROP TABLE IF EXISTS contact_group_members;');\n db.exec('DROP TABLE IF EXISTS contact_groups;');\n db.exec('DROP TABLE IF EXISTS contacts;');\n db.exec('DROP TABLE IF EXISTS filter_actions;');\n db.exec('DROP TABLE IF EXISTS filter_conditions;');\n db.exec('DROP TABLE IF EXISTS filters;');\n db.exec('DROP TABLE IF EXISTS email_tags;');\n db.exec('DROP TABLE IF EXISTS tags;');\n db.exec('DROP TABLE IF EXISTS threads;');\n db.exec('DROP TABLE IF EXISTS saved_searches;');\n db.exec('DROP TABLE IF EXISTS accounts;');\n}\n","import type { SQLiteDatabase } from '../../types/database';\n\nconst createTemplatesTable = `\nCREATE TABLE IF NOT EXISTS templates (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n subject TEXT NOT NULL,\n body_text TEXT,\n body_html TEXT,\n variables TEXT,\n account_id INTEGER,\n is_enabled BOOLEAN DEFAULT 1,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst createNotificationsTable = `\nCREATE TABLE IF NOT EXISTS notifications (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n email_id INTEGER NOT NULL,\n type TEXT NOT NULL,\n title TEXT,\n message TEXT,\n sent_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n read_at DATETIME,\n account_id INTEGER,\n FOREIGN KEY (email_id) REFERENCES emails(id) ON DELETE CASCADE,\n FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n);\n`;\n\nconst createIndexes = [\n 'CREATE INDEX IF NOT EXISTS idx_templates_name ON templates(name);',\n 'CREATE INDEX IF NOT EXISTS idx_templates_account ON templates(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_templates_enabled ON templates(is_enabled);',\n 'CREATE INDEX IF NOT EXISTS idx_notifications_email ON notifications(email_id);',\n 'CREATE INDEX IF NOT EXISTS idx_notifications_type ON notifications(type);',\n 'CREATE INDEX IF NOT EXISTS idx_notifications_account ON notifications(account_id);',\n 'CREATE INDEX IF NOT EXISTS idx_notifications_sent_at ON notifications(sent_at);',\n 'CREATE INDEX IF NOT EXISTS idx_notifications_read_at ON notifications(read_at);',\n];\n\n/**\n * Apply migration.\n */\nexport function up(db: SQLiteDatabase): void {\n db.exec(createTemplatesTable);\n db.exec(createNotificationsTable);\n createIndexes.forEach((indexSql) => db.exec(indexSql));\n\n const insertDefaultTemplate = db.prepare(`\n INSERT INTO templates (name, subject, body_text, body_html, variables)\n VALUES (?, ?, ?, ?, ?)\n `);\n\n const defaultTemplates = [\n {\n name: 'Welcome Email',\n subject: 'Welcome to {{company_name}}!',\n bodyText:\n 'Hi {{recipient_name}},\\n\\nWelcome to {{company_name}}! We are excited to have you on board.\\n\\nBest regards,\\n{{sender_name}}',\n bodyHtml:\n '<p>Hi {{recipient_name}},</p><p>Welcome to {{company_name}}! We are excited to have you on board.</p><p>Best regards,<br>{{sender_name}}</p>',\n variables: JSON.stringify([\n 'recipient_name',\n 'company_name',\n 'sender_name',\n ]),\n },\n {\n name: 'Meeting Reminder',\n subject: 'Reminder: Meeting on {{meeting_date}}',\n bodyText:\n 'Hi {{recipient_name}},\\n\\nThis is a reminder about our meeting scheduled for {{meeting_date}} at {{meeting_time}}.\\n\\nTopic: {{meeting_topic}}\\nLocation: {{meeting_location}}\\n\\nSee you there!\\n{{sender_name}}',\n bodyHtml:\n '<p>Hi {{recipient_name}},</p><p>This is a reminder about our meeting scheduled for {{meeting_date}} at {{meeting_time}}.</p><p><strong>Topic:</strong> {{meeting_topic}}<br><strong>Location:</strong> {{meeting_location}}</p><p>See you there!<br>{{sender_name}}</p>',\n variables: JSON.stringify([\n 'recipient_name',\n 'meeting_date',\n 'meeting_time',\n 'meeting_topic',\n 'meeting_location',\n 'sender_name',\n ]),\n },\n {\n name: 'Follow Up',\n subject: 'Following up on {{subject}}',\n bodyText:\n 'Hi {{recipient_name}},\\n\\nI wanted to follow up on {{subject}}. Please let me know if you have any questions or need any additional information.\\n\\nBest regards,\\n{{sender_name}}',\n bodyHtml:\n '<p>Hi {{recipient_name}},</p><p>I wanted to follow up on {{subject}}. Please let me know if you have any questions or need any additional information.</p><p>Best regards,<br>{{sender_name}}</p>',\n variables: JSON.stringify(['recipient_name', 'subject', 'sender_name']),\n },\n ];\n\n defaultTemplates.forEach((template) => {\n try {\n insertDefaultTemplate.run(\n template.name,\n template.subject,\n template.bodyText,\n template.bodyHtml,\n template.variables\n );\n } catch {\n // Ignore duplicate inserts to keep migration idempotent.\n }\n });\n}\n\n/**\n * Roll back migration.\n */\nexport function down(db: SQLiteDatabase): void {\n db.exec('DROP TABLE IF EXISTS notifications;');\n db.exec('DROP TABLE IF EXISTS templates;');\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport Database from 'better-sqlite3';\n\nimport { type SQLiteDatabase } from '../types/database';\nimport { StorageError } from '../utils/errors';\nimport { getDataDir } from '../utils/helpers';\nimport logger from '../utils/logger';\nimport { up as up001 } from './migrations/001_initial';\nimport { up as up002 } from './migrations/002_p0_features';\nimport { up as up003 } from './migrations/003_p1_features';\nimport { up as up004 } from './migrations/004_p2_features';\n\n/**\n * Convert unknown error payload to displayable message.\n */\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Database Manager.\n * Handles SQLite database connection and migrations.\n */\nexport class DatabaseManager {\n private dataDir: string;\n private dbPath: string;\n private db: SQLiteDatabase | null;\n\n /**\n * Create database manager.\n */\n constructor(dbPath: string | null = null) {\n if (dbPath) {\n this.dbPath = dbPath;\n this.dataDir = path.dirname(dbPath);\n } else {\n this.dataDir = getDataDir();\n this.dbPath = path.join(this.dataDir, 'mail.db');\n }\n this.db = null;\n }\n\n /**\n * Ensure data directory exists.\n */\n private ensureDataDir(): void {\n if (!fs.existsSync(this.dataDir)) {\n fs.mkdirSync(this.dataDir, { recursive: true });\n logger.info('Created data directory', { path: this.dataDir });\n }\n }\n\n /**\n * Initialize database connection.\n */\n initialize(): SQLiteDatabase {\n try {\n this.ensureDataDir();\n this.db = new Database(this.dbPath);\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n logger.info('Database initialized', { path: this.dbPath });\n this.runMigrations();\n return this.db;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to initialize database', { error: errorMessage });\n throw new StorageError(`Failed to initialize database: ${errorMessage}`);\n }\n }\n\n /**\n * Run database migrations.\n */\n runMigrations(): void {\n try {\n if (!this.db) {\n throw new StorageError('Database not initialized');\n }\n\n up001(this.db);\n up002(this.db);\n up003(this.db);\n up004(this.db);\n\n logger.info('Database migrations completed');\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to run migrations', { error: errorMessage });\n throw new StorageError(`Failed to run migrations: ${errorMessage}`);\n }\n }\n\n /**\n * Get database instance.\n */\n getDb(): SQLiteDatabase {\n if (!this.db) {\n return this.initialize();\n }\n return this.db;\n }\n\n /**\n * Close database connection.\n */\n close(): void {\n if (this.db) {\n this.db.close();\n this.db = null;\n logger.info('Database connection closed');\n }\n }\n}\n\nconst databaseManager = new DatabaseManager();\nexport default databaseManager;\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport { decrypt, encrypt } from '../../utils/helpers';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface AccountInput {\n email: string;\n displayName?: string;\n imapHost: string;\n imapPort?: number;\n imapSecure?: boolean;\n smtpHost: string;\n smtpPort?: number;\n smtpSecure?: boolean;\n username?: string;\n password: string;\n isDefault?: boolean;\n isEnabled?: boolean;\n syncInterval?: number;\n}\n\ntype AccountUpdateInput = Partial<AccountInput>;\n\ninterface AccountFindOptions {\n enabledOnly?: boolean;\n}\n\ninterface AccountRow {\n id: number;\n email: string;\n display_name: string;\n imap_host: string;\n imap_port: number;\n imap_secure: number;\n smtp_host: string;\n smtp_port: number;\n smtp_secure: number;\n username: string;\n password: string;\n is_default: number;\n is_enabled: number;\n sync_interval: number;\n last_sync: string | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface CountRow {\n count: number;\n}\n\ninterface DefaultFlagRow {\n is_default: number;\n}\n\nexport interface AccountRecord {\n id: number;\n email: string;\n displayName: string;\n imapHost: string;\n imapPort: number;\n imapSecure: boolean;\n smtpHost: string;\n smtpPort: number;\n smtpSecure: boolean;\n username: string;\n isDefault: boolean;\n isEnabled: boolean;\n syncInterval: number;\n lastSync: string | null;\n createdAt: string;\n updatedAt: string;\n password?: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Account model.\n */\nexport class AccountModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(accountData: AccountInput): number {\n try {\n const db = this.getDb();\n const encryptedPassword = encrypt(accountData.password);\n\n const stmt = db.prepare(`\n INSERT INTO accounts (\n email, display_name, imap_host, imap_port, imap_secure,\n smtp_host, smtp_port, smtp_secure, username, password,\n is_default, is_enabled, sync_interval\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n accountData.email,\n accountData.displayName ?? accountData.email,\n accountData.imapHost,\n accountData.imapPort ?? 993,\n accountData.imapSecure !== false ? 1 : 0,\n accountData.smtpHost,\n accountData.smtpPort ?? 465,\n accountData.smtpSecure !== false ? 1 : 0,\n accountData.username ?? accountData.email,\n encryptedPassword,\n accountData.isDefault ? 1 : 0,\n accountData.isEnabled !== false ? 1 : 0,\n accountData.syncInterval ?? 300\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.info('Account created', {\n id: insertId,\n email: accountData.email,\n });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create account', { error: errorMessage });\n throw new StorageError(`Failed to create account: ${errorMessage}`);\n }\n }\n\n findById(id: number): AccountRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], AccountRow>(\n 'SELECT * FROM accounts WHERE id = ?'\n );\n const account = stmt.get(id);\n return account ? this.formatAccount(account) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find account by ID', { id, error: errorMessage });\n throw new StorageError(`Failed to find account: ${errorMessage}`);\n }\n }\n\n findByEmail(email: string): AccountRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[string], AccountRow>(\n 'SELECT * FROM accounts WHERE email = ?'\n );\n const account = stmt.get(email);\n return account ? this.formatAccount(account) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find account by email', {\n email,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find account: ${errorMessage}`);\n }\n }\n\n findAll(options: AccountFindOptions = {}): AccountRecord[] {\n try {\n const db = this.getDb();\n const { enabledOnly = false } = options;\n\n let query = 'SELECT * FROM accounts';\n if (enabledOnly) {\n query += ' WHERE is_enabled = 1';\n }\n query += ' ORDER BY is_default DESC, email ASC';\n\n const stmt = db.prepare<[], AccountRow>(query);\n const accounts = stmt.all();\n return accounts.map((account) => this.formatAccount(account));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find accounts', { error: errorMessage });\n throw new StorageError(`Failed to find accounts: ${errorMessage}`);\n }\n }\n\n getDefault(): AccountRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[], AccountRow>(\n 'SELECT * FROM accounts WHERE is_default = 1 AND is_enabled = 1 LIMIT 1'\n );\n const account = stmt.get();\n return account ? this.formatAccount(account) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to get default account', { error: errorMessage });\n throw new StorageError(`Failed to get default account: ${errorMessage}`);\n }\n }\n\n setDefault(id: number): boolean {\n try {\n const db = this.getDb();\n\n const transaction = db.transaction((): void => {\n db.prepare('UPDATE accounts SET is_default = 0').run();\n\n const stmt = db.prepare(\n 'UPDATE accounts SET is_default = 1, updated_at = CURRENT_TIMESTAMP WHERE id = ?'\n );\n const result = stmt.run(id);\n\n if (result.changes === 0) {\n throw new StorageError('Account not found');\n }\n });\n\n transaction();\n logger.info('Default account set', { id });\n return true;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to set default account', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to set default account: ${errorMessage}`);\n }\n }\n\n update(id: number, data: AccountUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number> = [];\n\n if (data.email !== undefined) {\n fields.push('email = ?');\n params.push(data.email);\n }\n\n if (data.displayName !== undefined) {\n fields.push('display_name = ?');\n params.push(data.displayName);\n }\n\n if (data.imapHost !== undefined) {\n fields.push('imap_host = ?');\n params.push(data.imapHost);\n }\n\n if (data.imapPort !== undefined) {\n fields.push('imap_port = ?');\n params.push(data.imapPort);\n }\n\n if (data.imapSecure !== undefined) {\n fields.push('imap_secure = ?');\n params.push(data.imapSecure ? 1 : 0);\n }\n\n if (data.smtpHost !== undefined) {\n fields.push('smtp_host = ?');\n params.push(data.smtpHost);\n }\n\n if (data.smtpPort !== undefined) {\n fields.push('smtp_port = ?');\n params.push(data.smtpPort);\n }\n\n if (data.smtpSecure !== undefined) {\n fields.push('smtp_secure = ?');\n params.push(data.smtpSecure ? 1 : 0);\n }\n\n if (data.username !== undefined) {\n fields.push('username = ?');\n params.push(data.username);\n }\n\n if (data.password !== undefined) {\n fields.push('password = ?');\n params.push(encrypt(data.password));\n }\n\n if (data.isEnabled !== undefined) {\n fields.push('is_enabled = ?');\n params.push(data.isEnabled ? 1 : 0);\n }\n\n if (data.syncInterval !== undefined) {\n fields.push('sync_interval = ?');\n params.push(data.syncInterval);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE accounts SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.info('Account updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update account', { id, error: errorMessage });\n throw new StorageError(`Failed to update account: ${errorMessage}`);\n }\n }\n\n updateLastSync(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare(\n 'UPDATE accounts SET last_sync = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE id = ?'\n );\n const result = stmt.run(id);\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update last sync', { id, error: errorMessage });\n throw new StorageError(`Failed to update last sync: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n\n const countStmt = db.prepare<[], CountRow>(\n 'SELECT COUNT(*) as count FROM accounts'\n );\n const countResult = countStmt.get();\n const totalCount = countResult?.count ?? 0;\n\n if (totalCount === 1) {\n throw new StorageError('Cannot delete the only account');\n }\n\n const accountStmt = db.prepare<[number], DefaultFlagRow>(\n 'SELECT is_default FROM accounts WHERE id = ?'\n );\n const account = accountStmt.get(id);\n\n if (!account) {\n throw new StorageError('Account not found');\n }\n\n const stmt = db.prepare('DELETE FROM accounts WHERE id = ?');\n const result = stmt.run(id);\n\n if (account.is_default === 1) {\n const newDefaultStmt = db.prepare(\n 'UPDATE accounts SET is_default = 1 WHERE id = (SELECT id FROM accounts LIMIT 1)'\n );\n newDefaultStmt.run();\n }\n\n logger.info('Account deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete account', { id, error: errorMessage });\n throw new StorageError(`Failed to delete account: ${errorMessage}`);\n }\n }\n\n count(): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[], CountRow>(\n 'SELECT COUNT(*) as count FROM accounts'\n );\n const result = stmt.get();\n return result?.count ?? 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to count accounts', { error: errorMessage });\n throw new StorageError(`Failed to count accounts: ${errorMessage}`);\n }\n }\n\n getWithPassword(id: number): AccountRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], AccountRow>(\n 'SELECT * FROM accounts WHERE id = ?'\n );\n const account = stmt.get(id);\n return account ? this.formatAccount(account, true) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to get account with password', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to get account: ${errorMessage}`);\n }\n }\n\n private formatAccount(\n account: AccountRow,\n includePassword = false\n ): AccountRecord {\n const formatted: AccountRecord = {\n id: account.id,\n email: account.email,\n displayName: account.display_name,\n imapHost: account.imap_host,\n imapPort: account.imap_port,\n imapSecure: account.imap_secure === 1,\n smtpHost: account.smtp_host,\n smtpPort: account.smtp_port,\n smtpSecure: account.smtp_secure === 1,\n username: account.username,\n isDefault: account.is_default === 1,\n isEnabled: account.is_enabled === 1,\n syncInterval: account.sync_interval,\n lastSync: account.last_sync,\n createdAt: account.created_at,\n updatedAt: account.updated_at,\n };\n\n if (includePassword) {\n formatted.password = decrypt(account.password);\n }\n\n return formatted;\n }\n}\n\nconst accountModel = new AccountModel();\nexport default accountModel;\n","import configManager from '../config';\nimport ImapClient from '../imap/client';\nimport SmtpClient from '../smtp/client';\nimport database from '../storage/database';\nimport accountModel from '../storage/models/account';\nimport { ConfigError } from '../utils/errors';\nimport logger from '../utils/logger';\n\n/**\n * Account Manager\n * High-level account management operations\n */\nclass AccountManager {\n /**\n * Add a new account\n */\n async addAccount(accountData) {\n try {\n // Validate required fields\n this._validateAccountData(accountData);\n\n // Check if account already exists\n const existing = accountModel.findByEmail(accountData.email);\n if (existing) {\n throw new ConfigError(\n `Account with email ${accountData.email} already exists`\n );\n }\n\n // If this is the first account, make it default\n const accountCount = accountModel.count();\n if (accountCount === 0) {\n accountData.isDefault = true;\n }\n\n // Create account\n const accountId = accountModel.create(accountData);\n logger.info('Account added successfully', {\n id: accountId,\n email: accountData.email,\n });\n\n return accountModel.findById(accountId);\n } catch (error) {\n logger.error('Failed to add account', { error: error.message });\n throw error;\n }\n }\n\n /**\n * Get account by ID\n */\n getAccount(id) {\n return accountModel.findById(id);\n }\n\n /**\n * Get account with password (for connections)\n */\n getAccountWithPassword(id) {\n return accountModel.getWithPassword(id);\n }\n\n /**\n * Get all accounts\n */\n getAllAccounts(enabledOnly = false) {\n return accountModel.findAll({ enabledOnly });\n }\n\n /**\n * Get default account\n */\n getDefaultAccount() {\n return accountModel.getDefault();\n }\n\n /**\n * Set account as default\n */\n setDefaultAccount(id) {\n const account = accountModel.findById(id);\n if (!account) {\n throw new ConfigError('Account not found');\n }\n\n accountModel.setDefault(id);\n logger.info('Default account changed', { id, email: account.email });\n return true;\n }\n\n /**\n * Update account\n */\n updateAccount(id, data) {\n const account = accountModel.findById(id);\n if (!account) {\n throw new ConfigError('Account not found');\n }\n\n // Validate if email is being changed\n if (data.email && data.email !== account.email) {\n const existing = accountModel.findByEmail(data.email);\n if (existing) {\n throw new ConfigError(\n `Account with email ${data.email} already exists`\n );\n }\n }\n\n accountModel.update(id, data);\n logger.info('Account updated', { id });\n return accountModel.findById(id);\n }\n\n /**\n * Delete account\n */\n deleteAccount(id) {\n const account = accountModel.findById(id);\n if (!account) {\n throw new ConfigError('Account not found');\n }\n\n accountModel.delete(id);\n logger.info('Account deleted', { id, email: account.email });\n return true;\n }\n\n /**\n * Enable account\n */\n enableAccount(id) {\n return accountModel.update(id, { isEnabled: true });\n }\n\n /**\n * Disable account\n */\n disableAccount(id) {\n return accountModel.update(id, { isEnabled: false });\n }\n\n /**\n * Migrate legacy single-account config to multi-account\n */\n migrateLegacyConfig() {\n try {\n // Check if accounts already exist\n const accountCount = accountModel.count();\n if (accountCount > 0) {\n logger.info('Accounts already exist, skipping migration');\n return false;\n }\n\n // Load legacy config\n const config = configManager.load();\n if (!config.imap || !config.smtp) {\n logger.info('No legacy config found, skipping migration');\n return false;\n }\n\n // Create account from legacy config\n const accountData = {\n email: config.imap.user || config.smtp.user,\n displayName: config.imap.user || config.smtp.user,\n imapHost: config.imap.host,\n imapPort: config.imap.port,\n imapSecure: config.imap.secure !== false,\n smtpHost: config.smtp.host,\n smtpPort: config.smtp.port,\n smtpSecure: config.smtp.secure !== false,\n username: config.imap.user,\n password: config.imap.password,\n isDefault: true,\n isEnabled: true,\n syncInterval: 300,\n };\n\n const accountId = accountModel.create(accountData);\n logger.info('Legacy config migrated to account', { id: accountId });\n\n // Update all existing emails to associate with this account\n const db = database.getDb();\n const updateStmt = db.prepare(\n 'UPDATE emails SET account_id = ? WHERE account_id IS NULL'\n );\n const result = updateStmt.run(accountId);\n logger.info('Associated existing emails with migrated account', {\n count: result.changes,\n });\n\n // Update all existing folders to associate with this account\n const updateFoldersStmt = db.prepare(\n 'UPDATE folders SET account_id = ? WHERE account_id IS NULL'\n );\n const foldersResult = updateFoldersStmt.run(accountId);\n logger.info('Associated existing folders with migrated account', {\n count: foldersResult.changes,\n });\n\n return true;\n } catch (error) {\n logger.error('Failed to migrate legacy config', { error: error.message });\n throw new ConfigError(\n `Failed to migrate legacy config: ${error.message}`\n );\n }\n }\n\n /**\n * Test account connection\n */\n async testAccount(id) {\n const account = accountModel.getWithPassword(id);\n if (!account) {\n throw new ConfigError('Account not found');\n }\n\n const errors = [];\n\n // Test IMAP connection\n try {\n const imapClient = new ImapClient({\n host: account.imapHost,\n port: account.imapPort,\n secure: account.imapSecure,\n user: account.username,\n password: account.password,\n });\n await imapClient.connect();\n await imapClient.disconnect();\n logger.info('IMAP connection test successful', { accountId: id });\n } catch (error) {\n errors.push({ type: 'IMAP', message: error.message });\n logger.error('IMAP connection test failed', {\n accountId: id,\n error: error.message,\n });\n }\n\n // Test SMTP connection\n try {\n const smtpClient = new SmtpClient({\n host: account.smtpHost,\n port: account.smtpPort,\n secure: account.smtpSecure,\n user: account.username,\n password: account.password,\n });\n await smtpClient.connect();\n await smtpClient.disconnect();\n logger.info('SMTP connection test successful', { accountId: id });\n } catch (error) {\n errors.push({ type: 'SMTP', message: error.message });\n logger.error('SMTP connection test failed', {\n accountId: id,\n error: error.message,\n });\n }\n\n return {\n success: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Validate account data\n */\n _validateAccountData(data) {\n const required = ['email', 'imapHost', 'smtpHost', 'username', 'password'];\n const missing = required.filter((field) => !data[field]);\n\n if (missing.length > 0) {\n throw new ConfigError(`Missing required fields: ${missing.join(', ')}`);\n }\n\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(data.email)) {\n throw new ConfigError('Invalid email format');\n }\n\n return true;\n }\n}\n\nmodule.exports = new AccountManager();\n","import chalk from 'chalk';\nimport prompts from 'prompts';\n\nimport accountManager from '../../accounts/manager';\nimport logger from '../../utils/logger';\n\n/**\n * Account command handler\n */\nasync function accountCommand(action, options) {\n try {\n switch (action) {\n case 'add':\n await addAccount(options);\n break;\n case 'list':\n await listAccounts(options);\n break;\n case 'show':\n await showAccount(options);\n break;\n case 'edit':\n await editAccount(options);\n break;\n case 'delete':\n await deleteAccount(options);\n break;\n case 'default':\n await setDefaultAccount(options);\n break;\n case 'enable':\n await enableAccount(options);\n break;\n case 'disable':\n await disableAccount(options);\n break;\n case 'test':\n await testAccount(options);\n break;\n case 'migrate':\n await migrateConfig(options);\n break;\n default:\n console.log(chalk.red(`Unknown action: ${action}`));\n console.log(\n chalk.yellow(\n 'Available actions: add, list, show, edit, delete, default, enable, disable, test, migrate'\n )\n );\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Account command failed', { action, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Add new account\n */\nasync function addAccount(options) {\n console.log(chalk.blue.bold('\\nAdd New Email Account\\n'));\n\n const questions = [];\n\n if (!options.email) {\n questions.push({\n type: 'text',\n name: 'email',\n message: 'Email address:',\n validate: (value) =>\n /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value) || 'Invalid email format',\n });\n }\n\n if (!options.name) {\n questions.push({\n type: 'text',\n name: 'displayName',\n message: 'Display name (optional):',\n initial: options.email,\n });\n }\n\n if (!options.imapHost) {\n questions.push({\n type: 'text',\n name: 'imapHost',\n message: 'IMAP host:',\n validate: (value) => value.length > 0 || 'IMAP host is required',\n });\n }\n\n if (!options.imapPort) {\n questions.push({\n type: 'number',\n name: 'imapPort',\n message: 'IMAP port:',\n initial: 993,\n });\n }\n\n if (!options.smtpHost) {\n questions.push({\n type: 'text',\n name: 'smtpHost',\n message: 'SMTP host:',\n validate: (value) => value.length > 0 || 'SMTP host is required',\n });\n }\n\n if (!options.smtpPort) {\n questions.push({\n type: 'number',\n name: 'smtpPort',\n message: 'SMTP port:',\n initial: 465,\n });\n }\n\n if (!options.username) {\n questions.push({\n type: 'text',\n name: 'username',\n message: 'Username:',\n initial: options.email,\n validate: (value) => value.length > 0 || 'Username is required',\n });\n }\n\n if (!options.password) {\n questions.push({\n type: 'password',\n name: 'password',\n message: 'Password:',\n validate: (value) => value.length > 0 || 'Password is required',\n });\n }\n\n const answers = await prompts(questions);\n\n // Merge options and answers\n const accountData = {\n email: options.email || answers.email,\n displayName: options.name || answers.displayName || answers.email,\n imapHost: options.imapHost || answers.imapHost,\n imapPort: options.imapPort || answers.imapPort,\n imapSecure: options.imapSecure !== false,\n smtpHost: options.smtpHost || answers.smtpHost,\n smtpPort: options.smtpPort || answers.smtpPort,\n smtpSecure: options.smtpSecure !== false,\n username: options.username || answers.username || answers.email,\n password: options.password || answers.password,\n isEnabled: true,\n };\n\n // Test connection if requested\n if (options.test) {\n console.log(chalk.yellow('\\nTesting connection...'));\n // We'll create a temporary account to test\n // For now, just add the account\n }\n\n const account = await accountManager.addAccount(accountData);\n console.log(chalk.green('\\n✓ Account added successfully!'));\n console.log(chalk.gray(`Account ID: ${account.id}`));\n console.log(chalk.gray(`Email: ${account.email}`));\n if (account.isDefault) {\n console.log(chalk.yellow('This account is set as default'));\n }\n}\n\n/**\n * List all accounts\n */\nasync function listAccounts(options) {\n const accounts = accountManager.getAllAccounts(options.enabledOnly);\n\n if (accounts.length === 0) {\n console.log(chalk.yellow('No accounts found'));\n console.log(chalk.gray('Use \"account add\" to add a new account'));\n return;\n }\n\n console.log(chalk.blue.bold('\\nEmail Accounts\\n'));\n\n accounts.forEach((account) => {\n const status = [];\n if (account.isDefault) status.push(chalk.yellow('DEFAULT'));\n if (!account.isEnabled) status.push(chalk.red('DISABLED'));\n\n console.log(chalk.bold(`[${account.id}] ${account.email}`));\n if (status.length > 0) {\n console.log(` ${status.join(' ')}`);\n }\n console.log(chalk.gray(` Display Name: ${account.displayName}`));\n console.log(\n chalk.gray(` IMAP: ${account.imapHost}:${account.imapPort}`)\n );\n console.log(\n chalk.gray(` SMTP: ${account.smtpHost}:${account.smtpPort}`)\n );\n if (account.lastSync) {\n console.log(\n chalk.gray(\n ` Last Sync: ${new Date(account.lastSync).toLocaleString()}`\n )\n );\n }\n console.log('');\n });\n\n console.log(chalk.gray(`Total: ${accounts.length} account(s)`));\n}\n\n/**\n * Show account details\n */\nasync function showAccount(options) {\n if (!options.id) {\n console.error(chalk.red('Error: Account ID is required'));\n console.log(chalk.gray('Usage: account show --id <id>'));\n process.exit(1);\n }\n\n const account = accountManager.getAccount(options.id);\n if (!account) {\n console.error(chalk.red(`Account with ID ${options.id} not found`));\n process.exit(1);\n }\n\n console.log(chalk.blue.bold('\\nAccount Details\\n'));\n console.log(chalk.bold('ID:'), account.id);\n console.log(chalk.bold('Email:'), account.email);\n console.log(chalk.bold('Display Name:'), account.displayName);\n console.log(chalk.bold('Username:'), account.username);\n console.log('');\n console.log(chalk.bold('IMAP Configuration:'));\n console.log(` Host: ${account.imapHost}`);\n console.log(` Port: ${account.imapPort}`);\n console.log(` Secure: ${account.imapSecure ? 'Yes' : 'No'}`);\n console.log('');\n console.log(chalk.bold('SMTP Configuration:'));\n console.log(` Host: ${account.smtpHost}`);\n console.log(` Port: ${account.smtpPort}`);\n console.log(` Secure: ${account.smtpSecure ? 'Yes' : 'No'}`);\n console.log('');\n console.log(chalk.bold('Status:'));\n console.log(` Default: ${account.isDefault ? chalk.yellow('Yes') : 'No'}`);\n console.log(\n ` Enabled: ${account.isEnabled ? chalk.green('Yes') : chalk.red('No')}`\n );\n console.log(` Sync Interval: ${account.syncInterval} seconds`);\n if (account.lastSync) {\n console.log(` Last Sync: ${new Date(account.lastSync).toLocaleString()}`);\n }\n console.log('');\n console.log(\n chalk.gray(`Created: ${new Date(account.createdAt).toLocaleString()}`)\n );\n console.log(\n chalk.gray(`Updated: ${new Date(account.updatedAt).toLocaleString()}`)\n );\n}\n\n/**\n * Edit account\n */\nasync function editAccount(options) {\n if (!options.id) {\n console.error(chalk.red('Error: Account ID is required'));\n console.log(chalk.gray('Usage: account edit --id <id>'));\n process.exit(1);\n }\n\n const account = accountManager.getAccount(options.id);\n if (!account) {\n console.error(chalk.red(`Account with ID ${options.id} not found`));\n process.exit(1);\n }\n\n console.log(chalk.blue.bold('\\nEdit Account\\n'));\n console.log(chalk.gray('Leave blank to keep current value\\n'));\n\n const questions = [\n {\n type: 'text',\n name: 'displayName',\n message: 'Display name:',\n initial: account.displayName,\n },\n {\n type: 'text',\n name: 'imapHost',\n message: 'IMAP host:',\n initial: account.imapHost,\n },\n {\n type: 'number',\n name: 'imapPort',\n message: 'IMAP port:',\n initial: account.imapPort,\n },\n {\n type: 'text',\n name: 'smtpHost',\n message: 'SMTP host:',\n initial: account.smtpHost,\n },\n {\n type: 'number',\n name: 'smtpPort',\n message: 'SMTP port:',\n initial: account.smtpPort,\n },\n {\n type: 'text',\n name: 'username',\n message: 'Username:',\n initial: account.username,\n },\n {\n type: 'confirm',\n name: 'changePassword',\n message: 'Change password?',\n initial: false,\n },\n ];\n\n const answers = await prompts(questions);\n\n if (answers.changePassword) {\n const passwordAnswer = await prompts({\n type: 'password',\n name: 'password',\n message: 'New password:',\n validate: (value) => value.length > 0 || 'Password is required',\n });\n answers.password = passwordAnswer.password;\n }\n\n const updateData = {};\n if (answers.displayName && answers.displayName !== account.displayName) {\n updateData.displayName = answers.displayName;\n }\n if (answers.imapHost && answers.imapHost !== account.imapHost) {\n updateData.imapHost = answers.imapHost;\n }\n if (answers.imapPort && answers.imapPort !== account.imapPort) {\n updateData.imapPort = answers.imapPort;\n }\n if (answers.smtpHost && answers.smtpHost !== account.smtpHost) {\n updateData.smtpHost = answers.smtpHost;\n }\n if (answers.smtpPort && answers.smtpPort !== account.smtpPort) {\n updateData.smtpPort = answers.smtpPort;\n }\n if (answers.username && answers.username !== account.username) {\n updateData.username = answers.username;\n }\n if (answers.password) {\n updateData.password = answers.password;\n }\n\n if (Object.keys(updateData).length === 0) {\n console.log(chalk.yellow('No changes made'));\n return;\n }\n\n accountManager.updateAccount(options.id, updateData);\n console.log(chalk.green('\\n✓ Account updated successfully!'));\n}\n\n/**\n * Delete account\n */\nasync function deleteAccount(options) {\n if (!options.id) {\n console.error(chalk.red('Error: Account ID is required'));\n console.log(chalk.gray('Usage: account delete --id <id>'));\n process.exit(1);\n }\n\n const account = accountManager.getAccount(options.id);\n if (!account) {\n console.error(chalk.red(`Account with ID ${options.id} not found`));\n process.exit(1);\n }\n\n if (!options.yes) {\n const answer = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: `Delete account \"${account.email}\"? This will also delete all associated emails and data.`,\n initial: false,\n });\n\n if (!answer.confirm) {\n console.log(chalk.yellow('Cancelled'));\n return;\n }\n }\n\n accountManager.deleteAccount(options.id);\n console.log(chalk.green('\\n✓ Account deleted successfully'));\n}\n\n/**\n * Set default account\n */\nasync function setDefaultAccount(options) {\n if (!options.id) {\n console.error(chalk.red('Error: Account ID is required'));\n console.log(chalk.gray('Usage: account default --id <id>'));\n process.exit(1);\n }\n\n accountManager.setDefaultAccount(options.id);\n const account = accountManager.getAccount(options.id);\n console.log(chalk.green(`\\n✓ \"${account.email}\" is now the default account`));\n}\n\n/**\n * Enable account\n */\nasync function enableAccount(options) {\n if (!options.id) {\n console.error(chalk.red('Error: Account ID is required'));\n console.log(chalk.gray('Usage: account enable --id <id>'));\n process.exit(1);\n }\n\n accountManager.enableAccount(options.id);\n console.log(chalk.green('\\n✓ Account enabled'));\n}\n\n/**\n * Disable account\n */\nasync function disableAccount(options) {\n if (!options.id) {\n console.error(chalk.red('Error: Account ID is required'));\n console.log(chalk.gray('Usage: account disable --id <id>'));\n process.exit(1);\n }\n\n accountManager.disableAccount(options.id);\n console.log(chalk.yellow('\\n✓ Account disabled'));\n}\n\n/**\n * Test account connection\n */\nasync function testAccount(options) {\n if (!options.id) {\n console.error(chalk.red('Error: Account ID is required'));\n console.log(chalk.gray('Usage: account test --id <id>'));\n process.exit(1);\n }\n\n const account = accountManager.getAccount(options.id);\n if (!account) {\n console.error(chalk.red(`Account with ID ${options.id} not found`));\n process.exit(1);\n }\n\n console.log(chalk.blue.bold('\\nTesting Account Connection\\n'));\n console.log(chalk.gray(`Account: ${account.email}\\n`));\n\n const result = await accountManager.testAccount(options.id);\n\n if (result.success) {\n console.log(chalk.green('✓ All connections successful!'));\n console.log(chalk.green(' ✓ IMAP connection OK'));\n console.log(chalk.green(' ✓ SMTP connection OK'));\n } else {\n console.log(chalk.red('✗ Connection test failed\\n'));\n result.errors.forEach((error) => {\n console.log(chalk.red(` ✗ ${error.type}: ${error.message}`));\n });\n process.exit(1);\n }\n}\n\n/**\n * Migrate legacy config\n */\nasync function migrateConfig(options) {\n console.log(chalk.blue.bold('\\nMigrating Legacy Configuration\\n'));\n\n const result = accountManager.migrateLegacyConfig();\n\n if (result) {\n console.log(chalk.green('✓ Legacy configuration migrated successfully'));\n console.log(\n chalk.gray(\n 'Your existing account has been converted to the new multi-account system'\n )\n );\n } else {\n console.log(chalk.yellow('No migration needed'));\n console.log(\n chalk.gray('Either accounts already exist or no legacy config was found')\n );\n }\n}\n\nmodule.exports = accountCommand;\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\n\nimport config from '../../config';\nimport logger from '../../utils/logger';\n\n/**\n * Config command - Interactive configuration wizard\n */\nasync function configCommand(options) {\n try {\n if (options.show) {\n showConfig();\n return;\n }\n\n if (options.set) {\n setConfigValue(options.set);\n return;\n }\n\n // Interactive configuration wizard\n await configWizard();\n } catch (error) {\n console.error(chalk.red('Configuration error:'), error.message);\n logger.error('Config command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Show current configuration\n */\nfunction showConfig() {\n const currentConfig = config.load();\n console.log(chalk.bold.cyan('Current Configuration:'));\n console.log(chalk.gray('─'.repeat(60)));\n console.log(chalk.bold('IMAP:'));\n console.log(` Host: ${currentConfig.imap.host || chalk.gray('(not set)')}`);\n console.log(` Port: ${currentConfig.imap.port}`);\n console.log(` Secure: ${currentConfig.imap.secure}`);\n console.log(` User: ${currentConfig.imap.user || chalk.gray('(not set)')}`);\n console.log(\n ` Password: ${currentConfig.imap.password ? chalk.gray('(set)') : chalk.gray('(not set)')}`\n );\n console.log();\n console.log(chalk.bold('SMTP:'));\n console.log(` Host: ${currentConfig.smtp.host || chalk.gray('(not set)')}`);\n console.log(` Port: ${currentConfig.smtp.port}`);\n console.log(` Secure: ${currentConfig.smtp.secure}`);\n console.log(` User: ${currentConfig.smtp.user || chalk.gray('(not set)')}`);\n console.log(\n ` Password: ${currentConfig.smtp.password ? chalk.gray('(set)') : chalk.gray('(not set)')}`\n );\n}\n\n/**\n * Set configuration value\n */\nfunction setConfigValue(keyValue) {\n const [key, value] = keyValue.split('=');\n if (!key || value === undefined) {\n console.error(chalk.red('Invalid format. Use: --set key=value'));\n process.exit(1);\n }\n\n config.load();\n config.set(key, value);\n config.save();\n console.log(chalk.green(`✓ Configuration updated: ${key} = ${value}`));\n}\n\n/**\n * Interactive configuration wizard\n */\nasync function configWizard() {\n console.log(chalk.bold.cyan('Mail Client Configuration Wizard'));\n console.log(chalk.gray('Configure your IMAP and SMTP settings\\n'));\n\n const currentConfig = config.exists() ? config.load() : null;\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'imapHost',\n message: 'IMAP Host:',\n default: currentConfig?.imap.host,\n },\n {\n type: 'number',\n name: 'imapPort',\n message: 'IMAP Port:',\n default: currentConfig?.imap.port || 993,\n },\n {\n type: 'confirm',\n name: 'imapSecure',\n message: 'Use TLS/SSL for IMAP?',\n default: currentConfig?.imap.secure !== false,\n },\n {\n type: 'input',\n name: 'imapUser',\n message: 'IMAP Username (email):',\n default: currentConfig?.imap.user,\n },\n {\n type: 'password',\n name: 'imapPassword',\n message: 'IMAP Password:',\n mask: '*',\n },\n {\n type: 'input',\n name: 'smtpHost',\n message: 'SMTP Host:',\n default: currentConfig?.smtp.host,\n },\n {\n type: 'number',\n name: 'smtpPort',\n message: 'SMTP Port:',\n default: currentConfig?.smtp.port || 465,\n },\n {\n type: 'confirm',\n name: 'smtpSecure',\n message: 'Use TLS/SSL for SMTP?',\n default: currentConfig?.smtp.secure !== false,\n },\n {\n type: 'input',\n name: 'smtpUser',\n message: 'SMTP Username (email):',\n default: currentConfig?.smtp.user,\n },\n {\n type: 'password',\n name: 'smtpPassword',\n message: 'SMTP Password:',\n mask: '*',\n },\n ]);\n\n const newConfig = {\n imap: {\n host: answers.imapHost,\n port: answers.imapPort,\n secure: answers.imapSecure,\n user: answers.imapUser,\n password: answers.imapPassword,\n },\n smtp: {\n host: answers.smtpHost,\n port: answers.smtpPort,\n secure: answers.smtpSecure,\n user: answers.smtpUser,\n password: answers.smtpPassword,\n },\n storage: currentConfig?.storage || {\n dataDir: './data',\n maxAttachmentSize: 10485760,\n },\n sync: currentConfig?.sync || {\n autoSync: false,\n syncInterval: 300000,\n folders: ['INBOX'],\n },\n };\n\n config.save(newConfig);\n console.log(chalk.green('\\n✓ Configuration saved successfully!'));\n}\n\nmodule.exports = configCommand;\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface ContactInput {\n email: string;\n displayName?: string | null;\n firstName?: string | null;\n lastName?: string | null;\n nickname?: string | null;\n phone?: string | null;\n company?: string | null;\n jobTitle?: string | null;\n notes?: string | null;\n photoPath?: string | null;\n isFavorite?: boolean;\n accountId?: number | null;\n}\n\ntype ContactUpdateInput = Partial<ContactInput>;\n\ninterface ContactFindOptions {\n limit?: number;\n offset?: number;\n favoriteOnly?: boolean;\n}\n\ninterface ContactRow {\n id: number;\n email: string;\n display_name: string | null;\n first_name: string | null;\n last_name: string | null;\n nickname: string | null;\n phone: string | null;\n company: string | null;\n job_title: string | null;\n notes: string | null;\n photo_path: string | null;\n is_favorite: number;\n account_id: number | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface CountRow {\n count: number;\n}\n\nexport interface ContactRecord {\n id: number;\n email: string;\n displayName: string | null;\n firstName: string | null;\n lastName: string | null;\n nickname: string | null;\n phone: string | null;\n company: string | null;\n jobTitle: string | null;\n notes: string | null;\n photoPath: string | null;\n isFavorite: boolean;\n accountId: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Contact model.\n */\nexport class ContactModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(contactData: ContactInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO contacts (\n email, display_name, first_name, last_name, nickname,\n phone, company, job_title, notes, photo_path,\n is_favorite, account_id\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n contactData.email,\n contactData.displayName ?? null,\n contactData.firstName ?? null,\n contactData.lastName ?? null,\n contactData.nickname ?? null,\n contactData.phone ?? null,\n contactData.company ?? null,\n contactData.jobTitle ?? null,\n contactData.notes ?? null,\n contactData.photoPath ?? null,\n contactData.isFavorite ? 1 : 0,\n contactData.accountId ?? null\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Contact created', {\n id: insertId,\n email: contactData.email,\n });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('UNIQUE constraint failed')) {\n throw new StorageError(\n `Contact with email \"${contactData.email}\" already exists`\n );\n }\n logger.error('Failed to create contact', { error: errorMessage });\n throw new StorageError(`Failed to create contact: ${errorMessage}`);\n }\n }\n\n findAll(\n accountId: number | null = null,\n options: ContactFindOptions = {}\n ): ContactRecord[] {\n try {\n const db = this.getDb();\n const { limit = 100, offset = 0, favoriteOnly = false } = options;\n\n let query = 'SELECT * FROM contacts WHERE 1=1';\n const params: number[] = [];\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n if (favoriteOnly) {\n query += ' AND is_favorite = 1';\n }\n\n query += ' ORDER BY display_name ASC, email ASC LIMIT ? OFFSET ?';\n params.push(limit, offset);\n\n const stmt = db.prepare<unknown[], ContactRow>(query);\n const contacts = stmt.all(...params);\n return contacts.map((contact) => this.formatContact(contact));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find contacts', { error: errorMessage });\n throw new StorageError(`Failed to find contacts: ${errorMessage}`);\n }\n }\n\n findById(id: number): ContactRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], ContactRow>(\n 'SELECT * FROM contacts WHERE id = ?'\n );\n const contact = stmt.get(id);\n return contact ? this.formatContact(contact) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find contact by ID', { id, error: errorMessage });\n throw new StorageError(`Failed to find contact: ${errorMessage}`);\n }\n }\n\n findByEmail(\n email: string,\n accountId: number | null = null\n ): ContactRecord | null {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM contacts WHERE email = ?';\n const params: Array<string | number> = [email];\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n const stmt = db.prepare<unknown[], ContactRow>(query);\n const contact = stmt.get(...params);\n return contact ? this.formatContact(contact) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find contact by email', {\n email,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find contact: ${errorMessage}`);\n }\n }\n\n search(\n keyword: string,\n accountId: number | null = null,\n options: ContactFindOptions = {}\n ): ContactRecord[] {\n try {\n const db = this.getDb();\n const { limit = 50, offset = 0 } = options;\n const searchTerm = `%${keyword}%`;\n\n let query = `\n SELECT * FROM contacts\n WHERE (\n email LIKE ? OR\n display_name LIKE ? OR\n first_name LIKE ? OR\n last_name LIKE ? OR\n company LIKE ? OR\n notes LIKE ?\n )\n `;\n const params: Array<string | number> = [\n searchTerm,\n searchTerm,\n searchTerm,\n searchTerm,\n searchTerm,\n searchTerm,\n ];\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n query += ' ORDER BY display_name ASC, email ASC LIMIT ? OFFSET ?';\n params.push(limit, offset);\n\n const stmt = db.prepare<unknown[], ContactRow>(query);\n const contacts = stmt.all(...params);\n return contacts.map((contact) => this.formatContact(contact));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to search contacts', {\n keyword,\n error: errorMessage,\n });\n throw new StorageError(`Failed to search contacts: ${errorMessage}`);\n }\n }\n\n update(id: number, data: ContactUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number | null> = [];\n\n const fieldMap: Record<keyof ContactUpdateInput, string> = {\n email: 'email',\n displayName: 'display_name',\n firstName: 'first_name',\n lastName: 'last_name',\n nickname: 'nickname',\n phone: 'phone',\n company: 'company',\n jobTitle: 'job_title',\n notes: 'notes',\n photoPath: 'photo_path',\n isFavorite: 'is_favorite',\n accountId: 'account_id',\n };\n\n (Object.keys(fieldMap) as Array<keyof ContactUpdateInput>).forEach(\n (key) => {\n const value = data[key];\n if (value !== undefined) {\n fields.push(`${fieldMap[key]} = ?`);\n params.push(\n key === 'isFavorite'\n ? value\n ? 1\n : 0\n : (value as string | number | null)\n );\n }\n }\n );\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE contacts SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Contact updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('UNIQUE constraint failed')) {\n throw new StorageError('Contact email already exists');\n }\n logger.error('Failed to update contact', { id, error: errorMessage });\n throw new StorageError(`Failed to update contact: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM contacts WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Contact deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete contact', { id, error: errorMessage });\n throw new StorageError(`Failed to delete contact: ${errorMessage}`);\n }\n }\n\n count(accountId: number | null = null): number {\n try {\n const db = this.getDb();\n let query = 'SELECT COUNT(*) as count FROM contacts WHERE 1=1';\n const params: number[] = [];\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n const stmt = db.prepare<unknown[], CountRow>(query);\n const result = stmt.get(...params);\n return result?.count ?? 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to count contacts', { error: errorMessage });\n throw new StorageError(`Failed to count contacts: ${errorMessage}`);\n }\n }\n\n findOrCreate(\n email: string,\n data: Omit<ContactInput, 'email'> = {}\n ): { contact: ContactRecord | null; created: boolean } {\n try {\n const existing = this.findByEmail(email, data.accountId ?? null);\n if (existing) {\n return { contact: existing, created: false };\n }\n\n const contactData: ContactInput = {\n email,\n ...data,\n };\n\n const id = this.create(contactData);\n const contact = this.findById(id);\n return { contact, created: true };\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find or create contact', {\n email,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to find or create contact: ${errorMessage}`\n );\n }\n }\n\n private formatContact(contact: ContactRow): ContactRecord {\n return {\n id: contact.id,\n email: contact.email,\n displayName: contact.display_name,\n firstName: contact.first_name,\n lastName: contact.last_name,\n nickname: contact.nickname,\n phone: contact.phone,\n company: contact.company,\n jobTitle: contact.job_title,\n notes: contact.notes,\n photoPath: contact.photo_path,\n isFavorite: contact.is_favorite === 1,\n accountId: contact.account_id,\n createdAt: contact.created_at,\n updatedAt: contact.updated_at,\n };\n }\n}\n\nconst contactModel = new ContactModel();\nexport default contactModel;\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface ContactGroupInput {\n name: string;\n description?: string | null;\n accountId?: number | null;\n}\n\ninterface ContactGroupUpdateInput {\n name?: string;\n description?: string | null;\n}\n\ninterface ContactGroupRow {\n id: number;\n name: string;\n description: string | null;\n account_id: number | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface ContactRow {\n id: number;\n email: string;\n display_name: string | null;\n first_name: string | null;\n last_name: string | null;\n nickname: string | null;\n phone: string | null;\n company: string | null;\n job_title: string | null;\n notes: string | null;\n photo_path: string | null;\n is_favorite: number;\n account_id: number | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface CountRow {\n count: number;\n}\n\nexport interface ContactGroupRecord {\n id: number;\n name: string;\n description: string | null;\n accountId: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ContactRecord {\n id: number;\n email: string;\n displayName: string | null;\n firstName: string | null;\n lastName: string | null;\n nickname: string | null;\n phone: string | null;\n company: string | null;\n jobTitle: string | null;\n notes: string | null;\n photoPath: string | null;\n isFavorite: boolean;\n accountId: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Contact group model.\n */\nexport class ContactGroupModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(groupData: ContactGroupInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO contact_groups (name, description, account_id)\n VALUES (?, ?, ?)\n `);\n\n const result = stmt.run(\n groupData.name,\n groupData.description ?? null,\n groupData.accountId ?? null\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Contact group created', {\n id: insertId,\n name: groupData.name,\n });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create contact group', { error: errorMessage });\n throw new StorageError(`Failed to create contact group: ${errorMessage}`);\n }\n }\n\n findAll(accountId: number | null = null): ContactGroupRecord[] {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM contact_groups WHERE 1=1';\n const params: number[] = [];\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n query += ' ORDER BY name ASC';\n\n const stmt = db.prepare<unknown[], ContactGroupRow>(query);\n const groups = stmt.all(...params);\n return groups.map((group) => this.formatGroup(group));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find contact groups', { error: errorMessage });\n throw new StorageError(`Failed to find contact groups: ${errorMessage}`);\n }\n }\n\n findById(id: number): ContactGroupRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], ContactGroupRow>(\n 'SELECT * FROM contact_groups WHERE id = ?'\n );\n const group = stmt.get(id);\n return group ? this.formatGroup(group) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find contact group by ID', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find contact group: ${errorMessage}`);\n }\n }\n\n findByName(\n name: string,\n accountId: number | null = null\n ): ContactGroupRecord | null {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM contact_groups WHERE name = ?';\n const params: Array<string | number> = [name];\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n const stmt = db.prepare<unknown[], ContactGroupRow>(query);\n const group = stmt.get(...params);\n return group ? this.formatGroup(group) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find contact group by name', {\n name,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find contact group: ${errorMessage}`);\n }\n }\n\n update(id: number, data: ContactGroupUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number | null> = [];\n\n if (data.name !== undefined) {\n fields.push('name = ?');\n params.push(data.name);\n }\n\n if (data.description !== undefined) {\n fields.push('description = ?');\n params.push(data.description);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE contact_groups SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Contact group updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update contact group', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to update contact group: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM contact_groups WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Contact group deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete contact group', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to delete contact group: ${errorMessage}`);\n }\n }\n\n addContact(groupId: number, contactId: number): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO contact_group_members (group_id, contact_id)\n VALUES (?, ?)\n `);\n\n const result = stmt.run(groupId, contactId);\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Contact added to group', { groupId, contactId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('UNIQUE constraint failed')) {\n throw new StorageError('Contact is already in this group');\n }\n logger.error('Failed to add contact to group', {\n groupId,\n contactId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to add contact to group: ${errorMessage}`);\n }\n }\n\n removeContact(groupId: number, contactId: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n DELETE FROM contact_group_members\n WHERE group_id = ? AND contact_id = ?\n `);\n\n const result = stmt.run(groupId, contactId);\n logger.debug('Contact removed from group', {\n groupId,\n contactId,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to remove contact from group', {\n groupId,\n contactId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to remove contact from group: ${errorMessage}`\n );\n }\n }\n\n getContacts(\n groupId: number,\n options: { limit?: number; offset?: number } = {}\n ): ContactRecord[] {\n try {\n const db = this.getDb();\n const { limit = 100, offset = 0 } = options;\n\n const stmt = db.prepare<[number, number, number], ContactRow>(`\n SELECT c.* FROM contacts c\n INNER JOIN contact_group_members cgm ON c.id = cgm.contact_id\n WHERE cgm.group_id = ?\n ORDER BY c.display_name ASC, c.email ASC\n LIMIT ? OFFSET ?\n `);\n\n const contacts = stmt.all(groupId, limit, offset);\n return contacts.map((contact) => this.formatContact(contact));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to get contacts in group', {\n groupId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to get contacts in group: ${errorMessage}`\n );\n }\n }\n\n getGroupsByContact(contactId: number): ContactGroupRecord[] {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], ContactGroupRow>(`\n SELECT cg.* FROM contact_groups cg\n INNER JOIN contact_group_members cgm ON cg.id = cgm.group_id\n WHERE cgm.contact_id = ?\n ORDER BY cg.name ASC\n `);\n\n const groups = stmt.all(contactId);\n return groups.map((group) => this.formatGroup(group));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to get groups for contact', {\n contactId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to get groups for contact: ${errorMessage}`\n );\n }\n }\n\n countContacts(groupId: number): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], CountRow>(`\n SELECT COUNT(*) as count FROM contact_group_members\n WHERE group_id = ?\n `);\n\n const result = stmt.get(groupId);\n return result?.count ?? 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to count contacts in group', {\n groupId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to count contacts in group: ${errorMessage}`\n );\n }\n }\n\n private formatGroup(group: ContactGroupRow): ContactGroupRecord {\n return {\n id: group.id,\n name: group.name,\n description: group.description,\n accountId: group.account_id,\n createdAt: group.created_at,\n updatedAt: group.updated_at,\n };\n }\n\n private formatContact(contact: ContactRow): ContactRecord {\n return {\n id: contact.id,\n email: contact.email,\n displayName: contact.display_name,\n firstName: contact.first_name,\n lastName: contact.last_name,\n nickname: contact.nickname,\n phone: contact.phone,\n company: contact.company,\n jobTitle: contact.job_title,\n notes: contact.notes,\n photoPath: contact.photo_path,\n isFavorite: contact.is_favorite === 1,\n accountId: contact.account_id,\n createdAt: contact.created_at,\n updatedAt: contact.updated_at,\n };\n }\n}\n\nconst contactGroupModel = new ContactGroupModel();\nexport default contactGroupModel;\n","/**\n * Parsed email address representation.\n */\nexport interface ParsedEmailAddress {\n name: string | null;\n address: string;\n}\n\n/**\n * Parse email address with optional display name.\n */\nexport function parseEmailAddress(\n emailString: string | null | undefined\n): ParsedEmailAddress | null {\n if (!emailString || typeof emailString !== 'string') {\n return null;\n }\n\n const normalizedEmail = emailString.trim();\n\n const nameEmailMatch = normalizedEmail.match(/^(.+?)\\s*<([^>]+)>$/);\n if (nameEmailMatch) {\n const name = nameEmailMatch[1].replace(/^[\"']|[\"']$/g, '').trim();\n const address = nameEmailMatch[2].trim();\n return { name, address };\n }\n\n const emailMatch = normalizedEmail.match(/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/);\n if (emailMatch) {\n return { name: null, address: normalizedEmail };\n }\n\n return null;\n}\n\n/**\n * Format email address with optional display name.\n */\nexport function formatEmailAddress(\n address: string | null | undefined,\n name: string | null = null\n): string {\n if (!address) {\n return '';\n }\n\n if (name) {\n return `${name} <${address}>`;\n }\n\n return address;\n}\n\n/**\n * Parse multiple addresses from comma or semicolon separated list.\n */\nexport function parseEmailList(\n emailListString: string | null | undefined\n): ParsedEmailAddress[] {\n if (!emailListString) {\n return [];\n }\n\n const emails = emailListString\n .split(/[,;]/)\n .map((email) => email.trim())\n .filter((email) => email.length > 0);\n\n return emails\n .map((email) => parseEmailAddress(email))\n .filter((email): email is ParsedEmailAddress => email !== null);\n}\n","import contactModel from '../storage/models/contact';\nimport contactGroupModel from '../storage/models/contact_group';\nimport { parseEmailAddress } from '../utils/email-parser';\nimport { ValidationError } from '../utils/errors';\nimport logger from '../utils/logger';\n\n/**\n * Contact Manager\n * High-level contact management operations\n */\nclass ContactManager {\n /**\n * Add a new contact\n */\n async addContact(contactData) {\n this._validateEmail(contactData.email);\n\n try {\n const id = contactModel.create(contactData);\n const contact = contactModel.findById(id);\n logger.info('Contact added', { id, email: contactData.email });\n return contact;\n } catch (error) {\n logger.error('Failed to add contact', { error: error.message });\n throw error;\n }\n }\n\n /**\n * Get all contacts\n */\n async listContacts(accountId = null, options = {}) {\n try {\n return contactModel.findAll(accountId, options);\n } catch (error) {\n logger.error('Failed to list contacts', { error: error.message });\n throw error;\n }\n }\n\n /**\n * Get contact by ID\n */\n async getContact(id) {\n try {\n const contact = contactModel.findById(id);\n if (!contact) {\n throw new ValidationError(`Contact with ID ${id} not found`);\n }\n return contact;\n } catch (error) {\n logger.error('Failed to get contact', { id, error: error.message });\n throw error;\n }\n }\n\n /**\n * Update contact\n */\n async updateContact(id, data) {\n if (data.email) {\n this._validateEmail(data.email);\n }\n\n try {\n const updated = contactModel.update(id, data);\n if (!updated) {\n throw new ValidationError(`Contact with ID ${id} not found`);\n }\n const contact = contactModel.findById(id);\n logger.info('Contact updated', { id });\n return contact;\n } catch (error) {\n logger.error('Failed to update contact', { id, error: error.message });\n throw error;\n }\n }\n\n /**\n * Delete contact\n */\n async deleteContact(id) {\n try {\n const deleted = contactModel.delete(id);\n if (!deleted) {\n throw new ValidationError(`Contact with ID ${id} not found`);\n }\n logger.info('Contact deleted', { id });\n return true;\n } catch (error) {\n logger.error('Failed to delete contact', { id, error: error.message });\n throw error;\n }\n }\n\n /**\n * Search contacts\n */\n async searchContacts(keyword, accountId = null, options = {}) {\n try {\n return contactModel.search(keyword, accountId, options);\n } catch (error) {\n logger.error('Failed to search contacts', {\n keyword,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Create contact group\n */\n async createGroup(groupData) {\n try {\n const id = contactGroupModel.create(groupData);\n const group = contactGroupModel.findById(id);\n logger.info('Contact group created', { id, name: groupData.name });\n return group;\n } catch (error) {\n logger.error('Failed to create contact group', { error: error.message });\n throw error;\n }\n }\n\n /**\n * List all contact groups\n */\n async listGroups(accountId = null) {\n try {\n return contactGroupModel.findAll(accountId);\n } catch (error) {\n logger.error('Failed to list contact groups', { error: error.message });\n throw error;\n }\n }\n\n /**\n * Add contact to group\n */\n async addContactToGroup(contactId, groupId) {\n try {\n contactGroupModel.addContact(groupId, contactId);\n logger.info('Contact added to group', { contactId, groupId });\n return true;\n } catch (error) {\n logger.error('Failed to add contact to group', {\n contactId,\n groupId,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Remove contact from group\n */\n async removeContactFromGroup(contactId, groupId) {\n try {\n const removed = contactGroupModel.removeContact(groupId, contactId);\n if (!removed) {\n throw new ValidationError('Contact not found in group');\n }\n logger.info('Contact removed from group', { contactId, groupId });\n return true;\n } catch (error) {\n logger.error('Failed to remove contact from group', {\n contactId,\n groupId,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Get contacts in a group\n */\n async getGroupContacts(groupId, options = {}) {\n try {\n return contactGroupModel.getContacts(groupId, options);\n } catch (error) {\n logger.error('Failed to get group contacts', {\n groupId,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Auto-collect contact from email address\n */\n async autoCollectContact(emailAddress, accountId = null) {\n try {\n const parsed = parseEmailAddress(emailAddress);\n if (!parsed || !parsed.address) {\n return null;\n }\n\n const result = contactModel.findOrCreate(parsed.address, {\n displayName: parsed.name || null,\n accountId,\n });\n\n if (result.created) {\n logger.info('Contact auto-collected', { email: parsed.address });\n }\n\n return result.contact;\n } catch (error) {\n logger.error('Failed to auto-collect contact', {\n emailAddress,\n error: error.message,\n });\n return null;\n }\n }\n\n /**\n * Get contact suggestions for email composition\n */\n async getSuggestions(query, accountId = null, limit = 10) {\n try {\n if (!query || query.length < 2) {\n return [];\n }\n\n const contacts = await this.searchContacts(query, accountId, { limit });\n return contacts.map((contact) => ({\n email: contact.email,\n name: contact.displayName || contact.email,\n company: contact.company,\n }));\n } catch (error) {\n logger.error('Failed to get contact suggestions', {\n query,\n error: error.message,\n });\n return [];\n }\n }\n\n /**\n * Import contacts from CSV\n */\n async importFromCSV(csvData) {\n const lines = csvData.trim().split('\\n');\n if (lines.length < 2) {\n throw new ValidationError(\n 'CSV file must contain header and at least one contact'\n );\n }\n\n const header = lines[0].split(',').map((h) => h.trim().toLowerCase());\n const imported = [];\n const errors = [];\n\n for (let i = 1; i < lines.length; i++) {\n try {\n const values = lines[i].split(',').map((v) => v.trim());\n const contactData = {};\n\n header.forEach((field, index) => {\n const value = values[index];\n if (!value) return;\n\n switch (field) {\n case 'email':\n contactData.email = value;\n break;\n case 'name':\n case 'display_name':\n contactData.displayName = value;\n break;\n case 'first_name':\n contactData.firstName = value;\n break;\n case 'last_name':\n contactData.lastName = value;\n break;\n case 'phone':\n contactData.phone = value;\n break;\n case 'company':\n contactData.company = value;\n break;\n case 'job_title':\n case 'title':\n contactData.jobTitle = value;\n break;\n case 'notes':\n contactData.notes = value;\n break;\n }\n });\n\n if (!contactData.email) {\n errors.push({ line: i + 1, error: 'Missing email address' });\n continue;\n }\n\n const result = contactModel.findOrCreate(\n contactData.email,\n contactData\n );\n imported.push(result.contact);\n } catch (error) {\n errors.push({ line: i + 1, error: error.message });\n }\n }\n\n logger.info('Contacts imported from CSV', {\n imported: imported.length,\n errors: errors.length,\n });\n return { imported, errors };\n }\n\n /**\n * Export contacts to CSV\n */\n async exportToCSV(accountId = null) {\n try {\n const contacts = await this.listContacts(accountId, { limit: 10000 });\n\n const header =\n 'email,display_name,first_name,last_name,phone,company,job_title,notes';\n const rows = contacts.map((contact) => {\n return [\n contact.email,\n contact.displayName || '',\n contact.firstName || '',\n contact.lastName || '',\n contact.phone || '',\n contact.company || '',\n contact.jobTitle || '',\n contact.notes || '',\n ]\n .map((field) => `\"${field.replace(/\"/g, '\"\"')}\"`)\n .join(',');\n });\n\n return [header, ...rows].join('\\n');\n } catch (error) {\n logger.error('Failed to export contacts to CSV', {\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Validate email address\n */\n _validateEmail(email) {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email)) {\n throw new ValidationError(`Invalid email address: ${email}`);\n }\n }\n}\n\nmodule.exports = new ContactManager();\n","import fs from 'fs';\nimport path from 'path';\n\nimport chalk from 'chalk';\n\nimport contactManager from '../../contacts/manager';\nimport contactGroupModel from '../../storage/models/contact_group';\nimport logger from '../../utils/logger';\n\n/**\n * Contact command - Manage contacts\n */\nfunction contactCommand(action, args, options) {\n try {\n switch (action) {\n case 'add':\n return addContact(args, options);\n case 'list':\n return listContacts(args, options);\n case 'show':\n return showContact(args, options);\n case 'edit':\n return editContact(args, options);\n case 'delete':\n return deleteContact(args, options);\n case 'search':\n return searchContacts(args, options);\n case 'group':\n return groupCommand(args, options);\n case 'import':\n return importContacts(args, options);\n case 'export':\n return exportContacts(args, options);\n default:\n console.error(chalk.red('Error:'), `Unknown action: ${action}`);\n console.log(\n chalk.gray(\n 'Available actions: add, list, show, edit, delete, search, group, import, export'\n )\n );\n process.exit(1);\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Contact command failed', { action, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Add a new contact\n */\nasync function addContact(args, options) {\n if (!options.email) {\n console.error(chalk.red('Error:'), 'Email address is required');\n console.log(\n chalk.gray(\n 'Usage: contact add --email <email> [--name <name>] [--phone <phone>] [--company <company>]'\n )\n );\n process.exit(1);\n }\n\n const contactData = {\n email: options.email,\n displayName: options.name || null,\n phone: options.phone || null,\n company: options.company || null,\n jobTitle: options.title || null,\n notes: options.notes || null,\n };\n\n const contact = await contactManager.addContact(contactData);\n\n console.log(chalk.green('✓'), 'Contact added successfully');\n console.log(chalk.gray(` ID: ${contact.id}`));\n console.log(chalk.gray(` Email: ${contact.email}`));\n if (contact.displayName) {\n console.log(chalk.gray(` Name: ${contact.displayName}`));\n }\n if (contact.phone) {\n console.log(chalk.gray(` Phone: ${contact.phone}`));\n }\n if (contact.company) {\n console.log(chalk.gray(` Company: ${contact.company}`));\n }\n}\n\n/**\n * List all contacts\n */\nasync function listContacts(args, options) {\n const groupName = options.group;\n let contacts;\n\n if (groupName) {\n const group = contactGroupModel.findByName(groupName);\n if (!group) {\n console.error(chalk.red('Error:'), `Group \"${groupName}\" not found`);\n process.exit(1);\n }\n contacts = contactGroupModel.getContacts(group.id);\n console.log(chalk.bold.cyan(`Contacts in group \"${group.name}\":`));\n } else {\n contacts = await contactManager.listContacts(null, {\n limit: options.limit || 100,\n favoriteOnly: options.favorites || false,\n });\n console.log(chalk.bold.cyan('All Contacts:'));\n }\n\n if (contacts.length === 0) {\n console.log(chalk.yellow('No contacts found.'));\n return;\n }\n\n console.log();\n contacts.forEach((contact) => {\n const favorite = contact.isFavorite ? chalk.yellow('★ ') : ' ';\n console.log(\n `${favorite}${chalk.bold(contact.displayName || contact.email)}`\n );\n console.log(chalk.gray(` ID: ${contact.id} | Email: ${contact.email}`));\n if (contact.phone) {\n console.log(chalk.gray(` Phone: ${contact.phone}`));\n }\n if (contact.company) {\n console.log(chalk.gray(` Company: ${contact.company}`));\n }\n console.log();\n });\n\n console.log(chalk.gray(`Total: ${contacts.length} contacts`));\n}\n\n/**\n * Show contact details\n */\nasync function showContact(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Contact ID is required');\n console.log(chalk.gray('Usage: contact show <id>'));\n process.exit(1);\n }\n\n const contactId = parseInt(args[0]);\n const contact = await contactManager.getContact(contactId);\n\n console.log(chalk.bold.cyan('Contact Details:'));\n console.log();\n console.log(chalk.bold(' ID:'), contact.id);\n console.log(chalk.bold(' Email:'), contact.email);\n if (contact.displayName) {\n console.log(chalk.bold(' Name:'), contact.displayName);\n }\n if (contact.firstName) {\n console.log(chalk.bold(' First Name:'), contact.firstName);\n }\n if (contact.lastName) {\n console.log(chalk.bold(' Last Name:'), contact.lastName);\n }\n if (contact.phone) {\n console.log(chalk.bold(' Phone:'), contact.phone);\n }\n if (contact.company) {\n console.log(chalk.bold(' Company:'), contact.company);\n }\n if (contact.jobTitle) {\n console.log(chalk.bold(' Job Title:'), contact.jobTitle);\n }\n if (contact.notes) {\n console.log(chalk.bold(' Notes:'), contact.notes);\n }\n console.log(chalk.bold(' Favorite:'), contact.isFavorite ? 'Yes' : 'No');\n console.log(chalk.gray(` Created: ${contact.createdAt}`));\n console.log(chalk.gray(` Updated: ${contact.updatedAt}`));\n\n const groups = contactGroupModel.getGroupsByContact(contactId);\n if (groups.length > 0) {\n console.log();\n console.log(chalk.bold(' Groups:'));\n groups.forEach((group) => {\n console.log(chalk.gray(` - ${group.name}`));\n });\n }\n}\n\n/**\n * Edit contact\n */\nasync function editContact(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Contact ID is required');\n console.log(\n chalk.gray(\n 'Usage: contact edit <id> [--name <name>] [--email <email>] [--phone <phone>] [--company <company>]'\n )\n );\n process.exit(1);\n }\n\n const contactId = parseInt(args[0]);\n const updateData = {};\n\n if (options.name !== undefined) updateData.displayName = options.name;\n if (options.email !== undefined) updateData.email = options.email;\n if (options.phone !== undefined) updateData.phone = options.phone;\n if (options.company !== undefined) updateData.company = options.company;\n if (options.title !== undefined) updateData.jobTitle = options.title;\n if (options.notes !== undefined) updateData.notes = options.notes;\n if (options.favorite !== undefined)\n updateData.isFavorite = options.favorite === 'true';\n\n if (Object.keys(updateData).length === 0) {\n console.error(chalk.red('Error:'), 'No fields to update');\n console.log(\n chalk.gray(\n 'Usage: contact edit <id> [--name <name>] [--email <email>] [--phone <phone>] [--company <company>]'\n )\n );\n process.exit(1);\n }\n\n const contact = await contactManager.updateContact(contactId, updateData);\n\n console.log(chalk.green('✓'), 'Contact updated successfully');\n console.log(chalk.gray(` ID: ${contact.id}`));\n console.log(chalk.gray(` Email: ${contact.email}`));\n if (contact.displayName) {\n console.log(chalk.gray(` Name: ${contact.displayName}`));\n }\n}\n\n/**\n * Delete contact\n */\nasync function deleteContact(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Contact ID is required');\n console.log(chalk.gray('Usage: contact delete <id> [--yes]'));\n process.exit(1);\n }\n\n const contactId = parseInt(args[0]);\n const contact = await contactManager.getContact(contactId);\n\n if (!options.yes) {\n console.log(\n chalk.yellow('Warning:'),\n `Delete contact \"${contact.displayName || contact.email}\"?`\n );\n console.log(chalk.gray('Use --yes to confirm deletion'));\n process.exit(1);\n }\n\n await contactManager.deleteContact(contactId);\n console.log(chalk.green('✓'), 'Contact deleted successfully');\n}\n\n/**\n * Search contacts\n */\nasync function searchContacts(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Search keyword is required');\n console.log(chalk.gray('Usage: contact search <keyword>'));\n process.exit(1);\n }\n\n const keyword = args.join(' ');\n const contacts = await contactManager.searchContacts(keyword, null, {\n limit: options.limit || 50,\n });\n\n if (contacts.length === 0) {\n console.log(chalk.yellow(`No contacts found matching \"${keyword}\".`));\n return;\n }\n\n console.log(chalk.bold.cyan(`Search results for \"${keyword}\":`));\n console.log();\n\n contacts.forEach((contact) => {\n const favorite = contact.isFavorite ? chalk.yellow('★ ') : ' ';\n console.log(\n `${favorite}${chalk.bold(contact.displayName || contact.email)}`\n );\n console.log(chalk.gray(` ID: ${contact.id} | Email: ${contact.email}`));\n if (contact.phone) {\n console.log(chalk.gray(` Phone: ${contact.phone}`));\n }\n if (contact.company) {\n console.log(chalk.gray(` Company: ${contact.company}`));\n }\n console.log();\n });\n\n console.log(chalk.gray(`Found: ${contacts.length} contacts`));\n}\n\n/**\n * Group command handler\n */\nasync function groupCommand(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Group action is required');\n console.log(\n chalk.gray('Available actions: create, list, add, remove, show')\n );\n process.exit(1);\n }\n\n const action = args[0];\n const subArgs = args.slice(1);\n\n switch (action) {\n case 'create':\n return createGroup(subArgs, options);\n case 'list':\n return listGroups(options);\n case 'add':\n return addToGroup(subArgs, options);\n case 'remove':\n return removeFromGroup(subArgs, options);\n case 'show':\n return showGroup(subArgs, options);\n default:\n console.error(chalk.red('Error:'), `Unknown group action: ${action}`);\n console.log(\n chalk.gray('Available actions: create, list, add, remove, show')\n );\n process.exit(1);\n }\n}\n\n/**\n * Create contact group\n */\nasync function createGroup(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Group name is required');\n console.log(\n chalk.gray('Usage: contact group create <name> [--description <text>]')\n );\n process.exit(1);\n }\n\n const name = args.join(' ');\n const group = await contactManager.createGroup({\n name,\n description: options.description || null,\n });\n\n console.log(chalk.green('✓'), `Group \"${group.name}\" created successfully`);\n console.log(chalk.gray(` ID: ${group.id}`));\n if (group.description) {\n console.log(chalk.gray(` Description: ${group.description}`));\n }\n}\n\n/**\n * List all groups\n */\nasync function listGroups(options) {\n const groups = await contactManager.listGroups();\n\n if (groups.length === 0) {\n console.log(chalk.yellow('No groups found.'));\n return;\n }\n\n console.log(chalk.bold.cyan('Contact Groups:'));\n console.log();\n\n for (const group of groups) {\n const count = contactGroupModel.countContacts(group.id);\n console.log(chalk.bold(group.name), chalk.gray(`(${count} contacts)`));\n console.log(chalk.gray(` ID: ${group.id}`));\n if (group.description) {\n console.log(chalk.gray(` ${group.description}`));\n }\n console.log();\n }\n\n console.log(chalk.gray(`Total: ${groups.length} groups`));\n}\n\n/**\n * Add contact to group\n */\nasync function addToGroup(args, options) {\n if (!args || args.length < 2) {\n console.error(\n chalk.red('Error:'),\n 'Contact ID and group name are required'\n );\n console.log(\n chalk.gray('Usage: contact group add <contact-id> <group-name>')\n );\n process.exit(1);\n }\n\n const contactId = parseInt(args[0]);\n const groupName = args.slice(1).join(' ');\n\n const contact = await contactManager.getContact(contactId);\n const group = contactGroupModel.findByName(groupName);\n\n if (!group) {\n console.error(chalk.red('Error:'), `Group \"${groupName}\" not found`);\n process.exit(1);\n }\n\n await contactManager.addContactToGroup(contactId, group.id);\n\n console.log(\n chalk.green('✓'),\n `Contact \"${contact.displayName || contact.email}\" added to group \"${group.name}\"`\n );\n}\n\n/**\n * Remove contact from group\n */\nasync function removeFromGroup(args, options) {\n if (!args || args.length < 2) {\n console.error(\n chalk.red('Error:'),\n 'Contact ID and group name are required'\n );\n console.log(\n chalk.gray('Usage: contact group remove <contact-id> <group-name>')\n );\n process.exit(1);\n }\n\n const contactId = parseInt(args[0]);\n const groupName = args.slice(1).join(' ');\n\n const contact = await contactManager.getContact(contactId);\n const group = contactGroupModel.findByName(groupName);\n\n if (!group) {\n console.error(chalk.red('Error:'), `Group \"${groupName}\" not found`);\n process.exit(1);\n }\n\n await contactManager.removeContactFromGroup(contactId, group.id);\n\n console.log(\n chalk.green('✓'),\n `Contact \"${contact.displayName || contact.email}\" removed from group \"${group.name}\"`\n );\n}\n\n/**\n * Show group details\n */\nasync function showGroup(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Group name is required');\n console.log(chalk.gray('Usage: contact group show <group-name>'));\n process.exit(1);\n }\n\n const groupName = args.join(' ');\n const group = contactGroupModel.findByName(groupName);\n\n if (!group) {\n console.error(chalk.red('Error:'), `Group \"${groupName}\" not found`);\n process.exit(1);\n }\n\n console.log(chalk.bold.cyan('Group Details:'));\n console.log();\n console.log(chalk.bold(' Name:'), group.name);\n console.log(chalk.bold(' ID:'), group.id);\n if (group.description) {\n console.log(chalk.bold(' Description:'), group.description);\n }\n\n const contacts = await contactManager.getGroupContacts(group.id);\n console.log();\n console.log(chalk.bold(' Contacts:'), contacts.length);\n\n if (contacts.length > 0) {\n console.log();\n contacts.forEach((contact) => {\n console.log(\n ` - ${contact.displayName || contact.email} (${contact.email})`\n );\n });\n }\n}\n\n/**\n * Import contacts from CSV\n */\nasync function importContacts(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'CSV file path is required');\n console.log(chalk.gray('Usage: contact import <file.csv>'));\n process.exit(1);\n }\n\n const filePath = args[0];\n\n if (!fs.existsSync(filePath)) {\n console.error(chalk.red('Error:'), `File not found: ${filePath}`);\n process.exit(1);\n }\n\n const csvData = fs.readFileSync(filePath, 'utf-8');\n const result = await contactManager.importFromCSV(csvData);\n\n console.log(chalk.green('✓'), 'Import completed');\n console.log(chalk.gray(` Imported: ${result.imported.length} contacts`));\n\n if (result.errors.length > 0) {\n console.log(chalk.yellow(` Errors: ${result.errors.length}`));\n console.log();\n console.log(chalk.yellow('Errors:'));\n result.errors.forEach((error) => {\n console.log(chalk.gray(` Line ${error.line}: ${error.error}`));\n });\n }\n}\n\n/**\n * Export contacts to CSV\n */\nasync function exportContacts(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Output file path is required');\n console.log(chalk.gray('Usage: contact export <file.csv>'));\n process.exit(1);\n }\n\n const filePath = args[0];\n const csvData = await contactManager.exportToCSV();\n\n fs.writeFileSync(filePath, csvData, 'utf-8');\n\n console.log(chalk.green('✓'), `Contacts exported to ${filePath}`);\n}\n\nmodule.exports = contactCommand;\n","import Database from 'better-sqlite3';\n\nimport type {\n Email,\n EmailCreateInput,\n DraftSaveInput,\n EmailSearchQuery,\n PaginationOptions,\n} from '../../types';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface EmailRow {\n id: number;\n uid: number;\n message_id: string;\n folder: string;\n from_address: string;\n to_address: string;\n cc_address: string | null;\n subject: string;\n date: string;\n body_text: string | null;\n body_html: string | null;\n has_attachments: number;\n is_read: number;\n is_draft: number;\n is_deleted: number;\n is_spam: number;\n is_starred: number;\n is_important: number;\n priority: number | null;\n deleted_at: string | null;\n in_reply_to: string | null;\n references: string | null;\n thread_id: number | null;\n account_id: number | null;\n flags: string | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface FindFolderOptions extends PaginationOptions {\n unreadOnly?: boolean;\n}\n\ninterface FindStarredOptions extends PaginationOptions {\n folder?: string | null;\n}\ninterface FindImportantOptions extends PaginationOptions {\n folder?: string | null;\n}\n\ninterface UpdateData {\n isRead?: boolean;\n flags?: string[];\n bodyText?: string;\n bodyHtml?: string;\n}\n\ninterface BodyData {\n bodyText?: string;\n bodyHtml?: string;\n}\n\ninterface ThreadMetadata {\n inReplyTo?: string;\n references?: string;\n threadId?: number;\n}\n\ninterface CountResult {\n count: number;\n}\n\nclass EmailModel {\n private db: Database.Database | null = null;\n\n private _getDb(): Database.Database {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(emailData: EmailCreateInput): number {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n INSERT INTO emails (\n uid, message_id, folder, from_address, to_address, cc_address,\n subject, date, body_text, body_html, has_attachments, is_read, flags\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n emailData.uid,\n emailData.messageId,\n emailData.folder,\n emailData.from,\n emailData.to,\n emailData.cc || null,\n emailData.subject,\n emailData.date,\n emailData.bodyText || null,\n emailData.bodyHtml || null,\n emailData.hasAttachments ? 1 : 0,\n emailData.isRead ? 1 : 0,\n emailData.flags ? JSON.stringify(emailData.flags) : null\n );\n\n logger.debug('Email created', { id: result.lastInsertRowid });\n return result.lastInsertRowid as number;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to create email', { error: errorMessage });\n throw new StorageError(`Failed to create email: ${errorMessage}`);\n }\n }\n\n findById(id: number): Email | null {\n try {\n const db = this._getDb();\n const stmt = db.prepare('SELECT * FROM emails WHERE id = ?');\n const email = stmt.get(id) as EmailRow | undefined;\n return email ? this._formatEmail(email) : null;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find email by ID', { id, error: errorMessage });\n throw new StorageError(`Failed to find email: ${errorMessage}`);\n }\n }\n\n findByUid(uid: number, folder = 'INBOX'): Email | null {\n try {\n const db = this._getDb();\n const stmt = db.prepare(\n 'SELECT * FROM emails WHERE uid = ? AND folder = ?'\n );\n const email = stmt.get(uid, folder) as EmailRow | undefined;\n return email ? this._formatEmail(email) : null;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find email by UID', { uid, error: errorMessage });\n throw new StorageError(`Failed to find email: ${errorMessage}`);\n }\n }\n\n findByMessageId(messageId: string): Email | null {\n try {\n const db = this._getDb();\n const stmt = db.prepare('SELECT * FROM emails WHERE message_id = ?');\n const email = stmt.get(messageId) as EmailRow | undefined;\n return email ? this._formatEmail(email) : null;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find email by message ID', {\n messageId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find email: ${errorMessage}`);\n }\n }\n\n findByFolder(folder = 'INBOX', options: FindFolderOptions = {}): Email[] {\n try {\n const db = this._getDb();\n const { limit = 50, offset = 0, unreadOnly = false } = options;\n\n let query = 'SELECT * FROM emails WHERE folder = ?';\n const params: (string | number)[] = [folder];\n\n if (unreadOnly) {\n query += ' AND is_read = 0';\n }\n\n query += ' ORDER BY date DESC LIMIT ? OFFSET ?';\n params.push(limit, offset);\n\n const stmt = db.prepare(query);\n const emails = stmt.all(...params) as EmailRow[];\n return emails.map((email) => this._formatEmail(email));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find emails by folder', {\n folder,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find emails: ${errorMessage}`);\n }\n }\n\n search(query: EmailSearchQuery): Email[] {\n try {\n const db = this._getDb();\n const {\n keyword,\n from,\n to,\n cc,\n subject,\n folder,\n dateFrom,\n dateTo,\n starred,\n flagged,\n unread,\n hasAttachment,\n noAttachment,\n tag,\n accountId,\n limit = 100,\n offset = 0,\n } = query;\n\n let sql = 'SELECT DISTINCT e.* FROM emails e';\n const params: (string | number | boolean)[] = [];\n const conditions: string[] = [];\n\n if (tag) {\n sql += ' LEFT JOIN email_tags et ON e.id = et.email_id';\n sql += ' LEFT JOIN tags t ON et.tag_id = t.id';\n }\n\n conditions.push('e.is_deleted = 0');\n\n if (keyword) {\n conditions.push(\n '(e.subject LIKE ? OR e.body_text LIKE ? OR e.from_address LIKE ?)'\n );\n const searchTerm = `%${keyword}%`;\n params.push(searchTerm, searchTerm, searchTerm);\n }\n\n if (from) {\n conditions.push('e.from_address LIKE ?');\n params.push(`%${from}%`);\n }\n\n if (to) {\n conditions.push('e.to_address LIKE ?');\n params.push(`%${to}%`);\n }\n\n if (cc) {\n conditions.push('e.cc_address LIKE ?');\n params.push(`%${cc}%`);\n }\n\n if (subject) {\n conditions.push('e.subject LIKE ?');\n params.push(`%${subject}%`);\n }\n\n if (folder) {\n conditions.push('e.folder = ?');\n params.push(folder);\n }\n\n if (dateFrom) {\n conditions.push('e.date >= ?');\n params.push(dateFrom);\n }\n\n if (dateTo) {\n conditions.push('e.date <= ?');\n params.push(dateTo);\n }\n\n if (starred !== undefined) {\n conditions.push('e.is_starred = ?');\n params.push(starred ? 1 : 0);\n }\n\n if (flagged !== undefined) {\n conditions.push('e.is_important = ?');\n params.push(flagged ? 1 : 0);\n }\n\n if (unread !== undefined) {\n conditions.push('e.is_read = ?');\n params.push(unread ? 0 : 1);\n }\n\n if (hasAttachment !== undefined) {\n conditions.push('e.has_attachments = ?');\n params.push(hasAttachment ? 1 : 0);\n }\n\n if (noAttachment) {\n conditions.push('e.has_attachments = 0');\n }\n\n if (tag) {\n conditions.push('t.name = ?');\n params.push(tag);\n }\n\n if (accountId !== undefined) {\n conditions.push('e.account_id = ?');\n params.push(accountId);\n }\n\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n\n sql += ' ORDER BY e.date DESC';\n sql += ' LIMIT ? OFFSET ?';\n params.push(limit, offset);\n\n const stmt = db.prepare(sql);\n const emails = stmt.all(...params) as EmailRow[];\n return emails.map((email) => this._formatEmail(email));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to search emails', { error: errorMessage });\n throw new StorageError(`Failed to search emails: ${errorMessage}`);\n }\n }\n\n update(id: number, data: UpdateData): boolean {\n try {\n const db = this._getDb();\n const fields: string[] = [];\n const params: (string | number)[] = [];\n\n if (data.isRead !== undefined) {\n fields.push('is_read = ?');\n params.push(data.isRead ? 1 : 0);\n }\n\n if (data.flags !== undefined) {\n fields.push('flags = ?');\n params.push(JSON.stringify(data.flags));\n }\n\n if (data.bodyText !== undefined) {\n fields.push('body_text = ?');\n params.push(data.bodyText);\n }\n\n if (data.bodyHtml !== undefined) {\n fields.push('body_html = ?');\n params.push(data.bodyHtml);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE emails SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Email updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to update email', { id, error: errorMessage });\n throw new StorageError(`Failed to update email: ${errorMessage}`);\n }\n }\n\n updateBody(id: number, bodyData: BodyData): boolean {\n return this.update(id, {\n bodyText: bodyData.bodyText,\n bodyHtml: bodyData.bodyHtml,\n });\n }\n\n markAsRead(id: number): boolean {\n return this.update(id, { isRead: true });\n }\n\n markAsUnread(id: number): boolean {\n return this.update(id, { isRead: false });\n }\n\n updateFolder(id: number, folder: string): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails SET folder = ?, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(folder, id);\n logger.debug('Email folder updated', {\n id,\n folder,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to update email folder', {\n id,\n folder,\n error: errorMessage,\n });\n throw new StorageError(`Failed to update email folder: ${errorMessage}`);\n }\n }\n\n markAsSpam(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails SET is_spam = 1, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email marked as spam', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to mark email as spam', { id, error: errorMessage });\n throw new StorageError(`Failed to mark email as spam: ${errorMessage}`);\n }\n }\n\n unmarkAsSpam(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails SET is_spam = 0, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email unmarked as spam', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to unmark email as spam', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to unmark email as spam: ${errorMessage}`);\n }\n }\n\n findSpam(options: FindSpamOptions = {}): Email[] {\n try {\n const db = this._getDb();\n const { limit = 50, offset = 0 } = options;\n\n const query = `\n SELECT * FROM emails\n WHERE is_spam = 1 AND is_deleted = 0\n ORDER BY date DESC\n LIMIT ? OFFSET ?\n `;\n\n const stmt = db.prepare(query);\n const emails = stmt.all(limit, offset) as EmailRow[];\n return emails.map((email) => this._formatEmail(email));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find spam emails', { error: errorMessage });\n throw new StorageError(`Failed to find spam emails: ${errorMessage}`);\n }\n }\n\n countSpam(): number {\n try {\n const db = this._getDb();\n const stmt = db.prepare(\n 'SELECT COUNT(*) as count FROM emails WHERE is_spam = 1 AND is_deleted = 0'\n );\n const result = stmt.get() as CountResult;\n return result.count;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to count spam emails', { error: errorMessage });\n throw new StorageError(`Failed to count spam emails: ${errorMessage}`);\n }\n }\n\n saveDraft(draftData: DraftSaveInput): number {\n try {\n const db = this._getDb();\n\n if (draftData.id) {\n const stmt = db.prepare(`\n UPDATE emails SET\n to_address = ?,\n cc_address = ?,\n subject = ?,\n body_text = ?,\n body_html = ?,\n updated_at = CURRENT_TIMESTAMP\n WHERE id = ? AND is_draft = 1\n `);\n\n const result = stmt.run(\n draftData.to || '',\n draftData.cc || '',\n draftData.subject || '',\n draftData.bodyText || '',\n draftData.bodyHtml || '',\n draftData.id\n );\n\n logger.debug('Draft updated', {\n id: draftData.id,\n changes: result.changes,\n });\n return draftData.id;\n } else {\n const stmt = db.prepare(`\n INSERT INTO emails (\n uid, message_id, folder, from_address, to_address, cc_address,\n subject, date, body_text, body_html, has_attachments, is_read, is_draft, flags\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n draftData.uid || 0,\n draftData.messageId || `draft-${Date.now()}@local`,\n 'Drafts',\n draftData.from || '',\n draftData.to || '',\n draftData.cc || '',\n draftData.subject || '',\n new Date().toISOString(),\n draftData.bodyText || '',\n draftData.bodyHtml || '',\n 0,\n 0,\n 1,\n JSON.stringify(['\\\\Draft'])\n );\n\n logger.debug('Draft created', { id: result.lastInsertRowid });\n return result.lastInsertRowid as number;\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to save draft', { error: errorMessage });\n throw new StorageError(`Failed to save draft: ${errorMessage}`);\n }\n }\n\n findDrafts(options: FindDraftsOptions = {}): Email[] {\n try {\n const db = this._getDb();\n const { limit = 50, offset = 0 } = options;\n\n const query = `\n SELECT * FROM emails\n WHERE is_draft = 1\n ORDER BY updated_at DESC\n LIMIT ? OFFSET ?\n `;\n\n const stmt = db.prepare(query);\n const drafts = stmt.all(limit, offset) as EmailRow[];\n return drafts.map((draft) => this._formatEmail(draft));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find drafts', { error: errorMessage });\n throw new StorageError(`Failed to find drafts: ${errorMessage}`);\n }\n }\n\n deleteDraft(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(\n 'DELETE FROM emails WHERE id = ? AND is_draft = 1'\n );\n const result = stmt.run(id);\n logger.debug('Draft deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to delete draft', { id, error: errorMessage });\n throw new StorageError(`Failed to delete draft: ${errorMessage}`);\n }\n }\n\n convertDraftToSent(id: number, messageId: string): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails SET\n is_draft = 0,\n folder = 'Sent',\n message_id = ?,\n date = CURRENT_TIMESTAMP,\n updated_at = CURRENT_TIMESTAMP\n WHERE id = ? AND is_draft = 1\n `);\n\n const result = stmt.run(messageId, id);\n logger.debug('Draft converted to sent', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to convert draft', { id, error: errorMessage });\n throw new StorageError(`Failed to convert draft: ${errorMessage}`);\n }\n }\n\n countDrafts(): number {\n try {\n const db = this._getDb();\n const stmt = db.prepare(\n 'SELECT COUNT(*) as count FROM emails WHERE is_draft = 1'\n );\n const result = stmt.get() as CountResult;\n return result.count;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to count drafts', { error: errorMessage });\n throw new StorageError(`Failed to count drafts: ${errorMessage}`);\n }\n }\n\n markAsDeleted(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails\n SET is_deleted = 1, deleted_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email marked as deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to mark email as deleted', {\n id,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to mark email as deleted: ${errorMessage}`\n );\n }\n }\n\n restoreDeleted(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails\n SET is_deleted = 0, deleted_at = NULL, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email restored', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to restore email', { id, error: errorMessage });\n throw new StorageError(`Failed to restore email: ${errorMessage}`);\n }\n }\n\n findDeleted(options: FindDeletedOptions = {}): Email[] {\n try {\n const db = this._getDb();\n const { limit = 50, offset = 0 } = options;\n\n const sql = `\n SELECT * FROM emails\n WHERE is_deleted = 1\n ORDER BY deleted_at DESC\n LIMIT ? OFFSET ?\n `;\n const stmt = db.prepare(sql);\n const emails = stmt.all(limit, offset) as EmailRow[];\n return emails.map((email) => this._formatEmail(email));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find deleted emails', { error: errorMessage });\n throw new StorageError(`Failed to find deleted emails: ${errorMessage}`);\n }\n }\n\n countDeleted(): number {\n try {\n const db = this._getDb();\n const stmt = db.prepare(\n 'SELECT COUNT(*) as count FROM emails WHERE is_deleted = 1'\n );\n const result = stmt.get() as CountResult;\n return result.count;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to count deleted emails', { error: errorMessage });\n throw new StorageError(`Failed to count deleted emails: ${errorMessage}`);\n }\n }\n\n permanentlyDelete(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare('DELETE FROM emails WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Email permanently deleted', {\n id,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to permanently delete email', {\n id,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to permanently delete email: ${errorMessage}`\n );\n }\n }\n\n emptyTrash(): number {\n try {\n const db = this._getDb();\n const stmt = db.prepare('DELETE FROM emails WHERE is_deleted = 1');\n const result = stmt.run();\n logger.info('Trash emptied', { deleted: result.changes });\n return result.changes;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to empty trash', { error: errorMessage });\n throw new StorageError(`Failed to empty trash: ${errorMessage}`);\n }\n }\n\n findByThreadId(\n threadId: number,\n options: FindByThreadIdOptions = {}\n ): Email[] {\n try {\n const db = this._getDb();\n const { limit = 50, offset = 0 } = options;\n\n const query = `\n SELECT * FROM emails\n WHERE thread_id = ? AND is_deleted = 0\n ORDER BY date ASC\n LIMIT ? OFFSET ?\n `;\n\n const stmt = db.prepare(query);\n const emails = stmt.all(threadId, limit, offset) as EmailRow[];\n return emails.map((email) => this._formatEmail(email));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find emails by thread ID', {\n threadId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to find emails by thread ID: ${errorMessage}`\n );\n }\n }\n\n updateThreadMetadata(id: number, metadata: ThreadMetadata): boolean {\n try {\n const db = this._getDb();\n const fields: string[] = [];\n const params: (string | number)[] = [];\n\n if (metadata.inReplyTo !== undefined) {\n fields.push('in_reply_to = ?');\n params.push(metadata.inReplyTo);\n }\n\n if (metadata.references !== undefined) {\n fields.push('references = ?');\n params.push(metadata.references);\n }\n\n if (metadata.threadId !== undefined) {\n fields.push('thread_id = ?');\n params.push(metadata.threadId);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE emails SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Email thread metadata updated', {\n id,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to update thread metadata', {\n id,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to update thread metadata: ${errorMessage}`\n );\n }\n }\n\n delete(id: number): boolean {\n return this.permanentlyDelete(id);\n }\n\n markAsStarred(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails\n SET is_starred = 1, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email marked as starred', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to mark email as starred', {\n id,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to mark email as starred: ${errorMessage}`\n );\n }\n }\n\n unmarkAsStarred(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails\n SET is_starred = 0, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email unmarked as starred', {\n id,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to unmark email as starred', {\n id,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to unmark email as starred: ${errorMessage}`\n );\n }\n }\n\n markAsImportant(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails\n SET is_important = 1, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email marked as important', {\n id,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to mark email as important', {\n id,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to mark email as important: ${errorMessage}`\n );\n }\n }\n\n unmarkAsImportant(id: number): boolean {\n try {\n const db = this._getDb();\n const stmt = db.prepare(`\n UPDATE emails\n SET is_important = 0, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n `);\n const result = stmt.run(id);\n logger.debug('Email unmarked as important', {\n id,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to unmark email as important', {\n id,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to unmark email as important: ${errorMessage}`\n );\n }\n }\n\n findStarred(options: FindStarredOptions = {}): Email[] {\n try {\n const db = this._getDb();\n const { limit = 50, offset = 0, folder = null } = options;\n\n let query =\n 'SELECT * FROM emails WHERE is_starred = 1 AND is_deleted = 0';\n const params: (string | number)[] = [];\n\n if (folder) {\n query += ' AND folder = ?';\n params.push(folder);\n }\n\n query += ' ORDER BY date DESC LIMIT ? OFFSET ?';\n params.push(limit, offset);\n\n const stmt = db.prepare(query);\n const emails = stmt.all(...params) as EmailRow[];\n return emails.map((email) => this._formatEmail(email));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find starred emails', { error: errorMessage });\n throw new StorageError(`Failed to find starred emails: ${errorMessage}`);\n }\n }\n\n findImportant(options: FindImportantOptions = {}): Email[] {\n try {\n const db = this._getDb();\n const { limit = 50, offset = 0, folder = null } = options;\n\n let query =\n 'SELECT * FROM emails WHERE is_important = 1 AND is_deleted = 0';\n const params: (string | number)[] = [];\n\n if (folder) {\n query += ' AND folder = ?';\n params.push(folder);\n }\n\n query += ' ORDER BY date DESC LIMIT ? OFFSET ?';\n params.push(limit, offset);\n\n const stmt = db.prepare(query);\n const emails = stmt.all(...params) as EmailRow[];\n return emails.map((email) => this._formatEmail(email));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to find important emails', { error: errorMessage });\n throw new StorageError(\n `Failed to find important emails: ${errorMessage}`\n );\n }\n }\n\n countStarred(folder = null): number {\n try {\n const db = this._getDb();\n let query =\n 'SELECT COUNT(*) as count FROM emails WHERE is_starred = 1 AND is_deleted = 0';\n const params: string[] = [];\n\n if (folder) {\n query += ' AND folder = ?';\n params.push(folder);\n }\n\n const stmt = db.prepare(query);\n const result = stmt.get(...params) as CountResult;\n return result.count;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to count starred emails', { error: errorMessage });\n throw new StorageError(`Failed to count starred emails: ${errorMessage}`);\n }\n }\n\n countImportant(folder = null): number {\n try {\n const db = this._getDb();\n let query =\n 'SELECT COUNT(*) as count FROM emails WHERE is_important = 1 AND is_deleted = 0';\n const params: string[] = [];\n\n if (folder) {\n query += ' AND folder = ?';\n params.push(folder);\n }\n\n const stmt = db.prepare(query);\n const result = stmt.get(...params) as CountResult;\n return result.count;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to count important emails', { error: errorMessage });\n throw new StorageError(\n `Failed to count important emails: ${errorMessage}`\n );\n }\n }\n\n countByFolder(folder = 'INBOX', unreadOnly = false): number {\n try {\n const db = this._getDb();\n let sql = 'SELECT COUNT(*) as count FROM emails WHERE folder = ?';\n const params: (string | number)[] = [folder];\n\n if (unreadOnly) {\n sql += ' AND is_read = 0';\n }\n\n const stmt = db.prepare(sql);\n const result = stmt.get(...params) as CountResult;\n return result.count;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error('Failed to count emails', { folder, error: errorMessage });\n throw new StorageError(`Failed to count emails: ${errorMessage}`);\n }\n }\n\n private _formatEmail(email: EmailRow): Email {\n return {\n id: email.id,\n uid: email.uid,\n messageId: email.message_id,\n folder: email.folder,\n from: email.from_address,\n to: email.to_address,\n cc: email.cc_address || '',\n subject: email.subject,\n date: email.date,\n bodyText: email.body_text || '',\n bodyHtml: email.body_html || '',\n hasAttachments: email.has_attachments === 1,\n isRead: email.is_read === 1,\n isDraft: email.is_draft === 1,\n isDeleted: email.is_deleted === 1,\n isSpam: email.is_spam === 1,\n isStarred: email.is_starred === 1,\n isImportant: email.is_important === 1,\n priority: email.priority || 0,\n deletedAt: email.deleted_at,\n inReplyTo: email.in_reply_to,\n references: email.references,\n threadId: email.thread_id,\n accountId: email.account_id,\n flags: email.flags ? JSON.parse(email.flags) : [],\n createdAt: email.created_at,\n updatedAt: email.updated_at,\n };\n }\n}\n\nexport default new EmailModel();\n","import emailModel from '../storage/models/email';\nimport logger from '../utils/logger';\n\n/**\n * Filter Action Executor\n * Executes filter actions on emails\n */\nclass ActionExecutor {\n /**\n * Execute a single action on an email\n */\n async executeAction(email, action) {\n const { type, value } = action;\n\n try {\n switch (type) {\n case 'move':\n return await this._moveEmail(email, value);\n\n case 'mark_read':\n return await this._markAsRead(email);\n\n case 'mark_unread':\n return await this._markAsUnread(email);\n\n case 'star':\n return await this._starEmail(email);\n\n case 'unstar':\n return await this._unstarEmail(email);\n\n case 'flag':\n return await this._flagEmail(email);\n\n case 'unflag':\n return await this._unflagEmail(email);\n\n case 'delete':\n return await this._deleteEmail(email);\n\n case 'mark_spam':\n return await this._markAsSpam(email);\n\n case 'add_tag':\n return await this._addTag(email, value);\n\n case 'remove_tag':\n return await this._removeTag(email, value);\n\n default:\n logger.warn('Unknown action type', { type });\n return { success: false, message: `Unknown action type: ${type}` };\n }\n } catch (error) {\n logger.error('Failed to execute action', {\n emailId: email.id,\n action: type,\n error: error.message,\n });\n return { success: false, message: error.message };\n }\n }\n\n /**\n * Execute multiple actions on an email\n */\n async executeActions(email, actions) {\n const results = [];\n\n for (const action of actions) {\n const result = await this.executeAction(email, action);\n results.push({\n action: action.type,\n ...result,\n });\n }\n\n return results;\n }\n\n /**\n * Move email to folder\n */\n async _moveEmail(email, folder) {\n try {\n const db = emailModel._getDb();\n const stmt = db.prepare(\n 'UPDATE emails SET folder = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?'\n );\n stmt.run(folder, email.id);\n\n logger.debug('Email moved', { emailId: email.id, folder });\n return { success: true, message: `Moved to ${folder}` };\n } catch (error) {\n throw new Error(`Failed to move email: ${error.message}`);\n }\n }\n\n /**\n * Mark email as read\n */\n async _markAsRead(email) {\n await emailModel.markAsRead(email.id);\n logger.debug('Email marked as read', { emailId: email.id });\n return { success: true, message: 'Marked as read' };\n }\n\n /**\n * Mark email as unread\n */\n async _markAsUnread(email) {\n await emailModel.markAsUnread(email.id);\n logger.debug('Email marked as unread', { emailId: email.id });\n return { success: true, message: 'Marked as unread' };\n }\n\n /**\n * Star email\n */\n async _starEmail(email) {\n try {\n const db = emailModel._getDb();\n const stmt = db.prepare(\n 'UPDATE emails SET is_starred = 1, updated_at = CURRENT_TIMESTAMP WHERE id = ?'\n );\n stmt.run(email.id);\n\n logger.debug('Email starred', { emailId: email.id });\n return { success: true, message: 'Starred' };\n } catch (error) {\n throw new Error(`Failed to star email: ${error.message}`);\n }\n }\n\n /**\n * Unstar email\n */\n async _unstarEmail(email) {\n try {\n const db = emailModel._getDb();\n const stmt = db.prepare(\n 'UPDATE emails SET is_starred = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ?'\n );\n stmt.run(email.id);\n\n logger.debug('Email unstarred', { emailId: email.id });\n return { success: true, message: 'Unstarred' };\n } catch (error) {\n throw new Error(`Failed to unstar email: ${error.message}`);\n }\n }\n\n /**\n * Flag email\n */\n async _flagEmail(email) {\n try {\n const db = emailModel._getDb();\n const stmt = db.prepare(\n 'UPDATE emails SET is_flagged = 1, updated_at = CURRENT_TIMESTAMP WHERE id = ?'\n );\n stmt.run(email.id);\n\n logger.debug('Email flagged', { emailId: email.id });\n return { success: true, message: 'Flagged' };\n } catch (error) {\n throw new Error(`Failed to flag email: ${error.message}`);\n }\n }\n\n /**\n * Unflag email\n */\n async _unflagEmail(email) {\n try {\n const db = emailModel._getDb();\n const stmt = db.prepare(\n 'UPDATE emails SET is_flagged = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ?'\n );\n stmt.run(email.id);\n\n logger.debug('Email unflagged', { emailId: email.id });\n return { success: true, message: 'Unflagged' };\n } catch (error) {\n throw new Error(`Failed to unflag email: ${error.message}`);\n }\n }\n\n /**\n * Delete email (soft delete)\n */\n async _deleteEmail(email) {\n await emailModel.markAsDeleted(email.id);\n logger.debug('Email deleted', { emailId: email.id });\n return { success: true, message: 'Deleted' };\n }\n\n /**\n * Mark email as spam\n */\n async _markAsSpam(email) {\n await emailModel.markAsSpam(email.id);\n logger.debug('Email marked as spam', { emailId: email.id });\n return { success: true, message: 'Marked as spam' };\n }\n\n /**\n * Add tag to email\n */\n async _addTag(email, tagName) {\n try {\n const db = emailModel._getDb();\n\n const tagStmt = db.prepare('SELECT id FROM tags WHERE name = ?');\n const tag = tagStmt.get(tagName);\n\n if (!tag) {\n return { success: false, message: `Tag \"${tagName}\" not found` };\n }\n\n const insertStmt = db.prepare(`\n INSERT OR IGNORE INTO email_tags (email_id, tag_id)\n VALUES (?, ?)\n `);\n insertStmt.run(email.id, tag.id);\n\n logger.debug('Tag added to email', { emailId: email.id, tagName });\n return { success: true, message: `Tagged with \"${tagName}\"` };\n } catch (error) {\n throw new Error(`Failed to add tag: ${error.message}`);\n }\n }\n\n /**\n * Remove tag from email\n */\n async _removeTag(email, tagName) {\n try {\n const db = emailModel._getDb();\n\n const tagStmt = db.prepare('SELECT id FROM tags WHERE name = ?');\n const tag = tagStmt.get(tagName);\n\n if (!tag) {\n return { success: false, message: `Tag \"${tagName}\" not found` };\n }\n\n const deleteStmt = db.prepare(\n 'DELETE FROM email_tags WHERE email_id = ? AND tag_id = ?'\n );\n deleteStmt.run(email.id, tag.id);\n\n logger.debug('Tag removed from email', { emailId: email.id, tagName });\n return { success: true, message: `Removed tag \"${tagName}\"` };\n } catch (error) {\n throw new Error(`Failed to remove tag: ${error.message}`);\n }\n }\n}\n\nmodule.exports = new ActionExecutor();\n","import logger from '../utils/logger';\n\n/**\n * Filter Condition Matcher\n * Evaluates filter conditions against email data\n */\nclass ConditionMatcher {\n /**\n * Check if email matches a single condition\n */\n matchCondition(email, condition) {\n const { field, operator, value } = condition;\n const emailValue = this._getEmailField(email, field);\n\n if (emailValue === null || emailValue === undefined) {\n return false;\n }\n\n switch (operator) {\n case 'equals':\n return this._matchEquals(emailValue, value);\n\n case 'not_equals':\n return !this._matchEquals(emailValue, value);\n\n case 'contains':\n return this._matchContains(emailValue, value);\n\n case 'not_contains':\n return !this._matchContains(emailValue, value);\n\n case 'starts_with':\n return this._matchStartsWith(emailValue, value);\n\n case 'ends_with':\n return this._matchEndsWith(emailValue, value);\n\n case 'matches_regex':\n return this._matchRegex(emailValue, value);\n\n case 'greater_than':\n return this._matchGreaterThan(emailValue, value);\n\n case 'less_than':\n return this._matchLessThan(emailValue, value);\n\n case 'is_empty':\n return this._matchIsEmpty(emailValue);\n\n case 'is_not_empty':\n return !this._matchIsEmpty(emailValue);\n\n default:\n logger.warn('Unknown operator', { operator });\n return false;\n }\n }\n\n /**\n * Check if email matches all conditions (AND logic)\n */\n matchAll(email, conditions) {\n if (!conditions || conditions.length === 0) {\n return true;\n }\n\n return conditions.every((condition) =>\n this.matchCondition(email, condition)\n );\n }\n\n /**\n * Check if email matches any condition (OR logic)\n */\n matchAny(email, conditions) {\n if (!conditions || conditions.length === 0) {\n return true;\n }\n\n return conditions.some((condition) =>\n this.matchCondition(email, condition)\n );\n }\n\n /**\n * Get email field value by field name\n */\n _getEmailField(email, field) {\n switch (field) {\n case 'from':\n return email.from || '';\n\n case 'to':\n return email.to || '';\n\n case 'cc':\n return email.cc || '';\n\n case 'subject':\n return email.subject || '';\n\n case 'body':\n return (email.bodyText || '') + ' ' + (email.bodyHtml || '');\n\n case 'has_attachments':\n return email.hasAttachments;\n\n case 'size':\n return this._calculateEmailSize(email);\n\n case 'date':\n return email.date;\n\n case 'folder':\n return email.folder || '';\n\n default:\n logger.warn('Unknown field', { field });\n return null;\n }\n }\n\n /**\n * Calculate approximate email size\n */\n _calculateEmailSize(email) {\n let size = 0;\n if (email.bodyText) size += email.bodyText.length;\n if (email.bodyHtml) size += email.bodyHtml.length;\n if (email.subject) size += email.subject.length;\n return size;\n }\n\n /**\n * Match equals operator\n */\n _matchEquals(emailValue, conditionValue) {\n if (typeof emailValue === 'boolean') {\n return (\n emailValue === (conditionValue === 'true' || conditionValue === true)\n );\n }\n return (\n String(emailValue).toLowerCase() === String(conditionValue).toLowerCase()\n );\n }\n\n /**\n * Match contains operator\n */\n _matchContains(emailValue, conditionValue) {\n return String(emailValue)\n .toLowerCase()\n .includes(String(conditionValue).toLowerCase());\n }\n\n /**\n * Match starts_with operator\n */\n _matchStartsWith(emailValue, conditionValue) {\n return String(emailValue)\n .toLowerCase()\n .startsWith(String(conditionValue).toLowerCase());\n }\n\n /**\n * Match ends_with operator\n */\n _matchEndsWith(emailValue, conditionValue) {\n return String(emailValue)\n .toLowerCase()\n .endsWith(String(conditionValue).toLowerCase());\n }\n\n /**\n * Match regex operator\n */\n _matchRegex(emailValue, pattern) {\n try {\n const regex = new RegExp(pattern, 'i');\n return regex.test(String(emailValue));\n } catch (error) {\n logger.error('Invalid regex pattern', { pattern, error: error.message });\n return false;\n }\n }\n\n /**\n * Match greater_than operator\n */\n _matchGreaterThan(emailValue, conditionValue) {\n const numValue = Number(emailValue);\n const numCondition = Number(conditionValue);\n\n if (isNaN(numValue) || isNaN(numCondition)) {\n return false;\n }\n\n return numValue > numCondition;\n }\n\n /**\n * Match less_than operator\n */\n _matchLessThan(emailValue, conditionValue) {\n const numValue = Number(emailValue);\n const numCondition = Number(conditionValue);\n\n if (isNaN(numValue) || isNaN(numCondition)) {\n return false;\n }\n\n return numValue < numCondition;\n }\n\n /**\n * Match is_empty operator\n */\n _matchIsEmpty(emailValue) {\n if (emailValue === null || emailValue === undefined) {\n return true;\n }\n\n if (typeof emailValue === 'string') {\n return emailValue.trim() === '';\n }\n\n if (Array.isArray(emailValue)) {\n return emailValue.length === 0;\n }\n\n return false;\n }\n}\n\nmodule.exports = new ConditionMatcher();\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface FilterInput {\n name: string;\n description?: string | null;\n isEnabled?: boolean;\n priority?: number;\n matchAll?: boolean;\n accountId?: number | null;\n}\n\ninterface FilterUpdateInput {\n name?: string;\n description?: string | null;\n isEnabled?: boolean;\n priority?: number;\n matchAll?: boolean;\n}\n\ninterface FilterConditionInput {\n field: string;\n operator: string;\n value: string;\n}\n\ninterface FilterActionInput {\n type: string;\n value?: string | null;\n}\n\ninterface FilterFindOptions {\n enabledOnly?: boolean;\n accountId?: number | null;\n}\n\ninterface FilterRow {\n id: number;\n name: string;\n description: string | null;\n is_enabled: number;\n priority: number;\n match_all: number;\n account_id: number | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface FilterConditionRow {\n id: number;\n field: string;\n operator: string;\n value: string;\n}\n\ninterface FilterActionRow {\n id: number;\n action_type: string;\n action_value: string | null;\n}\n\nexport interface FilterRecord {\n id: number;\n name: string;\n description: string | null;\n isEnabled: boolean;\n priority: number;\n matchAll: boolean;\n accountId: number | null;\n conditions: Array<{\n id: number;\n field: string;\n operator: string;\n value: string;\n }>;\n actions: Array<{\n id: number;\n type: string;\n value: string | null;\n }>;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Filter model.\n */\nexport class FilterModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(filterData: FilterInput): number {\n try {\n const db = this.getDb();\n\n const stmt = db.prepare(`\n INSERT INTO filters (\n name, description, is_enabled, priority, match_all, account_id\n ) VALUES (?, ?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n filterData.name,\n filterData.description ?? null,\n filterData.isEnabled !== undefined ? (filterData.isEnabled ? 1 : 0) : 1,\n filterData.priority ?? 0,\n filterData.matchAll !== undefined ? (filterData.matchAll ? 1 : 0) : 1,\n filterData.accountId ?? null\n );\n\n const filterId = toNumber(result.lastInsertRowid);\n logger.debug('Filter created', { id: filterId });\n return filterId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create filter', { error: errorMessage });\n throw new StorageError(`Failed to create filter: ${errorMessage}`);\n }\n }\n\n addCondition(filterId: number, condition: FilterConditionInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO filter_conditions (filter_id, field, operator, value)\n VALUES (?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n filterId,\n condition.field,\n condition.operator,\n condition.value\n );\n\n const conditionId = toNumber(result.lastInsertRowid);\n logger.debug('Filter condition added', { filterId, conditionId });\n return conditionId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to add filter condition', {\n filterId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to add filter condition: ${errorMessage}`);\n }\n }\n\n addAction(filterId: number, action: FilterActionInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO filter_actions (filter_id, action_type, action_value)\n VALUES (?, ?, ?)\n `);\n\n const result = stmt.run(filterId, action.type, action.value ?? null);\n\n const actionId = toNumber(result.lastInsertRowid);\n logger.debug('Filter action added', { filterId, actionId });\n return actionId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to add filter action', {\n filterId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to add filter action: ${errorMessage}`);\n }\n }\n\n findById(id: number): FilterRecord | null {\n try {\n const db = this.getDb();\n\n const filterStmt = db.prepare<[number], FilterRow>(\n 'SELECT * FROM filters WHERE id = ?'\n );\n const filter = filterStmt.get(id);\n\n if (!filter) {\n return null;\n }\n\n const conditionsStmt = db.prepare<[number], FilterConditionRow>(\n 'SELECT * FROM filter_conditions WHERE filter_id = ?'\n );\n const conditions = conditionsStmt.all(id);\n\n const actionsStmt = db.prepare<[number], FilterActionRow>(\n 'SELECT * FROM filter_actions WHERE filter_id = ?'\n );\n const actions = actionsStmt.all(id);\n\n return this.formatFilter(filter, conditions, actions);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find filter by ID', { id, error: errorMessage });\n throw new StorageError(`Failed to find filter: ${errorMessage}`);\n }\n }\n\n findAll(options: FilterFindOptions = {}): FilterRecord[] {\n try {\n const db = this.getDb();\n const { enabledOnly = false, accountId = null } = options;\n\n let query = 'SELECT * FROM filters WHERE 1=1';\n const params: number[] = [];\n\n if (enabledOnly) {\n query += ' AND is_enabled = 1';\n }\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n query += ' ORDER BY priority DESC, id ASC';\n\n const stmt = db.prepare<unknown[], FilterRow>(query);\n const filters = stmt.all(...params);\n\n return filters.map((filter) => {\n const conditionsStmt = db.prepare<[number], FilterConditionRow>(\n 'SELECT * FROM filter_conditions WHERE filter_id = ?'\n );\n const conditions = conditionsStmt.all(filter.id);\n\n const actionsStmt = db.prepare<[number], FilterActionRow>(\n 'SELECT * FROM filter_actions WHERE filter_id = ?'\n );\n const actions = actionsStmt.all(filter.id);\n\n return this.formatFilter(filter, conditions, actions);\n });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find filters', { error: errorMessage });\n throw new StorageError(`Failed to find filters: ${errorMessage}`);\n }\n }\n\n update(id: number, data: FilterUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number | null> = [];\n\n if (data.name !== undefined) {\n fields.push('name = ?');\n params.push(data.name);\n }\n\n if (data.description !== undefined) {\n fields.push('description = ?');\n params.push(data.description);\n }\n\n if (data.isEnabled !== undefined) {\n fields.push('is_enabled = ?');\n params.push(data.isEnabled ? 1 : 0);\n }\n\n if (data.priority !== undefined) {\n fields.push('priority = ?');\n params.push(data.priority);\n }\n\n if (data.matchAll !== undefined) {\n fields.push('match_all = ?');\n params.push(data.matchAll ? 1 : 0);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE filters SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Filter updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update filter', { id, error: errorMessage });\n throw new StorageError(`Failed to update filter: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM filters WHERE id = ?');\n const result = stmt.run(id);\n\n logger.debug('Filter deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete filter', { id, error: errorMessage });\n throw new StorageError(`Failed to delete filter: ${errorMessage}`);\n }\n }\n\n enable(id: number): boolean {\n return this.update(id, { isEnabled: true });\n }\n\n disable(id: number): boolean {\n return this.update(id, { isEnabled: false });\n }\n\n deleteConditions(filterId: number): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(\n 'DELETE FROM filter_conditions WHERE filter_id = ?'\n );\n const result = stmt.run(filterId);\n\n logger.debug('Filter conditions deleted', {\n filterId,\n changes: result.changes,\n });\n return result.changes;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete filter conditions', {\n filterId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to delete filter conditions: ${errorMessage}`\n );\n }\n }\n\n deleteActions(filterId: number): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM filter_actions WHERE filter_id = ?');\n const result = stmt.run(filterId);\n\n logger.debug('Filter actions deleted', {\n filterId,\n changes: result.changes,\n });\n return result.changes;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete filter actions', {\n filterId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to delete filter actions: ${errorMessage}`\n );\n }\n }\n\n private formatFilter(\n filter: FilterRow,\n conditions: FilterConditionRow[] = [],\n actions: FilterActionRow[] = []\n ): FilterRecord {\n return {\n id: filter.id,\n name: filter.name,\n description: filter.description,\n isEnabled: filter.is_enabled === 1,\n priority: filter.priority,\n matchAll: filter.match_all === 1,\n accountId: filter.account_id,\n conditions: conditions.map((condition) => ({\n id: condition.id,\n field: condition.field,\n operator: condition.operator,\n value: condition.value,\n })),\n actions: actions.map((action) => ({\n id: action.id,\n type: action.action_type,\n value: action.action_value,\n })),\n createdAt: filter.created_at,\n updatedAt: filter.updated_at,\n };\n }\n}\n\nconst filterModel = new FilterModel();\nexport default filterModel;\n","import executor from './executor';\nimport matcher from './matcher';\nimport emailModel from '../storage/models/email';\nimport filterModel from '../storage/models/filter';\nimport logger from '../utils/logger';\n\n/**\n * Filter Rules Engine\n * Main engine for processing email filter rules\n */\nclass FilterEngine {\n /**\n * Apply all enabled filters to an email\n */\n async applyFilters(email, options = {}) {\n try {\n const { accountId = null } = options;\n\n const filters = filterModel.findAll({\n enabledOnly: true,\n accountId,\n });\n\n if (filters.length === 0) {\n logger.debug('No filters to apply', { emailId: email.id });\n return { matched: false, appliedFilters: [] };\n }\n\n const appliedFilters = [];\n\n for (const filter of filters) {\n const matched = this._matchFilter(email, filter);\n\n if (matched) {\n logger.debug('Filter matched', {\n emailId: email.id,\n filterId: filter.id,\n filterName: filter.name,\n });\n\n const results = await executor.executeActions(email, filter.actions);\n\n appliedFilters.push({\n filterId: filter.id,\n filterName: filter.name,\n actions: results,\n });\n\n email = await emailModel.findById(email.id);\n }\n }\n\n return {\n matched: appliedFilters.length > 0,\n appliedFilters,\n };\n } catch (error) {\n logger.error('Failed to apply filters', {\n emailId: email.id,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Test if an email matches a filter (without executing actions)\n */\n testFilter(email, filterId) {\n try {\n const filter = filterModel.findById(filterId);\n\n if (!filter) {\n throw new Error(`Filter ${filterId} not found`);\n }\n\n const matched = this._matchFilter(email, filter);\n\n return {\n matched,\n filter: {\n id: filter.id,\n name: filter.name,\n conditions: filter.conditions,\n actions: filter.actions,\n },\n };\n } catch (error) {\n logger.error('Failed to test filter', {\n emailId: email.id,\n filterId,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Apply filters to multiple emails\n */\n async applyFiltersToEmails(emails, options = {}) {\n const results = [];\n\n for (const email of emails) {\n try {\n const result = await this.applyFilters(email, options);\n results.push({\n emailId: email.id,\n ...result,\n });\n } catch (error) {\n logger.error('Failed to apply filters to email', {\n emailId: email.id,\n error: error.message,\n });\n results.push({\n emailId: email.id,\n error: error.message,\n });\n }\n }\n\n return results;\n }\n\n /**\n * Apply a specific filter to an email\n */\n async applyFilter(email, filterId) {\n try {\n const filter = filterModel.findById(filterId);\n\n if (!filter) {\n throw new Error(`Filter ${filterId} not found`);\n }\n\n if (!filter.isEnabled) {\n return {\n matched: false,\n message: 'Filter is disabled',\n };\n }\n\n const matched = this._matchFilter(email, filter);\n\n if (!matched) {\n return {\n matched: false,\n message: 'Email does not match filter conditions',\n };\n }\n\n const results = await executor.executeActions(email, filter.actions);\n\n return {\n matched: true,\n filterId: filter.id,\n filterName: filter.name,\n actions: results,\n };\n } catch (error) {\n logger.error('Failed to apply filter', {\n emailId: email.id,\n filterId,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Check if email matches filter conditions\n */\n _matchFilter(email, filter) {\n if (!filter.conditions || filter.conditions.length === 0) {\n return true;\n }\n\n if (filter.matchAll) {\n return matcher.matchAll(email, filter.conditions);\n } else {\n return matcher.matchAny(email, filter.conditions);\n }\n }\n\n /**\n * Get filter statistics\n */\n getStatistics() {\n try {\n const allFilters = filterModel.findAll();\n const enabledFilters = filterModel.findAll({ enabledOnly: true });\n\n return {\n totalFilters: allFilters.length,\n enabledFilters: enabledFilters.length,\n disabledFilters: allFilters.length - enabledFilters.length,\n };\n } catch (error) {\n logger.error('Failed to get filter statistics', { error: error.message });\n throw error;\n }\n }\n}\n\nmodule.exports = new FilterEngine();\n","import path from 'path';\n\nimport notifier from 'node-notifier';\n\nimport config from '../config';\nimport logger from '../utils/logger';\n\n/**\n * Notification Manager\n * Manages email notifications with filtering and configuration\n */\nclass NotificationManager {\n constructor() {\n this.enabled = false;\n this.config = {\n enabled: false,\n filters: {\n senders: [], // Filter by sender email\n tags: [], // Filter by tags\n importantOnly: false, // Only notify for important emails\n },\n sound: true,\n desktop: true,\n };\n this.loadConfig();\n }\n\n /**\n * Load notification configuration\n */\n loadConfig() {\n try {\n const cfg = config.load();\n if (cfg.notifications) {\n this.config = { ...this.config, ...cfg.notifications };\n this.enabled = this.config.enabled;\n }\n } catch (error) {\n logger.error('Failed to load notification config', {\n error: error.message,\n });\n }\n }\n\n /**\n * Save notification configuration\n */\n saveConfig() {\n try {\n const cfg = config.load();\n cfg.notifications = this.config;\n config.save(cfg);\n logger.info('Notification config saved');\n } catch (error) {\n logger.error('Failed to save notification config', {\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Enable notifications\n */\n enable() {\n this.enabled = true;\n this.config.enabled = true;\n this.saveConfig();\n logger.info('Notifications enabled');\n return true;\n }\n\n /**\n * Disable notifications\n */\n disable() {\n this.enabled = false;\n this.config.enabled = false;\n this.saveConfig();\n logger.info('Notifications disabled');\n return true;\n }\n\n /**\n * Update notification filters\n */\n updateFilters(filters) {\n if (filters.senders !== undefined) {\n this.config.filters.senders = Array.isArray(filters.senders)\n ? filters.senders\n : [filters.senders];\n }\n\n if (filters.tags !== undefined) {\n this.config.filters.tags = Array.isArray(filters.tags)\n ? filters.tags\n : [filters.tags];\n }\n\n if (filters.importantOnly !== undefined) {\n this.config.filters.importantOnly = filters.importantOnly;\n }\n\n this.saveConfig();\n logger.info('Notification filters updated', {\n filters: this.config.filters,\n });\n return this.config.filters;\n }\n\n /**\n * Update notification settings\n */\n updateSettings(settings) {\n if (settings.sound !== undefined) {\n this.config.sound = settings.sound;\n }\n\n if (settings.desktop !== undefined) {\n this.config.desktop = settings.desktop;\n }\n\n this.saveConfig();\n logger.info('Notification settings updated', { settings });\n return this.config;\n }\n\n /**\n * Check if email should trigger notification\n */\n shouldNotify(email) {\n if (!this.enabled) {\n return false;\n }\n\n // Check important only filter\n if (this.config.filters.importantOnly && !email.isImportant) {\n return false;\n }\n\n // Check sender filter\n if (this.config.filters.senders.length > 0) {\n const senderEmail = email.from?.address || email.from;\n const matchesSender = this.config.filters.senders.some((sender) =>\n senderEmail.toLowerCase().includes(sender.toLowerCase())\n );\n if (!matchesSender) {\n return false;\n }\n }\n\n // Check tag filter\n if (this.config.filters.tags.length > 0 && email.tags) {\n const emailTags = Array.isArray(email.tags) ? email.tags : [email.tags];\n const matchesTag = this.config.filters.tags.some((tag) =>\n emailTags.includes(tag)\n );\n if (!matchesTag) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Send desktop notification\n */\n async sendDesktopNotification(email) {\n if (!this.config.desktop) {\n return;\n }\n\n try {\n const from = email.from?.address || email.from || 'Unknown';\n const subject = email.subject || '(No subject)';\n const preview = this.getEmailPreview(email);\n\n notifier.notify({\n title: `New Email from ${from}`,\n message: `${subject}\\n\\n${preview}`,\n sound: this.config.sound,\n wait: false,\n icon: path.join(__dirname, '../../assets/mail-icon.png'),\n timeout: 10,\n });\n\n logger.info('Desktop notification sent', { from, subject });\n } catch (error) {\n logger.error('Failed to send desktop notification', {\n error: error.message,\n });\n }\n }\n\n /**\n * Get email preview text\n */\n getEmailPreview(email, maxLength = 100) {\n let text = email.text || email.textAsHtml || '';\n\n // Remove extra whitespace and newlines\n text = text.replace(/\\s+/g, ' ').trim();\n\n // Truncate if too long\n if (text.length > maxLength) {\n text = text.substring(0, maxLength) + '...';\n }\n\n return text || '(No preview available)';\n }\n\n /**\n * Log notification\n */\n logNotification(email) {\n const from = email.from?.address || email.from || 'Unknown';\n const subject = email.subject || '(No subject)';\n\n logger.info('Email notification', {\n from,\n subject,\n date: email.date,\n isImportant: email.isImportant,\n });\n }\n\n /**\n * Notify about new email\n */\n async notify(email) {\n if (!this.shouldNotify(email)) {\n return false;\n }\n\n try {\n // Send desktop notification\n await this.sendDesktopNotification(email);\n\n // Log notification\n this.logNotification(email);\n\n return true;\n } catch (error) {\n logger.error('Failed to send notification', { error: error.message });\n return false;\n }\n }\n\n /**\n * Notify about multiple new emails\n */\n async notifyBatch(emails) {\n if (!this.enabled || !Array.isArray(emails) || emails.length === 0) {\n return 0;\n }\n\n let notifiedCount = 0;\n\n for (const email of emails) {\n const notified = await this.notify(email);\n if (notified) {\n notifiedCount++;\n }\n }\n\n // Send summary notification if multiple emails\n if (notifiedCount > 1 && this.config.desktop) {\n try {\n notifier.notify({\n title: 'New Emails',\n message: `You have ${notifiedCount} new emails`,\n sound: this.config.sound,\n wait: false,\n timeout: 5,\n });\n } catch (error) {\n logger.error('Failed to send batch notification', {\n error: error.message,\n });\n }\n }\n\n return notifiedCount;\n }\n\n /**\n * Test notification\n */\n async test() {\n try {\n notifier.notify({\n title: 'Mail Client - Test Notification',\n message: 'Notifications are working correctly!',\n sound: this.config.sound,\n wait: false,\n timeout: 5,\n });\n\n logger.info('Test notification sent');\n return true;\n } catch (error) {\n logger.error('Failed to send test notification', {\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Get current configuration\n */\n getConfig() {\n return {\n enabled: this.enabled,\n ...this.config,\n };\n }\n\n /**\n * Get filter statistics\n */\n getFilterStats() {\n return {\n senderCount: this.config.filters.senders.length,\n tagCount: this.config.filters.tags.length,\n importantOnly: this.config.filters.importantOnly,\n };\n }\n}\n\nmodule.exports = new NotificationManager();\n","/**\n * Spam Detection Rules\n * Contains various spam detection algorithms\n */\n\n/**\n * Check for spam keywords in email\n * @param {string} pattern - Regex pattern or keyword list (pipe-separated)\n * @param {Object} email - Email object\n * @returns {Object} - { matched: boolean, reason: string }\n */\nfunction checkKeywords(pattern, email) {\n try {\n const regex = new RegExp(pattern, 'i');\n const subject = email.subject || '';\n const body = email.bodyText || '';\n\n // Check subject\n if (regex.test(subject)) {\n return {\n matched: true,\n reason: `Spam keyword found in subject: \"${subject.match(regex)[0]}\"`,\n };\n }\n\n // Check body\n if (regex.test(body)) {\n const match = body.match(regex);\n return {\n matched: true,\n reason: `Spam keyword found in body: \"${match ? match[0] : 'keyword'}\"`,\n };\n }\n\n return { matched: false };\n } catch (error) {\n return { matched: false };\n }\n}\n\n/**\n * Check for suspicious links in email\n * @param {string} pattern - Pattern to match suspicious links\n * @param {Object} email - Email object\n * @returns {Object} - { matched: boolean, reason: string }\n */\nfunction checkSuspiciousLinks(pattern, email) {\n try {\n const body = email.bodyText || '';\n const html = email.bodyHtml || '';\n\n // Common suspicious link patterns\n const suspiciousPatterns = [\n /bit\\.ly|tinyurl|goo\\.gl/i, // URL shorteners\n /\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/, // IP addresses\n /https?:\\/\\/[^\\s]+\\.(tk|ml|ga|cf|gq)/i, // Suspicious TLDs\n ];\n\n // Check for URL shorteners and suspicious domains\n for (const suspPattern of suspiciousPatterns) {\n if (suspPattern.test(body) || suspPattern.test(html)) {\n return {\n matched: true,\n reason:\n 'Suspicious link detected (URL shortener or suspicious domain)',\n };\n }\n }\n\n // Check custom pattern if provided\n if (pattern) {\n const regex = new RegExp(pattern, 'i');\n if (regex.test(body) || regex.test(html)) {\n return {\n matched: true,\n reason: 'Suspicious link pattern matched',\n };\n }\n }\n\n return { matched: false };\n } catch (error) {\n return { matched: false };\n }\n}\n\n/**\n * Check email headers for spam indicators\n * @param {string} pattern - Header pattern to check\n * @param {Object} email - Email object\n * @returns {Object} - { matched: boolean, reason: string }\n */\nfunction checkHeaders(pattern, email) {\n try {\n // Check for common spam header indicators\n const spamIndicators = [\n { key: 'X-Spam-Flag', value: 'YES' },\n { key: 'X-Spam-Status', value: 'Yes' },\n ];\n\n // For now, we'll check if the pattern matches known spam headers\n // In a real implementation, we'd parse actual email headers\n if (\n pattern.includes('X-Spam-Flag: YES') ||\n pattern.includes('X-Spam-Status: Yes')\n ) {\n // This would need actual header data from the email\n // For now, return false as we don't have header data in the model\n return { matched: false };\n }\n\n return { matched: false };\n } catch (error) {\n return { matched: false };\n }\n}\n\n/**\n * Check sender reputation\n * @param {string} senderEmail - Sender email address\n * @returns {Object} - { matched: boolean, reason: string, score: number }\n */\nfunction checkSenderReputation(senderEmail) {\n try {\n // Check for suspicious sender patterns\n const suspiciousPatterns = [\n /noreply@/i,\n /no-reply@/i,\n /donotreply@/i,\n /\\d{5,}@/, // Many numbers in email\n /[a-z]{20,}@/i, // Very long random string\n ];\n\n for (const pattern of suspiciousPatterns) {\n if (pattern.test(senderEmail)) {\n return {\n matched: true,\n reason: 'Suspicious sender email pattern',\n score: 10,\n };\n }\n }\n\n return { matched: false, score: 0 };\n } catch (error) {\n return { matched: false, score: 0 };\n }\n}\n\n/**\n * Check for excessive capitalization (SHOUTING)\n * @param {Object} email - Email object\n * @returns {Object} - { matched: boolean, reason: string }\n */\nfunction checkExcessiveCaps(email) {\n try {\n const subject = email.subject || '';\n\n if (subject.length < 10) {\n return { matched: false };\n }\n\n // Count uppercase letters\n const upperCount = (subject.match(/[A-Z]/g) || []).length;\n const totalLetters = (subject.match(/[A-Za-z]/g) || []).length;\n\n if (totalLetters === 0) {\n return { matched: false };\n }\n\n const capsRatio = upperCount / totalLetters;\n\n // If more than 70% uppercase, likely spam\n if (capsRatio > 0.7) {\n return {\n matched: true,\n reason: 'Excessive capitalization in subject',\n };\n }\n\n return { matched: false };\n } catch (error) {\n return { matched: false };\n }\n}\n\n/**\n * Check for excessive punctuation (!!!, ???)\n * @param {Object} email - Email object\n * @returns {Object} - { matched: boolean, reason: string }\n */\nfunction checkExcessivePunctuation(email) {\n try {\n const subject = email.subject || '';\n\n // Check for repeated punctuation\n const patterns = [\n /!{3,}/, // Multiple exclamation marks\n /\\?{3,}/, // Multiple question marks\n /\\.{4,}/, // Multiple periods (more than ellipsis)\n ];\n\n for (const pattern of patterns) {\n if (pattern.test(subject)) {\n return {\n matched: true,\n reason: 'Excessive punctuation in subject',\n };\n }\n }\n\n return { matched: false };\n } catch (error) {\n return { matched: false };\n }\n}\n\n/**\n * Check for common phishing patterns\n * @param {Object} email - Email object\n * @returns {Object} - { matched: boolean, reason: string }\n */\nfunction checkPhishingPatterns(email) {\n try {\n const subject = (email.subject || '').toLowerCase();\n const body = (email.bodyText || '').toLowerCase();\n\n const phishingKeywords = [\n 'verify your account',\n 'confirm your identity',\n 'suspended account',\n 'unusual activity',\n 'click here to verify',\n 'update your information',\n 'security alert',\n 'your account will be closed',\n ];\n\n for (const keyword of phishingKeywords) {\n if (subject.includes(keyword) || body.includes(keyword)) {\n return {\n matched: true,\n reason: `Potential phishing: \"${keyword}\"`,\n };\n }\n }\n\n return { matched: false };\n } catch (error) {\n return { matched: false };\n }\n}\n\nexport {\n checkKeywords,\n checkSuspiciousLinks,\n checkHeaders,\n checkSenderReputation,\n checkExcessiveCaps,\n checkExcessivePunctuation,\n checkPhishingPatterns,\n};\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface SpamRuleInput {\n ruleType: string;\n pattern: string;\n action: string;\n isEnabled?: boolean;\n priority?: number;\n}\n\ninterface SpamRuleUpdateInput {\n ruleType?: string;\n pattern?: string;\n action?: string;\n isEnabled?: boolean;\n priority?: number;\n}\n\ninterface SpamRuleRow {\n id: number;\n rule_type: string;\n pattern: string;\n action: string;\n is_enabled: number;\n priority: number;\n created_at: string;\n}\n\ninterface EmailListRow {\n id: number;\n email_address: string;\n domain: string | null;\n reason?: string | null;\n created_at: string;\n}\n\ninterface CountRow {\n count: number;\n}\n\nexport interface SpamRuleRecord {\n id: number;\n ruleType: string;\n pattern: string;\n action: string;\n isEnabled: boolean;\n priority: number;\n createdAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Spam model.\n */\nexport class SpamModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n createRule(ruleData: SpamRuleInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO spam_rules (\n rule_type, pattern, action, is_enabled, priority\n ) VALUES (?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n ruleData.ruleType,\n ruleData.pattern,\n ruleData.action,\n ruleData.isEnabled !== undefined ? (ruleData.isEnabled ? 1 : 0) : 1,\n ruleData.priority ?? 0\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Spam rule created', { id: insertId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create spam rule', { error: errorMessage });\n throw new StorageError(`Failed to create spam rule: ${errorMessage}`);\n }\n }\n\n findAllRules(enabledOnly = false): SpamRuleRecord[] {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM spam_rules';\n\n if (enabledOnly) {\n query += ' WHERE is_enabled = 1';\n }\n\n query += ' ORDER BY priority DESC, created_at ASC';\n\n const stmt = db.prepare<[], SpamRuleRow>(query);\n const rules = stmt.all();\n return rules.map((rule) => this.formatRule(rule));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find spam rules', { error: errorMessage });\n throw new StorageError(`Failed to find spam rules: ${errorMessage}`);\n }\n }\n\n updateRule(id: number, data: SpamRuleUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number> = [];\n\n if (data.ruleType !== undefined) {\n fields.push('rule_type = ?');\n params.push(data.ruleType);\n }\n\n if (data.pattern !== undefined) {\n fields.push('pattern = ?');\n params.push(data.pattern);\n }\n\n if (data.action !== undefined) {\n fields.push('action = ?');\n params.push(data.action);\n }\n\n if (data.isEnabled !== undefined) {\n fields.push('is_enabled = ?');\n params.push(data.isEnabled ? 1 : 0);\n }\n\n if (data.priority !== undefined) {\n fields.push('priority = ?');\n params.push(data.priority);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n params.push(id);\n const sql = `UPDATE spam_rules SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Spam rule updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update spam rule', { id, error: errorMessage });\n throw new StorageError(`Failed to update spam rule: ${errorMessage}`);\n }\n }\n\n deleteRule(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM spam_rules WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Spam rule deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete spam rule', { id, error: errorMessage });\n throw new StorageError(`Failed to delete spam rule: ${errorMessage}`);\n }\n }\n\n addToBlacklist(emailAddress: string, reason: string | null = null): number {\n try {\n const db = this.getDb();\n const domain = this.extractDomain(emailAddress);\n\n const stmt = db.prepare(`\n INSERT OR REPLACE INTO blacklist (email_address, domain, reason)\n VALUES (?, ?, ?)\n `);\n\n const result = stmt.run(emailAddress, domain, reason);\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Email added to blacklist', { emailAddress });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to add to blacklist', {\n emailAddress,\n error: errorMessage,\n });\n throw new StorageError(`Failed to add to blacklist: ${errorMessage}`);\n }\n }\n\n removeFromBlacklist(emailAddress: string): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM blacklist WHERE email_address = ?');\n const result = stmt.run(emailAddress);\n logger.debug('Email removed from blacklist', {\n emailAddress,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to remove from blacklist', {\n emailAddress,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to remove from blacklist: ${errorMessage}`\n );\n }\n }\n\n isBlacklisted(emailAddress: string): boolean {\n try {\n const db = this.getDb();\n const domain = this.extractDomain(emailAddress);\n\n const stmt = db.prepare<[string, string | null], CountRow>(`\n SELECT COUNT(*) as count FROM blacklist\n WHERE email_address = ? OR domain = ?\n `);\n\n const result = stmt.get(emailAddress, domain);\n return (result?.count ?? 0) > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to check blacklist', {\n emailAddress,\n error: errorMessage,\n });\n throw new StorageError(`Failed to check blacklist: ${errorMessage}`);\n }\n }\n\n getBlacklist(): EmailListRow[] {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[], EmailListRow>(\n 'SELECT * FROM blacklist ORDER BY created_at DESC'\n );\n return stmt.all();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to get blacklist', { error: errorMessage });\n throw new StorageError(`Failed to get blacklist: ${errorMessage}`);\n }\n }\n\n addToWhitelist(emailAddress: string): number {\n try {\n const db = this.getDb();\n const domain = this.extractDomain(emailAddress);\n\n const stmt = db.prepare(`\n INSERT OR REPLACE INTO whitelist (email_address, domain)\n VALUES (?, ?)\n `);\n\n const result = stmt.run(emailAddress, domain);\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Email added to whitelist', { emailAddress });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to add to whitelist', {\n emailAddress,\n error: errorMessage,\n });\n throw new StorageError(`Failed to add to whitelist: ${errorMessage}`);\n }\n }\n\n removeFromWhitelist(emailAddress: string): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM whitelist WHERE email_address = ?');\n const result = stmt.run(emailAddress);\n logger.debug('Email removed from whitelist', {\n emailAddress,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to remove from whitelist', {\n emailAddress,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to remove from whitelist: ${errorMessage}`\n );\n }\n }\n\n isWhitelisted(emailAddress: string): boolean {\n try {\n const db = this.getDb();\n const domain = this.extractDomain(emailAddress);\n\n const stmt = db.prepare<[string, string | null], CountRow>(`\n SELECT COUNT(*) as count FROM whitelist\n WHERE email_address = ? OR domain = ?\n `);\n\n const result = stmt.get(emailAddress, domain);\n return (result?.count ?? 0) > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to check whitelist', {\n emailAddress,\n error: errorMessage,\n });\n throw new StorageError(`Failed to check whitelist: ${errorMessage}`);\n }\n }\n\n getWhitelist(): EmailListRow[] {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[], EmailListRow>(\n 'SELECT * FROM whitelist ORDER BY created_at DESC'\n );\n return stmt.all();\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to get whitelist', { error: errorMessage });\n throw new StorageError(`Failed to get whitelist: ${errorMessage}`);\n }\n }\n\n private extractDomain(emailAddress: string): string | null {\n const match = emailAddress.match(/@(.+)$/);\n return match ? match[1] : null;\n }\n\n private formatRule(rule: SpamRuleRow): SpamRuleRecord {\n return {\n id: rule.id,\n ruleType: rule.rule_type,\n pattern: rule.pattern,\n action: rule.action,\n isEnabled: rule.is_enabled === 1,\n priority: rule.priority,\n createdAt: rule.created_at,\n };\n }\n}\n\nconst spamModel = new SpamModel();\nexport default spamModel;\n","import { checkKeywords, checkSuspiciousLinks, checkHeaders } from './rules';\nimport emailModel from '../storage/models/email';\nimport spamModel from '../storage/models/spam';\nimport logger from '../utils/logger';\n\n/**\n * Spam Filter Engine\n * Detects and filters spam emails\n */\nclass SpamFilter {\n constructor() {\n this.threshold = 50; // Spam score threshold\n this.rules = [];\n }\n\n /**\n * Initialize spam filter with rules from database\n */\n async initialize() {\n try {\n this.rules = await spamModel.findAllRules(true);\n logger.info('Spam filter initialized', { rulesCount: this.rules.length });\n } catch (error) {\n logger.error('Failed to initialize spam filter', {\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Detect if an email is spam\n * @param {Object} email - Email object to check\n * @returns {Object} - { isSpam: boolean, score: number, reasons: string[] }\n */\n async detectSpam(email) {\n const result = {\n isSpam: false,\n score: 0,\n reasons: [],\n };\n\n try {\n // 1. Whitelist check (highest priority - always pass)\n if (await spamModel.isWhitelisted(email.from)) {\n logger.debug('Email from whitelisted sender', { from: email.from });\n return result;\n }\n\n // 2. Blacklist check (immediate spam)\n if (await spamModel.isBlacklisted(email.from)) {\n result.isSpam = true;\n result.score = 100;\n result.reasons.push('Sender is blacklisted');\n logger.debug('Email from blacklisted sender', { from: email.from });\n return result;\n }\n\n // 3. Apply spam detection rules\n for (const rule of this.rules) {\n const ruleResult = this._applyRule(rule, email);\n if (ruleResult.matched) {\n result.score += this._getRuleWeight(rule);\n result.reasons.push(ruleResult.reason);\n }\n }\n\n // 4. Determine if spam based on threshold\n result.isSpam = result.score >= this.threshold;\n\n logger.debug('Spam detection completed', {\n emailId: email.id,\n from: email.from,\n score: result.score,\n isSpam: result.isSpam,\n });\n\n return result;\n } catch (error) {\n logger.error('Spam detection failed', { error: error.message });\n throw error;\n }\n }\n\n /**\n * Apply a single spam rule to an email\n */\n _applyRule(rule, email) {\n try {\n switch (rule.ruleType) {\n case 'keyword':\n return checkKeywords(rule.pattern, email);\n case 'link':\n return checkSuspiciousLinks(rule.pattern, email);\n case 'header':\n return checkHeaders(rule.pattern, email);\n default:\n return { matched: false };\n }\n } catch (error) {\n logger.error('Failed to apply spam rule', {\n ruleId: rule.id,\n error: error.message,\n });\n return { matched: false };\n }\n }\n\n /**\n * Get weight for a spam rule based on priority\n */\n _getRuleWeight(rule) {\n // Priority maps to weight\n // Higher priority = higher weight\n return rule.priority || 10;\n }\n\n /**\n * Filter a single email\n * Marks as spam if detected\n */\n async filterEmail(emailId) {\n try {\n const email = await emailModel.findById(emailId);\n if (!email) {\n throw new Error(`Email not found: ${emailId}`);\n }\n\n const detection = await this.detectSpam(email);\n\n if (detection.isSpam) {\n await emailModel.markAsSpam(emailId);\n logger.info('Email marked as spam', {\n emailId,\n score: detection.score,\n reasons: detection.reasons,\n });\n }\n\n return detection;\n } catch (error) {\n logger.error('Failed to filter email', { emailId, error: error.message });\n throw error;\n }\n }\n\n /**\n * Filter multiple emails\n */\n async filterEmails(emailIds) {\n const results = [];\n for (const emailId of emailIds) {\n try {\n const result = await this.filterEmail(emailId);\n results.push({ emailId, ...result });\n } catch (error) {\n results.push({ emailId, error: error.message });\n }\n }\n return results;\n }\n\n /**\n * Learn from user feedback\n * Updates rules based on user marking emails as spam/not spam\n */\n async learnFromFeedback(emailId, isSpam) {\n try {\n const email = await emailModel.findById(emailId);\n if (!email) {\n throw new Error(`Email not found: ${emailId}`);\n }\n\n if (isSpam) {\n // User marked as spam - extract patterns\n await this._learnSpamPatterns(email);\n } else {\n // User marked as not spam - could be false positive\n await this._learnHamPatterns(email);\n }\n\n logger.info('Learned from user feedback', { emailId, isSpam });\n } catch (error) {\n logger.error('Failed to learn from feedback', {\n emailId,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Extract and learn spam patterns from email\n */\n async _learnSpamPatterns(email) {\n // Extract common spam keywords from subject\n const subject = email.subject.toLowerCase();\n const spamKeywords = [\n 'free',\n 'winner',\n 'prize',\n 'click here',\n 'act now',\n 'limited time',\n ];\n\n for (const keyword of spamKeywords) {\n if (subject.includes(keyword)) {\n // Check if rule already exists\n const existingRules = await spamModel.findAllRules();\n const hasRule = existingRules.some(\n (r) => r.ruleType === 'keyword' && r.pattern.includes(keyword)\n );\n\n if (!hasRule) {\n await spamModel.createRule({\n ruleType: 'keyword',\n pattern: keyword,\n action: 'mark_spam',\n priority: 5,\n });\n logger.debug('Created new spam keyword rule', { keyword });\n }\n }\n }\n }\n\n /**\n * Learn from ham (non-spam) patterns\n */\n async _learnHamPatterns(email) {\n // If email was marked as not spam but was detected as spam,\n // we might want to reduce rule weights or add to whitelist\n // For now, just log it\n logger.debug('Learning from ham email', { from: email.from });\n }\n\n /**\n * Get spam statistics\n */\n async getStatistics() {\n try {\n const spamCount = await emailModel.countSpam();\n const blacklistCount = (await spamModel.getBlacklist()).length;\n const whitelistCount = (await spamModel.getWhitelist()).length;\n const rulesCount = (await spamModel.findAllRules()).length;\n\n return {\n spamCount,\n blacklistCount,\n whitelistCount,\n rulesCount,\n threshold: this.threshold,\n };\n } catch (error) {\n logger.error('Failed to get spam statistics', { error: error.message });\n throw error;\n }\n }\n}\n\nmodule.exports = new SpamFilter();\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface AttachmentInput {\n emailId: number;\n filename: string;\n contentType?: string | null;\n size?: number | null;\n filePath?: string | null;\n}\n\ninterface AttachmentRow {\n id: number;\n email_id: number;\n filename: string;\n content_type: string | null;\n size: number | null;\n file_path: string | null;\n created_at: string;\n}\n\nexport interface AttachmentRecord {\n id: number;\n emailId: number;\n filename: string;\n contentType: string | null;\n size: number | null;\n filePath: string | null;\n createdAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Attachment model.\n */\nexport class AttachmentModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(attachmentData: AttachmentInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO attachments (email_id, filename, content_type, size, file_path)\n VALUES (?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n attachmentData.emailId,\n attachmentData.filename,\n attachmentData.contentType ?? null,\n attachmentData.size ?? null,\n attachmentData.filePath ?? null\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Attachment created', { id: insertId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create attachment', { error: errorMessage });\n throw new StorageError(`Failed to create attachment: ${errorMessage}`);\n }\n }\n\n findByEmailId(emailId: number): AttachmentRecord[] {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], AttachmentRow>(\n 'SELECT * FROM attachments WHERE email_id = ?'\n );\n const attachments = stmt.all(emailId);\n return attachments.map((attachment) => this.formatAttachment(attachment));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find attachments', {\n emailId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find attachments: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM attachments WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Attachment deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete attachment', { id, error: errorMessage });\n throw new StorageError(`Failed to delete attachment: ${errorMessage}`);\n }\n }\n\n private formatAttachment(attachment: AttachmentRow): AttachmentRecord {\n return {\n id: attachment.id,\n emailId: attachment.email_id,\n filename: attachment.filename,\n contentType: attachment.content_type,\n size: attachment.size,\n filePath: attachment.file_path,\n createdAt: attachment.created_at,\n };\n }\n}\n\nconst attachmentModel = new AttachmentModel();\nexport default attachmentModel;\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface FolderInput {\n name: string;\n delimiter?: string | null;\n flags?: string[];\n lastSync?: string | null;\n accountId?: number | null;\n parentId?: number | null;\n isFavorite?: boolean;\n sortOrder?: number;\n}\n\ninterface FolderRow {\n id: number;\n name: string;\n delimiter: string | null;\n flags: string | null;\n last_sync: string | null;\n account_id: number | null;\n parent_id: number | null;\n is_favorite: number;\n sort_order: number | null;\n unread_count: number | null;\n total_count: number | null;\n created_at: string;\n}\n\nexport interface FolderRecord {\n id: number;\n name: string;\n delimiter: string | null;\n flags: string[];\n lastSync: string | null;\n accountId: number | null;\n parentId: number | null;\n isFavorite: boolean;\n sortOrder: number;\n unreadCount: number;\n totalCount: number;\n createdAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Folder model.\n */\nexport class FolderModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n upsert(folderData: FolderInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO folders (name, delimiter, flags, last_sync, account_id, parent_id, is_favorite, sort_order)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(name) DO UPDATE SET\n delimiter = excluded.delimiter,\n flags = excluded.flags,\n last_sync = excluded.last_sync,\n account_id = excluded.account_id,\n parent_id = excluded.parent_id,\n is_favorite = excluded.is_favorite,\n sort_order = excluded.sort_order\n `);\n\n const result = stmt.run(\n folderData.name,\n folderData.delimiter ?? '/',\n folderData.flags ? JSON.stringify(folderData.flags) : null,\n folderData.lastSync ?? null,\n folderData.accountId ?? null,\n folderData.parentId ?? null,\n folderData.isFavorite ? 1 : 0,\n folderData.sortOrder ?? 0\n );\n\n logger.debug('Folder upserted', { name: folderData.name });\n return result.lastInsertRowid\n ? toNumber(result.lastInsertRowid)\n : result.changes;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to upsert folder', { error: errorMessage });\n throw new StorageError(`Failed to upsert folder: ${errorMessage}`);\n }\n }\n\n create(folderData: FolderInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO folders (name, delimiter, flags, account_id, parent_id, is_favorite, sort_order)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n folderData.name,\n folderData.delimiter ?? '/',\n folderData.flags ? JSON.stringify(folderData.flags) : null,\n folderData.accountId ?? null,\n folderData.parentId ?? null,\n folderData.isFavorite ? 1 : 0,\n folderData.sortOrder ?? 0\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Folder created', { name: folderData.name, id: insertId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create folder', { error: errorMessage });\n throw new StorageError(`Failed to create folder: ${errorMessage}`);\n }\n }\n\n deleteByName(name: string): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM folders WHERE name = ?');\n const result = stmt.run(name);\n logger.debug('Folder deleted', { name, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete folder', { name, error: errorMessage });\n throw new StorageError(`Failed to delete folder: ${errorMessage}`);\n }\n }\n\n rename(oldName: string, newName: string): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('UPDATE folders SET name = ? WHERE name = ?');\n const result = stmt.run(newName, oldName);\n logger.debug('Folder renamed', {\n oldName,\n newName,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to rename folder', {\n oldName,\n newName,\n error: errorMessage,\n });\n throw new StorageError(`Failed to rename folder: ${errorMessage}`);\n }\n }\n\n findChildren(parentId: number): FolderRecord[] {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], FolderRow>(\n 'SELECT * FROM folders WHERE parent_id = ? ORDER BY sort_order, name'\n );\n const folders = stmt.all(parentId);\n return folders.map((folder) => this.formatFolder(folder));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find child folders', {\n parentId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find child folders: ${errorMessage}`);\n }\n }\n\n updateCounts(name: string, unreadCount: number, totalCount: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare(\n 'UPDATE folders SET unread_count = ?, total_count = ? WHERE name = ?'\n );\n const result = stmt.run(unreadCount, totalCount, name);\n logger.debug('Folder counts updated', { name, unreadCount, totalCount });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update folder counts', {\n name,\n error: errorMessage,\n });\n throw new StorageError(`Failed to update folder counts: ${errorMessage}`);\n }\n }\n\n findAll(): FolderRecord[] {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[], FolderRow>(\n 'SELECT * FROM folders ORDER BY name'\n );\n const folders = stmt.all();\n return folders.map((folder) => this.formatFolder(folder));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find folders', { error: errorMessage });\n throw new StorageError(`Failed to find folders: ${errorMessage}`);\n }\n }\n\n findByName(name: string): FolderRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[string], FolderRow>(\n 'SELECT * FROM folders WHERE name = ?'\n );\n const folder = stmt.get(name);\n return folder ? this.formatFolder(folder) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find folder', { name, error: errorMessage });\n throw new StorageError(`Failed to find folder: ${errorMessage}`);\n }\n }\n\n updateLastSync(name: string, lastSync = new Date().toISOString()): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare(\n 'UPDATE folders SET last_sync = ? WHERE name = ?'\n );\n const result = stmt.run(lastSync, name);\n logger.debug('Folder last sync updated', { name, lastSync });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update folder last sync', {\n name,\n error: errorMessage,\n });\n throw new StorageError(`Failed to update folder: ${errorMessage}`);\n }\n }\n\n private formatFolder(folder: FolderRow): FolderRecord {\n let flags: string[] = [];\n if (folder.flags) {\n try {\n const parsed = JSON.parse(folder.flags) as unknown;\n flags = Array.isArray(parsed)\n ? parsed.filter((item): item is string => typeof item === 'string')\n : [];\n } catch {\n flags = [];\n }\n }\n\n return {\n id: folder.id,\n name: folder.name,\n delimiter: folder.delimiter,\n flags,\n lastSync: folder.last_sync,\n accountId: folder.account_id,\n parentId: folder.parent_id,\n isFavorite: folder.is_favorite === 1,\n sortOrder: folder.sort_order ?? 0,\n unreadCount: folder.unread_count ?? 0,\n totalCount: folder.total_count ?? 0,\n createdAt: folder.created_at,\n };\n }\n}\n\nconst folderModel = new FolderModel();\nexport default folderModel;\n","import fs from 'fs';\nimport path from 'path';\n\nimport type { ImapConfig } from '../types/imap';\nimport type { Attachment } from 'mailparser';\n\nimport IMAPClient from './client';\nimport contactManager from '../contacts/manager';\nimport filterEngine from '../filters/engine';\nimport notificationManager from '../notifications/manager';\nimport spamFilter from '../spam/filter';\nimport attachmentModel from '../storage/models/attachment';\nimport emailModel from '../storage/models/email';\nimport folderModel from '../storage/models/folder';\nimport { SyncError } from '../utils/errors';\nimport { getDataDir } from '../utils/helpers';\nimport logger from '../utils/logger';\n\ninterface SyncConfig extends ImapConfig {\n accountId: number;\n enableSpamFilter?: boolean;\n enableFilters?: boolean;\n}\n\ninterface SyncResult {\n success: boolean;\n folders: { [key: string]: FolderSyncResult | { error: string } };\n totalNew: number;\n totalErrors: number;\n spamDetected: number;\n filtersApplied: number;\n}\n\ninterface FolderSyncResult {\n newEmails: number;\n totalEmails: number;\n spamDetected?: number;\n filtersApplied?: number;\n}\n\ninterface DraftData {\n from?: string;\n to?: string;\n cc?: string;\n subject?: string;\n bodyText?: string;\n messageId?: string;\n}\n\nclass IMAPSync {\n private config: SyncConfig;\n private accountId: number;\n private client: IMAPClient | null;\n private attachmentDir: string;\n private enableSpamFilter: boolean;\n private spamFilterInitialized: boolean;\n private enableFilters: boolean;\n\n constructor(config: SyncConfig) {\n this.config = config;\n this.accountId = config.accountId;\n this.client = null;\n this.attachmentDir = path.join(getDataDir(), 'attachments');\n this.enableSpamFilter = config.enableSpamFilter !== false;\n this.spamFilterInitialized = false;\n this.enableFilters = config.enableFilters !== false;\n }\n\n private async _initializeSpamFilter(): Promise<void> {\n if (this.enableSpamFilter && !this.spamFilterInitialized) {\n try {\n await spamFilter.initialize();\n this.spamFilterInitialized = true;\n logger.info('Spam filter initialized for sync');\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to initialize spam filter', {\n error: err.message,\n });\n this.enableSpamFilter = false;\n }\n }\n }\n\n private _ensureAttachmentDir(): void {\n if (!fs.existsSync(this.attachmentDir)) {\n fs.mkdirSync(this.attachmentDir, { recursive: true });\n logger.info('Created attachment directory', { path: this.attachmentDir });\n }\n }\n\n async syncFolders(folders = ['INBOX']): Promise<SyncResult> {\n const syncStartTime = Date.now();\n try {\n logger.info('[PERF] Starting sync process');\n\n const connectStartTime = Date.now();\n this.client = new IMAPClient(this.config);\n await this.client.connect();\n logger.info('[PERF] IMAP connection established', {\n duration: `${Date.now() - connectStartTime}ms`,\n });\n\n const spamFilterStartTime = Date.now();\n await this._initializeSpamFilter();\n if (this.enableSpamFilter) {\n logger.info('[PERF] Spam filter initialized', {\n duration: `${Date.now() - spamFilterStartTime}ms`,\n });\n }\n\n const results: SyncResult = {\n success: true,\n folders: {},\n totalNew: 0,\n totalErrors: 0,\n spamDetected: 0,\n filtersApplied: 0,\n };\n\n for (const folderName of folders) {\n const folderStartTime = Date.now();\n try {\n logger.info('[PERF] Starting folder sync', { folder: folderName });\n const result = await this.syncFolder(folderName);\n results.folders[folderName] = result;\n results.totalNew += result.newEmails;\n results.spamDetected += result.spamDetected || 0;\n results.filtersApplied += result.filtersApplied || 0;\n logger.info('[PERF] Folder sync completed', {\n folder: folderName,\n duration: `${Date.now() - folderStartTime}ms`,\n newEmails: result.newEmails,\n });\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to sync folder', {\n folder: folderName,\n error: err.message,\n });\n results.folders[folderName] = { error: err.message };\n results.totalErrors++;\n }\n }\n\n this.client.disconnect();\n logger.info('[PERF] Sync completed', {\n totalDuration: `${Date.now() - syncStartTime}ms`,\n totalNew: results.totalNew,\n totalErrors: results.totalErrors,\n spamDetected: results.spamDetected,\n });\n return results;\n } catch (error) {\n const err = error as Error;\n logger.error('Sync failed', { error: err.message });\n if (this.client) {\n this.client.disconnect();\n }\n throw new SyncError(`Sync failed: ${err.message}`);\n }\n }\n\n async syncFolder(folderName: string): Promise<FolderSyncResult> {\n logger.info('Syncing folder', { folder: folderName });\n\n const openFolderStartTime = Date.now();\n const box = await this.client!.openFolder(folderName, true);\n logger.info('[PERF] Folder opened', {\n folder: folderName,\n duration: `${Date.now() - openFolderStartTime}ms`,\n totalMessages: box.messages?.total || 0,\n });\n\n const lastUid = this._getLastUid(folderName);\n\n let criteria: string[] = ['ALL'];\n if (lastUid > 0) {\n criteria = [`UID ${lastUid + 1}:*`];\n logger.debug('Incremental sync', {\n folder: folderName,\n fromUid: lastUid + 1,\n });\n } else {\n logger.debug('Full sync', { folder: folderName });\n }\n\n const fetchStartTime = Date.now();\n const emails = await this.client!.fetchEmails(criteria);\n logger.info('[PERF] Fetched emails from server', {\n folder: folderName,\n count: emails.length,\n duration: `${Date.now() - fetchStartTime}ms`,\n });\n\n let newEmails = 0;\n let spamDetected = 0;\n let filtersApplied = 0;\n const processingStartTime = Date.now();\n\n for (const emailData of emails) {\n const emailStartTime = Date.now();\n try {\n const existing = emailModel.findByUid(emailData.uid, folderName);\n if (existing) {\n logger.debug('Email already exists', { uid: emailData.uid });\n continue;\n }\n\n const parseStartTime = Date.now();\n const parsed = await this.client!.parseEmail(emailData);\n logger.debug('[PERF] Email parsed', {\n uid: emailData.uid,\n duration: `${Date.now() - parseStartTime}ms`,\n });\n\n if (parsed.messageId) {\n const existingByMessageId = emailModel.findByMessageId(\n parsed.messageId\n );\n if (existingByMessageId) {\n logger.debug('Email with same message_id already exists', {\n uid: emailData.uid,\n messageId: parsed.messageId,\n });\n continue;\n }\n }\n\n const dbStartTime = Date.now();\n const emailId = emailModel.create({\n uid: parsed.uid,\n messageId: parsed.messageId || '',\n folder: folderName,\n accountId: this.accountId,\n from: parsed.from,\n to: parsed.to,\n cc: parsed.cc,\n subject: parsed.subject,\n date: parsed.date,\n bodyText: parsed.bodyText,\n bodyHtml: parsed.bodyHtml,\n hasAttachments: parsed.attachments.length > 0,\n isRead: parsed.flags.includes('\\\\Seen'),\n flags: parsed.flags,\n });\n logger.debug('[PERF] Email saved to database', {\n uid: parsed.uid,\n duration: `${Date.now() - dbStartTime}ms`,\n });\n\n if (parsed.attachments.length > 0) {\n const attachmentStartTime = Date.now();\n await this._saveAttachments(emailId, parsed.attachments);\n logger.debug('[PERF] Attachments saved', {\n emailId,\n count: parsed.attachments.length,\n duration: `${Date.now() - attachmentStartTime}ms`,\n });\n }\n\n if (this.enableSpamFilter && folderName === 'INBOX') {\n try {\n const spamStartTime = Date.now();\n const email = emailModel.findById(emailId);\n const spamResult = await spamFilter.detectSpam(email);\n\n if (spamResult.isSpam) {\n await emailModel.markAsSpam(emailId);\n logger.info('Email marked as spam during sync', {\n emailId,\n score: spamResult.score,\n reasons: spamResult.reasons,\n });\n spamDetected++;\n }\n logger.debug('[PERF] Spam filter processed', {\n emailId,\n duration: `${Date.now() - spamStartTime}ms`,\n });\n } catch (error) {\n logger.error('Spam filter failed for email', {\n emailId,\n error: (error as Error).message,\n });\n }\n }\n\n if (this.enableFilters) {\n try {\n const filterStartTime = Date.now();\n const email = emailModel.findById(emailId);\n const filterResult = await filterEngine.applyFilters(email, {\n accountId: this.accountId,\n });\n\n if (filterResult.matched) {\n logger.info('Filters applied to email during sync', {\n emailId,\n filtersCount: filterResult.appliedFilters.length,\n filters: filterResult.appliedFilters.map(\n (f: { filterName: string }) => f.filterName\n ),\n });\n filtersApplied++;\n }\n logger.debug('[PERF] Filter engine processed', {\n emailId,\n duration: `${Date.now() - filterStartTime}ms`,\n });\n } catch (error) {\n logger.error('Filter engine failed for email', {\n emailId,\n error: (error as Error).message,\n });\n }\n }\n\n try {\n const contactStartTime = Date.now();\n\n if (parsed.from) {\n await contactManager.autoCollectContact(parsed.from);\n }\n\n if (folderName === 'Sent' || folderName === 'SENT') {\n const recipients = [\n ...(parsed.to ? parsed.to.split(',') : []),\n ...(parsed.cc ? parsed.cc.split(',') : []),\n ];\n\n for (const recipient of recipients) {\n await contactManager.autoCollectContact(recipient.trim());\n }\n }\n\n logger.debug('[PERF] Contact auto-collection completed', {\n emailId,\n duration: `${Date.now() - contactStartTime}ms`,\n });\n } catch (error) {\n logger.debug('Contact auto-collection failed', {\n emailId,\n error: (error as Error).message,\n });\n }\n\n if (folderName === 'INBOX') {\n try {\n const email = emailModel.findById(emailId);\n if (email && !email.isSpam) {\n await notificationManager.notify(email);\n }\n } catch (error) {\n logger.debug('Notification failed', {\n emailId,\n error: (error as Error).message,\n });\n }\n }\n\n newEmails++;\n logger.debug('[PERF] Email processing completed', {\n uid: parsed.uid,\n id: emailId,\n totalDuration: `${Date.now() - emailStartTime}ms`,\n });\n } catch (error) {\n logger.error('Failed to save email', {\n uid: emailData.uid,\n error: (error as Error).message,\n });\n }\n }\n\n logger.info('[PERF] All emails processed', {\n folder: folderName,\n count: emails.length,\n duration: `${Date.now() - processingStartTime}ms`,\n avgPerEmail:\n emails.length > 0\n ? `${Math.round((Date.now() - processingStartTime) / emails.length)}ms`\n : 'N/A',\n });\n\n folderModel.upsert({\n name: folderName,\n delimiter: '/',\n flags: [],\n lastSync: new Date().toISOString(),\n });\n\n logger.info('Folder sync completed', {\n folder: folderName,\n newEmails,\n spamDetected,\n filtersApplied,\n });\n return {\n newEmails,\n totalEmails: box.messages?.total || 0,\n spamDetected,\n filtersApplied,\n };\n }\n\n private async _saveAttachments(\n emailId: number,\n attachments: Attachment[]\n ): Promise<void> {\n this._ensureAttachmentDir();\n\n for (const attachment of attachments) {\n try {\n const filename = attachment.filename || `attachment_${Date.now()}`;\n const sanitizedFilename = this._sanitizeFilename(filename);\n const filePath = path.join(\n this.attachmentDir,\n `${emailId}_${sanitizedFilename}`\n );\n\n fs.writeFileSync(filePath, attachment.content);\n\n attachmentModel.create({\n emailId,\n filename: sanitizedFilename,\n contentType: attachment.contentType,\n size: attachment.size,\n filePath,\n });\n\n logger.debug('Attachment saved', {\n emailId,\n filename: sanitizedFilename,\n });\n } catch (error) {\n logger.error('Failed to save attachment', {\n emailId,\n error: (error as Error).message,\n });\n }\n }\n }\n\n private _getLastUid(folderName: string): number {\n try {\n const emails = emailModel.findByFolder(folderName, {\n limit: 1,\n offset: 0,\n });\n if (emails.length > 0) {\n return emails[0].uid;\n }\n return 0;\n } catch (error) {\n logger.error('Failed to get last UID', {\n folder: folderName,\n error: (error as Error).message,\n });\n return 0;\n }\n }\n\n private _sanitizeFilename(filename: string): string {\n return filename\n .replace(/[<>:\"/\\\\|?*]/g, '_')\n .replace(/\\s+/g, ' ')\n .trim()\n .substring(0, 255);\n }\n\n async syncDrafts(): Promise<{ synced: number; total: number }> {\n try {\n logger.info('Syncing drafts from server');\n\n if (!this.client) {\n this.client = new IMAPClient(this.config);\n await this.client.connect();\n }\n\n await this.client.openFolder('Drafts', true);\n\n const emails = await this.client.fetchEmails(['ALL']);\n logger.info('Fetched drafts from server', { count: emails.length });\n\n let syncedDrafts = 0;\n for (const emailData of emails) {\n try {\n const existing = emailModel.findByUid(emailData.uid, 'Drafts');\n if (existing) {\n logger.debug('Draft already exists', { uid: emailData.uid });\n continue;\n }\n\n const parsed = await this.client.parseEmail(emailData);\n\n emailModel.saveDraft({\n uid: parsed.uid,\n messageId: parsed.messageId,\n from: parsed.from,\n to: parsed.to,\n cc: parsed.cc,\n subject: parsed.subject,\n bodyText: parsed.bodyText,\n bodyHtml: parsed.bodyHtml,\n });\n\n syncedDrafts++;\n logger.debug('Draft synced', { uid: parsed.uid });\n } catch (error) {\n logger.error('Failed to sync draft', {\n uid: emailData.uid,\n error: (error as Error).message,\n });\n }\n }\n\n logger.info('Drafts sync completed', { synced: syncedDrafts });\n return { synced: syncedDrafts, total: emails.length };\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to sync drafts', { error: err.message });\n throw new SyncError(`Failed to sync drafts: ${err.message}`);\n }\n }\n\n async uploadDraft(draftData: DraftData): Promise<boolean> {\n try {\n logger.info('Uploading draft to server');\n\n if (!this.client) {\n this.client = new IMAPClient(this.config);\n await this.client.connect();\n }\n\n await this.client.openFolder('Drafts', false);\n\n const message = this._composeDraftMessage(draftData);\n\n await this._appendMessage('Drafts', message, ['\\\\Draft']);\n\n logger.info('Draft uploaded to server');\n return true;\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to upload draft', { error: err.message });\n throw new SyncError(`Failed to upload draft: ${err.message}`);\n }\n }\n\n private _composeDraftMessage(draftData: DraftData): string {\n const lines: string[] = [];\n\n if (draftData.from) {\n lines.push(`From: ${draftData.from}`);\n }\n if (draftData.to) {\n lines.push(`To: ${draftData.to}`);\n }\n if (draftData.cc) {\n lines.push(`Cc: ${draftData.cc}`);\n }\n if (draftData.subject) {\n lines.push(`Subject: ${draftData.subject}`);\n }\n lines.push(`Date: ${new Date().toUTCString()}`);\n lines.push(\n `Message-ID: ${draftData.messageId || `<draft-${Date.now()}@local>`}`\n );\n lines.push('MIME-Version: 1.0');\n lines.push('Content-Type: text/plain; charset=utf-8');\n lines.push('');\n\n lines.push(draftData.bodyText || '');\n\n return lines.join('\\r\\n');\n }\n\n private _appendMessage(\n folderName: string,\n message: string,\n flags: string[] = []\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n const imap = this.client?.getImap();\n if (!imap) {\n return reject(new SyncError('IMAP client not connected'));\n }\n\n imap.append(\n message,\n { mailbox: folderName, flags },\n (err: Error | null) => {\n if (err) {\n logger.error('Failed to append message', {\n folder: folderName,\n error: err.message,\n });\n return reject(\n new SyncError(`Failed to append message: ${err.message}`)\n );\n }\n logger.debug('Message appended', { folder: folderName });\n resolve();\n }\n );\n });\n }\n}\n\nexport default IMAPSync;\n","import fs from 'fs';\nimport path from 'path';\n\nimport type { Signature } from '../types/index';\n\nimport logger from '../utils/logger';\n\ninterface EmailData {\n from: string | null;\n to: string[];\n cc: string[];\n bcc: string[];\n subject: string;\n text: string;\n html: string;\n attachments: Array<{\n filename: string;\n path?: string;\n content?: Buffer;\n contentType?: string;\n }>;\n inReplyTo: string | null;\n references: string | null;\n}\n\ninterface OriginalEmail {\n date: string;\n from: string;\n bodyText: string;\n to?: string;\n cc?: string;\n references?: string;\n messageId?: string;\n}\n\nclass EmailComposer {\n private emailData: EmailData;\n\n constructor() {\n this.emailData = {\n from: null,\n to: [],\n cc: [],\n bcc: [],\n subject: '',\n text: '',\n html: '',\n attachments: [],\n inReplyTo: null,\n references: null,\n };\n }\n\n setFrom(address: string): this {\n this.emailData.from = address;\n return this;\n }\n\n setTo(addresses: string | string[]): this {\n this.emailData.to = Array.isArray(addresses) ? addresses : [addresses];\n return this;\n }\n\n setCc(addresses: string | string[]): this {\n this.emailData.cc = Array.isArray(addresses) ? addresses : [addresses];\n return this;\n }\n\n setBcc(addresses: string | string[]): this {\n this.emailData.bcc = Array.isArray(addresses) ? addresses : [addresses];\n return this;\n }\n\n setSubject(subject: string): this {\n this.emailData.subject = subject;\n return this;\n }\n\n setBody(text: string, html: string | null = null): this {\n this.emailData.text = text;\n if (html) {\n this.emailData.html = html;\n }\n return this;\n }\n\n addAttachment(filePath: string, filename: string | null = null): this {\n try {\n if (!fs.existsSync(filePath)) {\n throw new Error(`File not found: ${filePath}`);\n }\n\n const attachmentName = filename || path.basename(filePath);\n this.emailData.attachments.push({\n filename: attachmentName,\n path: filePath,\n });\n\n logger.debug('Attachment added', { filename: attachmentName });\n return this;\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to add attachment', {\n filePath,\n error: err.message,\n });\n throw error;\n }\n }\n\n addAttachmentFromBuffer(\n buffer: Buffer,\n filename: string,\n contentType = 'application/octet-stream'\n ): this {\n this.emailData.attachments.push({\n filename,\n content: buffer,\n contentType,\n });\n logger.debug('Attachment added from buffer', { filename });\n return this;\n }\n\n compose(): EmailData {\n if (!this.emailData.to || this.emailData.to.length === 0) {\n throw new Error('Recipient (to) is required');\n }\n\n if (!this.emailData.subject) {\n throw new Error('Subject is required');\n }\n\n if (!this.emailData.text && !this.emailData.html) {\n throw new Error('Email body (text or html) is required');\n }\n\n logger.debug('Email composed', {\n to: this.emailData.to,\n subject: this.emailData.subject,\n attachments: this.emailData.attachments.length,\n });\n\n return { ...this.emailData };\n }\n\n setInReplyTo(messageId: string): this {\n this.emailData.inReplyTo = messageId;\n return this;\n }\n\n setReferences(references: string): this {\n this.emailData.references = references;\n return this;\n }\n\n quoteOriginalEmail(originalEmail: OriginalEmail): string {\n const header = `On ${originalEmail.date}, ${originalEmail.from} wrote:\\n\\n`;\n const quoted = originalEmail.bodyText\n .split('\\n')\n .map((line) => '> ' + line)\n .join('\\n');\n return header + quoted;\n }\n\n buildReferences(originalEmail: OriginalEmail): string {\n const refs: string[] = [];\n if (originalEmail.references) {\n refs.push(originalEmail.references);\n }\n if (originalEmail.messageId) {\n refs.push(originalEmail.messageId);\n }\n return refs.join(' ');\n }\n\n getAllRecipients(originalEmail: OriginalEmail, selfEmail: string): string[] {\n const recipients: string[] = [];\n\n if (originalEmail.from && originalEmail.from !== selfEmail) {\n recipients.push(originalEmail.from);\n }\n\n if (originalEmail.to) {\n const toAddresses = originalEmail.to.split(',').map((e) => e.trim());\n toAddresses.forEach((addr) => {\n if (addr && addr !== selfEmail && !recipients.includes(addr)) {\n recipients.push(addr);\n }\n });\n }\n\n if (originalEmail.cc) {\n const ccAddresses = originalEmail.cc.split(',').map((e) => e.trim());\n ccAddresses.forEach((addr) => {\n if (addr && addr !== selfEmail && !recipients.includes(addr)) {\n recipients.push(addr);\n }\n });\n }\n\n return recipients;\n }\n\n addSignature(signature: Signature | null): this {\n if (!signature) {\n return this;\n }\n\n if (signature.contentHtml && this.emailData.html) {\n this.emailData.html += '\\n\\n' + signature.contentHtml;\n } else if (signature.contentHtml && !this.emailData.html) {\n this.emailData.html = signature.contentHtml;\n }\n\n if (signature.contentText) {\n this.emailData.text += '\\n\\n' + signature.contentText;\n }\n\n logger.debug('Signature added to email');\n return this;\n }\n\n reset(): this {\n this.emailData = {\n from: null,\n to: [],\n cc: [],\n bcc: [],\n subject: '',\n text: '',\n html: '',\n attachments: [],\n inReplyTo: null,\n references: null,\n };\n return this;\n }\n}\n\nexport default EmailComposer;\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\n\nimport config from '../../config';\nimport IMAPSync from '../../imap/sync';\nimport SMTPClient from '../../smtp/client';\nimport EmailComposer from '../../smtp/composer';\nimport emailModel from '../../storage/models/email';\nimport logger from '../../utils/logger';\n\n/**\n * Draft command - Manage email drafts\n */\nasync function draftCommand(action, options) {\n try {\n switch (action) {\n case 'save':\n await saveDraft(options);\n break;\n case 'list':\n await listDrafts(options);\n break;\n case 'edit':\n await editDraft(options);\n break;\n case 'delete':\n await deleteDraft(options);\n break;\n case 'send':\n await sendDraft(options);\n break;\n case 'sync':\n await syncDrafts(options);\n break;\n default:\n console.error(chalk.red(`Unknown action: ${action}`));\n console.log(\n chalk.gray('Available actions: save, list, edit, delete, send, sync')\n );\n process.exit(1);\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Draft command failed', { action, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Save a new draft\n */\nasync function saveDraft(options) {\n let draftData;\n\n if (options.to && options.subject && options.body) {\n // Non-interactive mode\n draftData = {\n to: options.to,\n cc: options.cc || '',\n subject: options.subject,\n bodyText: options.body,\n };\n } else {\n // Interactive mode\n draftData = await interactiveDraftCompose();\n }\n\n const spinner = ora('Saving draft...').start();\n\n try {\n const draftId = emailModel.saveDraft(draftData);\n spinner.succeed('Draft saved successfully!');\n console.log(chalk.gray(`Draft ID: ${draftId}`));\n\n // Optionally sync to server\n if (options.sync) {\n await syncDraftToServer(draftId);\n }\n } catch (error) {\n spinner.fail('Failed to save draft');\n throw error;\n }\n}\n\n/**\n * List all drafts\n */\nasync function listDrafts(options) {\n const spinner = ora('Loading drafts...').start();\n\n try {\n const drafts = emailModel.findDrafts({ limit: options.limit || 50 });\n spinner.stop();\n\n if (drafts.length === 0) {\n console.log(chalk.yellow('No drafts found.'));\n return;\n }\n\n console.log(chalk.bold.cyan(`\\nDrafts (${drafts.length}):\\n`));\n\n const table = new Table({\n head: ['ID', 'To', 'Subject', 'Updated'],\n colWidths: [8, 30, 40, 20],\n });\n\n drafts.forEach((draft) => {\n table.push([\n draft.id,\n truncate(draft.to || '(no recipient)', 28),\n truncate(draft.subject || '(no subject)', 38),\n formatDate(draft.updatedAt),\n ]);\n });\n\n console.log(table.toString());\n console.log(chalk.gray(`\\nTotal: ${drafts.length} drafts`));\n } catch (error) {\n spinner.fail('Failed to load drafts');\n throw error;\n }\n}\n\n/**\n * Edit an existing draft\n */\nasync function editDraft(options) {\n const draftId = options.id || options._[1];\n\n if (!draftId) {\n console.error(chalk.red('Draft ID is required'));\n console.log(chalk.gray('Usage: mail-client draft edit <draft-id>'));\n process.exit(1);\n }\n\n const spinner = ora('Loading draft...').start();\n\n try {\n const draft = emailModel.findById(draftId);\n\n if (!draft || !draft.isDraft) {\n spinner.fail('Draft not found');\n process.exit(1);\n }\n\n spinner.stop();\n\n console.log(chalk.bold.cyan('Edit Draft'));\n console.log();\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'to',\n message: 'To:',\n default: draft.to,\n },\n {\n type: 'input',\n name: 'cc',\n message: 'CC:',\n default: draft.cc,\n },\n {\n type: 'input',\n name: 'subject',\n message: 'Subject:',\n default: draft.subject,\n },\n {\n type: 'editor',\n name: 'body',\n message: 'Body:',\n default: draft.bodyText,\n },\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Save changes?',\n default: true,\n },\n ]);\n\n if (!answers.confirm) {\n console.log(chalk.yellow('Changes cancelled.'));\n return;\n }\n\n const updateSpinner = ora('Updating draft...').start();\n\n emailModel.saveDraft({\n id: draftId,\n to: answers.to,\n cc: answers.cc,\n subject: answers.subject,\n bodyText: answers.body,\n });\n\n updateSpinner.succeed('Draft updated successfully!');\n } catch (error) {\n spinner.fail('Failed to edit draft');\n throw error;\n }\n}\n\n/**\n * Delete a draft\n */\nasync function deleteDraft(options) {\n const draftId = options.id || options._[1];\n\n if (!draftId) {\n console.error(chalk.red('Draft ID is required'));\n console.log(chalk.gray('Usage: mail-client draft delete <draft-id>'));\n process.exit(1);\n }\n\n const draft = emailModel.findById(draftId);\n\n if (!draft || !draft.isDraft) {\n console.error(chalk.red('Draft not found'));\n process.exit(1);\n }\n\n console.log(chalk.bold.yellow('Delete Draft'));\n console.log(chalk.gray(`To: ${draft.to}`));\n console.log(chalk.gray(`Subject: ${draft.subject}`));\n console.log();\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Are you sure you want to delete this draft?',\n default: false,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('Deletion cancelled.'));\n return;\n }\n\n const spinner = ora('Deleting draft...').start();\n\n try {\n emailModel.deleteDraft(draftId);\n spinner.succeed('Draft deleted successfully!');\n } catch (error) {\n spinner.fail('Failed to delete draft');\n throw error;\n }\n}\n\n/**\n * Send a draft\n */\nasync function sendDraft(options) {\n const draftId = options.id || options._[1];\n\n if (!draftId) {\n console.error(chalk.red('Draft ID is required'));\n console.log(chalk.gray('Usage: mail-client draft send <draft-id>'));\n process.exit(1);\n }\n\n const draft = emailModel.findById(draftId);\n\n if (!draft || !draft.isDraft) {\n console.error(chalk.red('Draft not found'));\n process.exit(1);\n }\n\n // Validate draft has required fields\n if (!draft.to || !draft.subject) {\n console.error(chalk.red('Draft is incomplete. Please edit it first.'));\n console.log(\n chalk.gray('Missing: ') +\n (!draft.to ? 'recipient ' : '') +\n (!draft.subject ? 'subject' : '')\n );\n process.exit(1);\n }\n\n console.log(chalk.bold.cyan('Send Draft'));\n console.log(chalk.gray(`To: ${draft.to}`));\n console.log(chalk.gray(`Subject: ${draft.subject}`));\n console.log();\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Send this draft?',\n default: true,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('Sending cancelled.'));\n return;\n }\n\n const spinner = ora('Sending email...').start();\n\n try {\n // Load SMTP configuration\n const cfg = config.load();\n if (!cfg.smtp.host || !cfg.smtp.user || !cfg.smtp.password) {\n spinner.fail('SMTP configuration incomplete');\n console.error(chalk.red('Please run: mail-client config'));\n process.exit(1);\n }\n\n // Compose email\n const composer = new EmailComposer();\n composer\n .setTo(draft.to.split(',').map((e) => e.trim()))\n .setSubject(draft.subject)\n .setBody(draft.bodyText || '', draft.bodyHtml || '');\n\n if (draft.cc) {\n composer.setCc(draft.cc.split(',').map((e) => e.trim()));\n }\n\n // Send email\n const smtpClient = new SMTPClient(cfg.smtp);\n const result = await smtpClient.sendEmail(composer.compose());\n\n // Convert draft to sent email\n emailModel.convertDraftToSent(draftId, result.messageId);\n\n spinner.succeed('Email sent successfully!');\n console.log(chalk.gray(`Message ID: ${result.messageId}`));\n\n smtpClient.disconnect();\n } catch (error) {\n spinner.fail('Failed to send email');\n throw error;\n }\n}\n\n/**\n * Sync drafts with IMAP server\n */\nasync function syncDrafts(options) {\n const spinner = ora('Syncing drafts with server...').start();\n\n try {\n const cfg = config.load();\n if (!cfg.imap.host || !cfg.imap.user || !cfg.imap.password) {\n spinner.fail('IMAP configuration incomplete');\n console.error(chalk.red('Please run: mail-client config'));\n process.exit(1);\n }\n\n const sync = new IMAPSync(cfg.imap);\n const result = await sync.syncDrafts();\n\n spinner.succeed('Drafts synced successfully!');\n console.log(chalk.gray(`Synced: ${result.synced} drafts`));\n console.log(chalk.gray(`Total on server: ${result.total} drafts`));\n } catch (error) {\n spinner.fail('Failed to sync drafts');\n throw error;\n }\n}\n\n/**\n * Interactive draft composition\n */\nasync function interactiveDraftCompose() {\n console.log(chalk.bold.cyan('Compose Draft'));\n console.log();\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'to',\n message: 'To (comma-separated):',\n },\n {\n type: 'input',\n name: 'cc',\n message: 'CC (comma-separated, optional):',\n },\n {\n type: 'input',\n name: 'subject',\n message: 'Subject:',\n },\n {\n type: 'editor',\n name: 'body',\n message: 'Body (opens editor):',\n },\n ]);\n\n return {\n to: answers.to,\n cc: answers.cc,\n subject: answers.subject,\n bodyText: answers.body,\n };\n}\n\n/**\n * Sync draft to IMAP server\n */\nasync function syncDraftToServer(draftId) {\n const spinner = ora('Syncing draft to server...').start();\n\n try {\n const cfg = config.load();\n const draft = emailModel.findById(draftId);\n\n const sync = new IMAPSync(cfg.imap);\n await sync.uploadDraft(draft);\n\n spinner.succeed('Draft synced to server');\n } catch (error) {\n spinner.warn('Failed to sync draft to server (saved locally)');\n logger.error('Failed to sync draft to server', {\n draftId,\n error: error.message,\n });\n }\n}\n\n/**\n * Truncate string to specified length\n */\nfunction truncate(str, maxLength) {\n if (!str) return '';\n if (str.length <= maxLength) return str;\n return str.substring(0, maxLength - 3) + '...';\n}\n\n/**\n * Format date for display\n */\nfunction formatDate(dateString) {\n if (!dateString) return '';\n const date = new Date(dateString);\n const now = new Date();\n const diff = now - date;\n const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n\n if (days === 0) {\n return date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n });\n } else if (days === 1) {\n return 'Yesterday';\n } else if (days < 7) {\n return `${days} days ago`;\n } else {\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n }\n}\n\nmodule.exports = draftCommand;\n","import chalk from 'chalk';\n\nimport { formatDate, truncate } from '../../utils/helpers';\n\n/**\n * Format email list for display\n */\nfunction formatEmailList(emails) {\n if (!emails || emails.length === 0) {\n return chalk.yellow('No emails found.');\n }\n\n const rows = [];\n rows.push([\n chalk.bold('ID'),\n chalk.bold('From'),\n chalk.bold('Subject'),\n chalk.bold('Date'),\n chalk.bold('Status'),\n ]);\n\n for (const email of emails) {\n const status = email.isRead ? chalk.gray('Read') : chalk.green('Unread');\n rows.push([\n email.id.toString(),\n truncate(email.from, 25),\n truncate(email.subject, 40),\n formatDate(email.date),\n status,\n ]);\n }\n\n return formatTable(rows);\n}\n\n/**\n * Format email details for display\n */\nfunction formatEmailDetails(email, attachments = []) {\n const lines = [];\n lines.push(chalk.bold.cyan('Email Details'));\n lines.push(chalk.gray('─'.repeat(60)));\n lines.push(`${chalk.bold('ID:')} ${email.id}`);\n lines.push(`${chalk.bold('From:')} ${email.from}`);\n lines.push(`${chalk.bold('To:')} ${email.to}`);\n if (email.cc) {\n lines.push(`${chalk.bold('CC:')} ${email.cc}`);\n }\n lines.push(`${chalk.bold('Subject:')} ${email.subject}`);\n lines.push(`${chalk.bold('Date:')} ${email.date}`);\n lines.push(`${chalk.bold('Status:')} ${email.isRead ? 'Read' : 'Unread'}`);\n\n if (attachments.length > 0) {\n lines.push(`${chalk.bold('Attachments:')} ${attachments.length}`);\n attachments.forEach((att) => {\n lines.push(` - ${att.filename} (${formatFileSize(att.size)})`);\n });\n }\n\n lines.push(chalk.gray('─'.repeat(60)));\n lines.push(chalk.bold('Body:'));\n lines.push(email.bodyText || email.bodyHtml || chalk.gray('(No content)'));\n\n return lines.join('\\n');\n}\n\n/**\n * Format simple table\n */\nfunction formatTable(rows) {\n if (!rows || rows.length === 0) return '';\n\n const colWidths = [];\n for (let i = 0; i < rows[0].length; i++) {\n colWidths[i] = Math.max(...rows.map((row) => stripAnsi(row[i]).length));\n }\n\n const lines = [];\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n const cells = row.map((cell, j) => {\n const stripped = stripAnsi(cell);\n const padding = ' '.repeat(colWidths[j] - stripped.length);\n return cell + padding;\n });\n lines.push(cells.join(' '));\n\n if (i === 0) {\n lines.push(colWidths.map((w) => '─'.repeat(w)).join(' '));\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Strip ANSI codes for length calculation\n */\nfunction stripAnsi(str) {\n let output = '';\n let index = 0;\n\n while (index < str.length) {\n const currentChar = str[index];\n const nextChar = str[index + 1];\n\n if (currentChar === '\\u001b' && nextChar === '[') {\n index += 2;\n while (index < str.length && str[index] !== 'm') {\n index += 1;\n }\n if (index < str.length) {\n index += 1;\n }\n continue;\n }\n\n output += currentChar;\n index += 1;\n }\n\n return output;\n}\n\n/**\n * Format file size\n */\nfunction formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n}\n\n/**\n * Format sync results\n */\nfunction formatSyncResults(results) {\n const lines = [];\n lines.push(chalk.bold.green('Sync Results'));\n lines.push(chalk.gray('─'.repeat(60)));\n\n for (const [folder, result] of Object.entries(results.folders)) {\n if (result.error) {\n lines.push(`${chalk.red('✗')} ${folder}: ${chalk.red(result.error)}`);\n } else {\n lines.push(\n `${chalk.green('✓')} ${folder}: ${result.newEmails} new emails`\n );\n }\n }\n\n lines.push(chalk.gray('─'.repeat(60)));\n lines.push(`${chalk.bold('Total new emails:')} ${results.totalNew}`);\n if (results.totalErrors > 0) {\n lines.push(`${chalk.bold('Errors:')} ${chalk.red(results.totalErrors)}`);\n }\n\n return lines.join('\\n');\n}\n\nexport {\n formatEmailList,\n formatEmailDetails,\n formatTable,\n formatFileSize,\n formatSyncResults,\n};\n","import { Command } from 'commander';\n\nimport config from '../../config';\nimport IMAPClient from '../../imap/client';\nimport emailModel from '../../storage/models/email';\nimport folderModel from '../../storage/models/folder';\nimport logger from '../../utils/logger';\nimport { formatTable } from '../utils/formatter';\n\n/**\n * Folder management commands\n */\nconst folderCommand = new Command('folder');\n\nfolderCommand.description('Manage email folders');\n\n/**\n * Create folder command\n */\nfolderCommand\n .command('create <name>')\n .description('Create a new folder')\n .option('-p, --parent <parent>', 'Parent folder name')\n .option('-f, --favorite', 'Mark as favorite')\n .action(async (name, options) => {\n try {\n logger.info('Creating folder', { name, parent: options.parent });\n\n const imapConfig = config.get('imap');\n const client = new IMAPClient(imapConfig);\n\n await client.connect();\n await client.createFolder(name);\n\n let parentId = null;\n if (options.parent) {\n const parentFolder = folderModel.findByName(options.parent);\n if (parentFolder) {\n parentId = parentFolder.id;\n }\n }\n\n folderModel.create({\n name,\n delimiter: '/',\n parentId,\n isFavorite: options.favorite || false,\n });\n\n client.disconnect();\n\n console.log(`Folder \"${name}\" created successfully`);\n } catch (error) {\n logger.error('Failed to create folder', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * List folders command\n */\nfolderCommand\n .command('list')\n .description('List all folders')\n .option('-t, --tree', 'Display as tree structure')\n .action(async (options) => {\n try {\n logger.info('Listing folders');\n\n const folders = folderModel.findAll();\n\n if (folders.length === 0) {\n console.log('No folders found');\n return;\n }\n\n if (options.tree) {\n displayFolderTree(folders);\n } else {\n const tableData = folders.map((folder) => ({\n Name: folder.name,\n Unread: folder.unreadCount,\n Total: folder.totalCount,\n Favorite: folder.isFavorite ? 'Yes' : 'No',\n 'Last Sync': folder.lastSync\n ? new Date(folder.lastSync).toLocaleString()\n : 'Never',\n }));\n\n console.log(formatTable(tableData));\n }\n } catch (error) {\n logger.error('Failed to list folders', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Display folders as tree structure\n */\nfunction displayFolderTree(folders) {\n const folderMap = new Map();\n const rootFolders = [];\n\n folders.forEach((folder) => {\n folderMap.set(folder.id, { ...folder, children: [] });\n });\n\n folders.forEach((folder) => {\n if (folder.parentId) {\n const parent = folderMap.get(folder.parentId);\n if (parent) {\n parent.children.push(folderMap.get(folder.id));\n } else {\n rootFolders.push(folderMap.get(folder.id));\n }\n } else {\n rootFolders.push(folderMap.get(folder.id));\n }\n });\n\n function printTree(folder, prefix = '', isLast = true) {\n const connector = isLast ? '└── ' : '├── ';\n const favorite = folder.isFavorite ? ' ★' : '';\n const counts = ` (${folder.unreadCount}/${folder.totalCount})`;\n console.log(prefix + connector + folder.name + favorite + counts);\n\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n folder.children.forEach((child, index) => {\n printTree(child, childPrefix, index === folder.children.length - 1);\n });\n }\n\n rootFolders.forEach((folder, index) => {\n printTree(folder, '', index === rootFolders.length - 1);\n });\n}\n\n/**\n * Rename folder command\n */\nfolderCommand\n .command('rename <old-name> <new-name>')\n .description('Rename a folder')\n .action(async (oldName, newName) => {\n try {\n logger.info('Renaming folder', { oldName, newName });\n\n const imapConfig = config.get('imap');\n const client = new IMAPClient(imapConfig);\n\n await client.connect();\n await client.renameFolder(oldName, newName);\n\n folderModel.rename(oldName, newName);\n\n client.disconnect();\n\n console.log(`Folder \"${oldName}\" renamed to \"${newName}\" successfully`);\n } catch (error) {\n logger.error('Failed to rename folder', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Delete folder command\n */\nfolderCommand\n .command('delete <name>')\n .description('Delete a folder')\n .action(async (name) => {\n try {\n logger.info('Deleting folder', { name });\n\n const imapConfig = config.get('imap');\n const client = new IMAPClient(imapConfig);\n\n await client.connect();\n await client.deleteFolder(name);\n\n folderModel.deleteByName(name);\n\n client.disconnect();\n\n console.log(`Folder \"${name}\" deleted successfully`);\n } catch (error) {\n logger.error('Failed to delete folder', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Move email(s) to folder command\n */\nfolderCommand\n .command('move <email-ids> <folder>')\n .description('Move email(s) to a folder (comma-separated IDs for batch)')\n .action(async (emailIds, folder) => {\n try {\n const ids = emailIds.split(',').map((id) => parseInt(id.trim()));\n logger.info('Moving emails to folder', { ids, folder });\n\n const imapConfig = config.get('imap');\n const client = new IMAPClient(imapConfig);\n\n await client.connect();\n\n const uids = [];\n for (const id of ids) {\n const email = emailModel.findById(id);\n if (!email) {\n console.warn(`Email ID ${id} not found, skipping`);\n continue;\n }\n\n await client.openFolder(email.folder, false);\n uids.push(email.uid);\n }\n\n if (uids.length > 0) {\n if (uids.length === 1) {\n await client.moveEmail(uids[0], folder);\n } else {\n await client.batchMoveEmails(uids, folder);\n }\n\n ids.forEach((id) => {\n emailModel.updateFolder(id, folder);\n });\n\n console.log(\n `${uids.length} email(s) moved to \"${folder}\" successfully`\n );\n } else {\n console.log('No valid emails found to move');\n }\n\n client.disconnect();\n } catch (error) {\n logger.error('Failed to move emails', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Copy email(s) to folder command\n */\nfolderCommand\n .command('copy <email-ids> <folder>')\n .description('Copy email(s) to a folder (comma-separated IDs for batch)')\n .action(async (emailIds, folder) => {\n try {\n const ids = emailIds.split(',').map((id) => parseInt(id.trim()));\n logger.info('Copying emails to folder', { ids, folder });\n\n const imapConfig = config.get('imap');\n const client = new IMAPClient(imapConfig);\n\n await client.connect();\n\n const uids = [];\n for (const id of ids) {\n const email = emailModel.findById(id);\n if (!email) {\n console.warn(`Email ID ${id} not found, skipping`);\n continue;\n }\n\n await client.openFolder(email.folder, false);\n uids.push(email.uid);\n }\n\n if (uids.length > 0) {\n if (uids.length === 1) {\n await client.copyEmail(uids[0], folder);\n } else {\n await client.batchCopyEmails(uids, folder);\n }\n\n console.log(\n `${uids.length} email(s) copied to \"${folder}\" successfully`\n );\n } else {\n console.log('No valid emails found to copy');\n }\n\n client.disconnect();\n } catch (error) {\n logger.error('Failed to copy emails', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\nmodule.exports = folderCommand;\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\n\nimport config from '../../config';\nimport SMTPClient from '../../smtp/client';\nimport EmailComposer from '../../smtp/composer';\nimport attachmentModel from '../../storage/models/attachment';\nimport emailModel from '../../storage/models/email';\nimport logger from '../../utils/logger';\n\n/**\n * Forward command - Forward an email\n */\nasync function forwardCommand(emailId, options) {\n try {\n // Load configuration\n const cfg = config.load();\n if (!cfg.smtp.host || !cfg.smtp.user || !cfg.smtp.password) {\n console.error(\n chalk.red(\n 'SMTP configuration incomplete. Please run: mail-client config'\n )\n );\n process.exit(1);\n }\n\n // Get original email\n const originalEmail = emailModel.findById(emailId);\n if (!originalEmail) {\n console.error(chalk.red(`Email with ID ${emailId} not found`));\n process.exit(1);\n }\n\n // Display original email info\n console.log(chalk.bold.cyan('Forwarding:'));\n console.log(chalk.gray(`From: ${originalEmail.from}`));\n console.log(chalk.gray(`Subject: ${originalEmail.subject}`));\n console.log(chalk.gray(`Date: ${originalEmail.date}`));\n console.log();\n\n // Get recipient(s)\n let recipients;\n if (options.to) {\n recipients = options.to.split(',').map((e) => e.trim());\n } else {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'to',\n message: 'Forward to (comma-separated):',\n validate: (input) => (input.trim() ? true : 'Recipient is required'),\n },\n ]);\n recipients = answers.to.split(',').map((e) => e.trim());\n }\n\n // Create composer\n const composer = new EmailComposer();\n composer.setTo(recipients);\n\n // Set subject with \"Fwd:\" prefix\n let subject = originalEmail.subject;\n if (!subject.toLowerCase().startsWith('fwd:')) {\n subject = `Fwd: ${subject}`;\n }\n composer.setSubject(subject);\n\n // Get forward message (optional)\n let forwardMessage = '';\n if (options.body) {\n forwardMessage = options.body;\n } else {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'message',\n message: 'Forward message (optional):',\n },\n ]);\n forwardMessage = answers.message;\n }\n\n // Build forwarded email body\n const forwardHeader =\n `---------- Forwarded message ---------\\n` +\n `From: ${originalEmail.from}\\n` +\n `Date: ${originalEmail.date}\\n` +\n `Subject: ${originalEmail.subject}\\n` +\n `To: ${originalEmail.to}\\n`;\n\n let fullBody = '';\n if (forwardMessage) {\n fullBody = forwardMessage + '\\n\\n';\n }\n fullBody += forwardHeader + '\\n' + originalEmail.bodyText;\n\n composer.setBody(fullBody);\n\n // Handle attachments\n if (originalEmail.hasAttachments && !options.noAttachments) {\n try {\n const attachments = attachmentModel.findByEmailId(emailId);\n if (attachments && attachments.length > 0) {\n console.log(\n chalk.gray(`Including ${attachments.length} attachment(s)`)\n );\n for (const attachment of attachments) {\n if (attachment.filePath) {\n composer.addAttachment(attachment.filePath, attachment.filename);\n }\n }\n }\n } catch (error) {\n console.warn(\n chalk.yellow(`Warning: Could not attach files: ${error.message}`)\n );\n }\n }\n\n // Confirm before sending\n if (!options.to) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Send this forwarded email?',\n default: true,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('Forward cancelled.'));\n process.exit(0);\n }\n }\n\n // Send email\n const spinner = ora('Forwarding email...').start();\n\n const smtpClient = new SMTPClient(cfg.smtp);\n const emailData = composer.compose();\n const result = await smtpClient.sendEmail(emailData);\n\n spinner.succeed('Email forwarded successfully!');\n console.log(chalk.gray(`Message ID: ${result.messageId}`));\n\n smtpClient.disconnect();\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Forward command failed', { error: error.message });\n process.exit(1);\n }\n}\n\nmodule.exports = forwardCommand;\n","import { promises as fs } from 'fs';\n\nimport { simpleParser } from 'mailparser';\n\nimport { StorageError } from '../utils/errors';\nimport logger from '../utils/logger';\n\n/**\n * EML Format Handler\n * Handles parsing and generating EML format emails\n */\nclass EmlHandler {\n /**\n * Parse EML file\n * @param {string} filePath - Path to EML file\n * @returns {Promise<Object>} Parsed email data\n */\n async parse(filePath) {\n try {\n logger.debug('Parsing EML file', { filePath });\n\n const emlContent = await fs.readFile(filePath, 'utf8');\n const parsed = await simpleParser(emlContent);\n\n // Extract email data\n const emailData = {\n messageId: parsed.messageId,\n from: this._formatAddress(parsed.from),\n to: this._formatAddress(parsed.to),\n cc: this._formatAddress(parsed.cc),\n bcc: this._formatAddress(parsed.bcc),\n subject: parsed.subject || '(No Subject)',\n date: parsed.date\n ? parsed.date.toISOString()\n : new Date().toISOString(),\n bodyText: parsed.text || '',\n bodyHtml: parsed.html || '',\n headers: parsed.headers,\n attachments: [],\n };\n\n // Process attachments\n if (parsed.attachments && parsed.attachments.length > 0) {\n emailData.attachments = parsed.attachments.map((att) => ({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content: att.content,\n }));\n }\n\n logger.debug('EML file parsed successfully', {\n messageId: emailData.messageId,\n attachmentCount: emailData.attachments.length,\n });\n\n return emailData;\n } catch (error) {\n logger.error('Failed to parse EML file', {\n filePath,\n error: error.message,\n });\n throw new StorageError(`Failed to parse EML file: ${error.message}`);\n }\n }\n\n /**\n * Generate EML file from email data\n * @param {Object} emailData - Email data\n * @param {string} filePath - Output file path\n * @returns {Promise<void>}\n */\n async generate(emailData, filePath) {\n try {\n logger.debug('Generating EML file', { filePath });\n\n const emlContent = this._buildEmlContent(emailData);\n await fs.writeFile(filePath, emlContent, 'utf8');\n\n logger.info('EML file generated successfully', { filePath });\n } catch (error) {\n logger.error('Failed to generate EML file', {\n filePath,\n error: error.message,\n });\n throw new StorageError(`Failed to generate EML file: ${error.message}`);\n }\n }\n\n /**\n * Build EML content from email data\n * @param {Object} emailData - Email data\n * @returns {string} EML content\n */\n _buildEmlContent(emailData) {\n const lines = [];\n\n // Add headers\n if (emailData.messageId) {\n lines.push(`Message-ID: ${emailData.messageId}`);\n }\n if (emailData.date) {\n const date = new Date(emailData.date);\n lines.push(`Date: ${date.toUTCString()}`);\n }\n if (emailData.from) {\n lines.push(`From: ${emailData.from}`);\n }\n if (emailData.to) {\n lines.push(`To: ${emailData.to}`);\n }\n if (emailData.cc) {\n lines.push(`Cc: ${emailData.cc}`);\n }\n if (emailData.subject) {\n lines.push(`Subject: ${emailData.subject}`);\n }\n\n // Add MIME headers\n lines.push('MIME-Version: 1.0');\n\n if (emailData.bodyHtml && emailData.bodyText) {\n // Multipart alternative\n const boundary = `----=_Part_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n lines.push(`Content-Type: multipart/alternative; boundary=\"${boundary}\"`);\n lines.push('');\n lines.push(`--${boundary}`);\n lines.push('Content-Type: text/plain; charset=utf-8');\n lines.push('Content-Transfer-Encoding: 8bit');\n lines.push('');\n lines.push(emailData.bodyText);\n lines.push('');\n lines.push(`--${boundary}`);\n lines.push('Content-Type: text/html; charset=utf-8');\n lines.push('Content-Transfer-Encoding: 8bit');\n lines.push('');\n lines.push(emailData.bodyHtml);\n lines.push('');\n lines.push(`--${boundary}--`);\n } else if (emailData.bodyHtml) {\n // HTML only\n lines.push('Content-Type: text/html; charset=utf-8');\n lines.push('Content-Transfer-Encoding: 8bit');\n lines.push('');\n lines.push(emailData.bodyHtml);\n } else {\n // Plain text only\n lines.push('Content-Type: text/plain; charset=utf-8');\n lines.push('Content-Transfer-Encoding: 8bit');\n lines.push('');\n lines.push(emailData.bodyText || '');\n }\n\n return lines.join('\\r\\n');\n }\n\n /**\n * Format address for display\n * @param {Object|Array} address - Address object or array\n * @returns {string} Formatted address\n */\n _formatAddress(address) {\n if (!address) return '';\n\n if (Array.isArray(address)) {\n return address\n .map((addr) => {\n if (addr.name) {\n return `\"${addr.name}\" <${addr.address}>`;\n }\n return addr.address;\n })\n .join(', ');\n }\n\n if (address.value && Array.isArray(address.value)) {\n return this._formatAddress(address.value);\n }\n\n if (address.name) {\n return `\"${address.name}\" <${address.address}>`;\n }\n\n return address.address || address.toString();\n }\n}\n\nmodule.exports = new EmlHandler();\n","import { promises as fs } from 'fs';\n\nimport { simpleParser } from 'mailparser';\n\nimport { StorageError } from '../utils/errors';\nimport logger from '../utils/logger';\n\n/**\n * MBOX Format Handler\n * Handles parsing and generating MBOX format mailboxes\n */\nclass MboxHandler {\n /**\n * Parse MBOX file\n * @param {string} filePath - Path to MBOX file\n * @param {Function} onEmail - Callback for each parsed email\n * @returns {Promise<number>} Number of emails parsed\n */\n async parse(filePath, onEmail) {\n try {\n logger.debug('Parsing MBOX file', { filePath });\n\n const mboxContent = await fs.readFile(filePath, 'utf8');\n const emails = this._splitMboxMessages(mboxContent);\n\n let count = 0;\n for (const emailContent of emails) {\n try {\n const parsed = await simpleParser(emailContent);\n\n const emailData = {\n messageId: parsed.messageId,\n from: this._formatAddress(parsed.from),\n to: this._formatAddress(parsed.to),\n cc: this._formatAddress(parsed.cc),\n bcc: this._formatAddress(parsed.bcc),\n subject: parsed.subject || '(No Subject)',\n date: parsed.date\n ? parsed.date.toISOString()\n : new Date().toISOString(),\n bodyText: parsed.text || '',\n bodyHtml: parsed.html || '',\n headers: parsed.headers,\n attachments: [],\n };\n\n // Process attachments\n if (parsed.attachments && parsed.attachments.length > 0) {\n emailData.attachments = parsed.attachments.map((att) => ({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content: att.content,\n }));\n }\n\n await onEmail(emailData);\n count++;\n } catch (error) {\n logger.warn('Failed to parse email in MBOX', {\n error: error.message,\n });\n }\n }\n\n logger.info('MBOX file parsed successfully', { filePath, count });\n return count;\n } catch (error) {\n logger.error('Failed to parse MBOX file', {\n filePath,\n error: error.message,\n });\n throw new StorageError(`Failed to parse MBOX file: ${error.message}`);\n }\n }\n\n /**\n * Generate MBOX file from emails\n * @param {Array<Object>} emails - Array of email data\n * @param {string} filePath - Output file path\n * @returns {Promise<void>}\n */\n async generate(emails, filePath) {\n try {\n logger.debug('Generating MBOX file', { filePath, count: emails.length });\n\n const mboxContent = this._buildMboxContent(emails);\n await fs.writeFile(filePath, mboxContent, 'utf8');\n\n logger.info('MBOX file generated successfully', {\n filePath,\n count: emails.length,\n });\n } catch (error) {\n logger.error('Failed to generate MBOX file', {\n filePath,\n error: error.message,\n });\n throw new StorageError(`Failed to generate MBOX file: ${error.message}`);\n }\n }\n\n /**\n * Append email to existing MBOX file\n * @param {Object} emailData - Email data\n * @param {string} filePath - MBOX file path\n * @returns {Promise<void>}\n */\n async append(emailData, filePath) {\n try {\n const emailContent = this._buildEmailContent(emailData);\n const mboxEntry = this._wrapInMboxFormat(emailContent, emailData.date);\n\n await fs.appendFile(filePath, mboxEntry, 'utf8');\n\n logger.debug('Email appended to MBOX', { filePath });\n } catch (error) {\n logger.error('Failed to append to MBOX file', {\n filePath,\n error: error.message,\n });\n throw new StorageError(`Failed to append to MBOX file: ${error.message}`);\n }\n }\n\n /**\n * Split MBOX content into individual messages\n * @param {string} mboxContent - MBOX file content\n * @returns {Array<string>} Array of email contents\n */\n _splitMboxMessages(mboxContent) {\n const messages = [];\n const lines = mboxContent.split('\\n');\n let currentMessage = [];\n let inMessage = false;\n\n for (const line of lines) {\n // MBOX format: messages start with \"From \" line\n if (line.startsWith('From ') && inMessage) {\n // Save previous message\n messages.push(currentMessage.join('\\n'));\n currentMessage = [];\n } else if (line.startsWith('From ')) {\n inMessage = true;\n continue; // Skip the \"From \" line\n }\n\n if (inMessage) {\n currentMessage.push(line);\n }\n }\n\n // Add last message\n if (currentMessage.length > 0) {\n messages.push(currentMessage.join('\\n'));\n }\n\n return messages;\n }\n\n /**\n * Build MBOX content from emails\n * @param {Array<Object>} emails - Array of email data\n * @returns {string} MBOX content\n */\n _buildMboxContent(emails) {\n const entries = emails.map((email) => {\n const emailContent = this._buildEmailContent(email);\n return this._wrapInMboxFormat(emailContent, email.date);\n });\n\n return entries.join('');\n }\n\n /**\n * Build email content\n * @param {Object} emailData - Email data\n * @returns {string} Email content\n */\n _buildEmailContent(emailData) {\n const lines = [];\n\n // Add headers\n if (emailData.messageId) {\n lines.push(`Message-ID: ${emailData.messageId}`);\n }\n if (emailData.date) {\n const date = new Date(emailData.date);\n lines.push(`Date: ${date.toUTCString()}`);\n }\n if (emailData.from) {\n lines.push(`From: ${emailData.from}`);\n }\n if (emailData.to) {\n lines.push(`To: ${emailData.to}`);\n }\n if (emailData.cc) {\n lines.push(`Cc: ${emailData.cc}`);\n }\n if (emailData.subject) {\n lines.push(`Subject: ${emailData.subject}`);\n }\n\n // Add MIME headers\n lines.push('MIME-Version: 1.0');\n\n if (emailData.bodyHtml && emailData.bodyText) {\n // Multipart alternative\n const boundary = `----=_Part_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n lines.push(`Content-Type: multipart/alternative; boundary=\"${boundary}\"`);\n lines.push('');\n lines.push(`--${boundary}`);\n lines.push('Content-Type: text/plain; charset=utf-8');\n lines.push('');\n lines.push(emailData.bodyText);\n lines.push('');\n lines.push(`--${boundary}`);\n lines.push('Content-Type: text/html; charset=utf-8');\n lines.push('');\n lines.push(emailData.bodyHtml);\n lines.push('');\n lines.push(`--${boundary}--`);\n } else if (emailData.bodyHtml) {\n lines.push('Content-Type: text/html; charset=utf-8');\n lines.push('');\n lines.push(emailData.bodyHtml);\n } else {\n lines.push('Content-Type: text/plain; charset=utf-8');\n lines.push('');\n lines.push(emailData.bodyText || '');\n }\n\n return lines.join('\\r\\n');\n }\n\n /**\n * Wrap email content in MBOX format\n * @param {string} emailContent - Email content\n * @param {string} date - Email date\n * @returns {string} MBOX formatted entry\n */\n _wrapInMboxFormat(emailContent, date) {\n const emailDate = date ? new Date(date) : new Date();\n const fromLine = `From MAILER-DAEMON ${emailDate.toString()}\\r\\n`;\n\n // Escape lines starting with \"From \" (MBOX requirement)\n const escapedContent = emailContent.replace(/^From /gm, '>From ');\n\n return fromLine + escapedContent + '\\r\\n\\r\\n';\n }\n\n /**\n * Format address for display\n * @param {Object|Array} address - Address object or array\n * @returns {string} Formatted address\n */\n _formatAddress(address) {\n if (!address) return '';\n\n if (Array.isArray(address)) {\n return address\n .map((addr) => {\n if (addr.name) {\n return `\"${addr.name}\" <${addr.address}>`;\n }\n return addr.address;\n })\n .join(', ');\n }\n\n if (address.value && Array.isArray(address.value)) {\n return this._formatAddress(address.value);\n }\n\n if (address.name) {\n return `\"${address.name}\" <${address.address}>`;\n }\n\n return address.address || address.toString();\n }\n}\n\nmodule.exports = new MboxHandler();\n","import { promises as fs } from 'fs';\nimport path from 'path';\n\nimport emlHandler from './eml';\nimport mboxHandler from './mbox';\nimport attachmentModel from '../storage/models/attachment';\nimport emailModel from '../storage/models/email';\nimport { StorageError } from '../utils/errors';\nimport { getDataDir } from '../utils/helpers';\nimport logger from '../utils/logger';\n\n/**\n * Import/Export Manager\n * High-level operations for importing and exporting emails\n */\nclass ImportExportManager {\n /**\n * Export single email to EML file\n * @param {number} emailId - Email ID\n * @param {string} filePath - Output file path\n * @returns {Promise<void>}\n */\n async exportEmailToEml(emailId, filePath) {\n try {\n logger.info('Exporting email to EML', { emailId, filePath });\n\n const email = emailModel.findById(emailId);\n if (!email) {\n throw new StorageError('Email not found');\n }\n\n // Get attachments\n const attachments = attachmentModel.findByEmailId(emailId);\n\n // Read attachment contents\n const attachmentsWithContent = [];\n for (const att of attachments) {\n try {\n const content = await fs.readFile(att.filePath);\n attachmentsWithContent.push({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content,\n });\n } catch (error) {\n logger.warn('Failed to read attachment file', {\n filePath: att.filePath,\n error: error.message,\n });\n }\n }\n\n const emailData = {\n messageId: email.messageId,\n from: email.fromAddress,\n to: email.toAddress,\n cc: email.ccAddress,\n subject: email.subject,\n date: email.date,\n bodyText: email.bodyText,\n bodyHtml: email.bodyHtml,\n attachments: attachmentsWithContent,\n };\n\n await emlHandler.generate(emailData, filePath);\n\n logger.info('Email exported to EML successfully', { emailId, filePath });\n } catch (error) {\n logger.error('Failed to export email to EML', {\n emailId,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Export folder to MBOX file\n * @param {string} folderName - Folder name\n * @param {string} filePath - Output file path\n * @param {Function} onProgress - Progress callback\n * @returns {Promise<number>} Number of emails exported\n */\n async exportFolderToMbox(folderName, filePath, onProgress = null) {\n try {\n logger.info('Exporting folder to MBOX', { folderName, filePath });\n\n // Get all emails from folder (no limit)\n const emails = emailModel.findByFolder(folderName, {\n limit: 999999,\n offset: 0,\n });\n\n if (emails.length === 0) {\n logger.warn('No emails found in folder', { folderName });\n return 0;\n }\n\n const emailsData = [];\n for (let i = 0; i < emails.length; i++) {\n const email = emails[i];\n const attachments = attachmentModel.findByEmailId(email.id);\n\n // Read attachment contents\n const attachmentsWithContent = [];\n for (const att of attachments) {\n try {\n const content = await fs.readFile(att.filePath);\n attachmentsWithContent.push({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content,\n });\n } catch (error) {\n logger.warn('Failed to read attachment file', {\n filePath: att.filePath,\n error: error.message,\n });\n }\n }\n\n emailsData.push({\n messageId: email.messageId,\n from: email.fromAddress,\n to: email.toAddress,\n cc: email.ccAddress,\n subject: email.subject,\n date: email.date,\n bodyText: email.bodyText,\n bodyHtml: email.bodyHtml,\n attachments: attachmentsWithContent,\n });\n\n if (onProgress) {\n onProgress(i + 1, emails.length);\n }\n }\n\n await mboxHandler.generate(emailsData, filePath);\n\n logger.info('Folder exported to MBOX successfully', {\n folderName,\n filePath,\n count: emails.length,\n });\n\n return emails.length;\n } catch (error) {\n logger.error('Failed to export folder to MBOX', {\n folderName,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Export all emails to MBOX file\n * @param {string} filePath - Output file path\n * @param {Function} onProgress - Progress callback\n * @returns {Promise<number>} Number of emails exported\n */\n async exportAllToMbox(filePath, onProgress = null) {\n try {\n logger.info('Exporting all emails to MBOX', { filePath });\n\n // Use search with no filters to get all emails\n const emails = emailModel.search({ limit: 999999, offset: 0 });\n\n if (emails.length === 0) {\n logger.warn('No emails found');\n return 0;\n }\n\n const emailsData = [];\n for (let i = 0; i < emails.length; i++) {\n const email = emails[i];\n const attachments = attachmentModel.findByEmailId(email.id);\n\n // Read attachment contents\n const attachmentsWithContent = [];\n for (const att of attachments) {\n try {\n const content = await fs.readFile(att.filePath);\n attachmentsWithContent.push({\n filename: att.filename,\n contentType: att.contentType,\n size: att.size,\n content,\n });\n } catch (error) {\n logger.warn('Failed to read attachment file', {\n filePath: att.filePath,\n error: error.message,\n });\n }\n }\n\n emailsData.push({\n messageId: email.messageId,\n from: email.fromAddress,\n to: email.toAddress,\n cc: email.ccAddress,\n subject: email.subject,\n date: email.date,\n bodyText: email.bodyText,\n bodyHtml: email.bodyHtml,\n attachments: attachmentsWithContent,\n });\n\n if (onProgress) {\n onProgress(i + 1, emails.length);\n }\n }\n\n await mboxHandler.generate(emailsData, filePath);\n\n logger.info('All emails exported to MBOX successfully', {\n filePath,\n count: emails.length,\n });\n\n return emails.length;\n } catch (error) {\n logger.error('Failed to export all emails to MBOX', {\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Import EML file\n * @param {string} filePath - EML file path\n * @param {string} folder - Target folder (default: INBOX)\n * @param {number} accountId - Account ID\n * @returns {Promise<Object>} Import result\n */\n async importEml(filePath, folder = 'INBOX', accountId = null) {\n try {\n logger.info('Importing EML file', { filePath, folder });\n\n const emailData = await emlHandler.parse(filePath);\n\n // Check for duplicate based on Message-ID\n if (emailData.messageId) {\n const existing = emailModel.findByMessageId(emailData.messageId);\n if (existing) {\n logger.warn('Email already exists (duplicate Message-ID)', {\n messageId: emailData.messageId,\n });\n return {\n success: false,\n reason: 'duplicate',\n messageId: emailData.messageId,\n };\n }\n }\n\n // Create email record\n const emailId = emailModel.create({\n uid: null,\n messageId: emailData.messageId,\n folder,\n from: emailData.from,\n to: emailData.to,\n cc: emailData.cc,\n subject: emailData.subject,\n date: emailData.date,\n bodyText: emailData.bodyText,\n bodyHtml: emailData.bodyHtml,\n hasAttachments: emailData.attachments.length > 0,\n isRead: false,\n flags: [],\n accountId,\n });\n\n // Save attachments\n if (emailData.attachments.length > 0) {\n const dataDir = getDataDir();\n const attachmentsDir = path.join(dataDir, 'attachments');\n\n // Ensure attachments directory exists\n await fs.mkdir(attachmentsDir, { recursive: true });\n\n for (const attachment of emailData.attachments) {\n // Save attachment content to file\n const attachmentPath = path.join(\n attachmentsDir,\n `${emailId}_${attachment.filename}`\n );\n await fs.writeFile(attachmentPath, attachment.content);\n\n attachmentModel.create({\n emailId,\n filename: attachment.filename,\n contentType: attachment.contentType,\n size: attachment.size,\n filePath: attachmentPath,\n });\n }\n }\n\n logger.info('EML file imported successfully', { filePath, emailId });\n\n return {\n success: true,\n emailId,\n attachmentCount: emailData.attachments.length,\n };\n } catch (error) {\n logger.error('Failed to import EML file', {\n filePath,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Import MBOX file\n * @param {string} filePath - MBOX file path\n * @param {string} folder - Target folder (default: INBOX)\n * @param {number} accountId - Account ID\n * @param {Function} onProgress - Progress callback\n * @returns {Promise<Object>} Import result\n */\n async importMbox(\n filePath,\n folder = 'INBOX',\n accountId = null,\n onProgress = null\n ) {\n try {\n logger.info('Importing MBOX file', { filePath, folder });\n\n let imported = 0;\n let skipped = 0;\n let errors = 0;\n\n const onEmail = async (emailData) => {\n try {\n // Check for duplicate based on Message-ID\n if (emailData.messageId) {\n const existing = emailModel.findByMessageId(emailData.messageId);\n if (existing) {\n logger.debug('Skipping duplicate email', {\n messageId: emailData.messageId,\n });\n skipped++;\n if (onProgress) {\n onProgress({ imported, skipped, errors });\n }\n return;\n }\n }\n\n // Create email record\n const emailId = emailModel.create({\n uid: null,\n messageId: emailData.messageId,\n folder,\n from: emailData.from,\n to: emailData.to,\n cc: emailData.cc,\n subject: emailData.subject,\n date: emailData.date,\n bodyText: emailData.bodyText,\n bodyHtml: emailData.bodyHtml,\n hasAttachments: emailData.attachments.length > 0,\n isRead: false,\n flags: [],\n accountId,\n });\n\n // Save attachments\n if (emailData.attachments.length > 0) {\n const dataDir = getDataDir();\n const attachmentsDir = path.join(dataDir, 'attachments');\n\n // Ensure attachments directory exists\n await fs.mkdir(attachmentsDir, { recursive: true });\n\n for (const attachment of emailData.attachments) {\n // Save attachment content to file\n const attachmentPath = path.join(\n attachmentsDir,\n `${emailId}_${attachment.filename}`\n );\n await fs.writeFile(attachmentPath, attachment.content);\n\n attachmentModel.create({\n emailId,\n filename: attachment.filename,\n contentType: attachment.contentType,\n size: attachment.size,\n filePath: attachmentPath,\n });\n }\n }\n\n imported++;\n if (onProgress) {\n onProgress({ imported, skipped, errors });\n }\n } catch (error) {\n logger.error('Failed to import email from MBOX', {\n error: error.message,\n });\n errors++;\n if (onProgress) {\n onProgress({ imported, skipped, errors });\n }\n }\n };\n\n await mboxHandler.parse(filePath, onEmail);\n\n logger.info('MBOX file imported successfully', {\n filePath,\n imported,\n skipped,\n errors,\n });\n\n return { success: true, imported, skipped, errors };\n } catch (error) {\n logger.error('Failed to import MBOX file', {\n filePath,\n error: error.message,\n });\n throw error;\n }\n }\n\n /**\n * Batch export emails to MBOX\n * @param {Array<number>} emailIds - Array of email IDs\n * @param {string} filePath - Output file path\n * @param {Function} onProgress - Progress callback\n * @returns {Promise<number>} Number of emails exported\n */\n async batchExportToMbox(emailIds, filePath, onProgress = null) {\n try {\n logger.info('Batch exporting emails to MBOX', {\n count: emailIds.length,\n filePath,\n });\n\n const emailsData = [];\n for (let i = 0; i < emailIds.length; i++) {\n const emailId = emailIds[i];\n const email = emailModel.findById(emailId);\n\n if (!email) {\n logger.warn('Email not found, skipping', { emailId });\n continue;\n }\n\n const attachments = attachmentModel.findByEmailId(emailId);\n\n emailsData.push({\n messageId: email.messageId,\n from: email.fromAddress,\n to: email.toAddress,\n cc: email.ccAddress,\n subject: email.subject,\n date: email.date,\n bodyText: email.bodyText,\n bodyHtml: email.bodyHtml,\n attachments,\n });\n\n if (onProgress) {\n onProgress(i + 1, emailIds.length);\n }\n }\n\n await mboxHandler.generate(emailsData, filePath);\n\n logger.info('Batch export to MBOX completed', {\n filePath,\n count: emailsData.length,\n });\n\n return emailsData.length;\n } catch (error) {\n logger.error('Failed to batch export to MBOX', { error: error.message });\n throw error;\n }\n }\n}\n\nmodule.exports = new ImportExportManager();\n","import logger from '../utils/logger';\n\n/**\n * Email Thread Analyzer\n * Analyzes email relationships to build conversation threads\n */\nclass ThreadAnalyzer {\n /**\n * Normalize subject by removing Re:, Fwd:, etc. prefixes\n */\n normalizeSubject(subject) {\n if (!subject) return '';\n\n // Remove common prefixes (case-insensitive)\n return subject\n .replace(/^(re|fw|fwd|回复|转发):\\s*/gi, '')\n .trim()\n .toLowerCase();\n }\n\n /**\n * Extract email addresses from References header\n */\n parseReferences(references) {\n if (!references) return [];\n\n // References can be space or comma separated\n return references\n .split(/[\\s,]+/)\n .map((ref) => ref.trim())\n .filter((ref) => ref.length > 0);\n }\n\n /**\n * Calculate subject similarity score (0-1)\n */\n calculateSubjectSimilarity(subject1, subject2) {\n const norm1 = this.normalizeSubject(subject1);\n const norm2 = this.normalizeSubject(subject2);\n\n if (!norm1 || !norm2) return 0;\n if (norm1 === norm2) return 1;\n\n // Simple Levenshtein-based similarity\n const maxLen = Math.max(norm1.length, norm2.length);\n const distance = this._levenshteinDistance(norm1, norm2);\n return 1 - distance / maxLen;\n }\n\n /**\n * Levenshtein distance algorithm\n */\n _levenshteinDistance(str1, str2) {\n const matrix = [];\n\n for (let i = 0; i <= str2.length; i++) {\n matrix[i] = [i];\n }\n\n for (let j = 0; j <= str1.length; j++) {\n matrix[0][j] = j;\n }\n\n for (let i = 1; i <= str2.length; i++) {\n for (let j = 1; j <= str1.length; j++) {\n if (str2.charAt(i - 1) === str1.charAt(j - 1)) {\n matrix[i][j] = matrix[i - 1][j - 1];\n } else {\n matrix[i][j] = Math.min(\n matrix[i - 1][j - 1] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j] + 1\n );\n }\n }\n }\n\n return matrix[str2.length][str1.length];\n }\n\n /**\n * Analyze email relationships and determine thread connections\n * Returns array of { emailId, parentId, confidence }\n */\n analyzeRelationships(emails) {\n const relationships = [];\n const messageIdMap = new Map();\n\n // Build message ID index\n emails.forEach((email) => {\n if (email.messageId) {\n messageIdMap.set(email.messageId, email);\n }\n });\n\n // Analyze each email\n emails.forEach((email) => {\n let parentId = null;\n let confidence = 0;\n let method = null;\n\n // Method 1: In-Reply-To header (highest confidence)\n if (email.inReplyTo) {\n const parent = messageIdMap.get(email.inReplyTo);\n if (parent) {\n parentId = parent.id;\n confidence = 1.0;\n method = 'in-reply-to';\n }\n }\n\n // Method 2: References header (high confidence)\n if (!parentId && email.references) {\n const refs = this.parseReferences(email.references);\n // Try to find the most recent reference\n for (let i = refs.length - 1; i >= 0; i--) {\n const parent = messageIdMap.get(refs[i]);\n if (parent) {\n parentId = parent.id;\n confidence = 0.9;\n method = 'references';\n break;\n }\n }\n }\n\n // Method 3: Subject similarity (medium confidence)\n if (!parentId && email.subject) {\n const normalizedSubject = this.normalizeSubject(email.subject);\n let bestMatch = null;\n let bestScore = 0;\n\n emails.forEach((otherEmail) => {\n if (otherEmail.id === email.id) return;\n if (!otherEmail.subject) return;\n if (new Date(otherEmail.date) >= new Date(email.date)) return;\n\n const similarity = this.calculateSubjectSimilarity(\n email.subject,\n otherEmail.subject\n );\n\n if (similarity > bestScore && similarity >= 0.8) {\n bestScore = similarity;\n bestMatch = otherEmail;\n }\n });\n\n if (bestMatch) {\n parentId = bestMatch.id;\n confidence = bestScore * 0.7; // Reduce confidence for subject-based matching\n method = 'subject-similarity';\n }\n }\n\n relationships.push({\n emailId: email.id,\n parentId,\n confidence,\n method,\n });\n\n logger.debug('Analyzed email relationship', {\n emailId: email.id,\n subject: email.subject,\n parentId,\n confidence,\n method,\n });\n });\n\n return relationships;\n }\n\n /**\n * Find thread root for an email\n */\n findThreadRoot(email, relationships) {\n const relationshipMap = new Map();\n relationships.forEach((rel) => {\n relationshipMap.set(rel.emailId, rel);\n });\n\n let current = email;\n const visited = new Set();\n\n while (current) {\n if (visited.has(current.id)) {\n logger.warn('Circular reference detected in thread', {\n emailId: current.id,\n });\n break;\n }\n visited.add(current.id);\n\n const rel = relationshipMap.get(current.id);\n if (!rel || !rel.parentId) {\n return current;\n }\n\n // Find parent email\n const parent = relationships.find((r) => r.emailId === rel.parentId);\n if (!parent) {\n return current;\n }\n\n current = { id: rel.parentId };\n }\n\n return current;\n }\n}\n\nmodule.exports = new ThreadAnalyzer();\n","import analyzer from './analyzer';\nimport logger from '../utils/logger';\n\n/**\n * Thread Builder\n * Builds thread trees from email relationships\n */\nclass ThreadBuilder {\n /**\n * Build thread tree from emails\n * Returns array of thread roots with nested children\n */\n buildThreads(emails, relationships) {\n if (!emails || emails.length === 0) {\n return [];\n }\n\n // Create email lookup map\n const emailMap = new Map();\n emails.forEach((email) => {\n emailMap.set(email.id, {\n ...email,\n children: [],\n depth: 0,\n });\n });\n\n // Create relationship lookup map\n const relationshipMap = new Map();\n relationships.forEach((rel) => {\n relationshipMap.set(rel.emailId, rel);\n });\n\n // Build parent-child relationships\n const roots = [];\n emails.forEach((email) => {\n const emailNode = emailMap.get(email.id);\n const rel = relationshipMap.get(email.id);\n\n if (rel && rel.parentId) {\n const parent = emailMap.get(rel.parentId);\n if (parent) {\n parent.children.push(emailNode);\n emailNode.depth = parent.depth + 1;\n emailNode.parentId = rel.parentId;\n emailNode.confidence = rel.confidence;\n emailNode.method = rel.method;\n } else {\n // Parent not found, treat as root\n roots.push(emailNode);\n }\n } else {\n // No parent, this is a root\n roots.push(emailNode);\n }\n });\n\n // Sort children by date\n const sortChildren = (node) => {\n if (node.children && node.children.length > 0) {\n node.children.sort((a, b) => new Date(a.date) - new Date(b.date));\n node.children.forEach((child) => sortChildren(child));\n }\n };\n\n roots.forEach((root) => sortChildren(root));\n\n // Sort roots by most recent activity\n roots.sort((a, b) => {\n const aLatest = this._getLatestDate(a);\n const bLatest = this._getLatestDate(b);\n return new Date(bLatest) - new Date(aLatest);\n });\n\n logger.debug('Built threads', {\n totalEmails: emails.length,\n threadCount: roots.length,\n });\n\n return roots;\n }\n\n /**\n * Get latest date in thread (including children)\n */\n _getLatestDate(node) {\n let latest = node.date;\n\n if (node.children && node.children.length > 0) {\n node.children.forEach((child) => {\n const childLatest = this._getLatestDate(child);\n if (new Date(childLatest) > new Date(latest)) {\n latest = childLatest;\n }\n });\n }\n\n return latest;\n }\n\n /**\n * Get thread statistics\n */\n getThreadStats(thread) {\n const stats = {\n messageCount: 0,\n participants: new Set(),\n firstDate: thread.date,\n lastDate: thread.date,\n hasUnread: false,\n depth: 0,\n };\n\n const traverse = (node, currentDepth = 0) => {\n stats.messageCount++;\n stats.depth = Math.max(stats.depth, currentDepth);\n\n if (node.from) {\n stats.participants.add(node.from);\n }\n\n if (new Date(node.date) < new Date(stats.firstDate)) {\n stats.firstDate = node.date;\n }\n\n if (new Date(node.date) > new Date(stats.lastDate)) {\n stats.lastDate = node.date;\n }\n\n if (!node.isRead) {\n stats.hasUnread = true;\n }\n\n if (node.children && node.children.length > 0) {\n node.children.forEach((child) => traverse(child, currentDepth + 1));\n }\n };\n\n traverse(thread);\n\n return {\n ...stats,\n participants: Array.from(stats.participants),\n };\n }\n\n /**\n * Flatten thread tree to array\n */\n flattenThread(thread) {\n const result = [];\n\n const traverse = (node) => {\n result.push(node);\n if (node.children && node.children.length > 0) {\n node.children.forEach((child) => traverse(child));\n }\n };\n\n traverse(thread);\n return result;\n }\n\n /**\n * Generate thread ID from root email\n */\n generateThreadId(rootEmail) {\n // Use message ID if available, otherwise use email ID\n if (rootEmail.messageId) {\n return `thread-${rootEmail.messageId}`;\n }\n return `thread-${rootEmail.id}`;\n }\n\n /**\n * Find thread by email ID\n */\n findThreadByEmailId(threads, emailId) {\n for (const thread of threads) {\n const found = this._findInThread(thread, emailId);\n if (found) {\n return thread;\n }\n }\n return null;\n }\n\n /**\n * Find email in thread tree\n */\n _findInThread(node, emailId) {\n if (node.id === emailId) {\n return node;\n }\n\n if (node.children && node.children.length > 0) {\n for (const child of node.children) {\n const found = this._findInThread(child, emailId);\n if (found) {\n return found;\n }\n }\n }\n\n return null;\n }\n}\n\nexport default new ThreadBuilder();\n","import chalk from 'chalk';\n\nimport emailModel from '../../storage/models/email';\nimport threadModel from '../../storage/models/thread';\nimport analyzer from '../../threads/analyzer';\nimport builder from '../../threads/builder';\nimport logger from '../../utils/logger';\n\n/**\n * Format thread tree for display\n */\nfunction formatThreadTree(thread, options = {}) {\n const { expanded = true, depth = 0, prefix = '', isLast = true } = options;\n const lines = [];\n\n // Thread connector\n const connector = depth === 0 ? '' : isLast ? '└─ ' : '├─ ';\n const childPrefix = depth === 0 ? '' : isLast ? ' ' : '│ ';\n\n // Format email info\n const unreadMark = thread.isRead ? ' ' : chalk.bold.blue('●');\n const starMark = thread.isStarred ? chalk.yellow('★') : ' ';\n const from = thread.from || 'Unknown';\n const subject = thread.subject || '(No subject)';\n const date = new Date(thread.date).toLocaleString();\n\n // Main line\n lines.push(\n `${prefix}${connector}${unreadMark}${starMark} ` +\n `${chalk.cyan(from)} - ${chalk.white(subject)} ` +\n `${chalk.gray(date)}`\n );\n\n // Show children if expanded\n if (expanded && thread.children && thread.children.length > 0) {\n thread.children.forEach((child, index) => {\n const isLastChild = index === thread.children.length - 1;\n const childLines = formatThreadTree(child, {\n expanded,\n depth: depth + 1,\n prefix: prefix + childPrefix,\n isLast: isLastChild,\n });\n lines.push(...childLines);\n });\n } else if (thread.children && thread.children.length > 0) {\n lines.push(\n `${prefix}${childPrefix}${chalk.gray(` [${thread.children.length} more messages...]`)}`\n );\n }\n\n return lines;\n}\n\n/**\n * Thread list command\n */\nasync function listThreads(options = {}) {\n try {\n const { folder = 'INBOX', limit = 20, accountId = null } = options;\n\n console.log(chalk.bold(`\\nThreaded view of ${folder}:\\n`));\n\n // Fetch emails\n const emails = await emailModel.findByFolder(folder, {\n limit: limit * 5, // Fetch more to build threads\n includeDeleted: false,\n });\n\n if (emails.length === 0) {\n console.log(chalk.gray('No emails found.'));\n return;\n }\n\n // Analyze relationships\n const relationships = analyzer.analyzeRelationships(emails);\n\n // Build threads\n const threads = builder.buildThreads(emails, relationships);\n\n // Display threads\n threads.slice(0, limit).forEach((thread, index) => {\n const stats = builder.getThreadStats(thread);\n const threadLines = formatThreadTree(thread, { expanded: false });\n\n console.log(threadLines.join('\\n'));\n console.log(\n chalk.gray(\n ` ${stats.messageCount} messages, ` +\n `${stats.participants.length} participants, ` +\n `${stats.hasUnread ? chalk.blue('unread') : 'all read'}`\n )\n );\n console.log('');\n });\n\n console.log(\n chalk.gray(\n `Showing ${Math.min(limit, threads.length)} of ${threads.length} threads`\n )\n );\n } catch (error) {\n logger.error('Failed to list threads', { error: error.message });\n console.error(chalk.red(`Error: ${error.message}`));\n process.exit(1);\n }\n}\n\n/**\n * Show thread command\n */\nasync function showThread(emailId, options = {}) {\n try {\n const { expanded = true } = options;\n\n // Fetch email\n const email = await emailModel.findById(emailId);\n if (!email) {\n console.error(chalk.red(`Email ${emailId} not found.`));\n process.exit(1);\n }\n\n // Fetch all emails in the same folder\n const emails = await emailModel.findByFolder(email.folder, {\n limit: 1000,\n includeDeleted: false,\n });\n\n // Analyze relationships\n const relationships = analyzer.analyzeRelationships(emails);\n\n // Build threads\n const threads = builder.buildThreads(emails, relationships);\n\n // Find the thread containing this email\n const thread = builder.findThreadByEmailId(threads, emailId);\n\n if (!thread) {\n console.error(chalk.red('Thread not found.'));\n process.exit(1);\n }\n\n // Display thread\n console.log(chalk.bold('\\nThread:\\n'));\n const stats = builder.getThreadStats(thread);\n const threadLines = formatThreadTree(thread, { expanded });\n\n console.log(threadLines.join('\\n'));\n console.log('');\n console.log(chalk.bold('Thread Statistics:'));\n console.log(chalk.gray(` Messages: ${stats.messageCount}`));\n console.log(chalk.gray(` Participants: ${stats.participants.join(', ')}`));\n console.log(\n chalk.gray(\n ` First message: ${new Date(stats.firstDate).toLocaleString()}`\n )\n );\n console.log(\n chalk.gray(` Last message: ${new Date(stats.lastDate).toLocaleString()}`)\n );\n console.log(chalk.gray(` Max depth: ${stats.depth}`));\n console.log(chalk.gray(` Unread: ${stats.hasUnread ? 'Yes' : 'No'}`));\n } catch (error) {\n logger.error('Failed to show thread', { error: error.message });\n console.error(chalk.red(`Error: ${error.message}`));\n process.exit(1);\n }\n}\n\n/**\n * Delete thread command\n */\nasync function deleteThread(emailId, options = {}) {\n try {\n const { permanent = false } = options;\n\n // Fetch email\n const email = await emailModel.findById(emailId);\n if (!email) {\n console.error(chalk.red(`Email ${emailId} not found.`));\n process.exit(1);\n }\n\n // Fetch all emails in the same folder\n const emails = await emailModel.findByFolder(email.folder, {\n limit: 1000,\n includeDeleted: false,\n });\n\n // Analyze relationships\n const relationships = analyzer.analyzeRelationships(emails);\n\n // Build threads\n const threads = builder.buildThreads(emails, relationships);\n\n // Find the thread containing this email\n const thread = builder.findThreadByEmailId(threads, emailId);\n\n if (!thread) {\n console.error(chalk.red('Thread not found.'));\n process.exit(1);\n }\n\n // Get all emails in thread\n const threadEmails = builder.flattenThread(thread);\n\n console.log(\n chalk.yellow(`\\nDeleting thread with ${threadEmails.length} messages...`)\n );\n\n // Delete each email\n for (const threadEmail of threadEmails) {\n if (permanent) {\n await emailModel.permanentlyDelete(threadEmail.id);\n } else {\n await emailModel.moveToTrash(threadEmail.id);\n }\n }\n\n console.log(\n chalk.green(`✓ Thread deleted (${threadEmails.length} messages)`)\n );\n } catch (error) {\n logger.error('Failed to delete thread', { error: error.message });\n console.error(chalk.red(`Error: ${error.message}`));\n process.exit(1);\n }\n}\n\n/**\n * Move thread command\n */\nasync function moveThread(emailId, targetFolder, options = {}) {\n try {\n // Fetch email\n const email = await emailModel.findById(emailId);\n if (!email) {\n console.error(chalk.red(`Email ${emailId} not found.`));\n process.exit(1);\n }\n\n // Fetch all emails in the same folder\n const emails = await emailModel.findByFolder(email.folder, {\n limit: 1000,\n includeDeleted: false,\n });\n\n // Analyze relationships\n const relationships = analyzer.analyzeRelationships(emails);\n\n // Build threads\n const threads = builder.buildThreads(emails, relationships);\n\n // Find the thread containing this email\n const thread = builder.findThreadByEmailId(threads, emailId);\n\n if (!thread) {\n console.error(chalk.red('Thread not found.'));\n process.exit(1);\n }\n\n // Get all emails in thread\n const threadEmails = builder.flattenThread(thread);\n\n console.log(\n chalk.yellow(\n `\\nMoving thread with ${threadEmails.length} messages to ${targetFolder}...`\n )\n );\n\n // Move each email\n for (const threadEmail of threadEmails) {\n await emailModel.move(threadEmail.id, targetFolder);\n }\n\n console.log(\n chalk.green(\n `✓ Thread moved to ${targetFolder} (${threadEmails.length} messages)`\n )\n );\n } catch (error) {\n logger.error('Failed to move thread', { error: error.message });\n console.error(chalk.red(`Error: ${error.message}`));\n process.exit(1);\n }\n}\n\nexport { listThreads, showThread, deleteThread, moveThread, formatThreadTree };\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface TagInput {\n name: string;\n color?: string;\n description?: string | null;\n accountId?: number | null;\n}\n\ninterface TagUpdateInput {\n name?: string;\n color?: string;\n description?: string | null;\n}\n\ninterface TagRow {\n id: number;\n name: string;\n color: string;\n description: string | null;\n account_id: number | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface CountRow {\n count: number;\n}\n\nexport interface TagRecord {\n id: number;\n name: string;\n color: string;\n description: string | null;\n accountId: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Tag model.\n */\nexport class TagModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(tagData: TagInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO tags (name, color, description, account_id)\n VALUES (?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n tagData.name,\n tagData.color ?? '#808080',\n tagData.description ?? null,\n tagData.accountId ?? null\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Tag created', { id: insertId, name: tagData.name });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('UNIQUE constraint failed')) {\n throw new StorageError(`Tag \"${tagData.name}\" already exists`);\n }\n logger.error('Failed to create tag', { error: errorMessage });\n throw new StorageError(`Failed to create tag: ${errorMessage}`);\n }\n }\n\n findAll(accountId: number | null = null): TagRecord[] {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM tags';\n const params: number[] = [];\n\n if (accountId !== null) {\n query += ' WHERE account_id = ? OR account_id IS NULL';\n params.push(accountId);\n }\n\n query += ' ORDER BY name ASC';\n\n const stmt = db.prepare<unknown[], TagRow>(query);\n const tags = stmt.all(...params);\n return tags.map((tag) => this.formatTag(tag));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find tags', { error: errorMessage });\n throw new StorageError(`Failed to find tags: ${errorMessage}`);\n }\n }\n\n findById(id: number): TagRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], TagRow>(\n 'SELECT * FROM tags WHERE id = ?'\n );\n const tag = stmt.get(id);\n return tag ? this.formatTag(tag) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find tag by ID', { id, error: errorMessage });\n throw new StorageError(`Failed to find tag: ${errorMessage}`);\n }\n }\n\n findByName(name: string, accountId: number | null = null): TagRecord | null {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM tags WHERE name = ?';\n const params: Array<string | number> = [name];\n\n if (accountId !== null) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n const stmt = db.prepare<unknown[], TagRow>(query);\n const tag = stmt.get(...params);\n return tag ? this.formatTag(tag) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find tag by name', { name, error: errorMessage });\n throw new StorageError(`Failed to find tag: ${errorMessage}`);\n }\n }\n\n update(id: number, data: TagUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number | null> = [];\n\n if (data.name !== undefined) {\n fields.push('name = ?');\n params.push(data.name);\n }\n\n if (data.color !== undefined) {\n fields.push('color = ?');\n params.push(data.color);\n }\n\n if (data.description !== undefined) {\n fields.push('description = ?');\n params.push(data.description);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE tags SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Tag updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('UNIQUE constraint failed')) {\n throw new StorageError('Tag name already exists');\n }\n logger.error('Failed to update tag', { id, error: errorMessage });\n throw new StorageError(`Failed to update tag: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM tags WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Tag deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete tag', { id, error: errorMessage });\n throw new StorageError(`Failed to delete tag: ${errorMessage}`);\n }\n }\n\n addToEmail(emailId: number, tagId: number): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO email_tags (email_id, tag_id)\n VALUES (?, ?)\n `);\n\n const result = stmt.run(emailId, tagId);\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Tag added to email', { emailId, tagId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('UNIQUE constraint failed')) {\n throw new StorageError('Email already has this tag');\n }\n logger.error('Failed to add tag to email', {\n emailId,\n tagId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to add tag to email: ${errorMessage}`);\n }\n }\n\n removeFromEmail(emailId: number, tagId: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n DELETE FROM email_tags\n WHERE email_id = ? AND tag_id = ?\n `);\n\n const result = stmt.run(emailId, tagId);\n logger.debug('Tag removed from email', {\n emailId,\n tagId,\n changes: result.changes,\n });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to remove tag from email', {\n emailId,\n tagId,\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to remove tag from email: ${errorMessage}`\n );\n }\n }\n\n findByEmailId(emailId: number): TagRecord[] {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], TagRow>(`\n SELECT t.* FROM tags t\n INNER JOIN email_tags et ON t.id = et.tag_id\n WHERE et.email_id = ?\n ORDER BY t.name ASC\n `);\n\n const tags = stmt.all(emailId);\n return tags.map((tag) => this.formatTag(tag));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find tags for email', {\n emailId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find tags for email: ${errorMessage}`);\n }\n }\n\n findEmailsByTag(\n tagId: number,\n options: { limit?: number; offset?: number } = {}\n ): Record<string, unknown>[] {\n try {\n const db = this.getDb();\n const { limit = 50, offset = 0 } = options;\n\n const stmt = db.prepare<\n [number, number, number],\n Record<string, unknown>\n >(`\n SELECT e.* FROM emails e\n INNER JOIN email_tags et ON e.id = et.email_id\n WHERE et.tag_id = ? AND e.is_deleted = 0\n ORDER BY e.date DESC\n LIMIT ? OFFSET ?\n `);\n\n return stmt.all(tagId, limit, offset);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find emails by tag', {\n tagId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find emails by tag: ${errorMessage}`);\n }\n }\n\n countEmailsByTag(tagId: number): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], CountRow>(`\n SELECT COUNT(*) as count FROM email_tags et\n INNER JOIN emails e ON et.email_id = e.id\n WHERE et.tag_id = ? AND e.is_deleted = 0\n `);\n\n const result = stmt.get(tagId);\n return result?.count ?? 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to count emails by tag', {\n tagId,\n error: errorMessage,\n });\n throw new StorageError(`Failed to count emails by tag: ${errorMessage}`);\n }\n }\n\n private formatTag(tag: TagRow): TagRecord {\n return {\n id: tag.id,\n name: tag.name,\n color: tag.color,\n description: tag.description,\n accountId: tag.account_id,\n createdAt: tag.created_at,\n updatedAt: tag.updated_at,\n };\n }\n}\n\nconst tagModel = new TagModel();\nexport default tagModel;\n","import chalk from 'chalk';\n\nimport { formatThreadTree } from './thread';\nimport accountModel from '../../storage/models/account';\nimport emailModel from '../../storage/models/email';\nimport tagModel from '../../storage/models/tag';\nimport analyzer from '../../threads/analyzer';\nimport builder from '../../threads/builder';\nimport logger from '../../utils/logger';\nimport { formatEmailList } from '../utils/formatter';\n\n/**\n * List command - List emails from local storage\n */\nfunction listCommand(options) {\n try {\n const folder = options.folder || 'INBOX';\n const limit = options.limit || 50;\n const page = options.page || 1;\n const offset = (page - 1) * limit;\n const unreadOnly = options.unread || false;\n const starred = options.starred || false;\n const flagged = options.flagged || false;\n const tag = options.tag || null;\n const accountId = options.account ? parseInt(options.account) : null;\n const allAccounts = options.allAccounts || false;\n const threadView = options.thread || false;\n\n let emails;\n let total;\n let title;\n\n // Handle different filtering modes\n if (starred) {\n title = 'Starred Emails';\n emails = emailModel.findStarred({\n limit,\n offset,\n folder: options.folder ? folder : null,\n accountId,\n allAccounts,\n });\n total = emailModel.countStarred(\n options.folder ? folder : null,\n accountId,\n allAccounts\n );\n } else if (flagged) {\n title = 'Flagged (Important) Emails';\n emails = emailModel.findImportant({\n limit,\n offset,\n folder: options.folder ? folder : null,\n accountId,\n allAccounts,\n });\n total = emailModel.countImportant(\n options.folder ? folder : null,\n accountId,\n allAccounts\n );\n } else if (tag) {\n // Find tag by name\n const tagObj = tagModel.findByName(tag);\n if (!tagObj) {\n console.error(chalk.red('Error:'), `Tag \"${tag}\" not found`);\n process.exit(1);\n }\n title = `Emails tagged with \"${tag}\"`;\n const rawEmails = tagModel.findEmailsByTag(tagObj.id, {\n limit,\n offset,\n accountId,\n allAccounts,\n });\n emails = rawEmails.map((email) => emailModel._formatEmail(email));\n total = tagModel.countEmailsByTag(tagObj.id, accountId, allAccounts);\n } else {\n title = `Emails in ${folder}`;\n emails = emailModel.findByFolder(folder, {\n limit,\n offset,\n unreadOnly,\n accountId,\n allAccounts,\n });\n total = emailModel.countByFolder(\n folder,\n unreadOnly,\n accountId,\n allAccounts\n );\n }\n\n // Add account info to title if filtering by account\n if (accountId) {\n const account = accountModel.findById(accountId);\n if (account) {\n title += ` (${account.email})`;\n }\n } else if (allAccounts) {\n title += ' (All Accounts)';\n }\n\n console.log(chalk.bold.cyan(`${title}:`));\n console.log();\n\n if (emails.length === 0) {\n console.log(chalk.yellow('No emails found.'));\n return;\n }\n\n // Display in thread view or flat view\n if (threadView) {\n // Fetch more emails to build complete threads\n const allEmails = emailModel.findByFolder(folder, {\n limit: limit * 5,\n offset: 0,\n unreadOnly,\n accountId,\n allAccounts,\n });\n\n // Analyze relationships\n const relationships = analyzer.analyzeRelationships(allEmails);\n\n // Build threads\n const threads = builder.buildThreads(allEmails, relationships);\n\n // Display threads\n threads.slice(0, limit).forEach((thread, index) => {\n const stats = builder.getThreadStats(thread);\n const threadLines = formatThreadTree(thread, { expanded: false });\n\n console.log(threadLines.join('\\n'));\n console.log(\n chalk.gray(\n ` ${stats.messageCount} messages, ` +\n `${stats.participants.length} participants, ` +\n `${stats.hasUnread ? chalk.blue('unread') : 'all read'}`\n )\n );\n console.log('');\n });\n\n console.log(\n chalk.gray(\n `Showing ${Math.min(limit, threads.length)} of ${threads.length} threads (thread view)`\n )\n );\n } else {\n // Flat view\n console.log(formatEmailList(emails));\n console.log();\n\n const totalPages = Math.ceil(total / limit);\n console.log(\n chalk.gray(`Page ${page} of ${totalPages} (${total} total emails)`)\n );\n }\n\n if (unreadOnly) {\n console.log(chalk.gray('Showing unread emails only'));\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('List command failed', { error: error.message });\n process.exit(1);\n }\n}\n\nmodule.exports = listCommand;\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\n\nimport notificationManager from '../../notifications/manager';\nimport logger from '../../utils/logger';\n\n/**\n * Notify command - Manage email notifications\n */\nasync function notifyCommand(action, options = {}) {\n try {\n switch (action) {\n case 'enable':\n return handleEnable();\n\n case 'disable':\n return handleDisable();\n\n case 'config':\n return handleConfig(options);\n\n case 'test':\n return handleTest();\n\n case 'status':\n return handleStatus();\n\n default:\n console.error(chalk.red(`Unknown notify command: ${action}`));\n console.log(\n 'Available commands: enable, disable, config, test, status'\n );\n process.exit(1);\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Notify command failed', { action, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Enable notifications\n */\nfunction handleEnable() {\n notificationManager.enable();\n console.log(chalk.green('✓ Notifications enabled'));\n console.log();\n console.log(\n chalk.gray('Use \"notify config\" to configure notification filters')\n );\n console.log(chalk.gray('Use \"notify test\" to test notifications'));\n}\n\n/**\n * Disable notifications\n */\nfunction handleDisable() {\n notificationManager.disable();\n console.log(chalk.yellow('✓ Notifications disabled'));\n}\n\n/**\n * Configure notifications\n */\nasync function handleConfig(options) {\n const currentConfig = notificationManager.getConfig();\n\n console.log(chalk.blue('Current Notification Configuration:'));\n console.log();\n displayConfig(currentConfig);\n console.log();\n\n // Handle command-line options\n if (options.sender || options.tag || options.important !== undefined) {\n return handleConfigOptions(options);\n }\n\n // Interactive configuration\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to configure?',\n choices: [\n { name: 'Add sender filter', value: 'add-sender' },\n { name: 'Remove sender filter', value: 'remove-sender' },\n { name: 'Add tag filter', value: 'add-tag' },\n { name: 'Remove tag filter', value: 'remove-tag' },\n { name: 'Toggle important only', value: 'toggle-important' },\n { name: 'Toggle sound', value: 'toggle-sound' },\n { name: 'Toggle desktop notifications', value: 'toggle-desktop' },\n { name: 'Clear all filters', value: 'clear-filters' },\n { name: 'Back', value: 'back' },\n ],\n },\n ]);\n\n if (answers.action === 'back') {\n return;\n }\n\n await handleConfigAction(answers.action, currentConfig);\n}\n\n/**\n * Handle configuration options from command line\n */\nfunction handleConfigOptions(options) {\n const filters = {};\n\n if (options.sender) {\n const senders = options.sender.split(',').map((s) => s.trim());\n filters.senders = senders;\n console.log(chalk.green(`✓ Sender filter set: ${senders.join(', ')}`));\n }\n\n if (options.tag) {\n const tags = options.tag.split(',').map((t) => t.trim());\n filters.tags = tags;\n console.log(chalk.green(`✓ Tag filter set: ${tags.join(', ')}`));\n }\n\n if (options.important !== undefined) {\n filters.importantOnly = options.important;\n console.log(chalk.green(`✓ Important only: ${options.important}`));\n }\n\n if (Object.keys(filters).length > 0) {\n notificationManager.updateFilters(filters);\n }\n}\n\n/**\n * Handle interactive configuration action\n */\nasync function handleConfigAction(action, currentConfig) {\n switch (action) {\n case 'add-sender': {\n const answer = await inquirer.prompt([\n {\n type: 'input',\n name: 'sender',\n message: 'Enter sender email or domain:',\n validate: (input) =>\n input.trim().length > 0 || 'Sender cannot be empty',\n },\n ]);\n const senders = [...currentConfig.filters.senders, answer.sender.trim()];\n notificationManager.updateFilters({ senders });\n console.log(chalk.green(`✓ Added sender filter: ${answer.sender}`));\n break;\n }\n\n case 'remove-sender': {\n if (currentConfig.filters.senders.length === 0) {\n console.log(chalk.yellow('No sender filters to remove'));\n break;\n }\n const answer = await inquirer.prompt([\n {\n type: 'list',\n name: 'sender',\n message: 'Select sender to remove:',\n choices: currentConfig.filters.senders,\n },\n ]);\n const senders = currentConfig.filters.senders.filter(\n (s) => s !== answer.sender\n );\n notificationManager.updateFilters({ senders });\n console.log(chalk.green(`✓ Removed sender filter: ${answer.sender}`));\n break;\n }\n\n case 'add-tag': {\n const answer = await inquirer.prompt([\n {\n type: 'input',\n name: 'tag',\n message: 'Enter tag name:',\n validate: (input) => input.trim().length > 0 || 'Tag cannot be empty',\n },\n ]);\n const tags = [...currentConfig.filters.tags, answer.tag.trim()];\n notificationManager.updateFilters({ tags });\n console.log(chalk.green(`✓ Added tag filter: ${answer.tag}`));\n break;\n }\n\n case 'remove-tag': {\n if (currentConfig.filters.tags.length === 0) {\n console.log(chalk.yellow('No tag filters to remove'));\n break;\n }\n const answer = await inquirer.prompt([\n {\n type: 'list',\n name: 'tag',\n message: 'Select tag to remove:',\n choices: currentConfig.filters.tags,\n },\n ]);\n const tags = currentConfig.filters.tags.filter((t) => t !== answer.tag);\n notificationManager.updateFilters({ tags });\n console.log(chalk.green(`✓ Removed tag filter: ${answer.tag}`));\n break;\n }\n\n case 'toggle-important': {\n const importantOnly = !currentConfig.filters.importantOnly;\n notificationManager.updateFilters({ importantOnly });\n console.log(\n chalk.green(\n `✓ Important only: ${importantOnly ? 'enabled' : 'disabled'}`\n )\n );\n break;\n }\n\n case 'toggle-sound': {\n const sound = !currentConfig.sound;\n notificationManager.updateSettings({ sound });\n console.log(chalk.green(`✓ Sound: ${sound ? 'enabled' : 'disabled'}`));\n break;\n }\n\n case 'toggle-desktop': {\n const desktop = !currentConfig.desktop;\n notificationManager.updateSettings({ desktop });\n console.log(\n chalk.green(\n `✓ Desktop notifications: ${desktop ? 'enabled' : 'disabled'}`\n )\n );\n break;\n }\n\n case 'clear-filters': {\n notificationManager.updateFilters({\n senders: [],\n tags: [],\n importantOnly: false,\n });\n console.log(chalk.green('✓ All filters cleared'));\n break;\n }\n }\n}\n\n/**\n * Test notifications\n */\nasync function handleTest() {\n console.log(chalk.blue('Sending test notification...'));\n\n try {\n await notificationManager.test();\n console.log(chalk.green('✓ Test notification sent'));\n console.log();\n console.log(chalk.gray('Check your system notifications'));\n } catch (error) {\n console.error(chalk.red('✗ Failed to send test notification'));\n console.error(chalk.red('Error:'), error.message);\n console.log();\n console.log(\n chalk.yellow(\n 'Note: Desktop notifications may not work in all environments'\n )\n );\n }\n}\n\n/**\n * Show notification status\n */\nfunction handleStatus() {\n const config = notificationManager.getConfig();\n const stats = notificationManager.getFilterStats();\n\n console.log(chalk.blue('Notification Status:'));\n console.log();\n\n if (config.enabled) {\n console.log(chalk.green('✓ Enabled'));\n } else {\n console.log(chalk.yellow('✗ Disabled'));\n }\n\n console.log();\n console.log(chalk.blue('Settings:'));\n console.log(\n chalk.gray(\n ` Desktop notifications: ${config.desktop ? 'enabled' : 'disabled'}`\n )\n );\n console.log(chalk.gray(` Sound: ${config.sound ? 'enabled' : 'disabled'}`));\n\n console.log();\n console.log(chalk.blue('Filters:'));\n console.log(chalk.gray(` Sender filters: ${stats.senderCount}`));\n console.log(chalk.gray(` Tag filters: ${stats.tagCount}`));\n console.log(\n chalk.gray(` Important only: ${stats.importantOnly ? 'yes' : 'no'}`)\n );\n\n if (config.filters.senders.length > 0) {\n console.log();\n console.log(chalk.blue('Sender Filters:'));\n config.filters.senders.forEach((sender) => {\n console.log(chalk.gray(` - ${sender}`));\n });\n }\n\n if (config.filters.tags.length > 0) {\n console.log();\n console.log(chalk.blue('Tag Filters:'));\n config.filters.tags.forEach((tag) => {\n console.log(chalk.gray(` - ${tag}`));\n });\n }\n}\n\n/**\n * Display configuration\n */\nfunction displayConfig(config) {\n console.log(\n chalk.gray(` Status: ${config.enabled ? 'enabled' : 'disabled'}`)\n );\n console.log(\n chalk.gray(` Desktop: ${config.desktop ? 'enabled' : 'disabled'}`)\n );\n console.log(chalk.gray(` Sound: ${config.sound ? 'enabled' : 'disabled'}`));\n console.log(\n chalk.gray(\n ` Important only: ${config.filters.importantOnly ? 'yes' : 'no'}`\n )\n );\n console.log(chalk.gray(` Sender filters: ${config.filters.senders.length}`));\n console.log(chalk.gray(` Tag filters: ${config.filters.tags.length}`));\n}\n\nmodule.exports = notifyCommand;\n","import chalk from 'chalk';\nimport ora from 'ora';\n\nimport config from '../../config';\nimport IMAPClient from '../../imap/client';\nimport attachmentModel from '../../storage/models/attachment';\nimport emailModel from '../../storage/models/email';\nimport logger from '../../utils/logger';\nimport { formatEmailDetails } from '../utils/formatter';\n\n/**\n * Read command - Read email details\n */\nasync function readCommand(emailId, options) {\n try {\n if (!emailId) {\n console.error(chalk.red('Error: Email ID is required'));\n console.log('Usage: mail-client read <id>');\n process.exit(1);\n }\n\n const email = emailModel.findById(emailId);\n\n if (!email) {\n console.error(chalk.red(`Email with ID ${emailId} not found`));\n process.exit(1);\n }\n\n // Check if body needs to be fetched from server\n if (!email.bodyText && !email.bodyHtml) {\n const spinner = ora('Fetching email body from server...').start();\n\n try {\n // Load IMAP config\n const cfg = config.load();\n if (!cfg.imap.host || !cfg.imap.user || !cfg.imap.password) {\n spinner.warn(\n 'IMAP configuration incomplete. Showing email without body.'\n );\n } else {\n // Connect to IMAP and fetch body\n const imapClient = new IMAPClient(cfg.imap);\n await imapClient.connect();\n await imapClient.openFolder(email.folder, true);\n\n const bodyData = await imapClient.fetchEmailBody(email.uid);\n\n // Update email in database with body\n emailModel.updateBody(emailId, {\n bodyText: bodyData.bodyText,\n bodyHtml: bodyData.bodyHtml,\n });\n\n // Update local email object\n email.bodyText = bodyData.bodyText;\n email.bodyHtml = bodyData.bodyHtml;\n\n imapClient.disconnect();\n spinner.succeed('Email body fetched from server');\n }\n } catch (error) {\n spinner.fail('Failed to fetch email body from server');\n logger.error('Failed to fetch email body', {\n emailId,\n error: error.message,\n });\n console.log(chalk.yellow('Showing email without body content'));\n }\n }\n\n // Get attachments\n const attachments = email.hasAttachments\n ? attachmentModel.findByEmailId(emailId)\n : [];\n\n // Display email\n console.log();\n console.log(formatEmailDetails(email, attachments));\n console.log();\n\n // Mark as read if not already\n if (!email.isRead) {\n emailModel.markAsRead(emailId);\n console.log(chalk.gray('(Marked as read)'));\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Read command failed', { emailId, error: error.message });\n process.exit(1);\n }\n}\n\nmodule.exports = readCommand;\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\n\nimport config from '../../config';\nimport SMTPClient from '../../smtp/client';\nimport EmailComposer from '../../smtp/composer';\nimport emailModel from '../../storage/models/email';\nimport logger from '../../utils/logger';\n\n/**\n * Reply command - Reply to an email\n */\nasync function replyCommand(emailId, options) {\n try {\n // Load configuration\n const cfg = config.load();\n if (!cfg.smtp.host || !cfg.smtp.user || !cfg.smtp.password) {\n console.error(\n chalk.red(\n 'SMTP configuration incomplete. Please run: mail-client config'\n )\n );\n process.exit(1);\n }\n\n // Get original email\n const originalEmail = emailModel.findById(emailId);\n if (!originalEmail) {\n console.error(chalk.red(`Email with ID ${emailId} not found`));\n process.exit(1);\n }\n\n // Display original email info\n console.log(chalk.bold.cyan('Replying to:'));\n console.log(chalk.gray(`From: ${originalEmail.from}`));\n console.log(chalk.gray(`Subject: ${originalEmail.subject}`));\n console.log(chalk.gray(`Date: ${originalEmail.date}`));\n console.log();\n\n // Create composer\n const composer = new EmailComposer();\n\n // Set recipients\n if (options.all) {\n // Reply to all\n const allRecipients = composer.getAllRecipients(\n originalEmail,\n cfg.smtp.user\n );\n if (allRecipients.length === 0) {\n console.error(chalk.red('No recipients found for reply-all'));\n process.exit(1);\n }\n composer.setTo(allRecipients);\n console.log(chalk.gray(`Reply to all: ${allRecipients.join(', ')}`));\n } else {\n // Reply to sender only\n composer.setTo([originalEmail.from]);\n console.log(chalk.gray(`Reply to: ${originalEmail.from}`));\n }\n\n // Set subject with \"Re:\" prefix\n let subject = originalEmail.subject;\n if (!subject.toLowerCase().startsWith('re:')) {\n subject = `Re: ${subject}`;\n }\n composer.setSubject(subject);\n\n // Set reply headers\n if (originalEmail.messageId) {\n composer.setInReplyTo(originalEmail.messageId);\n }\n composer.setReferences(composer.buildReferences(originalEmail));\n\n // Get reply body\n let replyBody;\n if (options.body) {\n // Non-interactive mode\n replyBody = options.body;\n } else if (options.editor) {\n // Interactive mode with editor\n const answers = await inquirer.prompt([\n {\n type: 'editor',\n name: 'body',\n message: 'Reply body (opens editor):',\n validate: (input) => (input.trim() ? true : 'Reply body is required'),\n },\n ]);\n replyBody = answers.body;\n } else {\n // Interactive mode with input\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'body',\n message: 'Reply body:',\n validate: (input) => (input.trim() ? true : 'Reply body is required'),\n },\n ]);\n replyBody = answers.body;\n }\n\n // Quote original email\n const quotedBody = composer.quoteOriginalEmail(originalEmail);\n\n // Combine reply and quoted text\n const fullBody = replyBody + '\\n\\n' + quotedBody;\n composer.setBody(fullBody);\n\n // Confirm before sending\n if (!options.body) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Send this reply?',\n default: true,\n },\n ]);\n\n if (!confirm) {\n console.log(chalk.yellow('Reply cancelled.'));\n process.exit(0);\n }\n }\n\n // Send email\n const spinner = ora('Sending reply...').start();\n\n const smtpClient = new SMTPClient(cfg.smtp);\n const emailData = composer.compose();\n const result = await smtpClient.sendEmail(emailData);\n\n spinner.succeed('Reply sent successfully!');\n console.log(chalk.gray(`Message ID: ${result.messageId}`));\n\n smtpClient.disconnect();\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Reply command failed', { error: error.message });\n process.exit(1);\n }\n}\n\nmodule.exports = replyCommand;\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface SavedSearchCreateInput {\n name: string;\n query: unknown;\n description?: string | null;\n accountId?: number | null;\n}\n\ninterface SavedSearchUpdateInput {\n name?: string;\n query?: unknown;\n description?: string | null;\n}\n\ninterface SavedSearchRow {\n id: number;\n name: string;\n query: string;\n description: string | null;\n account_id: number | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface CountRow {\n count: number;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Saved search model.\n */\nexport class SavedSearchModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(searchData: SavedSearchCreateInput): number {\n try {\n const db = this.getDb();\n const stmt = db.prepare(`\n INSERT INTO saved_searches (name, query, description, account_id)\n VALUES (?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n searchData.name,\n JSON.stringify(searchData.query),\n searchData.description ?? null,\n searchData.accountId ?? null\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Saved search created', { id: insertId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create saved search', { error: errorMessage });\n throw new StorageError(`Failed to create saved search: ${errorMessage}`);\n }\n }\n\n findById(id: number): SavedSearchRow | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], SavedSearchRow>(\n 'SELECT * FROM saved_searches WHERE id = ?'\n );\n return stmt.get(id) ?? null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find saved search by ID', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find saved search: ${errorMessage}`);\n }\n }\n\n findByName(name: string): SavedSearchRow | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[string], SavedSearchRow>(\n 'SELECT * FROM saved_searches WHERE name = ?'\n );\n return stmt.get(name) ?? null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find saved search by name', {\n name,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find saved search: ${errorMessage}`);\n }\n }\n\n findAll(accountId: number | null = null): SavedSearchRow[] {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM saved_searches';\n const params: number[] = [];\n\n if (accountId !== null) {\n query += ' WHERE account_id = ?';\n params.push(accountId);\n }\n\n query += ' ORDER BY name ASC';\n\n const stmt = db.prepare<unknown[], SavedSearchRow>(query);\n return stmt.all(...params);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find saved searches', { error: errorMessage });\n throw new StorageError(`Failed to find saved searches: ${errorMessage}`);\n }\n }\n\n update(id: number, data: SavedSearchUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number | null> = [];\n\n if (data.name !== undefined) {\n fields.push('name = ?');\n params.push(data.name);\n }\n\n if (data.query !== undefined) {\n fields.push('query = ?');\n params.push(JSON.stringify(data.query));\n }\n\n if (data.description !== undefined) {\n fields.push('description = ?');\n params.push(data.description);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE saved_searches SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Saved search updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update saved search', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to update saved search: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM saved_searches WHERE id = ?');\n const result = stmt.run(id);\n\n logger.debug('Saved search deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete saved search', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to delete saved search: ${errorMessage}`);\n }\n }\n\n count(accountId: number | null = null): number {\n try {\n const db = this.getDb();\n let query = 'SELECT COUNT(*) as count FROM saved_searches';\n const params: number[] = [];\n\n if (accountId !== null) {\n query += ' WHERE account_id = ?';\n params.push(accountId);\n }\n\n const stmt = db.prepare<unknown[], CountRow>(query);\n const result = stmt.get(...params);\n return result?.count ?? 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to count saved searches', { error: errorMessage });\n throw new StorageError(`Failed to count saved searches: ${errorMessage}`);\n }\n }\n}\n\nconst savedSearchModel = new SavedSearchModel();\nexport default savedSearchModel;\n","import chalk from 'chalk';\n\nimport emailModel from '../../storage/models/email';\nimport savedSearchModel from '../../storage/models/saved-search';\nimport logger from '../../utils/logger';\nimport { formatEmailList } from '../utils/formatter';\n\n/**\n * Search command - Search emails with advanced criteria\n */\nfunction searchCommand(action, options) {\n try {\n // Handle subcommands\n if (action === 'save') {\n return saveSearch(options);\n } else if (action === 'load') {\n return loadSearch(options);\n } else if (action === 'list-saved') {\n return listSavedSearches();\n } else if (action === 'delete-saved') {\n return deleteSavedSearch(options);\n }\n\n // Treat action as keyword if it's not a subcommand\n const keyword = action;\n\n const query = buildSearchQuery(keyword, options);\n\n if (\n Object.keys(query).length === 0 ||\n (Object.keys(query).length === 1 && query.limit)\n ) {\n console.error(chalk.red('Error: Please provide search criteria'));\n console.log('Usage: mail-client search <keyword> [options]');\n console.log();\n console.log('Options:');\n console.log(' --from <email> Search by sender');\n console.log(' --to <email> Search by recipient');\n console.log(' --cc <email> Search by CC');\n console.log(' --subject <text> Search by subject');\n console.log(' --folder <name> Search in specific folder');\n console.log(' --date <date> Search from date (YYYY-MM-DD)');\n console.log(' --date-to <date> Search to date (YYYY-MM-DD)');\n console.log(' --starred Search starred emails');\n console.log(' --flagged Search flagged emails');\n console.log(' --unread Search unread emails');\n console.log(' --has-attachment Search emails with attachments');\n console.log(' --no-attachment Search emails without attachments');\n console.log(' --tag <name> Search by tag');\n console.log(' --limit <number> Limit results (default: 100)');\n console.log();\n console.log('Saved searches:');\n console.log(' search save --name <name> Save current search');\n console.log(' search load --name <name> Load saved search');\n console.log(' search list-saved List saved searches');\n console.log(' search delete-saved --name <name> Delete saved search');\n process.exit(1);\n }\n\n // Display search criteria\n console.log(chalk.bold.cyan('Search Criteria:'));\n displaySearchCriteria(query);\n console.log();\n\n console.log(chalk.bold.cyan('Search Results:'));\n console.log();\n\n const emails = emailModel.search(query);\n\n if (emails.length === 0) {\n console.log(chalk.yellow('No emails found matching your criteria.'));\n return;\n }\n\n console.log(formatEmailList(emails));\n console.log();\n console.log(chalk.gray(`Found ${emails.length} email(s)`));\n\n // Store last search for potential saving\n global.lastSearchQuery = query;\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Search command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Build search query from options\n */\nfunction buildSearchQuery(keyword, options) {\n const query = {};\n\n if (\n keyword &&\n keyword !== 'save' &&\n keyword !== 'load' &&\n keyword !== 'list-saved' &&\n keyword !== 'delete-saved'\n ) {\n query.keyword = keyword;\n }\n\n if (options.from) query.from = options.from;\n if (options.to) query.to = options.to;\n if (options.cc) query.cc = options.cc;\n if (options.subject) query.subject = options.subject;\n if (options.folder) query.folder = options.folder;\n if (options.date) query.dateFrom = options.date;\n if (options.dateTo) query.dateTo = options.dateTo;\n if (options.starred) query.starred = true;\n if (options.flagged) query.flagged = true;\n if (options.unread) query.unread = true;\n if (options.hasAttachment) query.hasAttachment = true;\n if (options.noAttachment) query.noAttachment = true;\n if (options.tag) query.tag = options.tag;\n if (options.limit) query.limit = parseInt(options.limit);\n\n return query;\n}\n\n/**\n * Display search criteria\n */\nfunction displaySearchCriteria(query) {\n const criteria = [];\n\n if (query.keyword) criteria.push(`Keyword: \"${query.keyword}\"`);\n if (query.from) criteria.push(`From: ${query.from}`);\n if (query.to) criteria.push(`To: ${query.to}`);\n if (query.cc) criteria.push(`CC: ${query.cc}`);\n if (query.subject) criteria.push(`Subject: ${query.subject}`);\n if (query.folder) criteria.push(`Folder: ${query.folder}`);\n if (query.dateFrom) criteria.push(`From date: ${query.dateFrom}`);\n if (query.dateTo) criteria.push(`To date: ${query.dateTo}`);\n if (query.starred) criteria.push('Starred: Yes');\n if (query.flagged) criteria.push('Flagged: Yes');\n if (query.unread) criteria.push('Unread: Yes');\n if (query.hasAttachment) criteria.push('Has attachment: Yes');\n if (query.noAttachment) criteria.push('Has attachment: No');\n if (query.tag) criteria.push(`Tag: ${query.tag}`);\n if (query.limit) criteria.push(`Limit: ${query.limit}`);\n\n criteria.forEach((c) => console.log(chalk.gray(` ${c}`)));\n}\n\n/**\n * Save current search\n */\nfunction saveSearch(options) {\n if (!options.name) {\n console.error(chalk.red('Error: Search name is required'));\n console.log('Usage: search save --name <name>');\n process.exit(1);\n }\n\n if (!global.lastSearchQuery) {\n console.error(chalk.red('Error: No search to save. Run a search first.'));\n process.exit(1);\n }\n\n try {\n const searchId = savedSearchModel.create({\n name: options.name,\n query: global.lastSearchQuery,\n description: options.description || '',\n });\n\n console.log(\n chalk.green('✓'),\n `Search \"${options.name}\" saved successfully`\n );\n console.log(chalk.gray(` ID: ${searchId}`));\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n}\n\n/**\n * Load saved search\n */\nfunction loadSearch(options) {\n if (!options.name) {\n console.error(chalk.red('Error: Search name is required'));\n console.log('Usage: search load --name <name>');\n process.exit(1);\n }\n\n try {\n const savedSearch = savedSearchModel.findByName(options.name);\n\n if (!savedSearch) {\n console.error(\n chalk.red('Error:'),\n `Saved search \"${options.name}\" not found`\n );\n process.exit(1);\n }\n\n console.log(chalk.bold.cyan(`Loading saved search: \"${savedSearch.name}\"`));\n if (savedSearch.description) {\n console.log(chalk.gray(` ${savedSearch.description}`));\n }\n console.log();\n\n const query = JSON.parse(savedSearch.query);\n\n console.log(chalk.bold.cyan('Search Criteria:'));\n displaySearchCriteria(query);\n console.log();\n\n console.log(chalk.bold.cyan('Search Results:'));\n console.log();\n\n const emails = emailModel.search(query);\n\n if (emails.length === 0) {\n console.log(chalk.yellow('No emails found matching your criteria.'));\n return;\n }\n\n console.log(formatEmailList(emails));\n console.log();\n console.log(chalk.gray(`Found ${emails.length} email(s)`));\n\n // Store for potential re-saving\n global.lastSearchQuery = query;\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n}\n\n/**\n * List saved searches\n */\nfunction listSavedSearches() {\n try {\n const searches = savedSearchModel.findAll();\n\n if (searches.length === 0) {\n console.log(chalk.yellow('No saved searches found.'));\n return;\n }\n\n console.log(chalk.bold.cyan('Saved Searches:'));\n console.log();\n\n searches.forEach((search) => {\n console.log(chalk.bold(search.name));\n console.log(chalk.gray(` ID: ${search.id}`));\n if (search.description) {\n console.log(chalk.gray(` ${search.description}`));\n }\n const query = JSON.parse(search.query);\n const criteriaCount = Object.keys(query).length;\n console.log(chalk.gray(` Criteria: ${criteriaCount} condition(s)`));\n console.log(\n chalk.gray(` Created: ${new Date(search.created_at).toLocaleString()}`)\n );\n console.log();\n });\n\n console.log(chalk.gray(`Total: ${searches.length} saved search(es)`));\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n}\n\n/**\n * Delete saved search\n */\nfunction deleteSavedSearch(options) {\n if (!options.name) {\n console.error(chalk.red('Error: Search name is required'));\n console.log('Usage: search delete-saved --name <name>');\n process.exit(1);\n }\n\n try {\n const savedSearch = savedSearchModel.findByName(options.name);\n\n if (!savedSearch) {\n console.error(\n chalk.red('Error:'),\n `Saved search \"${options.name}\" not found`\n );\n process.exit(1);\n }\n\n savedSearchModel.delete(savedSearch.id);\n console.log(\n chalk.green('✓'),\n `Saved search \"${options.name}\" deleted successfully`\n );\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n}\n\nmodule.exports = searchCommand;\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface SignatureCreateInput {\n name: string;\n contentText?: string | null;\n contentHtml?: string | null;\n isDefault?: boolean;\n accountEmail?: string | null;\n}\n\ninterface SignatureUpdateInput {\n name?: string;\n contentText?: string | null;\n contentHtml?: string | null;\n isDefault?: boolean;\n accountEmail?: string | null;\n}\n\ninterface SignatureRow {\n id: number;\n name: string;\n content_text: string | null;\n content_html: string | null;\n is_default: number;\n account_email: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface SignatureRecord {\n id: number;\n name: string;\n contentText: string | null;\n contentHtml: string | null;\n isDefault: boolean;\n accountEmail: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Signature model.\n */\nexport class SignatureModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(signatureData: SignatureCreateInput): number {\n try {\n const db = this.getDb();\n\n if (signatureData.isDefault && signatureData.accountEmail) {\n this.unsetDefaultForAccount(signatureData.accountEmail);\n }\n\n const stmt = db.prepare(`\n INSERT INTO signatures (\n name, content_text, content_html, is_default, account_email\n ) VALUES (?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n signatureData.name,\n signatureData.contentText ?? null,\n signatureData.contentHtml ?? null,\n signatureData.isDefault ? 1 : 0,\n signatureData.accountEmail ?? null\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Signature created', { id: insertId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create signature', { error: errorMessage });\n throw new StorageError(`Failed to create signature: ${errorMessage}`);\n }\n }\n\n findById(id: number): SignatureRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], SignatureRow>(\n 'SELECT * FROM signatures WHERE id = ?'\n );\n const signature = stmt.get(id);\n return signature ? this.formatSignature(signature) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find signature by ID', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find signature: ${errorMessage}`);\n }\n }\n\n findAll(accountEmail: string | null = null): SignatureRecord[] {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM signatures';\n const params: string[] = [];\n\n if (accountEmail) {\n query += ' WHERE account_email = ? OR account_email IS NULL';\n params.push(accountEmail);\n }\n\n query += ' ORDER BY is_default DESC, created_at DESC';\n\n const stmt = db.prepare<unknown[], SignatureRow>(query);\n const signatures = stmt.all(...params);\n return signatures.map((signature) => this.formatSignature(signature));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find signatures', { error: errorMessage });\n throw new StorageError(`Failed to find signatures: ${errorMessage}`);\n }\n }\n\n findDefault(accountEmail: string | null = null): SignatureRecord | null {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM signatures WHERE is_default = 1';\n const params: string[] = [];\n\n if (accountEmail) {\n query += ' AND (account_email = ? OR account_email IS NULL)';\n params.push(accountEmail);\n }\n\n query += ' ORDER BY account_email DESC LIMIT 1';\n\n const stmt = db.prepare<unknown[], SignatureRow>(query);\n const signature = stmt.get(...params);\n return signature ? this.formatSignature(signature) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find default signature', { error: errorMessage });\n throw new StorageError(\n `Failed to find default signature: ${errorMessage}`\n );\n }\n }\n\n update(id: number, data: SignatureUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number | null> = [];\n\n if (data.name !== undefined) {\n fields.push('name = ?');\n params.push(data.name);\n }\n\n if (data.contentText !== undefined) {\n fields.push('content_text = ?');\n params.push(data.contentText);\n }\n\n if (data.contentHtml !== undefined) {\n fields.push('content_html = ?');\n params.push(data.contentHtml);\n }\n\n if (data.isDefault !== undefined) {\n fields.push('is_default = ?');\n params.push(data.isDefault ? 1 : 0);\n\n if (data.isDefault) {\n const signature = this.findById(id);\n if (signature?.accountEmail) {\n this.unsetDefaultForAccount(signature.accountEmail, id);\n }\n }\n }\n\n if (data.accountEmail !== undefined) {\n fields.push('account_email = ?');\n params.push(data.accountEmail);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE signatures SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Signature updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update signature', { id, error: errorMessage });\n throw new StorageError(`Failed to update signature: ${errorMessage}`);\n }\n }\n\n setAsDefault(id: number): boolean {\n const signature = this.findById(id);\n if (!signature) {\n throw new StorageError('Signature not found');\n }\n\n if (signature.accountEmail) {\n this.unsetDefaultForAccount(signature.accountEmail, id);\n }\n\n return this.update(id, { isDefault: true });\n }\n\n unsetDefaultForAccount(\n accountEmail: string,\n exceptId: number | null = null\n ): void {\n try {\n const db = this.getDb();\n let query =\n 'UPDATE signatures SET is_default = 0 WHERE account_email = ?';\n const params: Array<string | number> = [accountEmail];\n\n if (exceptId) {\n query += ' AND id != ?';\n params.push(exceptId);\n }\n\n const stmt = db.prepare(query);\n stmt.run(...params);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to unset default signatures', {\n error: errorMessage,\n });\n throw new StorageError(\n `Failed to unset default signatures: ${errorMessage}`\n );\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM signatures WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Signature deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete signature', { id, error: errorMessage });\n throw new StorageError(`Failed to delete signature: ${errorMessage}`);\n }\n }\n\n private formatSignature(signature: SignatureRow): SignatureRecord {\n return {\n id: signature.id,\n name: signature.name,\n contentText: signature.content_text,\n contentHtml: signature.content_html,\n isDefault: signature.is_default === 1,\n accountEmail: signature.account_email,\n createdAt: signature.created_at,\n updatedAt: signature.updated_at,\n };\n }\n}\n\nconst signatureModel = new SignatureModel();\nexport default signatureModel;\n","import signatureModel from '../storage/models/signature';\nimport logger from '../utils/logger';\n\n/**\n * Signature Manager\n * Manages email signatures with template variable support\n */\nclass SignatureManager {\n /**\n * Create a new signature\n */\n async create(options) {\n const {\n name,\n text,\n html,\n isDefault = false,\n accountEmail = null,\n } = options;\n\n if (!name) {\n throw new Error('Signature name is required');\n }\n\n if (!text && !html) {\n throw new Error('Signature content (text or html) is required');\n }\n\n const signatureData = {\n name,\n contentText: text,\n contentHtml: html,\n isDefault,\n accountEmail,\n };\n\n const id = signatureModel.create(signatureData);\n logger.info('Signature created', { id, name });\n return id;\n }\n\n /**\n * Get signature by ID\n */\n async getById(id) {\n return signatureModel.findById(id);\n }\n\n /**\n * Get all signatures\n */\n async getAll(accountEmail = null) {\n return signatureModel.findAll(accountEmail);\n }\n\n /**\n * Get default signature for an account\n */\n async getDefault(accountEmail = null) {\n return signatureModel.findDefault(accountEmail);\n }\n\n /**\n * Update signature\n */\n async update(id, options) {\n const signature = signatureModel.findById(id);\n if (!signature) {\n throw new Error(`Signature not found: ${id}`);\n }\n\n const updateData = {};\n\n if (options.name !== undefined) {\n updateData.name = options.name;\n }\n\n if (options.text !== undefined) {\n updateData.contentText = options.text;\n }\n\n if (options.html !== undefined) {\n updateData.contentHtml = options.html;\n }\n\n if (options.isDefault !== undefined) {\n updateData.isDefault = options.isDefault;\n }\n\n if (options.accountEmail !== undefined) {\n updateData.accountEmail = options.accountEmail;\n }\n\n const updated = signatureModel.update(id, updateData);\n if (updated) {\n logger.info('Signature updated', { id });\n }\n return updated;\n }\n\n /**\n * Set signature as default\n */\n async setDefault(id) {\n const result = signatureModel.setAsDefault(id);\n logger.info('Signature set as default', { id });\n return result;\n }\n\n /**\n * Delete signature\n */\n async delete(id) {\n const signature = signatureModel.findById(id);\n if (!signature) {\n throw new Error(`Signature not found: ${id}`);\n }\n\n const deleted = signatureModel.delete(id);\n if (deleted) {\n logger.info('Signature deleted', { id, name: signature.name });\n }\n return deleted;\n }\n\n /**\n * Process signature template variables\n */\n processTemplate(signature, variables = {}) {\n const defaultVars = {\n name: variables.name || '',\n email: variables.email || '',\n date: new Date().toLocaleDateString(),\n time: new Date().toLocaleTimeString(),\n };\n\n const allVars = { ...defaultVars, ...variables };\n\n let processedText = signature.contentText || '';\n let processedHtml = signature.contentHtml || '';\n\n // Replace template variables\n Object.keys(allVars).forEach((key) => {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g');\n processedText = processedText.replace(regex, allVars[key]);\n processedHtml = processedHtml.replace(regex, allVars[key]);\n });\n\n return {\n text: processedText,\n html: processedHtml,\n };\n }\n\n /**\n * Get signature for email composition\n * Returns processed signature with template variables replaced\n */\n async getForEmail(accountEmail = null, variables = {}) {\n const signature = await this.getDefault(accountEmail);\n if (!signature) {\n return null;\n }\n\n return this.processTemplate(signature, variables);\n }\n}\n\nmodule.exports = new SignatureManager();\n","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\n\nimport config from '../../config';\nimport contactManager from '../../contacts/manager';\nimport signatureManager from '../../signatures/manager';\nimport SMTPClient from '../../smtp/client';\nimport EmailComposer from '../../smtp/composer';\nimport logger from '../../utils/logger';\n\n/**\n * Send command - Send email via SMTP\n */\nasync function sendCommand(options) {\n try {\n // Load configuration\n const cfg = config.load();\n if (!cfg.smtp.host || !cfg.smtp.user || !cfg.smtp.password) {\n console.error(\n chalk.red(\n 'SMTP configuration incomplete. Please run: mail-client config'\n )\n );\n process.exit(1);\n }\n\n let emailData;\n\n if (options.to && options.subject && options.body) {\n // Non-interactive mode\n const composer = new EmailComposer();\n composer\n .setTo(options.to.split(',').map((e) => e.trim()))\n .setSubject(options.subject)\n .setBody(options.body);\n\n if (options.cc) {\n composer.setCc(options.cc.split(',').map((e) => e.trim()));\n }\n\n // Add signature if available\n try {\n const signature = await signatureManager.getForEmail(cfg.smtp.user, {\n name: cfg.smtp.user.split('@')[0],\n email: cfg.smtp.user,\n });\n if (signature) {\n composer.addSignature(signature);\n }\n } catch (error) {\n logger.debug('Could not add signature', { error: error.message });\n }\n\n emailData = composer.compose();\n } else {\n // Interactive mode\n emailData = await interactiveSend();\n }\n\n // Send email\n const spinner = ora('Sending email...').start();\n\n const smtpClient = new SMTPClient(cfg.smtp);\n const result = await smtpClient.sendEmail(emailData);\n\n spinner.succeed('Email sent successfully!');\n console.log(chalk.gray(`Message ID: ${result.messageId}`));\n\n // Auto-collect contacts from recipients\n try {\n const recipients = [\n ...(emailData.to || []),\n ...(emailData.cc || []),\n ...(emailData.bcc || []),\n ];\n\n for (const recipient of recipients) {\n await contactManager.autoCollectContact(recipient);\n }\n } catch (error) {\n logger.debug('Failed to auto-collect contacts', { error: error.message });\n }\n\n smtpClient.disconnect();\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Send command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Interactive email sending\n */\nasync function interactiveSend() {\n console.log(chalk.bold.cyan('Compose Email'));\n console.log();\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'to',\n message: 'To (comma-separated):',\n validate: (input) => (input.trim() ? true : 'Recipient is required'),\n },\n {\n type: 'input',\n name: 'cc',\n message: 'CC (comma-separated, optional):',\n },\n {\n type: 'input',\n name: 'subject',\n message: 'Subject:',\n validate: (input) => (input.trim() ? true : 'Subject is required'),\n },\n {\n type: 'editor',\n name: 'body',\n message: 'Body (opens editor):',\n validate: (input) => (input.trim() ? true : 'Body is required'),\n },\n {\n type: 'input',\n name: 'attachments',\n message: 'Attachments (comma-separated file paths, optional):',\n },\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Send this email?',\n default: true,\n },\n ]);\n\n if (!answers.confirm) {\n console.log(chalk.yellow('Email cancelled.'));\n process.exit(0);\n }\n\n const composer = new EmailComposer();\n composer\n .setTo(answers.to.split(',').map((e) => e.trim()))\n .setSubject(answers.subject)\n .setBody(answers.body);\n\n if (answers.cc) {\n composer.setCc(answers.cc.split(',').map((e) => e.trim()));\n }\n\n if (answers.attachments) {\n const files = answers.attachments.split(',').map((f) => f.trim());\n for (const file of files) {\n try {\n composer.addAttachment(file);\n } catch (error) {\n console.error(\n chalk.yellow(\n `Warning: Could not add attachment ${file}: ${error.message}`\n )\n );\n }\n }\n }\n\n // Add signature if available\n try {\n const cfg = config.load();\n const signature = await signatureManager.getForEmail(cfg.smtp.user, {\n name: cfg.smtp.user.split('@')[0],\n email: cfg.smtp.user,\n });\n if (signature) {\n composer.addSignature(signature);\n }\n } catch (error) {\n // Signature is optional, just log the error\n logger.debug('Could not add signature', { error: error.message });\n }\n\n return composer.compose();\n}\n\nmodule.exports = sendCommand;\n","import chalk from 'chalk';\n\nimport signatureManager from '../../signatures/manager';\nimport logger from '../../utils/logger';\n\n/**\n * Signature command handler\n */\nasync function signatureCommand(action, options = {}) {\n try {\n switch (action) {\n case 'create':\n await createSignature(options);\n break;\n case 'list':\n await listSignatures(options);\n break;\n case 'edit':\n await editSignature(options);\n break;\n case 'delete':\n await deleteSignature(options);\n break;\n case 'set-default':\n await setDefaultSignature(options);\n break;\n default:\n console.error(chalk.red(`Unknown action: ${action}`));\n console.log(\n 'Available actions: create, list, edit, delete, set-default'\n );\n process.exit(1);\n }\n } catch (error) {\n logger.error('Signature command failed', { action, error: error.message });\n console.error(chalk.red(`Error: ${error.message}`));\n process.exit(1);\n }\n}\n\n/**\n * Create a new signature\n */\nasync function createSignature(options) {\n const { name, text, html, default: isDefault, account } = options;\n\n if (!name) {\n throw new Error('Signature name is required (--name)');\n }\n\n if (!text && !html) {\n throw new Error('Signature content is required (--text or --html)');\n }\n\n const id = await signatureManager.create({\n name,\n text,\n html,\n isDefault: isDefault || false,\n accountEmail: account,\n });\n\n console.log(chalk.green(`✓ Signature created successfully`));\n console.log(` ID: ${id}`);\n console.log(` Name: ${name}`);\n if (isDefault) {\n console.log(chalk.yellow(' Set as default'));\n }\n}\n\n/**\n * List all signatures\n */\nasync function listSignatures(options) {\n const { account } = options;\n const signatures = await signatureManager.getAll(account);\n\n if (signatures.length === 0) {\n console.log(chalk.yellow('No signatures found'));\n return;\n }\n\n console.log(chalk.bold(`\\nSignatures (${signatures.length}):\\n`));\n\n signatures.forEach((sig) => {\n const defaultBadge = sig.isDefault ? chalk.yellow(' [DEFAULT]') : '';\n const accountInfo = sig.accountEmail\n ? chalk.gray(` (${sig.accountEmail})`)\n : '';\n\n console.log(\n `${chalk.cyan(`#${sig.id}`)} ${chalk.bold(sig.name)}${defaultBadge}${accountInfo}`\n );\n\n if (sig.contentText) {\n const preview = sig.contentText.substring(0, 60);\n console.log(\n chalk.gray(\n ` Text: ${preview}${sig.contentText.length > 60 ? '...' : ''}`\n )\n );\n }\n\n if (sig.contentHtml) {\n console.log(chalk.gray(` HTML: Yes`));\n }\n\n console.log(\n chalk.gray(` Created: ${new Date(sig.createdAt).toLocaleString()}`)\n );\n console.log();\n });\n}\n\n/**\n * Edit a signature\n */\nasync function editSignature(options) {\n const { id, name, text, html, default: isDefault, account } = options;\n\n if (!id) {\n throw new Error('Signature ID is required (--id)');\n }\n\n const updateData = {};\n\n if (name !== undefined) updateData.name = name;\n if (text !== undefined) updateData.text = text;\n if (html !== undefined) updateData.html = html;\n if (isDefault !== undefined) updateData.isDefault = isDefault;\n if (account !== undefined) updateData.accountEmail = account;\n\n if (Object.keys(updateData).length === 0) {\n throw new Error('No update data provided');\n }\n\n const updated = await signatureManager.update(id, updateData);\n\n if (updated) {\n console.log(chalk.green(`✓ Signature #${id} updated successfully`));\n } else {\n console.log(chalk.yellow(`No changes made to signature #${id}`));\n }\n}\n\n/**\n * Delete a signature\n */\nasync function deleteSignature(options) {\n const { id } = options;\n\n if (!id) {\n throw new Error('Signature ID is required (--id)');\n }\n\n const deleted = await signatureManager.delete(id);\n\n if (deleted) {\n console.log(chalk.green(`✓ Signature #${id} deleted successfully`));\n } else {\n console.log(chalk.yellow(`Signature #${id} not found`));\n }\n}\n\n/**\n * Set signature as default\n */\nasync function setDefaultSignature(options) {\n const { id } = options;\n\n if (!id) {\n throw new Error('Signature ID is required (--id)');\n }\n\n await signatureManager.setDefault(id);\n console.log(chalk.green(`✓ Signature #${id} set as default`));\n}\n\nmodule.exports = signatureCommand;\n","import spamFilter from '../../spam/filter';\nimport emailModel from '../../storage/models/email';\nimport spamModel from '../../storage/models/spam';\nimport logger from '../../utils/logger';\nimport { formatTable } from '../utils/formatter';\n\n/**\n * Spam management commands\n */\n\n/**\n * Mark email as spam\n */\nasync function markAsSpam(emailId) {\n try {\n const email = await emailModel.findById(emailId);\n if (!email) {\n console.error(`Error: Email with ID ${emailId} not found`);\n return;\n }\n\n await emailModel.markAsSpam(emailId);\n console.log(`Email #${emailId} marked as spam`);\n\n // Learn from user feedback\n await spamFilter.learnFromFeedback(emailId, true);\n console.log('Spam filter updated based on your feedback');\n } catch (error) {\n console.error('Failed to mark email as spam:', error.message);\n logger.error('Mark as spam failed', { emailId, error: error.message });\n }\n}\n\n/**\n * Unmark email as spam\n */\nasync function unmarkAsSpam(emailId) {\n try {\n const email = await emailModel.findById(emailId);\n if (!email) {\n console.error(`Error: Email with ID ${emailId} not found`);\n return;\n }\n\n await emailModel.unmarkAsSpam(emailId);\n console.log(`Email #${emailId} unmarked as spam`);\n\n // Learn from user feedback\n await spamFilter.learnFromFeedback(emailId, false);\n console.log('Spam filter updated based on your feedback');\n } catch (error) {\n console.error('Failed to unmark email as spam:', error.message);\n logger.error('Unmark as spam failed', { emailId, error: error.message });\n }\n}\n\n/**\n * List spam emails\n */\nasync function listSpam(options = {}) {\n try {\n const { limit = 20, offset = 0 } = options;\n const spamEmails = await emailModel.findSpam({ limit, offset });\n const totalCount = await emailModel.countSpam();\n\n if (spamEmails.length === 0) {\n console.log('No spam emails found');\n return;\n }\n\n console.log(`\\nSpam Emails (${spamEmails.length} of ${totalCount}):\\n`);\n\n const tableData = spamEmails.map((email) => ({\n ID: email.id,\n From: email.from.substring(0, 30),\n Subject: email.subject.substring(0, 40),\n Date: new Date(email.date).toLocaleDateString(),\n }));\n\n console.log(formatTable(tableData));\n } catch (error) {\n console.error('Failed to list spam emails:', error.message);\n logger.error('List spam failed', { error: error.message });\n }\n}\n\n/**\n * Add email to blacklist\n */\nasync function addToBlacklist(emailAddress, reason) {\n try {\n await spamModel.addToBlacklist(emailAddress, reason);\n console.log(`Added ${emailAddress} to blacklist`);\n\n if (reason) {\n console.log(`Reason: ${reason}`);\n }\n } catch (error) {\n console.error('Failed to add to blacklist:', error.message);\n logger.error('Add to blacklist failed', {\n emailAddress,\n error: error.message,\n });\n }\n}\n\n/**\n * Remove email from blacklist\n */\nasync function removeFromBlacklist(emailAddress) {\n try {\n const removed = await spamModel.removeFromBlacklist(emailAddress);\n\n if (removed) {\n console.log(`Removed ${emailAddress} from blacklist`);\n } else {\n console.log(`${emailAddress} was not in blacklist`);\n }\n } catch (error) {\n console.error('Failed to remove from blacklist:', error.message);\n logger.error('Remove from blacklist failed', {\n emailAddress,\n error: error.message,\n });\n }\n}\n\n/**\n * List blacklist\n */\nasync function listBlacklist() {\n try {\n const blacklist = await spamModel.getBlacklist();\n\n if (blacklist.length === 0) {\n console.log('Blacklist is empty');\n return;\n }\n\n console.log(`\\nBlacklist (${blacklist.length} entries):\\n`);\n\n const tableData = blacklist.map((entry) => ({\n ID: entry.id,\n Email: entry.email_address,\n Domain: entry.domain || 'N/A',\n Reason: (entry.reason || 'N/A').substring(0, 30),\n Added: new Date(entry.created_at).toLocaleDateString(),\n }));\n\n console.log(formatTable(tableData));\n } catch (error) {\n console.error('Failed to list blacklist:', error.message);\n logger.error('List blacklist failed', { error: error.message });\n }\n}\n\n/**\n * Add email to whitelist\n */\nasync function addToWhitelist(emailAddress) {\n try {\n await spamModel.addToWhitelist(emailAddress);\n console.log(`Added ${emailAddress} to whitelist`);\n } catch (error) {\n console.error('Failed to add to whitelist:', error.message);\n logger.error('Add to whitelist failed', {\n emailAddress,\n error: error.message,\n });\n }\n}\n\n/**\n * Remove email from whitelist\n */\nasync function removeFromWhitelist(emailAddress) {\n try {\n const removed = await spamModel.removeFromWhitelist(emailAddress);\n\n if (removed) {\n console.log(`Removed ${emailAddress} from whitelist`);\n } else {\n console.log(`${emailAddress} was not in whitelist`);\n }\n } catch (error) {\n console.error('Failed to remove from whitelist:', error.message);\n logger.error('Remove from whitelist failed', {\n emailAddress,\n error: error.message,\n });\n }\n}\n\n/**\n * List whitelist\n */\nasync function listWhitelist() {\n try {\n const whitelist = await spamModel.getWhitelist();\n\n if (whitelist.length === 0) {\n console.log('Whitelist is empty');\n return;\n }\n\n console.log(`\\nWhitelist (${whitelist.length} entries):\\n`);\n\n const tableData = whitelist.map((entry) => ({\n ID: entry.id,\n Email: entry.email_address,\n Domain: entry.domain || 'N/A',\n Added: new Date(entry.created_at).toLocaleDateString(),\n }));\n\n console.log(formatTable(tableData));\n } catch (error) {\n console.error('Failed to list whitelist:', error.message);\n logger.error('List whitelist failed', { error: error.message });\n }\n}\n\n/**\n * Run spam filter on inbox\n */\nasync function runFilter(options = {}) {\n try {\n console.log('Initializing spam filter...');\n await spamFilter.initialize();\n\n console.log('Scanning inbox for spam...');\n\n // Get all non-spam, non-deleted emails\n const emails = await emailModel.findByFolder('INBOX', { limit: 100 });\n const unscannedEmails = emails.filter((e) => !e.isSpam && !e.isDeleted);\n\n if (unscannedEmails.length === 0) {\n console.log('No emails to scan');\n return;\n }\n\n console.log(`Scanning ${unscannedEmails.length} emails...`);\n\n let spamCount = 0;\n for (const email of unscannedEmails) {\n const result = await spamFilter.filterEmail(email.id);\n if (result.isSpam) {\n spamCount++;\n console.log(\n ` [SPAM] Email #${email.id}: ${email.subject.substring(0, 50)}`\n );\n console.log(\n ` Score: ${result.score}, Reasons: ${result.reasons.join(', ')}`\n );\n }\n }\n\n console.log(`\\nScan complete: ${spamCount} spam emails detected`);\n } catch (error) {\n console.error('Failed to run spam filter:', error.message);\n logger.error('Run filter failed', { error: error.message });\n }\n}\n\n/**\n * Show spam statistics\n */\nasync function showStatistics() {\n try {\n await spamFilter.initialize();\n const stats = await spamFilter.getStatistics();\n\n console.log('\\nSpam Filter Statistics:\\n');\n console.log(` Spam emails: ${stats.spamCount}`);\n console.log(` Blacklist entries: ${stats.blacklistCount}`);\n console.log(` Whitelist entries: ${stats.whitelistCount}`);\n console.log(` Active rules: ${stats.rulesCount}`);\n console.log(` Detection threshold: ${stats.threshold}`);\n } catch (error) {\n console.error('Failed to get statistics:', error.message);\n logger.error('Get statistics failed', { error: error.message });\n }\n}\n\n/**\n * Main spam command handler\n */\nasync function spamCommand(action, ...args) {\n try {\n switch (action) {\n case 'mark':\n if (!args[0]) {\n console.error('Usage: mail-client spam mark <email-id>');\n return;\n }\n await markAsSpam(parseInt(args[0]));\n break;\n\n case 'unmark':\n if (!args[0]) {\n console.error('Usage: mail-client spam unmark <email-id>');\n return;\n }\n await unmarkAsSpam(parseInt(args[0]));\n break;\n\n case 'list':\n await listSpam();\n break;\n\n case 'blacklist':\n const blacklistAction = args[0];\n if (blacklistAction === 'add') {\n if (!args[1]) {\n console.error(\n 'Usage: mail-client spam blacklist add <email> [reason]'\n );\n return;\n }\n await addToBlacklist(args[1], args.slice(2).join(' '));\n } else if (blacklistAction === 'remove') {\n if (!args[1]) {\n console.error('Usage: mail-client spam blacklist remove <email>');\n return;\n }\n await removeFromBlacklist(args[1]);\n } else if (blacklistAction === 'list') {\n await listBlacklist();\n } else {\n console.error(\n 'Usage: mail-client spam blacklist <add|remove|list> [email]'\n );\n }\n break;\n\n case 'whitelist':\n const whitelistAction = args[0];\n if (whitelistAction === 'add') {\n if (!args[1]) {\n console.error('Usage: mail-client spam whitelist add <email>');\n return;\n }\n await addToWhitelist(args[1]);\n } else if (whitelistAction === 'remove') {\n if (!args[1]) {\n console.error('Usage: mail-client spam whitelist remove <email>');\n return;\n }\n await removeFromWhitelist(args[1]);\n } else if (whitelistAction === 'list') {\n await listWhitelist();\n } else {\n console.error(\n 'Usage: mail-client spam whitelist <add|remove|list> [email]'\n );\n }\n break;\n\n case 'filter':\n await runFilter();\n break;\n\n case 'stats':\n await showStatistics();\n break;\n\n default:\n console.log('Spam Management Commands:');\n console.log(\n ' mail-client spam mark <email-id> - Mark email as spam'\n );\n console.log(\n ' mail-client spam unmark <email-id> - Unmark email as spam'\n );\n console.log(\n ' mail-client spam list - List spam emails'\n );\n console.log(\n ' mail-client spam blacklist add <email> - Add to blacklist'\n );\n console.log(\n ' mail-client spam blacklist remove <email> - Remove from blacklist'\n );\n console.log(\n ' mail-client spam blacklist list - List blacklist'\n );\n console.log(\n ' mail-client spam whitelist add <email> - Add to whitelist'\n );\n console.log(\n ' mail-client spam whitelist remove <email> - Remove from whitelist'\n );\n console.log(\n ' mail-client spam whitelist list - List whitelist'\n );\n console.log(\n ' mail-client spam filter - Run spam filter on inbox'\n );\n console.log(\n ' mail-client spam stats - Show spam statistics'\n );\n }\n } catch (error) {\n console.error('Spam command failed:', error.message);\n logger.error('Spam command failed', { action, error: error.message });\n }\n}\n\nmodule.exports = spamCommand;\n","import database from '../storage/database';\nimport logger from '../utils/logger';\n\n/**\n * Account Manager for Sync\n * Handles account-specific sync configuration\n */\nclass AccountManager {\n constructor() {\n this.db = null;\n }\n\n _getDb() {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n /**\n * Get account by ID or email\n */\n getAccount(identifier) {\n try {\n const db = this._getDb();\n let query;\n if (typeof identifier === 'number') {\n query = db.prepare(\n 'SELECT * FROM accounts WHERE id = ? AND is_enabled = 1'\n );\n } else {\n query = db.prepare(\n 'SELECT * FROM accounts WHERE email = ? AND is_enabled = 1'\n );\n }\n\n const account = query.get(identifier);\n return account || null;\n } catch (error) {\n logger.error('Failed to get account', {\n identifier,\n error: error.message,\n });\n return null;\n }\n }\n\n /**\n * Get all enabled accounts\n */\n getAllAccounts() {\n try {\n const db = this._getDb();\n const query = db.prepare(\n 'SELECT * FROM accounts WHERE is_enabled = 1 ORDER BY is_default DESC, email ASC'\n );\n return query.all();\n } catch (error) {\n logger.error('Failed to get all accounts', { error: error.message });\n return [];\n }\n }\n\n /**\n * Get default account\n */\n getDefaultAccount() {\n try {\n const db = this._getDb();\n const query = db.prepare(\n 'SELECT * FROM accounts WHERE is_default = 1 AND is_enabled = 1 LIMIT 1'\n );\n return query.get() || null;\n } catch (error) {\n logger.error('Failed to get default account', { error: error.message });\n return null;\n }\n }\n\n /**\n * Get IMAP config for account\n */\n getImapConfig(accountId) {\n const account = this.getAccount(accountId);\n if (!account) {\n return null;\n }\n\n return {\n host: account.imap_host,\n port: account.imap_port,\n secure: account.imap_secure === 1,\n user: account.username,\n password: account.password,\n accountId: account.id,\n accountEmail: account.email,\n };\n }\n\n /**\n * Get sync interval for account\n */\n getSyncInterval(accountId) {\n const account = this.getAccount(accountId);\n if (!account || !account.sync_interval) {\n return 300000; // Default 5 minutes\n }\n return account.sync_interval * 1000; // Convert seconds to milliseconds\n }\n\n /**\n * Update last sync time for account\n */\n updateLastSync(accountId) {\n try {\n const db = this._getDb();\n const query = db.prepare(\n 'UPDATE accounts SET last_sync = CURRENT_TIMESTAMP WHERE id = ?'\n );\n query.run(accountId);\n logger.debug('Updated last sync time', { accountId });\n } catch (error) {\n logger.error('Failed to update last sync time', {\n accountId,\n error: error.message,\n });\n }\n }\n\n /**\n * Check if accounts table exists\n */\n accountsTableExists() {\n try {\n const db = this._getDb();\n const query = db.prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name='accounts'\"\n );\n const result = query.get();\n return !!result;\n } catch (error) {\n logger.error('Failed to check accounts table', { error: error.message });\n return false;\n }\n }\n\n /**\n * Get account-specific folders\n */\n getAccountFolders(accountId) {\n try {\n const db = this._getDb();\n const query = db.prepare(\n 'SELECT name FROM folders WHERE account_id = ? OR account_id IS NULL ORDER BY name'\n );\n const folders = query.all(accountId);\n return folders.map((f) => f.name);\n } catch (error) {\n logger.error('Failed to get account folders', {\n accountId,\n error: error.message,\n });\n return ['INBOX']; // Default fallback\n }\n }\n}\n\nmodule.exports = new AccountManager();\n","import { spawn } from 'child_process';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { getDataDir } from '../utils/helpers';\nimport logger from '../utils/logger';\n\n/**\n * Sync Daemon Manager\n * Manages background sync process using child_process\n */\nclass SyncDaemon {\n constructor() {\n this.dataDir = getDataDir();\n this.pidFile = path.join(this.dataDir, 'sync-daemon.pid');\n this.logFile = path.join(this.dataDir, 'sync-daemon.log');\n this.workerScript = path.join(__dirname, 'daemon-worker.js');\n }\n\n /**\n * Start daemon process\n */\n async start(options = {}) {\n // Check if already running\n if (this.isRunning()) {\n const pid = this._readPidFile();\n throw new Error(`Daemon already running with PID ${pid}`);\n }\n\n logger.info('Starting sync daemon', options);\n\n // Ensure data directory exists\n if (!fs.existsSync(this.dataDir)) {\n fs.mkdirSync(this.dataDir, { recursive: true });\n }\n\n // Prepare daemon options\n const daemonOptions = {\n interval: options.interval || 300000, // 5 minutes default\n folders: options.folders || ['INBOX'],\n account: options.account || null,\n };\n\n // Spawn detached child process\n const child = spawn(\n process.execPath,\n [this.workerScript, JSON.stringify(daemonOptions)],\n {\n detached: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: process.cwd(),\n env: process.env,\n }\n );\n\n // Write PID file\n this._writePidFile(child.pid);\n\n // Setup log file streaming\n const logStream = fs.createWriteStream(this.logFile, { flags: 'a' });\n child.stdout.pipe(logStream);\n child.stderr.pipe(logStream);\n\n // Detach from parent\n child.unref();\n\n logger.info('Sync daemon started', { pid: child.pid });\n\n return {\n pid: child.pid,\n logFile: this.logFile,\n options: daemonOptions,\n };\n }\n\n /**\n * Stop daemon process\n */\n async stop() {\n if (!this.isRunning()) {\n throw new Error('Daemon is not running');\n }\n\n const pid = this._readPidFile();\n logger.info('Stopping sync daemon', { pid });\n\n try {\n // Send SIGTERM to gracefully stop\n process.kill(pid, 'SIGTERM');\n\n // Wait for process to exit\n await this._waitForProcessExit(pid, 5000);\n\n // Remove PID file\n this._removePidFile();\n\n logger.info('Sync daemon stopped', { pid });\n return { success: true, pid };\n } catch (error) {\n logger.error('Failed to stop daemon', { pid, error: error.message });\n\n // Try force kill\n try {\n process.kill(pid, 'SIGKILL');\n this._removePidFile();\n logger.warn('Daemon force killed', { pid });\n return { success: true, pid, forcedKill: true };\n } catch (killError) {\n // Process might already be dead\n this._removePidFile();\n throw new Error(`Failed to stop daemon: ${error.message}`);\n }\n }\n }\n\n /**\n * Get daemon status\n */\n getStatus() {\n const isRunning = this.isRunning();\n const pid = isRunning ? this._readPidFile() : null;\n\n const status = {\n isRunning,\n pid,\n pidFile: this.pidFile,\n logFile: this.logFile,\n };\n\n // Get last sync info from log if available\n if (fs.existsSync(this.logFile)) {\n status.logSize = fs.statSync(this.logFile).size;\n status.lastModified = fs.statSync(this.logFile).mtime;\n }\n\n return status;\n }\n\n /**\n * Get daemon logs\n */\n getLogs(lines = 50) {\n if (!fs.existsSync(this.logFile)) {\n return '';\n }\n\n const content = fs.readFileSync(this.logFile, 'utf8');\n const logLines = content.split('\\n').filter((line) => line.trim());\n\n // Return last N lines\n return logLines.slice(-lines).join('\\n');\n }\n\n /**\n * Clear daemon logs\n */\n clearLogs() {\n if (fs.existsSync(this.logFile)) {\n fs.writeFileSync(this.logFile, '');\n logger.info('Daemon logs cleared');\n }\n }\n\n /**\n * Check if daemon is running\n */\n isRunning() {\n if (!fs.existsSync(this.pidFile)) {\n return false;\n }\n\n const pid = this._readPidFile();\n if (!pid) {\n return false;\n }\n\n try {\n // Check if process exists (signal 0 doesn't kill, just checks)\n process.kill(pid, 0);\n return true;\n } catch (error) {\n // Process doesn't exist, clean up stale PID file\n this._removePidFile();\n return false;\n }\n }\n\n /**\n * Write PID file\n * @private\n */\n _writePidFile(pid) {\n fs.writeFileSync(this.pidFile, pid.toString(), 'utf8');\n }\n\n /**\n * Read PID file\n * @private\n */\n _readPidFile() {\n try {\n const content = fs.readFileSync(this.pidFile, 'utf8');\n return parseInt(content.trim(), 10);\n } catch (error) {\n return null;\n }\n }\n\n /**\n * Remove PID file\n * @private\n */\n _removePidFile() {\n if (fs.existsSync(this.pidFile)) {\n fs.unlinkSync(this.pidFile);\n }\n }\n\n /**\n * Wait for process to exit\n * @private\n */\n _waitForProcessExit(pid, timeout = 5000) {\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n const checkInterval = 100;\n\n const check = () => {\n try {\n process.kill(pid, 0);\n // Process still exists\n if (Date.now() - startTime > timeout) {\n reject(new Error('Timeout waiting for process to exit'));\n } else {\n setTimeout(check, checkInterval);\n }\n } catch (error) {\n // Process doesn't exist anymore\n resolve();\n }\n };\n\n check();\n });\n }\n}\n\nmodule.exports = SyncDaemon;\n","import EventEmitter from 'events';\n\nimport config from '../config';\nimport accountManager from './account-manager';\nimport IMAPSync from '../imap/sync';\nimport { SyncError } from '../utils/errors';\nimport logger from '../utils/logger';\n\n/**\n * Sync Scheduler\n * Manages automatic email synchronization at configured intervals\n */\nclass SyncScheduler extends EventEmitter {\n constructor(options = {}) {\n super();\n this.config = options.config || config.load();\n this.interval = options.interval || this.config.sync.syncInterval || 300000; // Default: 5 minutes\n this.folders = options.folders || this.config.sync.folders || ['INBOX'];\n this.account = options.account || null; // For multi-account support\n this.isRunning = false;\n this.timer = null;\n this.syncManager = null;\n this.lastSyncTime = null;\n this.lastSyncResult = null;\n this.stats = {\n totalSyncs: 0,\n successfulSyncs: 0,\n failedSyncs: 0,\n totalNewEmails: 0,\n totalErrors: 0,\n };\n }\n\n /**\n * Start automatic synchronization\n */\n async start() {\n if (this.isRunning) {\n logger.warn('Scheduler already running');\n return;\n }\n\n logger.info('Starting sync scheduler', {\n interval: this.interval,\n folders: this.folders,\n account: this.account,\n });\n\n this.isRunning = true;\n this.emit('started', { interval: this.interval, folders: this.folders });\n\n // Run initial sync\n await this._runSync();\n\n // Schedule periodic syncs\n this._scheduleNextSync();\n }\n\n /**\n * Stop automatic synchronization\n */\n stop() {\n if (!this.isRunning) {\n logger.warn('Scheduler not running');\n return;\n }\n\n logger.info('Stopping sync scheduler');\n\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n this.isRunning = false;\n this.emit('stopped');\n }\n\n /**\n * Get scheduler status\n */\n getStatus() {\n return {\n isRunning: this.isRunning,\n interval: this.interval,\n folders: this.folders,\n account: this.account,\n lastSyncTime: this.lastSyncTime,\n lastSyncResult: this.lastSyncResult,\n stats: this.stats,\n nextSyncIn: this.timer ? this.interval : null,\n };\n }\n\n /**\n * Update sync interval\n */\n setInterval(newInterval) {\n if (newInterval < 60000) {\n // Minimum 1 minute\n throw new Error('Sync interval must be at least 60000ms (1 minute)');\n }\n\n logger.info('Updating sync interval', {\n old: this.interval,\n new: newInterval,\n });\n this.interval = newInterval;\n\n // Reschedule if running\n if (this.isRunning) {\n if (this.timer) {\n clearTimeout(this.timer);\n }\n this._scheduleNextSync();\n }\n }\n\n /**\n * Update folders to sync\n */\n setFolders(folders) {\n if (!Array.isArray(folders) || folders.length === 0) {\n throw new Error('Folders must be a non-empty array');\n }\n\n logger.info('Updating sync folders', { old: this.folders, new: folders });\n this.folders = folders;\n }\n\n /**\n * Run sync immediately (manual trigger)\n */\n async syncNow() {\n if (!this.isRunning) {\n throw new Error('Scheduler not running. Start it first with start()');\n }\n\n logger.info('Manual sync triggered');\n await this._runSync();\n }\n\n /**\n * Schedule next sync\n * @private\n */\n _scheduleNextSync() {\n this.timer = setTimeout(async () => {\n await this._runSync();\n if (this.isRunning) {\n this._scheduleNextSync();\n }\n }, this.interval);\n }\n\n /**\n * Run synchronization\n * @private\n */\n async _runSync() {\n const syncStartTime = Date.now();\n this.stats.totalSyncs++;\n\n try {\n logger.info('Running scheduled sync', {\n folders: this.folders,\n account: this.account,\n });\n\n this.emit('sync-start', { folders: this.folders, account: this.account });\n\n // Create sync manager if not exists\n if (!this.syncManager) {\n const imapConfig = this.account\n ? this._getAccountConfig(this.account)\n : this.config.imap;\n this.syncManager = new IMAPSync(imapConfig);\n }\n\n // Run sync\n const results = await this.syncManager.syncFolders(this.folders);\n\n // Update stats\n this.stats.successfulSyncs++;\n this.stats.totalNewEmails += results.totalNew || 0;\n this.stats.totalErrors += results.totalErrors || 0;\n\n // Store results\n this.lastSyncTime = new Date().toISOString();\n this.lastSyncResult = {\n success: true,\n ...results,\n duration: Date.now() - syncStartTime,\n };\n\n logger.info('Scheduled sync completed', {\n duration: Date.now() - syncStartTime,\n newEmails: results.totalNew,\n errors: results.totalErrors,\n });\n\n this.emit('sync-complete', this.lastSyncResult);\n } catch (error) {\n this.stats.failedSyncs++;\n\n this.lastSyncTime = new Date().toISOString();\n this.lastSyncResult = {\n success: false,\n error: error.message,\n duration: Date.now() - syncStartTime,\n };\n\n logger.error('Scheduled sync failed', {\n error: error.message,\n duration: Date.now() - syncStartTime,\n });\n\n this.emit('sync-error', { error: error.message });\n }\n }\n\n /**\n * Get account-specific IMAP config\n * @private\n */\n _getAccountConfig(accountId) {\n // Try to get account from database if accounts table exists\n if (accountManager.accountsTableExists()) {\n const imapConfig = accountManager.getImapConfig(accountId);\n if (imapConfig) {\n logger.info('Using account-specific IMAP config', { accountId });\n return imapConfig;\n }\n }\n\n // Fallback to default config\n logger.warn(\n 'Account not found or accounts table not available, using default config',\n { accountId }\n );\n return this.config.imap;\n }\n}\n\nmodule.exports = SyncScheduler;\n","import chalk from 'chalk';\nimport ora from 'ora';\n\nimport config from '../../config';\nimport IMAPSync from '../../imap/sync';\nimport accountManager from '../../sync/account-manager';\nimport SyncDaemon from '../../sync/daemon';\nimport SyncScheduler from '../../sync/scheduler';\nimport logger from '../../utils/logger';\nimport { formatSyncResults } from '../utils/formatter';\n\n/**\n * Sync command - Synchronize emails from IMAP server\n */\nasync function syncCommand(action, options = {}) {\n // Handle daemon subcommands\n if (action === 'daemon') {\n return handleDaemonCommand(options);\n }\n\n // Handle auto sync mode\n if (options.auto) {\n return handleAutoSync(options);\n }\n\n // Handle regular sync\n return handleRegularSync(action, options);\n}\n\n/**\n * Handle regular sync operation\n */\nasync function handleRegularSync(action, options) {\n const spinner = ora('Initializing sync...').start();\n\n try {\n // Load configuration\n const cfg = config.load();\n if (!cfg.imap.host || !cfg.imap.user || !cfg.imap.password) {\n spinner.fail('Configuration incomplete. Please run: mail-client config');\n process.exit(1);\n }\n\n // Determine folders to sync\n let folders = cfg.sync.folders || ['INBOX'];\n\n // Support --folders option for multiple folders\n if (options.folders) {\n folders = options.folders.split(',').map((f) => f.trim());\n } else if (options.folder) {\n folders = [options.folder];\n }\n\n // Filter by account if specified\n const account = options.account || null;\n\n spinner.text = `Syncing folders: ${folders.join(', ')}`;\n\n // Create sync manager and sync\n const imapConfig = account ? getAccountConfig(cfg, account) : cfg.imap;\n const syncManager = new IMAPSync(imapConfig);\n\n // Apply date filter if specified\n if (options.since) {\n // TODO: Implement date filtering in IMAPSync\n spinner.info(\n `Date filtering (--since) will be implemented in future version`\n );\n }\n\n const results = await syncManager.syncFolders(folders);\n\n spinner.succeed('Sync completed');\n console.log();\n console.log(formatSyncResults(results));\n\n // Display sync statistics\n displaySyncStats(results);\n } catch (error) {\n spinner.fail('Sync failed');\n console.error(chalk.red('Error:'), error.message);\n logger.error('Sync command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Handle auto sync mode\n */\nasync function handleAutoSync(options) {\n console.log(chalk.blue('Starting automatic sync mode...'));\n\n try {\n const cfg = config.load();\n\n // Determine sync interval\n const interval = options.interval\n ? parseInt(options.interval) * 60000 // Convert minutes to milliseconds\n : cfg.sync.syncInterval || 300000;\n\n // Determine folders\n const folders = options.folders\n ? options.folders.split(',').map((f) => f.trim())\n : cfg.sync.folders || ['INBOX'];\n\n const account = options.account || null;\n\n // Create and start scheduler\n const scheduler = new SyncScheduler({\n config: cfg,\n interval,\n folders,\n account,\n });\n\n // Setup event handlers\n scheduler.on('started', (info) => {\n console.log(chalk.green('✓ Auto sync started'));\n console.log(chalk.gray(` Interval: ${info.interval / 1000}s`));\n console.log(chalk.gray(` Folders: ${info.folders.join(', ')}`));\n console.log();\n console.log(chalk.yellow('Press Ctrl+C to stop'));\n });\n\n scheduler.on('sync-start', (info) => {\n console.log(\n chalk.blue(`[${new Date().toLocaleTimeString()}] Syncing...`)\n );\n });\n\n scheduler.on('sync-complete', (result) => {\n console.log(\n chalk.green(`[${new Date().toLocaleTimeString()}] ✓ Sync completed`)\n );\n console.log(chalk.gray(` New emails: ${result.totalNew}`));\n console.log(chalk.gray(` Duration: ${result.duration}ms`));\n if (result.spamDetected > 0) {\n console.log(chalk.yellow(` Spam detected: ${result.spamDetected}`));\n }\n console.log();\n });\n\n scheduler.on('sync-error', (error) => {\n console.error(\n chalk.red(\n `[${new Date().toLocaleTimeString()}] ✗ Sync failed: ${error.error}`\n )\n );\n console.log();\n });\n\n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log();\n console.log(chalk.yellow('Stopping auto sync...'));\n scheduler.stop();\n\n const stats = scheduler.getStatus().stats;\n console.log();\n console.log(chalk.blue('Auto Sync Statistics:'));\n console.log(chalk.gray(` Total syncs: ${stats.totalSyncs}`));\n console.log(chalk.gray(` Successful: ${stats.successfulSyncs}`));\n console.log(chalk.gray(` Failed: ${stats.failedSyncs}`));\n console.log(chalk.gray(` Total new emails: ${stats.totalNewEmails}`));\n\n process.exit(0);\n });\n\n await scheduler.start();\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Auto sync failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Handle daemon subcommands\n */\nasync function handleDaemonCommand(options) {\n const daemon = new SyncDaemon();\n const subcommand = options.subcommand || 'status';\n\n try {\n switch (subcommand) {\n case 'start':\n await handleDaemonStart(daemon, options);\n break;\n\n case 'stop':\n await handleDaemonStop(daemon);\n break;\n\n case 'status':\n handleDaemonStatus(daemon);\n break;\n\n case 'logs':\n handleDaemonLogs(daemon, options);\n break;\n\n default:\n console.error(chalk.red(`Unknown daemon command: ${subcommand}`));\n console.log('Available commands: start, stop, status, logs');\n process.exit(1);\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Daemon command failed', { subcommand, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Start daemon\n */\nasync function handleDaemonStart(daemon, options) {\n const spinner = ora('Starting sync daemon...').start();\n\n try {\n const cfg = config.load();\n\n const daemonOptions = {\n interval: options.interval\n ? parseInt(options.interval) * 60000\n : cfg.sync.syncInterval || 300000,\n folders: options.folders\n ? options.folders.split(',').map((f) => f.trim())\n : cfg.sync.folders || ['INBOX'],\n account: options.account || null,\n };\n\n const result = await daemon.start(daemonOptions);\n\n spinner.succeed('Sync daemon started');\n console.log();\n console.log(chalk.blue('Daemon Information:'));\n console.log(chalk.gray(` PID: ${result.pid}`));\n console.log(chalk.gray(` Log file: ${result.logFile}`));\n console.log(chalk.gray(` Interval: ${result.options.interval / 1000}s`));\n console.log(chalk.gray(` Folders: ${result.options.folders.join(', ')}`));\n console.log();\n console.log(chalk.yellow('Use \"sync daemon logs\" to view logs'));\n console.log(chalk.yellow('Use \"sync daemon stop\" to stop the daemon'));\n } catch (error) {\n spinner.fail('Failed to start daemon');\n throw error;\n }\n}\n\n/**\n * Stop daemon\n */\nasync function handleDaemonStop(daemon) {\n const spinner = ora('Stopping sync daemon...').start();\n\n try {\n const result = await daemon.stop();\n\n spinner.succeed('Sync daemon stopped');\n console.log();\n console.log(chalk.gray(` PID: ${result.pid}`));\n if (result.forcedKill) {\n console.log(chalk.yellow(' (Force killed)'));\n }\n } catch (error) {\n spinner.fail('Failed to stop daemon');\n throw error;\n }\n}\n\n/**\n * Show daemon status\n */\nfunction handleDaemonStatus(daemon) {\n const status = daemon.getStatus();\n\n console.log(chalk.blue('Sync Daemon Status:'));\n console.log();\n\n if (status.isRunning) {\n console.log(chalk.green('✓ Running'));\n console.log(chalk.gray(` PID: ${status.pid}`));\n console.log(chalk.gray(` Log file: ${status.logFile}`));\n if (status.logSize !== undefined) {\n console.log(chalk.gray(` Log size: ${formatBytes(status.logSize)}`));\n console.log(\n chalk.gray(` Last activity: ${status.lastModified.toLocaleString()}`)\n );\n }\n } else {\n console.log(chalk.yellow('✗ Not running'));\n }\n\n console.log();\n console.log(chalk.gray(`PID file: ${status.pidFile}`));\n}\n\n/**\n * Show daemon logs\n */\nfunction handleDaemonLogs(daemon, options) {\n const lines = options.lines ? parseInt(options.lines) : 50;\n const logs = daemon.getLogs(lines);\n\n if (!logs) {\n console.log(chalk.yellow('No logs available'));\n return;\n }\n\n console.log(chalk.blue(`Last ${lines} log entries:`));\n console.log();\n console.log(logs);\n}\n\n/**\n * Display sync statistics\n */\nfunction displaySyncStats(results) {\n console.log(chalk.blue('Sync Statistics:'));\n console.log(chalk.gray(` Total new emails: ${results.totalNew}`));\n console.log(chalk.gray(` Total errors: ${results.totalErrors}`));\n if (results.spamDetected > 0) {\n console.log(chalk.yellow(` Spam detected: ${results.spamDetected}`));\n }\n if (results.filtersApplied > 0) {\n console.log(chalk.green(` Filters applied: ${results.filtersApplied}`));\n }\n\n console.log();\n console.log(chalk.blue('Folders:'));\n for (const [folder, result] of Object.entries(results.folders)) {\n if (result.error) {\n console.log(chalk.red(` ✗ ${folder}: ${result.error}`));\n } else {\n console.log(chalk.green(` ✓ ${folder}: ${result.newEmails} new emails`));\n }\n }\n}\n\n/**\n * Get account-specific config\n */\nfunction getAccountConfig(cfg, accountId) {\n // Try to get account from database if accounts table exists\n if (accountManager.accountsTableExists()) {\n const imapConfig = accountManager.getImapConfig(accountId);\n if (imapConfig) {\n logger.info('Using account-specific IMAP config', { accountId });\n return imapConfig;\n }\n }\n\n // Fallback to default config\n logger.warn(\n 'Account not found or accounts table not available, using default config',\n { accountId }\n );\n return cfg.imap;\n}\n\n/**\n * Format bytes to human readable\n */\nfunction formatBytes(bytes) {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\n}\n\nmodule.exports = syncCommand;\n","import chalk from 'chalk';\n\nimport emailModel from '../../storage/models/email';\nimport tagModel from '../../storage/models/tag';\nimport logger from '../../utils/logger';\nimport { formatEmailList } from '../utils/formatter';\n\n/**\n * Tag command - Manage email tags\n */\nfunction tagCommand(action, args, options) {\n try {\n switch (action) {\n case 'create':\n return createTag(args, options);\n case 'list':\n return listTags(options);\n case 'delete':\n return deleteTag(args, options);\n case 'add':\n return addTagToEmail(args, options);\n case 'remove':\n return removeTagFromEmail(args, options);\n case 'filter':\n return filterByTag(args, options);\n default:\n console.error(chalk.red('Error:'), `Unknown action: ${action}`);\n console.log(\n chalk.gray(\n 'Available actions: create, list, delete, add, remove, filter'\n )\n );\n process.exit(1);\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Tag command failed', { action, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Create a new tag\n */\nfunction createTag(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Tag name is required');\n console.log(\n chalk.gray(\n 'Usage: tag create <name> [--color <color>] [--description <text>]'\n )\n );\n process.exit(1);\n }\n\n const name = args[0];\n const color = options.color || '#808080';\n const description = options.description || '';\n\n const tagId = tagModel.create({ name, color, description });\n\n console.log(chalk.green('✓'), `Tag \"${name}\" created successfully`);\n console.log(chalk.gray(` ID: ${tagId}`));\n console.log(chalk.gray(` Color: ${color}`));\n if (description) {\n console.log(chalk.gray(` Description: ${description}`));\n }\n}\n\n/**\n * List all tags\n */\nfunction listTags(options) {\n const tags = tagModel.findAll();\n\n if (tags.length === 0) {\n console.log(chalk.yellow('No tags found.'));\n return;\n }\n\n console.log(chalk.bold.cyan('Tags:'));\n console.log();\n\n tags.forEach((tag) => {\n const emailCount = tagModel.countEmailsByTag(tag.id);\n const colorBox = chalk.hex(tag.color)('■');\n console.log(\n `${colorBox} ${chalk.bold(tag.name)} ${chalk.gray(`(${emailCount} emails)`)}`\n );\n console.log(chalk.gray(` ID: ${tag.id}`));\n if (tag.description) {\n console.log(chalk.gray(` ${tag.description}`));\n }\n console.log();\n });\n\n console.log(chalk.gray(`Total: ${tags.length} tags`));\n}\n\n/**\n * Delete a tag\n */\nfunction deleteTag(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Tag name or ID is required');\n console.log(chalk.gray('Usage: tag delete <name|id>'));\n process.exit(1);\n }\n\n const identifier = args[0];\n let tag;\n\n // Try to find by ID first, then by name\n if (/^\\d+$/.test(identifier)) {\n tag = tagModel.findById(parseInt(identifier));\n } else {\n tag = tagModel.findByName(identifier);\n }\n\n if (!tag) {\n console.error(chalk.red('Error:'), `Tag \"${identifier}\" not found`);\n process.exit(1);\n }\n\n const emailCount = tagModel.countEmailsByTag(tag.id);\n\n if (emailCount > 0 && !options.yes) {\n console.log(\n chalk.yellow('Warning:'),\n `This tag is used by ${emailCount} email(s)`\n );\n console.log(chalk.gray('Use --yes to confirm deletion'));\n process.exit(1);\n }\n\n tagModel.delete(tag.id);\n console.log(chalk.green('✓'), `Tag \"${tag.name}\" deleted successfully`);\n}\n\n/**\n * Add tag to email\n */\nfunction addTagToEmail(args, options) {\n if (!args || args.length < 2) {\n console.error(chalk.red('Error:'), 'Email ID and tag name are required');\n console.log(chalk.gray('Usage: tag add <email-id> <tag-name>'));\n process.exit(1);\n }\n\n const emailId = parseInt(args[0]);\n const tagName = args[1];\n\n // Verify email exists\n const email = emailModel.findById(emailId);\n if (!email) {\n console.error(chalk.red('Error:'), `Email with ID ${emailId} not found`);\n process.exit(1);\n }\n\n // Find or create tag\n let tag = tagModel.findByName(tagName);\n if (!tag) {\n console.log(chalk.yellow('Tag not found, creating new tag...'));\n const tagId = tagModel.create({ name: tagName });\n tag = tagModel.findById(tagId);\n }\n\n // Add tag to email\n tagModel.addToEmail(emailId, tag.id);\n\n console.log(chalk.green('✓'), `Tag \"${tag.name}\" added to email #${emailId}`);\n console.log(chalk.gray(` Subject: ${email.subject}`));\n}\n\n/**\n * Remove tag from email\n */\nfunction removeTagFromEmail(args, options) {\n if (!args || args.length < 2) {\n console.error(chalk.red('Error:'), 'Email ID and tag name are required');\n console.log(chalk.gray('Usage: tag remove <email-id> <tag-name>'));\n process.exit(1);\n }\n\n const emailId = parseInt(args[0]);\n const tagName = args[1];\n\n // Verify email exists\n const email = emailModel.findById(emailId);\n if (!email) {\n console.error(chalk.red('Error:'), `Email with ID ${emailId} not found`);\n process.exit(1);\n }\n\n // Find tag\n const tag = tagModel.findByName(tagName);\n if (!tag) {\n console.error(chalk.red('Error:'), `Tag \"${tagName}\" not found`);\n process.exit(1);\n }\n\n // Remove tag from email\n const removed = tagModel.removeFromEmail(emailId, tag.id);\n\n if (removed) {\n console.log(\n chalk.green('✓'),\n `Tag \"${tag.name}\" removed from email #${emailId}`\n );\n } else {\n console.log(chalk.yellow('Email does not have this tag'));\n }\n}\n\n/**\n * Filter emails by tag\n */\nfunction filterByTag(args, options) {\n if (!args || args.length === 0) {\n console.error(chalk.red('Error:'), 'Tag name is required');\n console.log(\n chalk.gray(\n 'Usage: tag filter <tag-name> [--limit <number>] [--page <number>]'\n )\n );\n process.exit(1);\n }\n\n const tagName = args[0];\n const limit = options.limit || 50;\n const page = options.page || 1;\n const offset = (page - 1) * limit;\n\n // Find tag\n const tag = tagModel.findByName(tagName);\n if (!tag) {\n console.error(chalk.red('Error:'), `Tag \"${tagName}\" not found`);\n process.exit(1);\n }\n\n console.log(chalk.bold.cyan(`Emails tagged with \"${tag.name}\":`));\n console.log();\n\n const emails = tagModel.findEmailsByTag(tag.id, { limit, offset });\n\n if (emails.length === 0) {\n console.log(chalk.yellow('No emails found with this tag.'));\n return;\n }\n\n // Format emails using the email model's formatter\n const formattedEmails = emails.map((email) => emailModel._formatEmail(email));\n console.log(formatEmailList(formattedEmails));\n console.log();\n\n const total = tagModel.countEmailsByTag(tag.id);\n const totalPages = Math.ceil(total / limit);\n\n console.log(\n chalk.gray(`Page ${page} of ${totalPages} (${total} total emails)`)\n );\n}\n\nmodule.exports = tagCommand;\n","import type { SQLiteDatabase } from '../../types/database';\n\nimport { StorageError } from '../../utils/errors';\nimport logger from '../../utils/logger';\nimport database from '../database';\n\ninterface TemplateCreateInput {\n name: string;\n subject: string;\n bodyText?: string | null;\n bodyHtml?: string | null;\n variables?: unknown[];\n accountId?: number | null;\n isEnabled?: boolean;\n}\n\ninterface TemplateUpdateInput {\n name?: string;\n subject?: string;\n bodyText?: string | null;\n bodyHtml?: string | null;\n variables?: unknown[] | null;\n accountId?: number | null;\n isEnabled?: boolean;\n}\n\ninterface TemplateRow {\n id: number;\n name: string;\n subject: string;\n body_text: string | null;\n body_html: string | null;\n variables: string | null;\n account_id: number | null;\n is_enabled: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface TemplateRecord {\n id: number;\n name: string;\n subject: string;\n bodyText: string | null;\n bodyHtml: string | null;\n variables: unknown[];\n accountId: number | null;\n isEnabled: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction toNumber(value: number | bigint): number {\n return typeof value === 'bigint' ? Number(value) : value;\n}\n\n/**\n * Template model.\n */\nexport class TemplateModel {\n private db: SQLiteDatabase | null;\n\n constructor() {\n this.db = null;\n }\n\n private getDb(): SQLiteDatabase {\n if (!this.db) {\n this.db = database.getDb();\n }\n return this.db;\n }\n\n create(templateData: TemplateCreateInput): number {\n try {\n const db = this.getDb();\n\n const stmt = db.prepare(`\n INSERT INTO templates (\n name, subject, body_text, body_html, variables, account_id, is_enabled\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n const result = stmt.run(\n templateData.name,\n templateData.subject,\n templateData.bodyText ?? null,\n templateData.bodyHtml ?? null,\n templateData.variables ? JSON.stringify(templateData.variables) : null,\n templateData.accountId ?? null,\n templateData.isEnabled !== undefined\n ? templateData.isEnabled\n ? 1\n : 0\n : 1\n );\n\n const insertId = toNumber(result.lastInsertRowid);\n logger.debug('Template created', { id: insertId });\n return insertId;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create template', { error: errorMessage });\n throw new StorageError(`Failed to create template: ${errorMessage}`);\n }\n }\n\n findById(id: number): TemplateRecord | null {\n try {\n const db = this.getDb();\n const stmt = db.prepare<[number], TemplateRow>(\n 'SELECT * FROM templates WHERE id = ?'\n );\n const template = stmt.get(id);\n return template ? this.formatTemplate(template) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find template by ID', {\n id,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find template: ${errorMessage}`);\n }\n }\n\n findAll(accountId: number | null = null): TemplateRecord[] {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM templates WHERE 1=1';\n const params: number[] = [];\n\n if (accountId) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n query += ' ORDER BY created_at DESC';\n\n const stmt = db.prepare<unknown[], TemplateRow>(query);\n const templates = stmt.all(...params);\n return templates.map((template) => this.formatTemplate(template));\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find templates', { error: errorMessage });\n throw new StorageError(`Failed to find templates: ${errorMessage}`);\n }\n }\n\n findByName(\n name: string,\n accountId: number | null = null\n ): TemplateRecord | null {\n try {\n const db = this.getDb();\n let query = 'SELECT * FROM templates WHERE name = ?';\n const params: Array<string | number> = [name];\n\n if (accountId) {\n query += ' AND (account_id = ? OR account_id IS NULL)';\n params.push(accountId);\n }\n\n query += ' LIMIT 1';\n\n const stmt = db.prepare<unknown[], TemplateRow>(query);\n const template = stmt.get(...params);\n return template ? this.formatTemplate(template) : null;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to find template by name', {\n name,\n error: errorMessage,\n });\n throw new StorageError(`Failed to find template: ${errorMessage}`);\n }\n }\n\n update(id: number, data: TemplateUpdateInput): boolean {\n try {\n const db = this.getDb();\n const fields: string[] = [];\n const params: Array<string | number | null> = [];\n\n if (data.name !== undefined) {\n fields.push('name = ?');\n params.push(data.name);\n }\n\n if (data.subject !== undefined) {\n fields.push('subject = ?');\n params.push(data.subject);\n }\n\n if (data.bodyText !== undefined) {\n fields.push('body_text = ?');\n params.push(data.bodyText);\n }\n\n if (data.bodyHtml !== undefined) {\n fields.push('body_html = ?');\n params.push(data.bodyHtml);\n }\n\n if (data.variables !== undefined) {\n fields.push('variables = ?');\n params.push(data.variables ? JSON.stringify(data.variables) : null);\n }\n\n if (data.accountId !== undefined) {\n fields.push('account_id = ?');\n params.push(data.accountId);\n }\n\n if (data.isEnabled !== undefined) {\n fields.push('is_enabled = ?');\n params.push(data.isEnabled ? 1 : 0);\n }\n\n if (fields.length === 0) {\n return false;\n }\n\n fields.push('updated_at = CURRENT_TIMESTAMP');\n params.push(id);\n\n const sql = `UPDATE templates SET ${fields.join(', ')} WHERE id = ?`;\n const stmt = db.prepare(sql);\n const result = stmt.run(...params);\n\n logger.debug('Template updated', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to update template', { id, error: errorMessage });\n throw new StorageError(`Failed to update template: ${errorMessage}`);\n }\n }\n\n delete(id: number): boolean {\n try {\n const db = this.getDb();\n const stmt = db.prepare('DELETE FROM templates WHERE id = ?');\n const result = stmt.run(id);\n logger.debug('Template deleted', { id, changes: result.changes });\n return result.changes > 0;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to delete template', { id, error: errorMessage });\n throw new StorageError(`Failed to delete template: ${errorMessage}`);\n }\n }\n\n private formatTemplate(template: TemplateRow): TemplateRecord {\n let variables: unknown[] = [];\n if (template.variables) {\n try {\n const parsed = JSON.parse(template.variables) as unknown;\n variables = Array.isArray(parsed) ? parsed : [];\n } catch {\n variables = [];\n }\n }\n\n return {\n id: template.id,\n name: template.name,\n subject: template.subject,\n bodyText: template.body_text,\n bodyHtml: template.body_html,\n variables,\n accountId: template.account_id,\n isEnabled: template.is_enabled === 1,\n createdAt: template.created_at,\n updatedAt: template.updated_at,\n };\n }\n}\n\nconst templateModel = new TemplateModel();\nexport default templateModel;\n","import templateModel from '../storage/models/template';\nimport logger from '../utils/logger';\n\n/**\n * Template Manager\n * Manages email templates with variable substitution support\n */\nclass TemplateManager {\n /**\n * Create a new template\n */\n async create(options) {\n const {\n name,\n subject,\n text,\n html,\n variables,\n accountId,\n isEnabled = true,\n } = options;\n\n if (!name) {\n throw new Error('Template name is required');\n }\n\n if (!subject) {\n throw new Error('Template subject is required');\n }\n\n if (!text && !html) {\n throw new Error('Template content (text or html) is required');\n }\n\n const templateData = {\n name,\n subject,\n bodyText: text,\n bodyHtml: html,\n variables: variables || this._extractVariables(subject, text, html),\n accountId,\n isEnabled,\n };\n\n const id = templateModel.create(templateData);\n logger.info('Template created', { id, name });\n return id;\n }\n\n /**\n * Get template by ID\n */\n async getById(id) {\n return templateModel.findById(id);\n }\n\n /**\n * Get template by name\n */\n async getByName(name, accountId = null) {\n return templateModel.findByName(name, accountId);\n }\n\n /**\n * Get all templates\n */\n async getAll(accountId = null) {\n return templateModel.findAll(accountId);\n }\n\n /**\n * Update template\n */\n async update(id, options) {\n const template = templateModel.findById(id);\n if (!template) {\n throw new Error(`Template not found: ${id}`);\n }\n\n const updateData = {};\n\n if (options.name !== undefined) {\n updateData.name = options.name;\n }\n\n if (options.subject !== undefined) {\n updateData.subject = options.subject;\n }\n\n if (options.text !== undefined) {\n updateData.bodyText = options.text;\n }\n\n if (options.html !== undefined) {\n updateData.bodyHtml = options.html;\n }\n\n if (options.variables !== undefined) {\n updateData.variables = options.variables;\n }\n\n if (options.accountId !== undefined) {\n updateData.accountId = options.accountId;\n }\n\n if (options.isEnabled !== undefined) {\n updateData.isEnabled = options.isEnabled;\n }\n\n const updated = templateModel.update(id, updateData);\n if (updated) {\n logger.info('Template updated', { id });\n }\n return updated;\n }\n\n /**\n * Delete template\n */\n async delete(id) {\n const template = templateModel.findById(id);\n if (!template) {\n throw new Error(`Template not found: ${id}`);\n }\n\n const deleted = templateModel.delete(id);\n if (deleted) {\n logger.info('Template deleted', { id, name: template.name });\n }\n return deleted;\n }\n\n /**\n * Render template with variables\n */\n async render(templateId, variables = {}) {\n const template = await this.getById(templateId);\n if (!template) {\n throw new Error(`Template not found: ${templateId}`);\n }\n\n return this.renderTemplate(template, variables);\n }\n\n /**\n * Render template object with variables\n */\n renderTemplate(template, variables = {}) {\n const defaultVars = {\n date: new Date().toLocaleDateString(),\n time: new Date().toLocaleTimeString(),\n datetime: new Date().toLocaleString(),\n };\n\n const allVars = { ...defaultVars, ...variables };\n\n let renderedSubject = template.subject;\n let renderedText = template.bodyText || '';\n let renderedHtml = template.bodyHtml || '';\n\n Object.keys(allVars).forEach((key) => {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g');\n const value = allVars[key] || '';\n renderedSubject = renderedSubject.replace(regex, value);\n renderedText = renderedText.replace(regex, value);\n renderedHtml = renderedHtml.replace(regex, value);\n });\n\n return {\n subject: renderedSubject,\n text: renderedText,\n html: renderedHtml,\n };\n }\n\n /**\n * Extract variables from template content\n */\n _extractVariables(subject, text, html) {\n const variableRegex = /\\{\\{(\\w+)\\}\\}/g;\n const variables = new Set();\n\n const extractFromString = (str) => {\n if (!str) return;\n let match;\n while ((match = variableRegex.exec(str)) !== null) {\n variables.add(match[1]);\n }\n };\n\n extractFromString(subject);\n extractFromString(text);\n extractFromString(html);\n\n return Array.from(variables);\n }\n\n /**\n * Get template for email composition\n */\n async getForEmail(templateId, variables = {}) {\n return this.render(templateId, variables);\n }\n}\n\nmodule.exports = new TemplateManager();\n","import chalk from 'chalk';\n\nimport templateManager from '../../templates/manager';\nimport logger from '../../utils/logger';\n\n/**\n * Template command handler\n */\nasync function templateCommand(action, options = {}) {\n try {\n switch (action) {\n case 'create':\n await createTemplate(options);\n break;\n case 'list':\n await listTemplates(options);\n break;\n case 'show':\n await showTemplate(options);\n break;\n case 'edit':\n await editTemplate(options);\n break;\n case 'delete':\n await deleteTemplate(options);\n break;\n case 'use':\n await useTemplate(options);\n break;\n default:\n console.error(chalk.red(`Unknown action: ${action}`));\n console.log('Available actions: create, list, show, edit, delete, use');\n process.exit(1);\n }\n } catch (error) {\n logger.error('Template command failed', { action, error: error.message });\n console.error(chalk.red(`Error: ${error.message}`));\n process.exit(1);\n }\n}\n\n/**\n * Create a new template\n */\nasync function createTemplate(options) {\n const { name, subject, text, html, account } = options;\n\n if (!name) {\n throw new Error('Template name is required (--name)');\n }\n\n if (!subject) {\n throw new Error('Template subject is required (--subject)');\n }\n\n if (!text && !html) {\n throw new Error('Template content is required (--text or --html)');\n }\n\n const id = await templateManager.create({\n name,\n subject,\n text,\n html,\n accountId: account,\n });\n\n console.log(chalk.green(`✓ Template created successfully`));\n console.log(` ID: ${id}`);\n console.log(` Name: ${name}`);\n console.log(` Subject: ${subject}`);\n}\n\n/**\n * List all templates\n */\nasync function listTemplates(options) {\n const { account } = options;\n const templates = await templateManager.getAll(account);\n\n if (templates.length === 0) {\n console.log(chalk.yellow('No templates found'));\n return;\n }\n\n console.log(chalk.bold(`\\nTemplates (${templates.length}):\\n`));\n\n templates.forEach((tpl) => {\n const enabledBadge = tpl.isEnabled\n ? chalk.green(' [ENABLED]')\n : chalk.gray(' [DISABLED]');\n const accountInfo = tpl.accountId\n ? chalk.gray(` (Account: ${tpl.accountId})`)\n : '';\n\n console.log(\n `${chalk.cyan(`#${tpl.id}`)} ${chalk.bold(tpl.name)}${enabledBadge}${accountInfo}`\n );\n console.log(chalk.gray(` Subject: ${tpl.subject}`));\n\n if (tpl.variables && tpl.variables.length > 0) {\n console.log(chalk.gray(` Variables: ${tpl.variables.join(', ')}`));\n }\n\n if (tpl.bodyText) {\n const preview = tpl.bodyText.substring(0, 60).replace(/\\n/g, ' ');\n console.log(\n chalk.gray(` Text: ${preview}${tpl.bodyText.length > 60 ? '...' : ''}`)\n );\n }\n\n if (tpl.bodyHtml) {\n console.log(chalk.gray(` HTML: Yes`));\n }\n\n console.log(\n chalk.gray(` Created: ${new Date(tpl.createdAt).toLocaleString()}`)\n );\n console.log();\n });\n}\n\n/**\n * Show template details\n */\nasync function showTemplate(options) {\n const { id, name } = options;\n\n if (!id && !name) {\n throw new Error('Template ID (--id) or name (--name) is required');\n }\n\n let template;\n if (id) {\n template = await templateManager.getById(id);\n } else {\n template = await templateManager.getByName(name);\n }\n\n if (!template) {\n console.log(chalk.yellow(`Template not found`));\n return;\n }\n\n console.log(chalk.bold(`\\nTemplate #${template.id}: ${template.name}\\n`));\n console.log(`${chalk.bold('Subject:')} ${template.subject}`);\n console.log(\n `${chalk.bold('Status:')} ${template.isEnabled ? chalk.green('Enabled') : chalk.gray('Disabled')}`\n );\n\n if (template.accountId) {\n console.log(`${chalk.bold('Account ID:')} ${template.accountId}`);\n }\n\n if (template.variables && template.variables.length > 0) {\n console.log(`${chalk.bold('Variables:')} ${template.variables.join(', ')}`);\n }\n\n if (template.bodyText) {\n console.log(`\\n${chalk.bold('Text Content:')}`);\n console.log(chalk.gray(template.bodyText));\n }\n\n if (template.bodyHtml) {\n console.log(`\\n${chalk.bold('HTML Content:')}`);\n console.log(chalk.gray(template.bodyHtml));\n }\n\n console.log(\n `\\n${chalk.gray('Created:')} ${new Date(template.createdAt).toLocaleString()}`\n );\n console.log(\n `${chalk.gray('Updated:')} ${new Date(template.updatedAt).toLocaleString()}`\n );\n}\n\n/**\n * Edit a template\n */\nasync function editTemplate(options) {\n const { id, name, subject, text, html, account, enabled } = options;\n\n if (!id) {\n throw new Error('Template ID is required (--id)');\n }\n\n const updateData = {};\n\n if (name !== undefined) updateData.name = name;\n if (subject !== undefined) updateData.subject = subject;\n if (text !== undefined) updateData.text = text;\n if (html !== undefined) updateData.html = html;\n if (account !== undefined) updateData.accountId = account;\n if (enabled !== undefined) updateData.isEnabled = enabled;\n\n if (Object.keys(updateData).length === 0) {\n throw new Error('No update data provided');\n }\n\n const updated = await templateManager.update(id, updateData);\n\n if (updated) {\n console.log(chalk.green(`✓ Template #${id} updated successfully`));\n } else {\n console.log(chalk.yellow(`No changes made to template #${id}`));\n }\n}\n\n/**\n * Delete a template\n */\nasync function deleteTemplate(options) {\n const { id } = options;\n\n if (!id) {\n throw new Error('Template ID is required (--id)');\n }\n\n const deleted = await templateManager.delete(id);\n\n if (deleted) {\n console.log(chalk.green(`✓ Template #${id} deleted successfully`));\n } else {\n console.log(chalk.yellow(`Template #${id} not found`));\n }\n}\n\n/**\n * Use template to generate email content\n */\nasync function useTemplate(options) {\n const { id, name, vars } = options;\n\n if (!id && !name) {\n throw new Error('Template ID (--id) or name (--name) is required');\n }\n\n let template;\n if (id) {\n template = await templateManager.getById(id);\n } else {\n template = await templateManager.getByName(name);\n }\n\n if (!template) {\n console.log(chalk.yellow(`Template not found`));\n return;\n }\n\n const variables = {};\n if (vars) {\n vars.split(',').forEach((pair) => {\n const [key, value] = pair.split('=');\n if (key && value) {\n variables[key.trim()] = value.trim();\n }\n });\n }\n\n const rendered = templateManager.renderTemplate(template, variables);\n\n console.log(chalk.bold(`\\nRendered Email:\\n`));\n console.log(`${chalk.bold('Subject:')} ${rendered.subject}`);\n\n if (rendered.text) {\n console.log(`\\n${chalk.bold('Text Content:')}`);\n console.log(rendered.text);\n }\n\n if (rendered.html) {\n console.log(`\\n${chalk.bold('HTML Content:')}`);\n console.log(chalk.gray(rendered.html));\n }\n\n if (template.variables && template.variables.length > 0) {\n const missingVars = template.variables.filter(\n (v) => !variables[v] && !['date', 'time', 'datetime'].includes(v)\n );\n if (missingVars.length > 0) {\n console.log(\n chalk.yellow(`\\nNote: Missing variables: ${missingVars.join(', ')}`)\n );\n }\n }\n}\n\nmodule.exports = templateCommand;\n","#!/usr/bin/env node\n\nimport chalk from 'chalk';\nimport { Command } from 'commander';\n\nimport packageJson from '../../package.json' assert { type: 'json' };\n\n// Import commands\nimport accountCommand from './commands/account';\nimport configCommand from './commands/config';\nimport contactCommand from './commands/contact';\nimport { deleteCommand } from './commands/delete';\nimport draftCommand from './commands/draft';\nimport folderCommand from './commands/folder';\nimport forwardCommand from './commands/forward';\nimport { exportCommand, importCommand } from './commands/import-export';\nimport listCommand from './commands/list';\nimport {\n starCommand,\n unstarCommand,\n flagCommand,\n unflagCommand,\n} from './commands/mark';\nimport notifyCommand from './commands/notify';\nimport readCommand from './commands/read';\nimport replyCommand from './commands/reply';\nimport searchCommand from './commands/search';\nimport sendCommand from './commands/send';\nimport signatureCommand from './commands/signature';\nimport spamCommand from './commands/spam';\nimport syncCommand from './commands/sync';\nimport tagCommand from './commands/tag';\nimport templateCommand from './commands/template';\nimport {\n listThreads,\n showThread,\n deleteThread,\n moveThread,\n} from './commands/thread';\nimport { trashCommand } from './commands/trash';\n\n/**\n * CLI Application\n */\nfunction createCLI(): Command {\n const program = new Command();\n\n program\n .name('mail-client')\n .description('A command-line email client with IMAP/SMTP support')\n .version(packageJson.version);\n\n // Config command\n program\n .command('config')\n .description('Configure IMAP and SMTP settings')\n .option('--show', 'Show current configuration')\n .option('--set <key=value>', 'Set a configuration value')\n .action(configCommand);\n\n // Sync command\n program\n .command('sync [action]')\n .description('Synchronize emails from IMAP server')\n .option('--folder <name>', 'Sync specific folder (default: INBOX)')\n .option('--folders <names>', 'Sync multiple folders (comma-separated)')\n .option('--since <date>', 'Sync emails since date (YYYY-MM-DD)')\n .option('--account <id>', 'Sync specific account')\n .option('--auto', 'Start automatic sync mode')\n .option(\n '--interval <minutes>',\n 'Sync interval in minutes (default: 5)',\n parseInt\n )\n .action((action, options) => {\n if (action === 'daemon') {\n const subcommand = process.argv[4];\n options.subcommand = subcommand;\n options.lines = parseInt(\n process.argv\n .find((arg) => arg.startsWith('--lines='))\n ?.split('=')[1] || '50',\n 10\n );\n }\n syncCommand(action, options);\n });\n\n // List command\n program\n .command('list')\n .description('List emails from local storage')\n .option(\n '--folder <name>',\n 'List emails from specific folder (default: INBOX)'\n )\n .option('--unread', 'Show only unread emails')\n .option('--starred', 'Show only starred emails')\n .option('--flagged', 'Show only flagged (important) emails')\n .option('--tag <name>', 'Filter by tag name')\n .option('--account <id>', 'Filter by account ID', parseInt)\n .option('--all-accounts', 'Show emails from all accounts (unified inbox)')\n .option(\n '--limit <number>',\n 'Number of emails to show (default: 50)',\n parseInt\n )\n .option('--page <number>', 'Page number (default: 1)', parseInt)\n .option('--thread', 'Display emails in thread view')\n .action(listCommand);\n\n // Read command\n program\n .command('read <id>')\n .description('Read email details')\n .option('--raw', 'Show raw email content')\n .action(readCommand);\n\n // Send command\n program\n .command('send')\n .description('Send an email')\n .option('--to <addresses>', 'Recipient email addresses (comma-separated)')\n .option('--cc <addresses>', 'CC email addresses (comma-separated)')\n .option('--subject <text>', 'Email subject')\n .option('--body <text>', 'Email body')\n .action(sendCommand);\n\n // Search command\n program\n .command('search [keyword]')\n .description('Search emails')\n .option('--from <address>', 'Search by sender')\n .option('--subject <text>', 'Search by subject')\n .option('--folder <name>', 'Search in specific folder')\n .option('--date <date>', 'Search from date (YYYY-MM-DD)')\n .action(searchCommand);\n\n // Draft command\n program\n .command('draft <action>')\n .description('Manage drafts (save|list|edit|delete|send|sync)')\n .option('--id <id>', 'Draft ID', parseInt)\n .option('--to <addresses>', 'Recipient email addresses (comma-separated)')\n .option('--cc <addresses>', 'CC email addresses (comma-separated)')\n .option('--subject <text>', 'Email subject')\n .option('--body <text>', 'Email body')\n .option('--sync', 'Sync draft to IMAP server')\n .option(\n '--limit <number>',\n 'Number of drafts to show (default: 50)',\n parseInt\n )\n .action(draftCommand);\n\n // Spam command\n program\n .command('spam <action> [args...]')\n .description(\n 'Manage spam (mark|unmark|list|blacklist|whitelist|filter|stats)'\n )\n .action(spamCommand);\n\n // Signature command\n program\n .command('signature <action>')\n .description('Manage signatures (create|list|edit|delete|set-default)')\n .option('--id <id>', 'Signature ID', parseInt)\n .option('--name <name>', 'Signature name')\n .option('--text <text>', 'Signature text content')\n .option('--html <html>', 'Signature HTML content')\n .option('--default', 'Set as default signature')\n .option('--account <email>', 'Account email address')\n .action(signatureCommand);\n\n // Template command\n program\n .command('template <action>')\n .description('Manage email templates (create|list|show|edit|delete|use)')\n .option('--id <id>', 'Template ID', parseInt)\n .option('--name <name>', 'Template name')\n .option('--subject <subject>', 'Template subject')\n .option('--text <text>', 'Template text content')\n .option('--html <html>', 'Template HTML content')\n .option('--account <id>', 'Account ID', parseInt)\n .option(\n '--enabled <boolean>',\n 'Enable/disable template',\n (val) => val === 'true'\n )\n .option(\n '--vars <vars>',\n 'Variables for template rendering (key=value,key2=value2)'\n )\n .action(templateCommand);\n\n // Notify command\n program\n .command('notify <action>')\n .description(\n 'Manage email notifications (enable|disable|config|test|status)'\n )\n .option(\n '--sender <email>',\n 'Filter by sender email or domain (comma-separated)'\n )\n .option('--tag <name>', 'Filter by tag name (comma-separated)')\n .option('--important', 'Only notify for important emails')\n .action(notifyCommand);\n\n // Delete command\n program\n .command('delete <email-id>')\n .description('Delete email (move to trash or permanently delete)')\n .option('--permanent', 'Permanently delete email')\n .option('--yes', 'Skip confirmation prompt')\n .action(deleteCommand);\n\n // Trash command\n program\n .command('trash <action> [args]')\n .description('Manage trash (list|empty|restore)')\n .option(\n '--limit <number>',\n 'Number of emails to show (default: 50)',\n parseInt\n )\n .option('--offset <number>', 'Offset for pagination (default: 0)', parseInt)\n .option('--yes', 'Skip confirmation prompt')\n .action(trashCommand);\n\n // Reply command\n program\n .command('reply <email-id>')\n .description('Reply to an email')\n .option('--all', 'Reply to all recipients')\n .option('--body <text>', 'Reply body (non-interactive mode)')\n .option('--editor', 'Use editor for reply body')\n .action(replyCommand);\n\n // Forward command\n program\n .command('forward <email-id>')\n .description('Forward an email')\n .option('--to <addresses>', 'Forward to (comma-separated)')\n .option('--body <text>', 'Forward message')\n .option('--no-attachments', 'Do not include attachments')\n .action(forwardCommand);\n\n // Tag command\n program\n .command('tag <action> [args...]')\n .description('Manage tags (create|list|delete|add|remove|filter)')\n .option('--color <color>', 'Tag color in hex format (e.g., #FF0000)')\n .option('--description <text>', 'Tag description')\n .option(\n '--limit <number>',\n 'Number of emails to show (default: 50)',\n parseInt\n )\n .option('--page <number>', 'Page number (default: 1)', parseInt)\n .option('--yes', 'Skip confirmation prompt')\n .action(tagCommand);\n\n // Star command\n program\n .command('star <email-id>')\n .description('Mark email as starred')\n .action(starCommand);\n\n // Unstar command\n program\n .command('unstar <email-id>')\n .description('Remove starred mark from email')\n .action(unstarCommand);\n\n // Flag command\n program\n .command('flag <email-id>')\n .description('Mark email as important (flagged)')\n .action(flagCommand);\n\n // Unflag command\n program\n .command('unflag <email-id>')\n .description('Remove important mark from email')\n .action(unflagCommand);\n\n // Account command\n program\n .command('account <action>')\n .description(\n 'Manage email accounts (add|list|show|edit|delete|default|enable|disable|test|migrate)'\n )\n .option('--id <id>', 'Account ID', parseInt)\n .option('--email <email>', 'Email address')\n .option('--name <name>', 'Display name')\n .option('--imap-host <host>', 'IMAP server host')\n .option('--imap-port <port>', 'IMAP server port', parseInt)\n .option('--smtp-host <host>', 'SMTP server host')\n .option('--smtp-port <port>', 'SMTP server port', parseInt)\n .option('--username <username>', 'Account username')\n .option('--password <password>', 'Account password')\n .option('--test', 'Test connection after adding account')\n .option('--enabled-only', 'Show only enabled accounts')\n .option('--yes', 'Skip confirmation prompts')\n .action(accountCommand);\n\n // Contact command\n program\n .command('contact <action> [args...]')\n .description(\n 'Manage contacts (add|list|show|edit|delete|search|group|import|export)'\n )\n .option('--email <email>', 'Contact email address')\n .option('--name <name>', 'Contact display name')\n .option('--phone <phone>', 'Contact phone number')\n .option('--company <company>', 'Contact company')\n .option('--title <title>', 'Contact job title')\n .option('--notes <notes>', 'Contact notes')\n .option('--favorite <boolean>', 'Mark as favorite (true/false)')\n .option('--group <name>', 'Filter by group name')\n .option('--favorites', 'Show only favorite contacts')\n .option('--limit <number>', 'Number of results to show', parseInt)\n .option('--description <text>', 'Group description')\n .option('--yes', 'Skip confirmation prompts')\n .action(contactCommand);\n\n // Folder command\n program\n .command('folder <action> [args...]')\n .description('Manage folders (list|create|delete|rename|favorite|stats)')\n .option('--name <name>', 'Folder name')\n .option('--new-name <name>', 'New folder name (for rename)')\n .option('--parent <name>', 'Parent folder name')\n .option('--account <id>', 'Account ID', parseInt)\n .option('--yes', 'Skip confirmation prompts')\n .action(folderCommand);\n\n interface ThreadOptions {\n folder?: string;\n limit?: number;\n account?: number;\n expanded?: boolean;\n permanent?: boolean;\n }\n\n // Thread command\n program\n .command('thread <action> [args...]')\n .description('Manage email threads (list|show|delete|move)')\n .option('--folder <name>', 'Folder to list threads from (default: INBOX)')\n .option(\n '--limit <number>',\n 'Number of threads to show (default: 20)',\n parseInt\n )\n .option('--account <id>', 'Filter by account ID', parseInt)\n .option('--expanded', 'Show expanded thread view')\n .option('--permanent', 'Permanently delete thread')\n .action((action: string, args: string[], options: ThreadOptions) => {\n if (action === 'list') {\n listThreads(options);\n } else if (action === 'show' && args.length > 0) {\n showThread(parseInt(args[0], 10), options);\n } else if (action === 'delete' && args.length > 0) {\n deleteThread(parseInt(args[0], 10), options);\n } else if (action === 'move' && args.length > 1) {\n moveThread(parseInt(args[0], 10), args[1], options);\n } else {\n console.error(\n chalk.red('Invalid thread command. Use: list|show|delete|move')\n );\n process.exit(1);\n }\n });\n\n // Export command\n program.addCommand(exportCommand);\n\n // Import command\n program.addCommand(importCommand);\n\n return program;\n}\n\nexport default createCLI;\n","{\n \"name\": \"open-mail-cli\",\n \"version\": \"1.0.0\",\n \"description\": \"A command-line email client with IMAP/SMTP support\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"email-cli\": \"./dist/index.js\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"tsx src/index.ts\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"type-check\": \"tsc --noEmit\",\n \"lint\": \"eslint src tests --ext .ts\",\n \"lint:fix\": \"eslint src tests --ext .ts --fix\",\n \"format\": \"prettier --write \\\".src/**/*.ts\\\" \\\".tests/**/*.ts\\\"\",\n \"format:check\": \"prettier --check \\\".src/**/*.ts\\\" \\\".tests/**/*.ts\\\"\",\n \"prepare\": \"husky\",\n \"build:binary\": \"pnpm build && pkg dist/index.js --targets node18-macos-x64,node18-macos-arm64,node18-linux-x64,node18-linux-arm64,node18-win-x64 --output dist/binary/mail-client\",\n \"build:binary:macos\": \"pnpm build && pkg dist/index.js --targets node18-macos-arm64 --output dist/binary/mail-client-macos\",\n \"build:binary:linux\": \"pnpm build && pkg dist/index.js --targets node18-linux-x64 --output dist/binary/mail-client-linux\",\n \"build:binary:windows\": \"pnpm build && pkg dist/index.js --targets node18-win-x64 --output dist/binary/mail-client.exe\",\n \"prepublishOnly\": \"pnpm build && pnpm lint\"\n },\n \"lint-staged\": {\n \"src/**/*.ts\": [\n \"eslint --fix\",\n \"prettier --write\"\n ],\n \"tests/**/*.ts\": [\n \"eslint --fix\",\n \"prettier --write\"\n ]\n },\n \"keywords\": [\n \"email\",\n \"imap\",\n \"smtp\",\n \"cli\",\n \"email-cli\"\n ],\n \"author\": \"\",\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"dependencies\": {\n \"better-sqlite3\": \"^9.0.0\",\n \"chalk\": \"^4.1.2\",\n \"cli-table3\": \"^0.6.3\",\n \"commander\": \"^11.1.0\",\n \"dotenv\": \"^16.3.1\",\n \"inquirer\": \"^8.2.6\",\n \"mailparser\": \"^3.6.5\",\n \"node-imap\": \"^0.9.6\",\n \"node-notifier\": \"^10.0.1\",\n \"nodemailer\": \"^6.9.7\",\n \"ora\": \"^5.4.1\",\n \"prompts\": \"^2.4.2\"\n },\n \"devDependencies\": {\n \"@types/better-sqlite3\": \"^7.6.13\",\n \"@types/inquirer\": \"^9.0.9\",\n \"@types/mailparser\": \"^3.4.6\",\n \"@types/node\": \"^25.2.2\",\n \"@types/node-notifier\": \"^8.0.5\",\n \"@types/nodemailer\": \"^7.0.9\",\n \"@typescript-eslint/eslint-plugin\": \"^8.54.0\",\n \"@typescript-eslint/parser\": \"^8.54.0\",\n \"@vitest/coverage-v8\": \"^4.0.18\",\n \"eslint\": \"^8.54.0\",\n \"eslint-plugin-import\": \"^2.32.0\",\n \"husky\": \"^9.1.7\",\n \"jest\": \"^29.7.0\",\n \"lint-staged\": \"^16.2.7\",\n \"pkg\": \"^5.8.1\",\n \"prettier\": \"^3.8.1\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^4.0.18\"\n },\n \"packageManager\": \"pnpm@10.15.1+sha512.34e538c329b5553014ca8e8f4535997f96180a1d0f614339357449935350d924e22f8614682191264ec33d1462ac21561aff97f6bb18065351c162c7e8f6de67\",\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ]\n}\n","import chalk from 'chalk';\n\nimport config from '../../config';\nimport IMAPClient from '../../imap/client';\nimport emailModel from '../../storage/models/email';\nimport logger from '../../utils/logger';\n\n/**\n * Delete email command\n * Moves email to trash or permanently deletes it\n */\nasync function deleteCommand(emailId, options) {\n try {\n const permanent = options.permanent || false;\n\n const email = emailModel.findById(emailId);\n if (!email) {\n console.error(chalk.red(`Error: Email with ID ${emailId} not found`));\n process.exit(1);\n }\n\n if (email.isDeleted && !permanent) {\n console.log(\n chalk.yellow(\n 'Email is already in trash. Use --permanent to delete permanently.'\n )\n );\n return;\n }\n\n if (permanent) {\n const confirmMsg = options.yes\n ? 'y'\n : await promptConfirm(\n 'Are you sure you want to permanently delete this email? This cannot be undone. (y/n): '\n );\n\n if (confirmMsg.toLowerCase() !== 'y') {\n console.log(chalk.yellow('Delete cancelled'));\n return;\n }\n\n const cfg = config.load();\n if (cfg.imap.host && cfg.imap.user && cfg.imap.password) {\n const imapClient = new IMAPClient({\n user: cfg.imap.user,\n password: cfg.imap.password,\n host: cfg.imap.host,\n port: cfg.imap.port,\n secure: cfg.imap.secure,\n });\n\n try {\n await imapClient.connect();\n await imapClient.openFolder(email.folder, false);\n await imapClient.deleteEmail(email.uid, true);\n await imapClient.disconnect();\n } catch (imapError) {\n logger.warn('IMAP delete failed, continuing with local delete', {\n error: imapError.message,\n });\n }\n }\n\n emailModel.permanentlyDelete(emailId);\n console.log(chalk.green(`Email ${emailId} permanently deleted`));\n logger.info('Email permanently deleted', { emailId });\n } else {\n const cfg = config.load();\n if (cfg.imap.host && cfg.imap.user && cfg.imap.password) {\n const imapClient = new IMAPClient({\n user: cfg.imap.user,\n password: cfg.imap.password,\n host: cfg.imap.host,\n port: cfg.imap.port,\n secure: cfg.imap.secure,\n });\n\n try {\n await imapClient.connect();\n await imapClient.openFolder(email.folder, false);\n await imapClient.deleteEmail(email.uid, false);\n await imapClient.disconnect();\n } catch (imapError) {\n logger.warn(\n 'IMAP move to trash failed, continuing with local operation',\n { error: imapError.message }\n );\n }\n }\n\n emailModel.markAsDeleted(emailId);\n console.log(chalk.green(`Email ${emailId} moved to trash`));\n logger.info('Email moved to trash', { emailId });\n }\n } catch (error) {\n console.error(chalk.red(`Error deleting email: ${error.message}`));\n logger.error('Delete command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Batch delete emails command\n */\nasync function batchDeleteCommand(emailIds, options) {\n try {\n const permanent = options.permanent || false;\n const ids = emailIds\n .split(',')\n .map((id) => parseInt(id.trim()))\n .filter((id) => !isNaN(id));\n\n if (ids.length === 0) {\n console.error(chalk.red('Error: No valid email IDs provided'));\n process.exit(1);\n }\n\n if (permanent) {\n const confirmMsg = options.yes\n ? 'y'\n : await promptConfirm(\n `Are you sure you want to permanently delete ${ids.length} emails? This cannot be undone. (y/n): `\n );\n\n if (confirmMsg.toLowerCase() !== 'y') {\n console.log(chalk.yellow('Delete cancelled'));\n return;\n }\n }\n\n let successCount = 0;\n let failCount = 0;\n\n for (const id of ids) {\n try {\n const email = emailModel.findById(id);\n if (!email) {\n console.log(chalk.yellow(`Email ${id} not found, skipping`));\n failCount++;\n continue;\n }\n\n if (permanent) {\n emailModel.permanentlyDelete(id);\n } else {\n emailModel.markAsDeleted(id);\n }\n successCount++;\n } catch (error) {\n console.log(\n chalk.yellow(`Failed to delete email ${id}: ${error.message}`)\n );\n failCount++;\n }\n }\n\n console.log(chalk.green(`\\nBatch delete completed:`));\n console.log(chalk.green(` Success: ${successCount}`));\n if (failCount > 0) {\n console.log(chalk.yellow(` Failed: ${failCount}`));\n }\n\n logger.info('Batch delete completed', {\n successCount,\n failCount,\n permanent,\n });\n } catch (error) {\n console.error(chalk.red(`Error in batch delete: ${error.message}`));\n logger.error('Batch delete command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Prompt for confirmation\n */\nfunction promptConfirm(message) {\n return new Promise((resolve) => {\n const readline = require('readline').createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n readline.question(message, (answer) => {\n readline.close();\n resolve(answer);\n });\n });\n}\n\nexport { deleteCommand, batchDeleteCommand };\n","import path from 'path';\n\nimport { Command } from 'commander';\nimport ora from 'ora';\n\nimport accountManager from '../../accounts/manager';\nimport importExportManager from '../../import-export/manager';\nimport logger from '../../utils/logger';\n\n/**\n * Import/Export commands\n */\nconst importExportCommand = new Command('export');\n\nimportExportCommand.description('Import and export emails');\n\n/**\n * Export single email to EML\n */\nimportExportCommand\n .command('email <id> <file>')\n .description('Export a single email to EML format')\n .action(async (id, file) => {\n const spinner = ora('Exporting email...').start();\n\n try {\n const emailId = parseInt(id);\n const filePath = path.resolve(file);\n\n await importExportManager.exportEmailToEml(emailId, filePath);\n\n spinner.succeed(`Email exported to ${filePath}`);\n } catch (error) {\n spinner.fail('Export failed');\n logger.error('Failed to export email', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Export folder to MBOX\n */\nimportExportCommand\n .command('folder <folder> <file>')\n .description('Export a folder to MBOX format')\n .action(async (folder, file) => {\n const spinner = ora('Exporting folder...').start();\n\n try {\n const filePath = path.resolve(file);\n\n let lastProgress = 0;\n const count = await importExportManager.exportFolderToMbox(\n folder,\n filePath,\n (current, total) => {\n const progress = Math.floor((current / total) * 100);\n if (progress !== lastProgress) {\n spinner.text = `Exporting folder... ${current}/${total} (${progress}%)`;\n lastProgress = progress;\n }\n }\n );\n\n spinner.succeed(\n `Exported ${count} emails from folder \"${folder}\" to ${filePath}`\n );\n } catch (error) {\n spinner.fail('Export failed');\n logger.error('Failed to export folder', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Export all emails to MBOX\n */\nimportExportCommand\n .command('all <file>')\n .description('Export all emails to MBOX format')\n .action(async (file) => {\n const spinner = ora('Exporting all emails...').start();\n\n try {\n const filePath = path.resolve(file);\n\n let lastProgress = 0;\n const count = await importExportManager.exportAllToMbox(\n filePath,\n (current, total) => {\n const progress = Math.floor((current / total) * 100);\n if (progress !== lastProgress) {\n spinner.text = `Exporting all emails... ${current}/${total} (${progress}%)`;\n lastProgress = progress;\n }\n }\n );\n\n spinner.succeed(`Exported ${count} emails to ${filePath}`);\n } catch (error) {\n spinner.fail('Export failed');\n logger.error('Failed to export all emails', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Import commands\n */\nconst importCommand = new Command('import');\n\nimportCommand.description('Import emails from files');\n\n/**\n * Import EML file\n */\nimportCommand\n .command('eml <file>')\n .description('Import an EML file')\n .option('-f, --folder <folder>', 'Target folder', 'INBOX')\n .option('-a, --account <id>', 'Account ID')\n .action(async (file, options) => {\n const spinner = ora('Importing EML file...').start();\n\n try {\n const filePath = path.resolve(file);\n let accountId = null;\n\n if (options.account) {\n accountId = parseInt(options.account);\n } else {\n const defaultAccount = accountManager.getDefaultAccount();\n if (defaultAccount) {\n accountId = defaultAccount.id;\n }\n }\n\n const result = await importExportManager.importEml(\n filePath,\n options.folder,\n accountId\n );\n\n if (result.success) {\n spinner.succeed(\n `Email imported successfully (ID: ${result.emailId}, Attachments: ${result.attachmentCount})`\n );\n } else {\n spinner.warn(\n `Email skipped: ${result.reason} (Message-ID: ${result.messageId})`\n );\n }\n } catch (error) {\n spinner.fail('Import failed');\n logger.error('Failed to import EML file', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\n/**\n * Import MBOX file\n */\nimportCommand\n .command('mbox <file>')\n .description('Import an MBOX file')\n .option('-f, --folder <folder>', 'Target folder', 'INBOX')\n .option('-a, --account <id>', 'Account ID')\n .action(async (file, options) => {\n const spinner = ora('Importing MBOX file...').start();\n\n try {\n const filePath = path.resolve(file);\n let accountId = null;\n\n if (options.account) {\n accountId = parseInt(options.account);\n } else {\n const defaultAccount = accountManager.getDefaultAccount();\n if (defaultAccount) {\n accountId = defaultAccount.id;\n }\n }\n\n const result = await importExportManager.importMbox(\n filePath,\n options.folder,\n accountId,\n (progress) => {\n spinner.text = `Importing MBOX... Imported: ${progress.imported}, Skipped: ${progress.skipped}, Errors: ${progress.errors}`;\n }\n );\n\n spinner.succeed(\n `MBOX import completed: ${result.imported} imported, ${result.skipped} skipped, ${result.errors} errors`\n );\n } catch (error) {\n spinner.fail('Import failed');\n logger.error('Failed to import MBOX file', { error: error.message });\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n });\n\nexport { importExportCommand as exportCommand, importCommand };\n","import chalk from 'chalk';\n\nimport emailModel from '../../storage/models/email';\nimport logger from '../../utils/logger';\n\n/**\n * Star command - Mark email as starred\n */\nfunction starCommand(emailId, options) {\n try {\n const id = parseInt(emailId);\n\n // Verify email exists\n const email = emailModel.findById(id);\n if (!email) {\n console.error(chalk.red('Error:'), `Email with ID ${id} not found`);\n process.exit(1);\n }\n\n emailModel.markAsStarred(id);\n\n console.log(chalk.green('✓'), `Email #${id} marked as starred`);\n console.log(chalk.gray(` Subject: ${email.subject}`));\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Star command failed', { emailId, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Unstar command - Remove starred mark from email\n */\nfunction unstarCommand(emailId, options) {\n try {\n const id = parseInt(emailId);\n\n // Verify email exists\n const email = emailModel.findById(id);\n if (!email) {\n console.error(chalk.red('Error:'), `Email with ID ${id} not found`);\n process.exit(1);\n }\n\n emailModel.unmarkAsStarred(id);\n\n console.log(chalk.green('✓'), `Email #${id} unmarked as starred`);\n console.log(chalk.gray(` Subject: ${email.subject}`));\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Unstar command failed', { emailId, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Flag command - Mark email as important\n */\nfunction flagCommand(emailId, options) {\n try {\n const id = parseInt(emailId);\n\n // Verify email exists\n const email = emailModel.findById(id);\n if (!email) {\n console.error(chalk.red('Error:'), `Email with ID ${id} not found`);\n process.exit(1);\n }\n\n emailModel.markAsImportant(id);\n\n console.log(chalk.green('✓'), `Email #${id} marked as important (flagged)`);\n console.log(chalk.gray(` Subject: ${email.subject}`));\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Flag command failed', { emailId, error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Unflag command - Remove important mark from email\n */\nfunction unflagCommand(emailId, options) {\n try {\n const id = parseInt(emailId);\n\n // Verify email exists\n const email = emailModel.findById(id);\n if (!email) {\n console.error(chalk.red('Error:'), `Email with ID ${id} not found`);\n process.exit(1);\n }\n\n emailModel.unmarkAsImportant(id);\n\n console.log(\n chalk.green('✓'),\n `Email #${id} unmarked as important (unflagged)`\n );\n console.log(chalk.gray(` Subject: ${email.subject}`));\n } catch (error) {\n console.error(chalk.red('Error:'), error.message);\n logger.error('Unflag command failed', { emailId, error: error.message });\n process.exit(1);\n }\n}\n\nexport { starCommand, unstarCommand, flagCommand, unflagCommand };\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\n\nimport emailModel from '../../storage/models/email';\nimport logger from '../../utils/logger';\n\n/**\n * List trash command\n * Shows all deleted emails\n */\nfunction listTrashCommand(options) {\n try {\n const limit = options.limit || 50;\n const offset = options.offset || 0;\n\n const deletedEmails = emailModel.findDeleted({ limit, offset });\n const totalCount = emailModel.countDeleted();\n\n if (deletedEmails.length === 0) {\n console.log(chalk.yellow('Trash is empty'));\n return;\n }\n\n const table = new Table({\n head: [\n chalk.cyan('ID'),\n chalk.cyan('From'),\n chalk.cyan('Subject'),\n chalk.cyan('Deleted At'),\n chalk.cyan('Folder'),\n ],\n colWidths: [8, 30, 40, 20, 15],\n });\n\n deletedEmails.forEach((email) => {\n table.push([\n email.id,\n truncate(email.from, 28),\n truncate(email.subject, 38),\n formatDate(email.deletedAt),\n email.folder,\n ]);\n });\n\n console.log(chalk.bold('\\nTrash:'));\n console.log(table.toString());\n console.log(\n chalk.gray(\n `\\nShowing ${deletedEmails.length} of ${totalCount} deleted emails`\n )\n );\n\n if (totalCount > limit) {\n console.log(chalk.gray(`Use --limit and --offset to see more`));\n }\n\n logger.info('Trash listed', {\n count: deletedEmails.length,\n total: totalCount,\n });\n } catch (error) {\n console.error(chalk.red(`Error listing trash: ${error.message}`));\n logger.error('List trash command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Empty trash command\n * Permanently deletes all emails in trash\n */\nasync function emptyTrashCommand(options) {\n try {\n const count = emailModel.countDeleted();\n\n if (count === 0) {\n console.log(chalk.yellow('Trash is already empty'));\n return;\n }\n\n const confirmMsg = options.yes\n ? 'y'\n : await promptConfirm(\n `Are you sure you want to permanently delete ${count} emails from trash? This cannot be undone. (y/n): `\n );\n\n if (confirmMsg.toLowerCase() !== 'y') {\n console.log(chalk.yellow('Empty trash cancelled'));\n return;\n }\n\n const deletedCount = emailModel.emptyTrash();\n console.log(\n chalk.green(`Trash emptied: ${deletedCount} emails permanently deleted`)\n );\n logger.info('Trash emptied', { deletedCount });\n } catch (error) {\n console.error(chalk.red(`Error emptying trash: ${error.message}`));\n logger.error('Empty trash command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Restore email from trash command\n */\nfunction restoreCommand(emailId, options) {\n try {\n const email = emailModel.findById(emailId);\n\n if (!email) {\n console.error(chalk.red(`Error: Email with ID ${emailId} not found`));\n process.exit(1);\n }\n\n if (!email.isDeleted) {\n console.log(chalk.yellow('Email is not in trash'));\n return;\n }\n\n emailModel.restoreDeleted(emailId);\n console.log(chalk.green(`Email ${emailId} restored from trash`));\n logger.info('Email restored', { emailId });\n } catch (error) {\n console.error(chalk.red(`Error restoring email: ${error.message}`));\n logger.error('Restore command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Batch restore emails from trash\n */\nfunction batchRestoreCommand(emailIds, options) {\n try {\n const ids = emailIds\n .split(',')\n .map((id) => parseInt(id.trim()))\n .filter((id) => !isNaN(id));\n\n if (ids.length === 0) {\n console.error(chalk.red('Error: No valid email IDs provided'));\n process.exit(1);\n }\n\n let successCount = 0;\n let failCount = 0;\n\n for (const id of ids) {\n try {\n const email = emailModel.findById(id);\n if (!email) {\n console.log(chalk.yellow(`Email ${id} not found, skipping`));\n failCount++;\n continue;\n }\n\n if (!email.isDeleted) {\n console.log(chalk.yellow(`Email ${id} is not in trash, skipping`));\n failCount++;\n continue;\n }\n\n emailModel.restoreDeleted(id);\n successCount++;\n } catch (error) {\n console.log(\n chalk.yellow(`Failed to restore email ${id}: ${error.message}`)\n );\n failCount++;\n }\n }\n\n console.log(chalk.green(`\\nBatch restore completed:`));\n console.log(chalk.green(` Success: ${successCount}`));\n if (failCount > 0) {\n console.log(chalk.yellow(` Failed: ${failCount}`));\n }\n\n logger.info('Batch restore completed', { successCount, failCount });\n } catch (error) {\n console.error(chalk.red(`Error in batch restore: ${error.message}`));\n logger.error('Batch restore command failed', { error: error.message });\n process.exit(1);\n }\n}\n\n/**\n * Trash command router\n */\nasync function trashCommand(action, args, options) {\n switch (action) {\n case 'list':\n listTrashCommand(options);\n break;\n case 'empty':\n await emptyTrashCommand(options);\n break;\n case 'restore':\n if (!args) {\n console.error(chalk.red('Error: Email ID required for restore'));\n process.exit(1);\n }\n if (args.includes(',')) {\n batchRestoreCommand(args, options);\n } else {\n restoreCommand(parseInt(args), options);\n }\n break;\n default:\n console.error(chalk.red(`Error: Unknown trash action: ${action}`));\n console.log(chalk.yellow('Available actions: list, empty, restore'));\n process.exit(1);\n }\n}\n\n/**\n * Truncate string to specified length\n */\nfunction truncate(str, maxLength) {\n if (!str) return '';\n if (str.length <= maxLength) return str;\n return str.substring(0, maxLength - 3) + '...';\n}\n\n/**\n * Format date for display\n */\nfunction formatDate(dateString) {\n if (!dateString) return 'N/A';\n const date = new Date(dateString);\n return date.toLocaleString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\n/**\n * Prompt for confirmation\n */\nfunction promptConfirm(message) {\n return new Promise((resolve) => {\n const readline = require('readline').createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n readline.question(message, (answer) => {\n readline.close();\n resolve(answer);\n });\n });\n}\n\nexport {\n trashCommand,\n listTrashCommand,\n emptyTrashCommand,\n restoreCommand,\n batchRestoreCommand,\n};\n","#!/usr/bin/env node\n\nimport createCLI from './cli/index';\nimport database from './storage/database';\nimport logger from './utils/logger';\n\n/**\n * Main entry point\n */\nasync function main(): Promise<void> {\n try {\n database.initialize();\n\n const program = createCLI();\n await program.parseAsync(process.argv);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error('Application error', { error: errorMessage });\n console.error('Fatal error:', errorMessage);\n process.exit(1);\n }\n}\n\nprocess.on('uncaughtException', (error: Error) => {\n logger.error('Uncaught exception', { error: error.message });\n console.error('Uncaught exception:', error.message);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n logger.error('Unhandled rejection', { reason });\n console.error('Unhandled rejection:', reason);\n process.exit(1);\n});\n\nmain();\n"],"mappings":"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","names":["crypto","os","path","import_node_path","path","fs","error","isRecord","error","import_node_fs","import_node_path","path","fs","Imap","error","info","client_default","init_client","nodemailer","error","info","getErrorMessage","error","up","createIndexes","getErrorMessage","error","up","alterEmailsTable","createIndexes","up","createIndexes","getErrorMessage","error","import_node_fs","import_node_path","path","fs","Database","up","getErrorMessage","error","exports","module","init_client","error","client_default","exports","module","import_chalk","import_manager","accountCommand","chalk","error","prompts","accountManager","exports","module","import_chalk","configCommand","error","chalk","inquirer","getErrorMessage","error","toNumber","getErrorMessage","error","toNumber","require_manager","exports","module","error","exports","module","import_fs","import_chalk","import_manager","contactCommand","chalk","error","contactManager","fs","error","exports","module","error","exports","module","error","getErrorMessage","error","toNumber","exports","module","executor","error","matcher","require_manager","exports","module","import_path","error","notifier","path","error","getErrorMessage","error","toNumber","exports","module","error","getErrorMessage","error","toNumber","getErrorMessage","error","toNumber","import_manager","path","spamFilter","error","fs","filterEngine","contactManager","notificationManager","import_fs","import_path","fs","path","error","exports","module","import_chalk","import_cli_table3","import_ora","init_client","draftCommand","chalk","error","ora","Table","truncate","formatDate","inquirer","client_default","chalk","import_chalk","exports","module","import_commander","folderCommand","error","exports","module","import_chalk","import_ora","init_client","forwardCommand","chalk","inquirer","error","ora","client_default","exports","module","import_fs","import_mailparser","fs","error","exports","module","import_fs","import_mailparser","fs","error","require_manager","exports","module","import_fs","import_path","fs","error","emlHandler","mboxHandler","path","exports","module","chalk","analyzer","error","import_chalk","getErrorMessage","error","toNumber","exports","module","import_chalk","import_analyzer","listCommand","chalk","analyzer","error","exports","module","import_chalk","import_manager","notifyCommand","chalk","error","notificationManager","inquirer","exports","module","import_chalk","import_ora","readCommand","chalk","ora","error","exports","module","import_chalk","import_ora","init_client","replyCommand","chalk","inquirer","ora","client_default","error","getErrorMessage","error","toNumber","exports","module","import_chalk","searchCommand","chalk","error","getErrorMessage","error","toNumber","require_manager","exports","module","exports","module","import_chalk","import_ora","import_manager","init_client","sendCommand","chalk","signatureManager","error","ora","client_default","contactManager","inquirer","exports","module","import_chalk","import_manager","signatureCommand","chalk","error","signatureManager","exports","module","import_filter","spamFilter","error","spamCommand","exports","module","error","exports","module","import_fs","import_path","path","fs","error","exports","module","EventEmitter","error","accountManager","exports","module","import_chalk","import_ora","syncCommand","ora","error","chalk","SyncScheduler","info","SyncDaemon","accountManager","exports","module","import_chalk","tagCommand","chalk","error","getErrorMessage","error","toNumber","require_manager","exports","module","exports","module","import_chalk","import_manager","templateCommand","chalk","error","templateManager","import_chalk","import_commander","import_config","chalk","error","import_folder","import_path","import_manager","ora","path","importExportManager","error","accountManager","import_chalk","chalk","error","import_chalk","chalk","Table","truncate","formatDate","error","promptConfirm","configCommand","syncCommand","listCommand","readCommand","sendCommand","searchCommand","draftCommand","spamCommand","signatureCommand","templateCommand","notifyCommand","replyCommand","forwardCommand","tagCommand","accountCommand","contactCommand","folderCommand","chalk","error"]}
|