@c9up/rover 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/dist/BaseMail.d.ts +28 -0
  4. package/dist/BaseMail.d.ts.map +1 -0
  5. package/dist/BaseMail.js +42 -0
  6. package/dist/BaseMail.js.map +1 -0
  7. package/dist/Mail.d.ts +166 -0
  8. package/dist/Mail.d.ts.map +1 -0
  9. package/dist/Mail.js +451 -0
  10. package/dist/Mail.js.map +1 -0
  11. package/dist/MessageBuilder.d.ts +38 -0
  12. package/dist/MessageBuilder.d.ts.map +1 -0
  13. package/dist/MessageBuilder.js +70 -0
  14. package/dist/MessageBuilder.js.map +1 -0
  15. package/dist/RoverError.d.ts +30 -0
  16. package/dist/RoverError.d.ts.map +1 -0
  17. package/dist/RoverError.js +33 -0
  18. package/dist/RoverError.js.map +1 -0
  19. package/dist/RoverProvider.d.ts +24 -0
  20. package/dist/RoverProvider.d.ts.map +1 -0
  21. package/dist/RoverProvider.js +51 -0
  22. package/dist/RoverProvider.js.map +1 -0
  23. package/dist/config.d.ts +4 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +4 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/index.d.ts +9 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +7 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/queue/MailJob.d.ts +41 -0
  32. package/dist/queue/MailJob.d.ts.map +1 -0
  33. package/dist/queue/MailJob.js +75 -0
  34. package/dist/queue/MailJob.js.map +1 -0
  35. package/dist/retry.d.ts +20 -0
  36. package/dist/retry.d.ts.map +1 -0
  37. package/dist/retry.js +101 -0
  38. package/dist/retry.js.map +1 -0
  39. package/dist/services/main.d.ts +20 -0
  40. package/dist/services/main.d.ts.map +1 -0
  41. package/dist/services/main.js +33 -0
  42. package/dist/services/main.js.map +1 -0
  43. package/dist/templating/SimpleTemplate.d.ts +7 -0
  44. package/dist/templating/SimpleTemplate.d.ts.map +1 -0
  45. package/dist/templating/SimpleTemplate.js +192 -0
  46. package/dist/templating/SimpleTemplate.js.map +1 -0
  47. package/dist/templating/loadNapi.d.ts +21 -0
  48. package/dist/templating/loadNapi.d.ts.map +1 -0
  49. package/dist/templating/loadNapi.js +115 -0
  50. package/dist/templating/loadNapi.js.map +1 -0
  51. package/dist/testing/FakeMail.d.ts +31 -0
  52. package/dist/testing/FakeMail.d.ts.map +1 -0
  53. package/dist/testing/FakeMail.js +90 -0
  54. package/dist/testing/FakeMail.js.map +1 -0
  55. package/dist/transports/MailgunTransport.d.ts +7 -0
  56. package/dist/transports/MailgunTransport.d.ts.map +1 -0
  57. package/dist/transports/MailgunTransport.js +149 -0
  58. package/dist/transports/MailgunTransport.js.map +1 -0
  59. package/dist/transports/ResendTransport.d.ts +7 -0
  60. package/dist/transports/ResendTransport.d.ts.map +1 -0
  61. package/dist/transports/ResendTransport.js +111 -0
  62. package/dist/transports/ResendTransport.js.map +1 -0
  63. package/dist/transports/SendGridTransport.d.ts +7 -0
  64. package/dist/transports/SendGridTransport.d.ts.map +1 -0
  65. package/dist/transports/SendGridTransport.js +165 -0
  66. package/dist/transports/SendGridTransport.js.map +1 -0
  67. package/dist/transports/SesTransport.d.ts +7 -0
  68. package/dist/transports/SesTransport.d.ts.map +1 -0
  69. package/dist/transports/SesTransport.js +334 -0
  70. package/dist/transports/SesTransport.js.map +1 -0
  71. package/dist/transports/fetchError.d.ts +13 -0
  72. package/dist/transports/fetchError.d.ts.map +1 -0
  73. package/dist/transports/fetchError.js +35 -0
  74. package/dist/transports/fetchError.js.map +1 -0
  75. package/dist/webhooks/context.d.ts +35 -0
  76. package/dist/webhooks/context.d.ts.map +1 -0
  77. package/dist/webhooks/context.js +7 -0
  78. package/dist/webhooks/context.js.map +1 -0
  79. package/dist/webhooks/mailgun.d.ts +13 -0
  80. package/dist/webhooks/mailgun.d.ts.map +1 -0
  81. package/dist/webhooks/mailgun.js +102 -0
  82. package/dist/webhooks/mailgun.js.map +1 -0
  83. package/dist/webhooks/resend.d.ts +16 -0
  84. package/dist/webhooks/resend.d.ts.map +1 -0
  85. package/dist/webhooks/resend.js +121 -0
  86. package/dist/webhooks/resend.js.map +1 -0
  87. package/dist/webhooks/sendgrid.d.ts +13 -0
  88. package/dist/webhooks/sendgrid.d.ts.map +1 -0
  89. package/dist/webhooks/sendgrid.js +104 -0
  90. package/dist/webhooks/sendgrid.js.map +1 -0
  91. package/index.darwin-arm64.node +0 -0
  92. package/index.darwin-x64.node +0 -0
  93. package/index.linux-arm64-gnu.node +0 -0
  94. package/index.linux-x64-gnu.node +0 -0
  95. package/index.win32-x64-msvc.node +0 -0
  96. package/package.json +97 -0
  97. package/scripts/copy-napi.mjs +62 -0
  98. package/src/BaseMail.ts +52 -0
  99. package/src/Mail.ts +663 -0
  100. package/src/MessageBuilder.ts +101 -0
  101. package/src/RoverError.ts +44 -0
  102. package/src/RoverProvider.ts +72 -0
  103. package/src/config.ts +7 -0
  104. package/src/index.ts +30 -0
  105. package/src/queue/MailJob.ts +131 -0
  106. package/src/retry.ts +135 -0
  107. package/src/services/main.ts +41 -0
  108. package/src/templating/SimpleTemplate.ts +240 -0
  109. package/src/templating/loadNapi.ts +169 -0
  110. package/src/testing/FakeMail.ts +112 -0
  111. package/src/transports/MailgunTransport.ts +204 -0
  112. package/src/transports/ResendTransport.ts +147 -0
  113. package/src/transports/SendGridTransport.ts +246 -0
  114. package/src/transports/SesTransport.ts +394 -0
  115. package/src/transports/fetchError.ts +42 -0
  116. package/src/webhooks/context.ts +41 -0
  117. package/src/webhooks/mailgun.ts +134 -0
  118. package/src/webhooks/resend.ts +164 -0
  119. package/src/webhooks/sendgrid.ts +133 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 C9up
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # @c9up/rover
2
+
3
+ Mail transport for Ream — SMTP, log, and pluggable transports (Mailgun, SendGrid, SES, Resend), plus class-based mailers (`BaseMail`), async templating (`htmlView`), in-process retry with exponential backoff, and an optional queue path via `@c9up/bay`.
4
+
5
+ ## Quick start
6
+
7
+ ```ts
8
+ import { Mail } from '@c9up/rover'
9
+ import '@c9up/rover/transports/mailgun' // opt-in side-effect registration
10
+
11
+ const mail = new Mail({
12
+ default: 'mailgun',
13
+ from: 'noreply@acme.com',
14
+ transports: {
15
+ mailgun: { transport: 'mailgun', apiKey: process.env.MAILGUN_KEY!, domain: 'mg.acme.com' },
16
+ },
17
+ })
18
+
19
+ await mail.send((m) => m.to('user@example.com').subject('Welcome').html('<p>Hi</p>'))
20
+ ```
21
+
22
+ ## Webhooks
23
+
24
+ Providers push delivery events (`delivered`, `bounced`, `failed`) to a URL you configure. Rover ships signature-verifying middleware for Mailgun, SendGrid, and Resend that emit canonical `mail.*` events into your event bus.
25
+
26
+ ```ts
27
+ import { createMailgunWebhookHandler } from '@c9up/rover/webhooks/mailgun'
28
+ import { Emitter } from '@c9up/ream/events'
29
+
30
+ const emitter = app.container.resolve(Emitter)
31
+
32
+ router.post(
33
+ '/webhooks/mailgun',
34
+ createMailgunWebhookHandler({
35
+ signingKey: process.env.MAILGUN_SIGNING_KEY!,
36
+ emitter,
37
+ // maxAgeSeconds: 300 (default) — rejects replayed-old signatures
38
+ }),
39
+ )
40
+ ```
41
+
42
+ The handler verifies the HMAC over `timestamp + token`, enforces a ±5 minute replay window, and emits `mail.delivered` / `mail.bounced` / `mail.failed` on the bus. Invalid / stale / missing signatures return `401` without leaking internals.
43
+
44
+ SendGrid (Ed25519 via `x-twilio-email-event-webhook-signature`) and Resend (Svix HMAC via `svix-signature`) use the same API shape:
45
+
46
+ ```ts
47
+ import { createSendGridWebhookHandler } from '@c9up/rover/webhooks/sendgrid'
48
+ import { createResendWebhookHandler } from '@c9up/rover/webhooks/resend'
49
+
50
+ router.post('/webhooks/sendgrid', createSendGridWebhookHandler({
51
+ publicKey: process.env.SENDGRID_WEBHOOK_PUBLIC_KEY!,
52
+ emitter,
53
+ }))
54
+
55
+ router.post('/webhooks/resend', createResendWebhookHandler({
56
+ secret: process.env.RESEND_WEBHOOK_SECRET!, // accepts both `whsec_...` and raw base64
57
+ emitter,
58
+ }))
59
+ ```
60
+
61
+ ### `rawBody()` contract
62
+
63
+ All three handlers rely on `ctx.request.rawBody()` returning the exact bytes the provider signed. If your framework re-parses the body into JSON before the handler sees it and your `rawBody()` returns a re-serialised copy, bytes differ and every signature fails. Mount these handlers on a route where the raw body is preserved (e.g. skip the JSON body parser on `/webhooks/**`).
64
+
65
+ ## Queue / `sendLater`
66
+
67
+ Register `@c9up/bay`'s `QueueManager` in your container and Rover will pick it up automatically:
68
+
69
+ ```ts
70
+ import '@c9up/rover/transports/mailgun'
71
+ import { QueueManager, MemoryDriver } from '@c9up/bay'
72
+
73
+ app.container.singleton('QueueManager', () => new QueueManager(new MemoryDriver()))
74
+
75
+ // Then in a request handler:
76
+ await mail.sendLater((m) => m.to('user@acme.com').subject('Welcome').html('<p>Hi</p>'))
77
+ // returns a job id string; the actual send runs on the Bay worker.
78
+ ```
79
+
80
+ Without a `QueueManager` wired, `sendLater` throws `MAIL_QUEUE_REQUIRED`.
81
+
82
+ ## Testing
83
+
84
+ ```ts
85
+ import '@c9up/rover/transports/mailgun' // register whatever transports your app uses
86
+
87
+ const fake = mail.fake()
88
+ await userRegistration({ email: 'user@acme.com' })
89
+ fake.assertSent({ to: 'user@acme.com', subject: 'Welcome' })
90
+ mail.restore()
91
+ ```
@@ -0,0 +1,28 @@
1
+ import { type MailMessage, MessageBuilder } from "./MessageBuilder.js";
2
+ export type MailAddress = string | {
3
+ address: string;
4
+ name: string;
5
+ };
6
+ /**
7
+ * Abstract base for class-based mail messages (Adonis parity).
8
+ *
9
+ * class WelcomeMail extends BaseMail {
10
+ * from = { address: "noreply@acme.com", name: "Acme" };
11
+ * subject = "Welcome!";
12
+ * constructor(private user: User) { super(); }
13
+ * async prepare() {
14
+ * this.message.to(this.user.email).html(...);
15
+ * }
16
+ * }
17
+ *
18
+ * await mail.send(new WelcomeMail(user));
19
+ */
20
+ export declare abstract class BaseMail {
21
+ protected readonly message: MessageBuilder;
22
+ from?: MailAddress;
23
+ subject?: string;
24
+ constructor();
25
+ abstract prepare(): void | Promise<void>;
26
+ build(): Promise<MailMessage>;
27
+ }
28
+ //# sourceMappingURL=BaseMail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseMail.d.ts","sourceRoot":"","sources":["../src/BaseMail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEvE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE;;;;;;;;;;;;;GAaG;AACH,8BAAsB,QAAQ;IAC7B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAwB;IAElE,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;;IAUjB,QAAQ,CAAC,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAElC,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;CAUnC"}
@@ -0,0 +1,42 @@
1
+ import { MessageBuilder } from "./MessageBuilder.js";
2
+ /**
3
+ * Abstract base for class-based mail messages (Adonis parity).
4
+ *
5
+ * class WelcomeMail extends BaseMail {
6
+ * from = { address: "noreply@acme.com", name: "Acme" };
7
+ * subject = "Welcome!";
8
+ * constructor(private user: User) { super(); }
9
+ * async prepare() {
10
+ * this.message.to(this.user.email).html(...);
11
+ * }
12
+ * }
13
+ *
14
+ * await mail.send(new WelcomeMail(user));
15
+ */
16
+ export class BaseMail {
17
+ message = new MessageBuilder();
18
+ from;
19
+ subject;
20
+ constructor() {
21
+ if (new.target === BaseMail) {
22
+ throw new Error("BaseMail is abstract and cannot be instantiated directly");
23
+ }
24
+ }
25
+ async build() {
26
+ if (this.from !== undefined) {
27
+ this.message.from(formatAddress(this.from));
28
+ }
29
+ if (this.subject !== undefined) {
30
+ this.message.subject(this.subject);
31
+ }
32
+ await this.prepare();
33
+ return this.message.build();
34
+ }
35
+ }
36
+ function formatAddress(addr) {
37
+ if (typeof addr === "string") {
38
+ return addr;
39
+ }
40
+ return `"${addr.name}" <${addr.address}>`;
41
+ }
42
+ //# sourceMappingURL=BaseMail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseMail.js","sourceRoot":"","sources":["../src/BaseMail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIvE;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAgB,QAAQ;IACV,OAAO,GAAmB,IAAI,cAAc,EAAE,CAAC;IAElE,IAAI,CAAe;IACnB,OAAO,CAAU;IAEjB;QACC,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACd,0DAA0D,CAC1D,CAAC;QACH,CAAC;IACF,CAAC;IAID,KAAK,CAAC,KAAK;QACV,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;CACD;AAED,SAAS,aAAa,CAAC,IAAiB;IACvC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,OAAO,GAAG,CAAC;AAC3C,CAAC"}
package/dist/Mail.d.ts ADDED
@@ -0,0 +1,166 @@
1
+ import { BaseMail } from "./BaseMail.js";
2
+ import { type MailAttachment, type MailMessage, MessageBuilder } from "./MessageBuilder.js";
3
+ import { type BayQueueLike } from "./queue/MailJob.js";
4
+ import { type RetryConfig } from "./retry.js";
5
+ import { FakeMail } from "./testing/FakeMail.js";
6
+ export type { MailAttachment, MailMessage };
7
+ export { MessageBuilder };
8
+ /**
9
+ * Mail — send emails via pluggable transports.
10
+ *
11
+ * Like AdonisJS Mail:
12
+ * await mail.send((message) => {
13
+ * message.to('user@example.com')
14
+ * message.subject('Welcome')
15
+ * message.html('<h1>Hello</h1>')
16
+ * })
17
+ *
18
+ * Transports: SMTP, log (dev), custom.
19
+ * Configured via config/mail.ts.
20
+ */
21
+ export interface MailSendResult {
22
+ /** Provider-returned message id (Mailgun `mg-abc`, SendGrid `X-Message-Id`, etc.). */
23
+ providerId?: string;
24
+ }
25
+ /**
26
+ * Return shape of `MailTransport.send`. Transports that don't surface a
27
+ * provider id may `return` nothing (implicit `undefined`); transports that
28
+ * do return `{ providerId }`. `undefined` rather than `void` in the union
29
+ * keeps the linter happy (`noConfusingVoidType`) while preserving the
30
+ * "no result" semantics.
31
+ */
32
+ export type MailSendOutcome = MailSendResult | undefined;
33
+ export interface MailTransport {
34
+ send(message: MailMessage): Promise<MailSendOutcome>;
35
+ }
36
+ /**
37
+ * Structural interface for the event bus `Emitter` — peer-dep friendly.
38
+ * Rover never hard-imports the event bus.
39
+ */
40
+ export interface EmitterLike {
41
+ emit(event: string, data: unknown): void;
42
+ }
43
+ export interface MailSentEvent {
44
+ messageId: string;
45
+ to: string[];
46
+ cc: string[];
47
+ bcc: string[];
48
+ transportName: string;
49
+ timestamp: number;
50
+ }
51
+ export interface MailFailedEvent {
52
+ messageId: string;
53
+ to: string[];
54
+ cc: string[];
55
+ bcc: string[];
56
+ transportName: string;
57
+ error: {
58
+ code: string;
59
+ message: string;
60
+ upstreamStatus?: number;
61
+ upstreamStatusRaw?: string;
62
+ attempts: number;
63
+ };
64
+ timestamp: number;
65
+ }
66
+ export interface MailConfig {
67
+ default: string;
68
+ from: string;
69
+ transports: Record<string, {
70
+ transport: string;
71
+ retry?: RetryConfig;
72
+ [key: string]: unknown;
73
+ }>;
74
+ /** Root directory for `htmlView(path, data)` template lookups. Default: `"resources/views/emails"`. */
75
+ viewsRoot?: string;
76
+ /** Optional Bay queue tuning for `sendLater()`. */
77
+ queue?: {
78
+ name?: string;
79
+ maxAttempts?: number;
80
+ };
81
+ /** Process-wide retry defaults. Overridden per-transport via `transports[name].retry`. */
82
+ retry?: RetryConfig;
83
+ }
84
+ /**
85
+ * Event hooks invoked by the internal dispatch loop. Default implementations
86
+ * are no-ops; when an event-bus `EmitterLike` is wired, the hooks emit
87
+ * `mail.sent` / `mail.failed`. Tests inject spies.
88
+ */
89
+ export interface MailHooks {
90
+ onSent?(event: MailSentEvent): void;
91
+ onFailed?(event: MailFailedEvent): void;
92
+ }
93
+ /**
94
+ * Message builder — fluent API for composing an email.
95
+ */
96
+ /**
97
+ * SMTP transport — thin wrapper around `nodemailer`. Nodemailer handles
98
+ * the SMTP state machine, TLS / STARTTLS negotiation, AUTH LOGIN /
99
+ * PLAIN / XOAUTH2, dot-stuffing, MIME assembly, attachments, and address
100
+ * encoding for 10+ years. We forward the `MailMessage` shape and surface
101
+ * the `messageId` returned by the server.
102
+ */
103
+ export declare class SmtpTransport implements MailTransport {
104
+ #private;
105
+ constructor(config: Record<string, unknown>);
106
+ send(message: MailMessage): Promise<MailSendOutcome>;
107
+ }
108
+ /**
109
+ * Log transport — logs emails to console (development).
110
+ */
111
+ export declare class LogTransport implements MailTransport {
112
+ send(message: MailMessage): Promise<MailSendOutcome>;
113
+ }
114
+ export type MailTransportFactory = (config: Record<string, unknown>) => MailTransport;
115
+ /**
116
+ * Register a custom transport factory globally.
117
+ *
118
+ * @example
119
+ * registerTransport('mailgun', (config) => new MailgunTransport(config))
120
+ * // Now config/mail.ts can reference `transport: 'mailgun'`
121
+ */
122
+ export declare function registerTransport(name: string, factory: MailTransportFactory): void;
123
+ /**
124
+ * Mail manager — send emails via configured transport.
125
+ */
126
+ export declare class Mail {
127
+ #private;
128
+ constructor(config: MailConfig, options?: {
129
+ queue?: BayQueueLike;
130
+ hooks?: MailHooks;
131
+ emitter?: EmitterLike;
132
+ });
133
+ /** Send an email using the fluent message builder. */
134
+ send(callback: (message: MessageBuilder) => void, transport?: string): Promise<void>;
135
+ /** Send an email using a class-based `BaseMail` instance. */
136
+ send(instance: BaseMail, transport?: string): Promise<void>;
137
+ /**
138
+ * Enqueue a send onto the Bay queue. Returns the job id. Throws
139
+ * `MAIL_QUEUE_REQUIRED` if no `QueueManager` was wired through the
140
+ * constructor options.
141
+ */
142
+ sendLater(arg: ((message: MessageBuilder) => void) | BaseMail, options?: {
143
+ transport?: string;
144
+ queue?: string;
145
+ }): Promise<string>;
146
+ /**
147
+ * Shared transport-resolve-then-send helper used by `send()` and `MailJobHandler`.
148
+ * Applies in-process retry with exponential backoff per `RetryConfig` resolution
149
+ * (per-transport > global > library default). Fires `onSent` / `onFailed` hooks.
150
+ *
151
+ * `overrideRetry` (optional) wins over config-level retry; `MailJobHandler` passes
152
+ * `{ maxAttempts: 1 }` so queue-level and sync-level retries don't compound.
153
+ */
154
+ dispatchMessage(message: MailMessage, transportName?: string, overrideRetry?: RetryConfig): Promise<void>;
155
+ /** Get a specific transport. */
156
+ use(name: string): MailTransport;
157
+ /**
158
+ * Swap the default transport with a `FakeMail` that captures every send.
159
+ * Call `restore()` to re-install the original. Throws if a fake is already
160
+ * active — nested fakes always indicate a forgotten `restore()`.
161
+ */
162
+ fake(): FakeMail;
163
+ /** Undo the swap installed by `fake()`. No-op if no fake is active. */
164
+ restore(): void;
165
+ }
166
+ //# sourceMappingURL=Mail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mail.d.ts","sourceRoot":"","sources":["../src/Mail.ts"],"names":[],"mappings":"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"}