Adapter options
Every constructor option on the four built-in mail adapters, what each one defaults to, and the Ethereal throwaway inbox for tests.
Email covers picking an adapter and swapping one.
Everything below goes in the same slot, email.adapter in
questpie.config.ts, and none of it changes a template or a send call.
Console
import { ConsoleAdapter } from "questpie/adapters/console";
new ConsoleAdapter(); // both options are optional
new ConsoleAdapter({ logHtml: true });| Option | Type | Default | Notes |
|---|---|---|---|
logHtml | boolean | false | When false the HTML body becomes a one-line hint. HTML is long. |
logger | (message: string) => void | console.log | Where every line goes. |
It prints From, To, CC, BCC, Reply-To, Subject, the plain-text body, attachment filenames, and the HTML only when you ask. It never sends.
SMTP
import { SmtpAdapter } from "questpie/adapters/smtp";
new SmtpAdapter({
transport: {
host: "smtp.example.com",
port: 587,
secure: false,
auth: { user: env.SMTP_USER, pass: env.SMTP_PASS },
},
});
new SmtpAdapter({ transport: "smtp://user:pass@smtp.example.com:587" });| Option | Type | Notes |
|---|---|---|
transport | SMTPTransport | SMTPTransport.Options | string | Handed straight to nodemailer.createTransport. Required. |
afterSendCallback | (info: SentMessageInfo) => void | Promise<void> | Runs after each send, with nodemailer's info object. |
SerializableMailOptions is passed to sendMail unchanged, so CC, BCC,
attachments, replyTo and custom headers all behave the way nodemailer
documents them. SmtpAdapter also exposes verify(): Promise<boolean>, which
proxies nodemailer's connection check.
Ethereal test inbox
createEtherealSmtpAdapter() creates a throwaway
Ethereal account and returns an SmtpAdapter already
wired to log a preview URL after every send.
import { createEtherealSmtpAdapter } from "questpie/adapters/smtp";
export default runtimeConfig({
email: { adapter: createEtherealSmtpAdapter() }, // a Promise<SmtpAdapter>
});It returns a promise, which MailerConfig.adapter accepts as-is because the
mailer awaits the adapter on send. Dev and tests only. It makes a network call
to create the account.
Resend
import { resendAdapter } from "questpie/adapters/resend";
resendAdapter({ apiKey: env.RESEND_API_KEY });| Option | Type | Default | Notes |
|---|---|---|---|
apiKey | string | required | A Resend key, or one for a Resend-compatible provider. |
baseUrl | string | "https://api.resend.com" | Point at a compatible API. Trailing slashes are stripped. |
userAgent | string | "questpie-resend-adapter" | Resend wants a User-Agent on direct HTTP calls. |
idempotencyKey | string | ((options) => string | undefined) | none | Static or per-message. Sets the Idempotency-Key header. |
fetch | typeof fetch | global fetch | Override for tests or a non-standard runtime. |
afterSendCallback | (response: ResendSendResponse, options) => void | Promise<void> | none | Gets the parsed JSON body, so the message id lands here. |
It POSTs to <baseUrl>/emails, maps replyTo to reply_to, and base64-encodes
Buffer attachments. A non-2xx response throws
Resend API error (<status> <statusText>): <body>.
Plunk
import { plunkAdapter } from "questpie/adapters/plunk";
plunkAdapter({ apiKey: env.PLUNK_SECRET_KEY });| Option | Type | Default | Notes |
|---|---|---|---|
apiKey | string | required | A Plunk secret key. Public keys only track events. |
baseUrl | string | "https://next-api.useplunk.com" | Override for self-hosted Plunk. |
fromName | string | none | Applied only when from is a bare address, no Name <…>. |
subscribed | boolean | none | Subscribes recipients to marketing. Leave it off. |
fetch | typeof fetch | global fetch | Override for tests or a non-standard runtime. |
afterSendCallback | (response: PlunkSendResponse, options) => void | Promise<void> | none | Gets the parsed body once Plunk accepts the message. |
It POSTs to <baseUrl>/v1/send with body set to html || text and reply
carrying replyTo. It base64-encodes Buffer attachments, same as Resend, and
sends string attachment content through unchanged.
Two failure modes, not one
Plunk throws on a non-2xx response, and also on a 2xx whose body carries
success: false. Either way the message is a Plunk API error line with the
status and Plunk's own error code. A cc or bcc throws before the request.
Related
- Email, the adapter slot, the swap, and the
MailAdapterinterface. - Emails, the templates and send calls above all of this.
- Environment, typed
env()for API keys and SMTP credentials.
Tag invalidation
Group KV keys under a tag and drop the whole group in one call. Every built-in adapter implements it, but the methods sit on the adapter rather than on ctx.kv, so reaching them takes one deliberate step.
Running the supervisor
The Deno process that actually spawns guest subprocesses, the command to start it, the environment it reads, and the shared secret without which it refuses every run your app sends.