import { BaseConnector } from '../../base/base.connector'; import type { IEmailOptions, IEmailProvider, ISendMessageSuccessResponse, WithPassthrough, EmailSendInput, EmailSendResult, IEmailConnector } from '../../types'; import { ChannelTypeEnum } from '../../types'; import type { PostmarkConfig } from './postmark.config'; export declare class PostmarkEmailConnector extends BaseConnector implements IEmailProvider, IEmailConnector { private config; readonly id = "postmark"; readonly channelType: ChannelTypeEnum.EMAIL; constructor(config: PostmarkConfig, fetchImpl?: typeof fetch); /** * Thinwrap-native send. Implements `IEmailConnector`. * Hand-builds Postmark's PascalCase JSON wire body and POSTs to * `https://api.postmarkapp.com/email` (or `/email/withTemplate` when the * merged body names a template) with `X-Postmark-Server-Token` auth. * * Postmark is also the canonical example of two outlier mappings: * 1. **Single-tag normalization** — Postmark accepts only one `Tag` per * email. Thinwrap's `tags: string[]` (9/9 providers conceptually) is * capped first-tag-wins inside `buildPostmarkBody()`. No error, no * warning — graceful degradation the >=90% baseline-coverage rule. * 2. **Headers Record→array adapter** — Postmark uniquely requires * `Headers: Array<{Name,Value}>` rather than the flat * `Record` shape every other connector uses. The * conversion lives inside this connector (outlier wire * translation locality). * * Postmark also returns 200 OK with `ErrorCode !== 0` on rejection (see * ) — those are mapped to a 422-equivalent application error * re-thrown through `mapVendorError()`. */ send(input: EmailSendInput): Promise; /** * Hand-build Postmark's PascalCase wire body from Thinwrap's `EmailSendInput`. * (locality), the structural wire translation is local to * this connector — no automatic casing transform on connector-built keys. * * Single-tag normalization rules: * - `tags === undefined || tags.length === 0` → omit `Tag`. * - `tags.length === 1` → `Tag: tags[0]`. * - `tags.length > 1` → `Tag: tags[0]` (first-tag-wins; remainder silently * dropped). No error, no warning the wrapper holds no state. */ private buildPostmarkBody; /** * Map Postmark error responses to canonical `ConnectorError` with the 6-value * `ProviderCode` union. Parses `Retry-After`: * parsed seconds embedded in `providerMessage` text; raw header value on * `cause.retryAfter`. No structured `retryAfterSeconds` field per * Retry is consumer policy (no retryAfterSeconds field). * * Used for both real HTTP errors (4xx/5xx) and Postmark's embedded * application-level errors (200 + `ErrorCode !== 0`) — the latter are passed * with `status: 422`. */ private mapVendorError; sendMessage(options: IEmailOptions, bridgeProviderData?: WithPassthrough>): Promise; }