@nwire/mail
v0.7.1
Published
Nwire — transactional-mail contract + InMemoryMailer default + mailPlugin. Adapters (SMTP/nodemailer, SES, SendGrid, …) live in separate packages.
Readme
@nwire/mail
Transactional-mail contract — narrow
Mailerinterface every adapter implements.
What it does
Defines Mailer (one send method) and ships mailPlugin({ mailer, defaultFrom? }) that registers it on the container with lifecycle hooks. Ships an in-memory InMemoryMailer that captures every send so tests can assert on subject/body/recipient.
Install
pnpm add @nwire/mailQuick start
import { mailPlugin, InMemoryMailer } from "@nwire/mail";
import { defineApp, defineAction } from "@nwire/forge";
const mailer = new InMemoryMailer();
defineApp("my-app", {
plugins: [mailPlugin({ mailer, defaultFrom: '"My App" <[email protected]>' })],
});
defineAction({
name: "users.sendWelcome",
handler: async ({ input }, ctx) => {
const mail = ctx.resolve<typeof mailer>("mailer");
await mail.send({ to: input.email, subject: "Welcome!", text: "..." });
},
});
// In tests:
expect(mailer.sent[0].subject).toBe("Welcome!");API surface
Mailer—send({ to, from?, cc?, bcc?, subject, text?, html?, attachments? }).mailPlugin({ mailer, defaultFrom? })— register on container; lifecycle-managed.InMemoryMailer— captures sends for assertions.MailAddress/MailRecipient/MailAttachment— message types.
When to use
Any app sending transactional mail (welcome, password reset, receipts).
Within nwire-app
For developers using this package as part of the Nwire stack — register it via app.use(...) or it auto-wires when you compose createApp({ modules }).
import { createApp } from "@nwire/forge";
const app = createApp({
/* ...config... */
});
// Adapter/plugin wiring happens here when applicable.