JSPM

@pearl-framework/mail

0.2.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 35
  • Score
    100M100P100Q51144F

Pearl.js mail — Nodemailer-powered mailable classes, transports, and queue support

Package Exports

  • @pearl-framework/mail

Readme

@pearl-framework/mail

Mailable classes and multi-transport email sending for Pearl.js.

npm

Installation

npm install @pearl-framework/mail @pearl-framework/core nodemailer

Requires nodemailer v7+. Types are bundled — @types/nodemailer is 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: 'hi@pearl.dev' })
      .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('alice@example.com', 'bob@example.com')
    .cc({ name: 'Manager', address: 'manager@example.com' })
    .bcc('audit@internal.com')
    .replyTo('support@example.com')
    .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  # production

The 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 tests

API 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