@rudderjs/mail 1.0.0 → 1.0.1
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/README.md +2 -3
- package/boost/guidelines.md +106 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -36,10 +36,9 @@ export default {
|
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
38
|
// bootstrap/providers.ts
|
|
39
|
-
import {
|
|
40
|
-
import configs from '../config/index.js'
|
|
39
|
+
import { MailProvider } from '@rudderjs/mail'
|
|
41
40
|
|
|
42
|
-
export default [
|
|
41
|
+
export default [MailProvider]
|
|
43
42
|
```
|
|
44
43
|
|
|
45
44
|
## Defining Mailables
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# @rudderjs/mail
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Mail facade + mailable abstraction with built-in `log` (for dev) and `smtp` drivers. Laravel's `Mail` facade for Node. Mailables are classes with a `build()` method that configures subject/to/cc/bcc/html/text/attachments fluently. Integrates with `@rudderjs/notification` — the `mail` channel accepts `Mailable` instances.
|
|
6
|
+
|
|
7
|
+
## Key Patterns
|
|
8
|
+
|
|
9
|
+
### Setup
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// config/mail.ts
|
|
13
|
+
import type { MailConfig } from '@rudderjs/mail'
|
|
14
|
+
|
|
15
|
+
export default {
|
|
16
|
+
default: 'smtp',
|
|
17
|
+
from: { address: 'noreply@example.com', name: 'My App' },
|
|
18
|
+
mailers: {
|
|
19
|
+
log: { driver: 'log' }, // logs to console, no send
|
|
20
|
+
smtp: { driver: 'smtp', host: '...', port: 587, username: '...', password: '...', encryption: 'tls' },
|
|
21
|
+
},
|
|
22
|
+
} satisfies MailConfig
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`MailProvider` is auto-discovered — run `pnpm rudder providers:discover` after install. To register explicitly, list `MailProvider` in `bootstrap/providers.ts`.
|
|
26
|
+
|
|
27
|
+
Use `log` driver in dev and tests — no external SMTP required, all mail prints to the console.
|
|
28
|
+
|
|
29
|
+
### Defining Mailables
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { Mailable } from '@rudderjs/mail'
|
|
33
|
+
|
|
34
|
+
export class WelcomeMail extends Mailable {
|
|
35
|
+
constructor(private user: { email: string; name: string }) { super() }
|
|
36
|
+
|
|
37
|
+
build() {
|
|
38
|
+
return this
|
|
39
|
+
.to(this.user.email, this.user.name)
|
|
40
|
+
.subject(`Welcome, ${this.user.name}!`)
|
|
41
|
+
.html(`<h1>Hi ${this.user.name}</h1><p>Thanks for signing up.</p>`)
|
|
42
|
+
.text(`Hi ${this.user.name}\n\nThanks for signing up.`)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Sending
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { Mail } from '@rudderjs/mail'
|
|
51
|
+
|
|
52
|
+
// Fluent
|
|
53
|
+
await Mail.to('user@example.com').send(new WelcomeMail(user))
|
|
54
|
+
await Mail.to(user.email, user.name).cc('team@example.com').bcc('log@example.com').send(new WelcomeMail(user))
|
|
55
|
+
|
|
56
|
+
// Send to multiple recipients
|
|
57
|
+
await Mail.to(['a@example.com', 'b@example.com']).send(new Announcement())
|
|
58
|
+
|
|
59
|
+
// Target a specific mailer
|
|
60
|
+
await Mail.mailer('log').to(user.email).send(new WelcomeMail(user))
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Attachments
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
build() {
|
|
67
|
+
return this
|
|
68
|
+
.subject('Invoice')
|
|
69
|
+
.html('<p>See attached.</p>')
|
|
70
|
+
.attach('storage/invoices/123.pdf') // from disk
|
|
71
|
+
.attachData(pdfBuffer, 'invoice.pdf', { contentType: 'application/pdf' }) // from buffer
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Testing
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { Mail } from '@rudderjs/mail'
|
|
79
|
+
|
|
80
|
+
const fake = Mail.fake()
|
|
81
|
+
await Mail.to('user@example.com').send(new WelcomeMail(user))
|
|
82
|
+
|
|
83
|
+
fake.assertSent(WelcomeMail)
|
|
84
|
+
fake.assertSent(WelcomeMail, m => m.to[0] === 'user@example.com')
|
|
85
|
+
fake.assertSentCount(1)
|
|
86
|
+
fake.assertNotSent(PasswordResetMail)
|
|
87
|
+
fake.restore()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Common Pitfalls
|
|
91
|
+
|
|
92
|
+
- **`smtp` driver with bad credentials.** The driver lazy-loads `nodemailer` and sends on first call. Failures surface at send-time, not at boot. Use `log` driver in dev to avoid hitting SMTP at all.
|
|
93
|
+
- **Missing `from` address.** Required in config — throws at send-time if unset. The `from: { address, name }` block is not optional.
|
|
94
|
+
- **Mailable without `build()`.** Silent — send goes through with empty headers. Always implement `build()` and return `this` from the chain so the configuration actually applies.
|
|
95
|
+
- **HTML without text fallback.** Best practice: always set both `.html()` and `.text()`. Some clients (plain-text subscribers, accessibility tools) don't render HTML.
|
|
96
|
+
- **Forgetting `fake.restore()` in tests.** Fake state persists — subsequent tests assert against stale sends. Always restore in `afterEach`.
|
|
97
|
+
- **Telescope records mail.** `@rudderjs/telescope`'s `mail` collector records every send with subject, recipients, html, attachments. Redact sensitive fields via config if needed.
|
|
98
|
+
- **Method-as-property bug.** `mailable['subject']` returns the fluent setter function, not the value. Use `mailable.getSubject()` or read the private `_subject` field. This has bitten several collectors — don't assume bracket-access returns values for fluent builder classes.
|
|
99
|
+
|
|
100
|
+
## Key Imports
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { Mail, Mailable, MailProvider, FakeMailAdapter } from '@rudderjs/mail'
|
|
104
|
+
|
|
105
|
+
import type { MailConfig, MailAdapter } from '@rudderjs/mail'
|
|
106
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rudderjs/mail",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"rudderjs": {
|
|
5
5
|
"provider": "MailProvider",
|
|
6
6
|
"stage": "feature"
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"type": "module",
|
|
15
15
|
"files": [
|
|
16
|
-
"dist"
|
|
16
|
+
"dist",
|
|
17
|
+
"boost"
|
|
17
18
|
],
|
|
18
19
|
"main": "./dist/index.js",
|
|
19
20
|
"types": "./dist/index.d.ts",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
}
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@rudderjs/core": "^1.
|
|
28
|
+
"@rudderjs/core": "^1.1.2"
|
|
28
29
|
},
|
|
29
30
|
"optionalDependencies": {
|
|
30
31
|
"nodemailer": "^6.9.0"
|