import * as plugins from './smartmail.plugins.js'; import { Smartmail } from './smartmail.classes.smartmail.js'; import { type IWireMessage, type IMailSendRequest, type IMailSendResponse, type IMailboxListRequest, type IMailboxListResponse, type IMailFetchRequest, type IMailFetchResponse, type IMailStatusRequest, type IMailStatusResponse, type ISettingsUpdateRequest, type ISettingsUpdateResponse, type IWireSettings, createMessageId, createTimestamp, } from './smartmail.wire.js'; /** * Options for configuring a WireTarget */ export interface IWireTargetOptions { /** URL of the SMTP service endpoint */ endpoint: string; /** Optional authentication token */ authToken?: string; } /** * WireTarget is used by the SaaS service to communicate with the SMTP service. * It provides methods for sending emails, updating settings, and managing mailboxes. */ export class WireTarget { private endpoint: string; private authToken?: string; constructor(options: IWireTargetOptions) { this.endpoint = options.endpoint; this.authToken = options.authToken; } /** * Send an email through this target * @param email The Smartmail instance to send * @returns Promise resolving to the send response */ public async sendEmail(email: Smartmail): Promise { const request: IMailSendRequest = { type: 'mail.send', messageId: createMessageId(), timestamp: createTimestamp(), email: email.toObject(), }; return this.send(request); } /** * Update settings on the target (SMTP config, etc.) * Settings are extensible - any key-value pairs can be sent * @param settings The settings to update * @returns Promise resolving to the update response */ public async updateSettings(settings: IWireSettings): Promise { const request: ISettingsUpdateRequest = { type: 'settings.update', messageId: createMessageId(), timestamp: createTimestamp(), settings, }; return this.send(request); } /** * List emails in a mailbox * @param mailbox The mailbox to list (e.g., 'INBOX', 'Sent') * @param options Optional limit and offset for pagination * @returns Promise resolving to the mailbox list response */ public async listMailbox( mailbox: string, options?: { limit?: number; offset?: number } ): Promise { const request: IMailboxListRequest = { type: 'mailbox.list', messageId: createMessageId(), timestamp: createTimestamp(), mailbox, limit: options?.limit, offset: options?.offset, }; return this.send(request); } /** * Fetch a specific email from a mailbox * @param mailbox The mailbox containing the email * @param emailId The ID of the email to fetch * @returns Promise resolving to the Smartmail or null if not found */ public async fetchEmail(mailbox: string, emailId: string): Promise | null> { const request: IMailFetchRequest = { type: 'mail.fetch', messageId: createMessageId(), timestamp: createTimestamp(), mailbox, emailId, }; const response = await this.send(request); if (response.email) { return Smartmail.fromObject(response.email); } return null; } /** * Check delivery status of a sent email * @param deliveryId The delivery ID returned from sendEmail * @returns Promise resolving to the status response */ public async getStatus(deliveryId: string): Promise { const request: IMailStatusRequest = { type: 'mail.status', messageId: createMessageId(), timestamp: createTimestamp(), deliveryId, }; return this.send(request); } /** * Sends a wire message to the endpoint * @param message The message to send * @returns Promise resolving to the response */ private async send(message: IWireMessage): Promise { let request = plugins.SmartRequest.create() .url(this.endpoint) .header('Content-Type', 'application/json'); if (this.authToken) { request = request.header('Authorization', `Bearer ${this.authToken}`); } const response = await request.json(message).post(); const responseData = await response.json(); return responseData as T; } }