@upyo/plunk
Version:
Plunk transport for Upyo email library
269 lines (267 loc) • 7.75 kB
text/typescript
import { Message, Receipt, Transport, TransportOptions } from "@upyo/core";
//#region src/config.d.ts
/**
* Configuration interface for Plunk transport connection settings.
*
* This interface defines all available options for configuring a Plunk
* API connection including authentication, HTTP options, and base URL for
* self-hosted instances.
*
* @example
* ```typescript
* const config: PlunkConfig = {
* apiKey: 'your-api-key',
* baseUrl: 'https://api.useplunk.com', // or self-hosted URL
* timeout: 30000,
* retries: 3
* };
* ```
*/
interface PlunkConfig {
/**
* Your Plunk API key.
*
* You can find your API key in your Plunk dashboard under Settings > API Keys.
* The key will be used as a Bearer token for authentication.
*/
readonly apiKey: string;
/**
* Base URL for the Plunk API.
*
* For Plunk's hosted service, use "https://api.useplunk.com" (default).
* For self-hosted instances, use your domain with "/api" path
* (e.g., "https://plunk.example.com/api").
*
* @default "https://api.useplunk.com"
*/
readonly baseUrl?: string;
/**
* HTTP request timeout in milliseconds.
*
* @default 30000
*/
readonly timeout?: number;
/**
* Number of retry attempts for failed requests.
*
* @default 3
*/
readonly retries?: number;
/**
* Whether to validate SSL certificates.
*
* @default true
*/
readonly validateSsl?: boolean;
/**
* Additional HTTP headers to include with requests.
*/
readonly headers?: Record<string, string>;
}
/**
* Resolved Plunk configuration with all optional fields filled with default values.
*
* This type represents the final configuration after applying defaults,
* used internally by the Plunk transport implementation.
*/
type ResolvedPlunkConfig = Required<PlunkConfig>;
/**
* Creates a resolved Plunk configuration by applying default values to optional fields.
*
* This function takes a partial Plunk configuration and returns a complete
* configuration with all optional fields filled with sensible defaults.
* It is used internally by the Plunk transport.
*
* @param config - The Plunk configuration with optional fields
* @returns A resolved configuration with all defaults applied
* @internal
*/
//#endregion
//#region src/plunk-transport.d.ts
/**
* Plunk transport implementation for sending emails via Plunk API.
*
* This transport provides efficient email delivery using Plunk's HTTP API,
* with support for both cloud-hosted and self-hosted instances, authentication,
* retry logic, and batch sending capabilities.
*
* @example
* ```typescript
* import { PlunkTransport } from '@upyo/plunk';
*
* const transport = new PlunkTransport({
* apiKey: 'your-plunk-api-key',
* baseUrl: 'https://api.useplunk.com', // or self-hosted URL
* timeout: 30000,
* retries: 3
* });
*
* const receipt = await transport.send(message);
* if (receipt.successful) {
* console.log('Message sent with ID:', receipt.messageId);
* } else {
* console.error('Send failed:', receipt.errorMessages.join(', '));
* }
* ```
*/
declare class PlunkTransport implements Transport {
/**
* The resolved Plunk configuration used by this transport.
*/
config: ResolvedPlunkConfig;
private httpClient;
/**
* Creates a new Plunk transport instance.
*
* @param config Plunk configuration including API key and options.
*/
constructor(config: PlunkConfig);
/**
* Sends a single email message via Plunk API.
*
* This method converts the message to Plunk format, makes an HTTP request
* to the Plunk API, and returns a receipt with the result.
*
* @example
* ```typescript
* const receipt = await transport.send({
* sender: { address: 'from@example.com' },
* recipients: [{ address: 'to@example.com' }],
* ccRecipients: [],
* bccRecipients: [],
* replyRecipients: [],
* subject: 'Hello',
* content: { text: 'Hello World!' },
* attachments: [],
* priority: 'normal',
* tags: [],
* headers: new Headers()
* });
*
* if (receipt.successful) {
* console.log('Message sent successfully');
* }
* ```
*
* @param message The email message to send.
* @param options Optional transport options including `AbortSignal` for
* cancellation.
* @returns A promise that resolves to a receipt indicating success or
* failure.
*/
send(message: Message, options?: TransportOptions): Promise<Receipt>;
/**
* Sends multiple email messages efficiently via Plunk API.
*
* This method sends each message individually but provides a streamlined
* interface for processing multiple messages. Each message is sent as a
* separate API request to Plunk.
*
* @example
* ```typescript
* const messages = [
* {
* sender: { address: 'from@example.com' },
* recipients: [{ address: 'user1@example.com' }],
* ccRecipients: [],
* bccRecipients: [],
* replyRecipients: [],
* subject: 'Message 1',
* content: { text: 'Hello User 1!' },
* attachments: [],
* priority: 'normal',
* tags: [],
* headers: new Headers()
* },
* {
* sender: { address: 'from@example.com' },
* recipients: [{ address: 'user2@example.com' }],
* ccRecipients: [],
* bccRecipients: [],
* replyRecipients: [],
* subject: 'Message 2',
* content: { text: 'Hello User 2!' },
* attachments: [],
* priority: 'normal',
* tags: [],
* headers: new Headers()
* }
* ];
*
* for await (const receipt of transport.sendMany(messages)) {
* if (receipt.successful) {
* console.log('Sent:', receipt.messageId);
* } else {
* console.error('Failed:', receipt.errorMessages);
* }
* }
* ```
*
* @param messages An iterable or async iterable of messages to send.
* @param options Optional transport options including `AbortSignal` for
* cancellation.
* @returns An async iterable of receipts, one for each message.
*/
sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt>;
/**
* Extracts or generates a message ID from the Plunk response.
*
* Plunk returns email details in the response, so we can use the contact ID
* and timestamp to create a meaningful message ID.
*
* @param response The Plunk API response.
* @param message The original message for fallback ID generation.
* @returns A message ID string.
*/
private extractMessageId;
}
//#endregion
//#region src/http-client.d.ts
/**
* Response from Plunk API for sending messages.
*/
interface PlunkResponse {
/**
* Indicates whether the API call was successful.
*/
readonly success: boolean;
/**
* Array of sent email details.
*/
readonly emails: readonly {
readonly contact: {
readonly id: string;
readonly email: string;
};
readonly email: string;
}[];
/**
* Timestamp of the send operation.
*/
readonly timestamp: string;
}
/**
* Error response from Plunk API.
*/
interface PlunkError {
/**
* Error message from Plunk.
*/
readonly message: string;
/**
* HTTP status code.
*/
readonly statusCode?: number;
/**
* Additional error details from Plunk API.
*/
readonly details?: unknown;
}
/**
* HTTP client wrapper for Plunk API requests.
*
* This class handles authentication, request formatting, error handling,
* and retry logic for the Plunk HTTP API.
*/
//#endregion
export { PlunkConfig, PlunkError, PlunkResponse, PlunkTransport, ResolvedPlunkConfig };