@kiwa-lab/email
v2.1.0
Published
Email provider mock harness for kiwa — Resend / SendGrid / Postmark / AWS SES を統一 interface で invoke する in-process mock。 send / template render / delivery event / bounce / webhook signature verify までを real provider と同じ signature で叩ける test infra。
Maintainers
Readme
@kiwa-lab/email
Email provider mock harness for kiwa — Resend / SendGrid / Postmark / AWS SES を統一 interface で in-process 実行する test infra。
Installation
pnpm add -D @kiwa-lab/email
# or
npm install -D @kiwa-lab/email
# or
yarn add -D @kiwa-lab/emailSupported providers
| Provider | Status | Signature algo | ID prefix |
|---|---|---|---|
| Resend | ✅ | HMAC-SHA256 (hex) | re- |
| SendGrid | ✅ | HMAC-SHA256 (base64) | sg- |
| Postmark | ✅ | HMAC-SHA256 (hex) | pm- |
| AWS SES | ✅ | HMAC-SHA1 (hex) | ses- |
Quick start
import { createEmailClient, verifyWebhookSignature, parseDeliveryEvent } from '@kiwa-lab/email';
import { createHmac } from 'node:crypto';
const client = createEmailClient({
provider: 'resend',
templates: { welcome: '<h1>hello {{name}}</h1>' },
});
const result = await client.send({
from: 'a@x', to: 'b@x', subject: 'w',
templateId: 'welcome', templateData: { name: 'kiwa' },
});
// result = { id: 're-1', provider: 'resend', status: 'queued', acceptedAt: ... }
const secret = 'whsec_test';
const payload = JSON.stringify({ type: 'email.delivered', email_id: result.id, timestamp: 1 });
const signature = createHmac('sha256', secret).update(payload).digest('hex');
const verify = verifyWebhookSignature(payload, signature, secret, 'resend');
const event = parseDeliveryEvent({ provider: 'resend', raw: JSON.parse(payload) });API reference
createEmailClient(options?: CreateEmailClientOptions): EmailClient— provider mock を生成EmailClient.send(msg: EmailMessage): Promise<EmailSendResult>— email を queued として記録EmailClient.renderTemplate(templateId: string, data: EmailTemplateContext): string— 事前登録 template を interpolateverifyWebhookSignature(payload, signature, secret, provider): SignatureVerifyResult— provider 別 HMAC 検証parseDeliveryEvent(rawEvent: RawDeliveryEvent): NormalizedDeliveryEvent— 4 provider 別 event payload を統一 shape に正規化renderTemplate(template: string, data: EmailTemplateContext): TemplateRenderResult— mustache-lite{{key}}interpolation
Test integration
import { describe, expect, it } from 'vitest';
import { createEmailClient } from '@kiwa-lab/email';
describe('user signup email', () => {
it('welcome mail が queued', async () => {
const client = createEmailClient({ provider: 'resend' });
const res = await client.send({ from: 'noreply@x', to: 'new@x', subject: 'welcome', text: 'hi' });
expect(res.status).toBe('queued');
expect(client.listSent()).toHaveLength(1);
});
});/kiwa-email skill を起動すると Layer 1 spec から send / verify / parse の 3 経路を含む test を生成できる。
License
UNLICENSED — see cardene777/kiwa for repo terms.
