@pearl-framework/mail
v1.0.0
Published
Pearl.js mail — Nodemailer-powered mailable classes, transports, and queue support
Downloads
47
Maintainers
Readme
@pearl-framework/mail
Mailable classes and multi-transport email sending for Pearl.js.
Installation
npm install @pearl-framework/mail @pearl-framework/core nodemailerRequires nodemailer v7+. Types are bundled —
@types/nodemaileris not needed.
Define a Mailable
A Mailable is a class that encapsulates a single email. Build it with a fluent API:
import { Mailable } from '@pearl-framework/mail'
export class WelcomeEmail extends Mailable {
constructor(private readonly user: User) { super() }
build(): this {
return this
.sendTo(this.user.email)
.from({ name: 'Pearl App', address: '[email protected]' })
.subject(`Welcome to Pearl, ${this.user.name}!`)
.html(`
<h1>Hi ${this.user.name}, welcome aboard!</h1>
<p>We're thrilled to have you.</p>
<a href="https://yourapp.com/dashboard">Get started →</a>
`)
.text(`Hi ${this.user.name}, welcome aboard! Visit https://yourapp.com/dashboard`)
}
}Send Mail
const mailer = app.make(Mailer)
await mailer.send(new WelcomeEmail(user))
await mailer.sendBulk([new InvoiceEmail(u1), new InvoiceEmail(u2)])Advanced Mailables
Multiple recipients
build(): this {
return this
.sendTo('[email protected]', '[email protected]')
.cc({ name: 'Manager', address: '[email protected]' })
.bcc('[email protected]')
.replyTo('[email protected]')
.subject('Team announcement')
.html('<p>Hello everyone!</p>')
}Attachments
build(): this {
return this
.sendTo(this.user.email)
.subject('Your invoice')
.html('<p>Please find your invoice attached.</p>')
.attach({
filename: 'invoice-2024-01.pdf',
path: `/tmp/invoices/${this.invoiceId}.pdf`,
contentType: 'application/pdf',
})
}Async build
build() can also be async — useful for fetching data inside the mailable:
async build(): Promise<this> {
const stats = await fetchUserStats(this.user.id)
return this
.sendTo(this.user.email)
.subject('Your weekly report')
.html(renderStatsTemplate(stats))
}MailServiceProvider
import { MailServiceProvider } from '@pearl-framework/mail'
import type { MailDriver } from '@pearl-framework/mail'
export class AppMailServiceProvider extends MailServiceProvider {
protected config = {
driver: (process.env.MAIL_DRIVER ?? 'log') as MailDriver,
from: {
name: 'Pearl App',
address: process.env.MAIL_FROM!,
},
smtp: {
host: process.env.MAIL_HOST!,
port: Number(process.env.MAIL_PORT ?? 587),
secure: false,
auth: {
user: process.env.MAIL_USER!,
pass: process.env.MAIL_PASS!,
},
},
}
}
app.register(AppMailServiceProvider)Transports
| Transport | Driver value | Description |
|---|---|---|
| SmtpTransport | 'smtp' | Send via any SMTP provider (Mailgun, Postmark, Resend, etc.) |
| SesTransport | 'ses' | Send via AWS SES (@aws-sdk/client-ses required) |
| LogTransport | 'log' | Print email details to the console instead of sending |
| ArrayTransport | 'array' | Capture sent mail in memory — for testing |
Switching by environment
// .env
MAIL_DRIVER=log # development
MAIL_DRIVER=smtp # productionThe LogTransport prints full email details to the console so you can verify emails look correct during development without needing an SMTP server.
Testing with ArrayTransport
import { ArrayTransport, Mailer } from '@pearl-framework/mail'
const transport = new ArrayTransport()
const mailer = new Mailer(transport)
await mailer.send(new WelcomeEmail(user))
const sent = transport.last()
assert.equal(sent?.subject, `Welcome to Pearl, ${user.name}!`)
assert.equal(transport.sent.length, 1)
transport.clear() // reset between testsAPI Reference
Mailable
| Method | Description |
|---|---|
| sendTo(...addresses) | Set recipient(s) — accepts strings or { name, address } objects |
| from(address) | Set the sender |
| cc(...addresses) | Add CC recipients |
| bcc(...addresses) | Add BCC recipients |
| replyTo(address) | Set the reply-to address |
| subject(value) | Set the subject line |
| html(content) | Set the HTML body |
| text(content) | Set the plain-text body |
| attach(attachment) | Add an attachment |
| build() | Required. Called by mailer.send() to build the mail — sync or async |
Mailer
| Method | Description |
|---|---|
| send(mailable) | Build and send a single mailable |
| sendBulk(mailables[]) | Build and send multiple mailables |
ArrayTransport
| Property / Method | Description |
|---|---|
| sent | Array of all BuiltMail objects that have been sent |
| last() | Returns the most recently sent mail, or undefined |
| clear() | Resets the sent array |
