feat(wire): Add wire protocol, WireTarget & WireParser, Smartmail JSON serialization; refactor plugins and update dependencies
This commit is contained in:
150
ts/smartmail.classes.wiretarget.ts
Normal file
150
ts/smartmail.classes.wiretarget.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
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<any>): Promise<IMailSendResponse> {
|
||||
const request: IMailSendRequest = {
|
||||
type: 'mail.send',
|
||||
messageId: createMessageId(),
|
||||
timestamp: createTimestamp(),
|
||||
email: email.toObject(),
|
||||
};
|
||||
return this.send<IMailSendResponse>(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<ISettingsUpdateResponse> {
|
||||
const request: ISettingsUpdateRequest = {
|
||||
type: 'settings.update',
|
||||
messageId: createMessageId(),
|
||||
timestamp: createTimestamp(),
|
||||
settings,
|
||||
};
|
||||
return this.send<ISettingsUpdateResponse>(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<IMailboxListResponse> {
|
||||
const request: IMailboxListRequest = {
|
||||
type: 'mailbox.list',
|
||||
messageId: createMessageId(),
|
||||
timestamp: createTimestamp(),
|
||||
mailbox,
|
||||
limit: options?.limit,
|
||||
offset: options?.offset,
|
||||
};
|
||||
return this.send<IMailboxListResponse>(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<Smartmail<any> | null> {
|
||||
const request: IMailFetchRequest = {
|
||||
type: 'mail.fetch',
|
||||
messageId: createMessageId(),
|
||||
timestamp: createTimestamp(),
|
||||
mailbox,
|
||||
emailId,
|
||||
};
|
||||
const response = await this.send<IMailFetchResponse>(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<IMailStatusResponse> {
|
||||
const request: IMailStatusRequest = {
|
||||
type: 'mail.status',
|
||||
messageId: createMessageId(),
|
||||
timestamp: createTimestamp(),
|
||||
deliveryId,
|
||||
};
|
||||
return this.send<IMailStatusResponse>(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a wire message to the endpoint
|
||||
* @param message The message to send
|
||||
* @returns Promise resolving to the response
|
||||
*/
|
||||
private async send<T extends IWireMessage>(message: IWireMessage): Promise<T> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user