@t4h.framework/smtp 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ai/skills/framework-smtp/SKILL.md +32 -104
- package/CHANGELOG.md +39 -0
- package/package.json +3 -3
|
@@ -6,7 +6,7 @@ description: >-
|
|
|
6
6
|
Smtp client, recipients/cc/bcc normalization, HTML bodies, Binary attachments,
|
|
7
7
|
and SmtpSendEmailOutput. Use when sending email from workflows, wiring SMTP
|
|
8
8
|
claim providers, testing email activities, implementing SmtpSendEmailClaim,
|
|
9
|
-
or working in packages/smtp
|
|
9
|
+
or working in packages/smtp.
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# @t4h.framework/smtp
|
|
@@ -72,19 +72,14 @@ type ISmtpSendEmailOutput = { messageId: string }
|
|
|
72
72
|
|
|
73
73
|
---
|
|
74
74
|
|
|
75
|
-
##
|
|
75
|
+
## Send options and payload
|
|
76
76
|
|
|
77
|
-
`
|
|
77
|
+
The exported `SmtpSendEmailActivity` — driven by `smtp.send` or directly via
|
|
78
|
+
`History.reconciler(SmtpSendEmailActivity, smtp, content)` — is replay-safe and
|
|
79
|
+
delegates to `SmtpSendEmailClaim.send`, returning a `SmtpSendEmailOutput`. Its
|
|
80
|
+
input shapes:
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|--------|------|
|
|
81
|
-
| `toInput(smtp, content)` | Builds serializable `SmtpSendEmailActivityInput` |
|
|
82
|
-
| `run(payload)` | `this.claims.smtp.send(payload)` |
|
|
83
|
-
| `toOutput(raw)` | `new SmtpSendEmailOutput(raw)` |
|
|
84
|
-
|
|
85
|
-
Claim wiring (private `Claim` with key `smtp` → `SmtpSendEmailClaim`).
|
|
86
|
-
|
|
87
|
-
### SmtpSendEmailActivityOptions (designer / `Smtp.send`)
|
|
82
|
+
### SmtpSendEmailActivityOptions (what `smtp.send` accepts)
|
|
88
83
|
|
|
89
84
|
| Field | Type | Required | Notes |
|
|
90
85
|
|-------|------|----------|-------|
|
|
@@ -120,7 +115,7 @@ type SmtpSendEmailActivityAttachment = {
|
|
|
120
115
|
}
|
|
121
116
|
```
|
|
122
117
|
|
|
123
|
-
Use framework `Binary` instances (e.g. from HTTP `response.body
|
|
118
|
+
Use framework `Binary` instances (e.g. from an HTTP `response.body`).
|
|
124
119
|
|
|
125
120
|
---
|
|
126
121
|
|
|
@@ -158,9 +153,11 @@ await smtp.send({
|
|
|
158
153
|
})
|
|
159
154
|
```
|
|
160
155
|
|
|
161
|
-
###
|
|
156
|
+
### Using the exported activity directly via `History.reconciler`
|
|
162
157
|
|
|
163
|
-
Prefer `smtp.send` in workflows.
|
|
158
|
+
Prefer `smtp.send` in workflows. When you need the exported activity directly,
|
|
159
|
+
drive the **shipped** `SmtpSendEmailActivity` through `History.reconciler` — a
|
|
160
|
+
ready, replay-safe helper. Never define or extend your own activity:
|
|
164
161
|
|
|
165
162
|
```typescript
|
|
166
163
|
import { History } from '@t4h.framework/core'
|
|
@@ -174,7 +171,7 @@ const result = await History.reconciler(SmtpSendEmailActivity, smtp, {
|
|
|
174
171
|
})
|
|
175
172
|
```
|
|
176
173
|
|
|
177
|
-
|
|
174
|
+
Runs inside a workflow (the runtime, or `TestWorkflowEnvironment` in tests, provides the reconciler context).
|
|
178
175
|
|
|
179
176
|
---
|
|
180
177
|
|
|
@@ -193,8 +190,6 @@ Activity and `Smtp.send` surface this type, not the raw `{ messageId }` object.
|
|
|
193
190
|
|
|
194
191
|
## Workflow example
|
|
195
192
|
|
|
196
|
-
From `examples/email/src/main.tsx`:
|
|
197
|
-
|
|
198
193
|
```typescript
|
|
199
194
|
import { App, EnvDesign, Workflow } from '@t4h.framework/core'
|
|
200
195
|
import { http } from '@t4h.framework/http'
|
|
@@ -234,99 +229,32 @@ Connection strings are opaque to the package; dev implementation expects URL for
|
|
|
234
229
|
|
|
235
230
|
Run package tests: `yarn test` in `packages/smtp` (Vitest).
|
|
236
231
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
232
|
+
Test the **workflow** with `TestWorkflowEnvironment` from
|
|
233
|
+
`@t4h.framework/core/testing`, mocking `SmtpSendEmailClaim` — the single claim
|
|
234
|
+
the send activity resolves. See the **framework-workflow-testing** skill for the
|
|
235
|
+
harness API.
|
|
240
236
|
|
|
241
237
|
```typescript
|
|
242
|
-
import {
|
|
243
|
-
import {
|
|
244
|
-
import {
|
|
245
|
-
Smtp,
|
|
246
|
-
SmtpSendEmailActivity,
|
|
247
|
-
SmtpSendEmailClaim,
|
|
248
|
-
type SmtpSendEmailActivityInput,
|
|
249
|
-
} from '@t4h.framework/smtp'
|
|
250
|
-
|
|
251
|
-
const mockSend = vi.fn().mockReturnValue({ messageId: 'msg-123' })
|
|
252
|
-
|
|
253
|
-
Claim.run(
|
|
254
|
-
[{ provide: SmtpSendEmailClaim, value: { send: mockSend } as SmtpSendEmailClaim }],
|
|
255
|
-
() => {
|
|
256
|
-
const activity = Reflect.construct(SmtpSendEmailActivity, [])
|
|
257
|
-
const input: SmtpSendEmailActivityInput = {
|
|
258
|
-
connectionString: 'smtp://user:pass@smtp.example.com:587',
|
|
259
|
-
from: 'sender@example.com',
|
|
260
|
-
subject: 'Test',
|
|
261
|
-
html: '<p>Hello</p>',
|
|
262
|
-
to: ['recipient@example.com'],
|
|
263
|
-
}
|
|
264
|
-
const output = activity.run(input)
|
|
265
|
-
expect(mockSend).toHaveBeenCalledWith(input)
|
|
266
|
-
expect(output).toEqual({ messageId: 'msg-123' })
|
|
267
|
-
},
|
|
268
|
-
)
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
Use `mockResolvedValue` when testing async `send` implementations.
|
|
272
|
-
|
|
273
|
-
Assert `toInput` normalization: single `to` → array; `content.from` over `smtp.options.from`; `cc`/`bcc` string → array; attachments reference equality.
|
|
238
|
+
import { TestWorkflowEnvironment, mockClaim } from '@t4h.framework/core/testing'
|
|
239
|
+
import { SmtpSendEmailClaim } from '@t4h.framework/smtp'
|
|
274
240
|
|
|
275
|
-
|
|
241
|
+
const mockSend = vi.fn().mockImplementation(async () => ({ messageId: 'msg-123' }))
|
|
276
242
|
|
|
277
|
-
|
|
243
|
+
const env = TestWorkflowEnvironment.create({ now: 0 })
|
|
278
244
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
async function captureReconcilerTrigger(fn: () => unknown) {
|
|
284
|
-
try {
|
|
285
|
-
await History.run([], fn)
|
|
286
|
-
} catch (error) {
|
|
287
|
-
if (error instanceof PushActivity) return error as PushActivity<Activity>
|
|
288
|
-
throw error
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const client = new Smtp(connectionString, { from: 'noreply@example.com' })
|
|
293
|
-
const trigger = await captureReconcilerTrigger(() =>
|
|
294
|
-
client.send({ to: 'a@example.com', subject: 'Test', html: '<p>Hi</p>' }),
|
|
295
|
-
)
|
|
245
|
+
await env.execute(workflow, input, {
|
|
246
|
+
claims: [mockClaim(SmtpSendEmailClaim, { send: mockSend })],
|
|
247
|
+
env: { SMTP_CONNECTION_STRING: 'smtp://user:pass@smtp.example.com:587' },
|
|
248
|
+
})
|
|
296
249
|
|
|
297
|
-
|
|
298
|
-
expect(
|
|
299
|
-
|
|
300
|
-
from: 'noreply@example.com',
|
|
250
|
+
// `send` receives the normalized activity input (single `to` becomes an array, etc.)
|
|
251
|
+
expect(mockSend.mock.calls[0][0]).toMatchObject({
|
|
252
|
+
to: ['recipient@example.com'],
|
|
301
253
|
subject: 'Test',
|
|
302
|
-
html: '<p>
|
|
303
|
-
to: ['a@example.com'],
|
|
304
|
-
cc: undefined,
|
|
305
|
-
bcc: undefined,
|
|
306
|
-
attachments: undefined,
|
|
254
|
+
html: '<p>Hello</p>',
|
|
307
255
|
})
|
|
308
256
|
```
|
|
309
257
|
|
|
310
|
-
### 3. Replay with history
|
|
311
|
-
|
|
312
|
-
```typescript
|
|
313
|
-
import { History } from '@t4h.framework/core'
|
|
314
|
-
import { Smtp, SmtpSendEmailOutput } from '@t4h.framework/smtp'
|
|
315
|
-
|
|
316
|
-
const result = await History.run(
|
|
317
|
-
[{ output: { messageId: '<msg-123@example.com>' }, type: 'sync' }],
|
|
318
|
-
() =>
|
|
319
|
-
client.send({
|
|
320
|
-
to: 'user@example.com',
|
|
321
|
-
subject: 'Subject',
|
|
322
|
-
html: '<p>Body</p>',
|
|
323
|
-
}),
|
|
324
|
-
)
|
|
325
|
-
|
|
326
|
-
expect(result).toBeInstanceOf(SmtpSendEmailOutput)
|
|
327
|
-
expect(result.messageId).toBe('<msg-123@example.com>')
|
|
328
|
-
```
|
|
329
|
-
|
|
330
258
|
---
|
|
331
259
|
|
|
332
260
|
## Implementing SmtpSendEmailClaim
|
|
@@ -341,14 +269,14 @@ expect(result.messageId).toBe('<msg-123@example.com>')
|
|
|
341
269
|
|
|
342
270
|
## Checklist for agents
|
|
343
271
|
|
|
344
|
-
1.
|
|
272
|
+
1. In workflows, use **`Smtp` + `smtp.send()`** (or `History.reconciler` with the exported `SmtpSendEmailActivity`) — never define or extend your own activity.
|
|
345
273
|
2. Ensure runtime provides **`SmtpSendEmailClaim`** (or a mock in tests).
|
|
346
274
|
3. Use **`html`** for the message body; required fields on send options are **`to`**, **`subject`**, **`html`**.
|
|
347
275
|
4. Set default **`from`** on `new Smtp(connectionString, { from })` or per-send; per-send wins.
|
|
348
276
|
5. Pass **`Binary`** for attachment `content`, not raw `Buffer` in activity options.
|
|
349
277
|
6. Expect **`SmtpSendEmailOutput`** from `send`, not a plain object — use `.messageId`.
|
|
350
|
-
7.
|
|
278
|
+
7. Test workflows with **`TestWorkflowEnvironment`** + **`mockClaim(SmtpSendEmailClaim, { send })`**; assert on the mock's `mock.calls`.
|
|
351
279
|
8. Do not document or import APIs not exported from `@t4h.framework/smtp`.
|
|
352
280
|
9. For core workflow/reconciler concepts, use the **framework-core** skill (`@t4h.framework/core`).
|
|
353
281
|
|
|
354
|
-
See also: `packages/smtp/README.md
|
|
282
|
+
See also: `packages/smtp/README.md`; **framework-workflow-testing** for the test harness.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @t4h.framework/smtp
|
|
2
|
+
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`8098041`](https://github.com/tech4humans-brasil/framework/commit/80980419d59a987378b7c94372ee2f7b7dcc00f5)]:
|
|
8
|
+
- @t4h.framework/core@0.10.0
|
|
9
|
+
|
|
10
|
+
## 0.5.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- Update history to satisfies core contract ([`30b3d38`](https://github.com/tech4humans-brasil/framework/commit/30b3d38bfd631990e4c4f740344910d5958ddfb9))
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Update skills ([`6d7e7bc`](https://github.com/tech4humans-brasil/framework/commit/6d7e7bca0c780a9c53a0c9e5aa0a865c5af67959))
|
|
19
|
+
|
|
20
|
+
## 0.4.0
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Internal dependency updates
|
|
25
|
+
|
|
26
|
+
## 0.3.0
|
|
27
|
+
|
|
28
|
+
### Minor Changes
|
|
29
|
+
|
|
30
|
+
- Implements smtp activity ([`ca20afd`](https://github.com/tech4humans-brasil/framework/commit/ca20afdfc324a1004e77ef1881c049e7f97f0eff))
|
|
31
|
+
- Adds type to history item ([#47](https://github.com/tech4humans-brasil/framework/pull/47))
|
|
32
|
+
- Adds .ai/skills in packages ([#88](https://github.com/tech4humans-brasil/framework/pull/88))
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Update package metadata and author information across multiple packages ([`2ca73df`](https://github.com/tech4humans-brasil/framework/commit/2ca73df42dc63c86ed44717b50d5402fca45b4e7))
|
|
37
|
+
- Improve repository info ([`1fad92d`](https://github.com/tech4humans-brasil/framework/commit/1fad92d959b804189fd1486d047115995ac81eb0))
|
|
38
|
+
- Up repo coverage ([`24c057c`](https://github.com/tech4humans-brasil/framework/commit/24c057c470d0829ea9a1e1f71011b6eff408180c))
|
|
39
|
+
- Fix resolve module resolution issues in check-types ([`c97a0d2`](https://github.com/tech4humans-brasil/framework/commit/c97a0d2747f38e561cc5c7d592b20de0459bc1ee))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t4h.framework/smtp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "SMTP module for the T4H Framework",
|
|
5
5
|
"homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/smtp",
|
|
6
6
|
"bugs": "https://github.com/tech4humans-brasil/framework/issues",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"test:watch": "vitest"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@t4h.framework/core": "^0.
|
|
34
|
+
"@t4h.framework/core": "^0.10.0",
|
|
35
35
|
"typescript": "^5.9.3",
|
|
36
36
|
"vitest": "^4.0.18"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@t4h.framework/core": "^0.
|
|
39
|
+
"@t4h.framework/core": "^0.10.0"
|
|
40
40
|
},
|
|
41
41
|
"packageManager": "yarn@4.12.0",
|
|
42
42
|
"engines": {
|