@samveys/mail
Dari packages/mail/README.md di repository framework.
Halaman ini belum diterjemahkan. Kamu sedang membaca versi bahasa Inggris.
Send mail through SMTP (written on node:net / node:tls, no dependencies), a log transport, or a fake for tests. Every failure is SVS_E103.
Send
import { defineMail, mail, smtp } from '@samveys/mail'
export const welcome = defineMail<{ name: string; email: string }>((user) => ({
to: { name: user.name, address: user.email },
subject: `Welcome, ${user.name} ✓`,
text: `Hello ${user.name}`,
html: `<p>Hello <b>${user.name}</b></p>`,
}))
export const plugins = [
mail({
from: { name: 'Sadata', address: 'noreply@sadata.id' },
transport: smtp({
host: 'smtp.example.com',
port: 587,
requireTLS: true, // STARTTLS or fail; never falls back to clear text
auth: { user: 'apikey', pass: process.env.SMTP_PASSWORD ?? '' },
}),
}),
]Then await app.container.make('mail').send(welcome, { name: 'Ada', email: 'ada@example.com' }), or pass a plain message: send({ to, cc, bcc, replyTo, subject, text, html, headers }).
What goes on the wire: From, To, Cc, Subject (RFC 2047 encoded when not ASCII), Date, a generated Message-ID, MIME-Version, and multipart/alternative when both text and html are given. Bodies are quoted-printable by default; base64 is available through the encoding option. bcc only reaches the envelope. Header values with line breaks, and invalid addresses, are refused before anything is sent.
SMTP: EHLO, STARTTLS (or implicit TLS with secure: true), AUTH PLAIN then LOGIN, MAIL FROM, RCPT TO (a partial rejection still delivers to the accepted recipients), and DATA with dot-stuffing. Credentials are never sent over an unencrypted connection unless you set allowInsecureAuth.
Test without a network
import { createMailer, fake } from '@samveys/mail'
const transport = fake()
const mailer = createMailer({ transport, from: 'noreply@sadata.id' })
await mailer.send({ to: 'ada@example.com', subject: 'Receipt', text: 'Thanks' })
transport.assertSent((message) => message.subject === 'Receipt')
transport.assertNotSent((message) => message.subject === 'Other')log() prints each raw message instead of sending it, for local development.