@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 CHANGED
@@ -36,10 +36,9 @@ export default {
36
36
 
37
37
  ```ts
38
38
  // bootstrap/providers.ts
39
- import { mail } from '@rudderjs/mail'
40
- import configs from '../config/index.js'
39
+ import { MailProvider } from '@rudderjs/mail'
41
40
 
42
- export default [mail(configs.mail)]
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.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.0.0"
28
+ "@rudderjs/core": "^1.1.2"
28
29
  },
29
30
  "optionalDependencies": {
30
31
  "nodemailer": "^6.9.0"