@gravito/signal 3.0.4 → 3.1.2
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.
- package/README.md +26 -15
- package/dist/Mailable.d.ts +453 -0
- package/dist/OrbitSignal.d.ts +267 -0
- package/{src/Queueable.ts → dist/Queueable.d.ts} +1 -1
- package/{src/TypedMailable.ts → dist/TypedMailable.d.ts} +12 -13
- package/dist/dev/DevMailbox.d.ts +79 -0
- package/dist/dev/DevServer.d.ts +39 -0
- package/dist/dev/storage/FileMailboxStorage.d.ts +16 -0
- package/dist/dev/storage/MailboxStorage.d.ts +14 -0
- package/dist/dev/storage/MemoryMailboxStorage.d.ts +13 -0
- package/dist/dev/ui/mailbox.d.ts +11 -0
- package/dist/dev/ui/preview.d.ts +11 -0
- package/dist/dev/ui/shared.d.ts +15 -0
- package/dist/errors.d.ts +58 -0
- package/{src/events.ts → dist/events.d.ts} +20 -29
- package/dist/{lib-HJTRWKU5.mjs → index.cjs} +4687 -10983
- package/dist/index.d.ts +303 -1874
- package/dist/index.js +317 -45939
- package/dist/index.mjs +59748 -27
- package/dist/renderers/HtmlRenderer.d.ts +34 -0
- package/dist/renderers/MjmlRenderer.d.ts +41 -0
- package/dist/renderers/ReactMjmlRenderer.d.ts +38 -0
- package/dist/renderers/ReactRenderer.d.ts +46 -0
- package/{src/renderers/Renderer.ts → dist/renderers/Renderer.d.ts} +23 -24
- package/dist/renderers/TemplateRenderer.d.ts +55 -0
- package/dist/renderers/VueMjmlRenderer.d.ts +39 -0
- package/dist/renderers/VueRenderer.d.ts +47 -0
- package/dist/renderers/mjml-templates.d.ts +11 -0
- package/dist/transports/BaseTransport.d.ts +111 -0
- package/dist/transports/LogTransport.d.ts +42 -0
- package/dist/transports/MemoryTransport.d.ts +51 -0
- package/dist/transports/SesTransport.d.ts +79 -0
- package/dist/transports/SmtpTransport.d.ts +124 -0
- package/dist/transports/Transport.d.ts +44 -0
- package/dist/types.d.ts +294 -0
- package/{src/utils/html.ts → dist/utils/html.d.ts} +1 -15
- package/dist/webhooks/SendGridWebhookDriver.d.ts +45 -0
- package/dist/webhooks/SesWebhookDriver.d.ts +23 -0
- package/package.json +20 -8
- package/CHANGELOG.md +0 -74
- package/dist/MjmlRenderer-IUH663FT.mjs +0 -8
- package/dist/ReactMjmlRenderer-C3P5YO5L.mjs +0 -8
- package/dist/ReactRenderer-24SQ4KRU.mjs +0 -27
- package/dist/ReactRenderer-2JFLRVST.mjs +0 -45
- package/dist/ReactRenderer-CMCAOEPH.mjs +0 -28
- package/dist/ReactRenderer-KYNA4WKE.mjs +0 -28
- package/dist/ReactRenderer-LYEOSYFS.mjs +0 -28
- package/dist/ReactRenderer-V54CUUEI.mjs +0 -45
- package/dist/VueMjmlRenderer-4F4CXHDB.mjs +0 -8
- package/dist/VueMjmlRenderer-5WZR4CQG.mjs +0 -8
- package/dist/VueMjmlRenderer-U5YMWI44.mjs +0 -8
- package/dist/VueRenderer-3YBRQXME.mjs +0 -48
- package/dist/VueRenderer-46JGXTJ2.mjs +0 -48
- package/dist/VueRenderer-5KWD4R3C.mjs +0 -48
- package/dist/VueRenderer-C23U4O5E.mjs +0 -48
- package/dist/VueRenderer-DWTCD2RF.mjs +0 -31
- package/dist/VueRenderer-IIR5SYTM.mjs +0 -31
- package/dist/VueRenderer-LEVDFLHP.mjs +0 -31
- package/dist/VueRenderer-RNHSCCRI.mjs +0 -48
- package/dist/VueRenderer-SUP66ISX.mjs +0 -29
- package/dist/chunk-3WOR3XSL.mjs +0 -82
- package/dist/chunk-DBFIVHHG.mjs +0 -79
- package/dist/chunk-EBO3CZXG.mjs +0 -15
- package/dist/chunk-HEBXNMVQ.mjs +0 -48
- package/dist/chunk-KB7IDDBT.mjs +0 -82
- package/dist/chunk-LZL5UUPC.mjs +0 -82
- package/dist/chunk-W6LXIJKK.mjs +0 -57
- package/dist/chunk-XBIVBJS2.mjs +0 -8
- package/dist/index.d.mts +0 -2115
- package/dist/server-renderer-4IM3P5XZ.mjs +0 -37183
- package/dist/server-renderer-4W4FI7YG.mjs +0 -37269
- package/dist/server-renderer-7KWFSTPV.mjs +0 -37193
- package/dist/server-renderer-S5FPSTJ2.mjs +0 -37183
- package/dist/server-renderer-X5LUFVWT.mjs +0 -37193
- package/doc/OPTIMIZATION_PLAN.md +0 -496
- package/scripts/check-coverage.ts +0 -64
- package/src/Mailable.ts +0 -674
- package/src/OrbitSignal.ts +0 -451
- package/src/dev/DevMailbox.ts +0 -146
- package/src/dev/DevServer.ts +0 -192
- package/src/dev/storage/FileMailboxStorage.ts +0 -66
- package/src/dev/storage/MailboxStorage.ts +0 -15
- package/src/dev/storage/MemoryMailboxStorage.ts +0 -36
- package/src/dev/ui/mailbox.ts +0 -77
- package/src/dev/ui/preview.ts +0 -103
- package/src/dev/ui/shared.ts +0 -60
- package/src/errors.ts +0 -69
- package/src/index.ts +0 -41
- package/src/renderers/HtmlRenderer.ts +0 -41
- package/src/renderers/MjmlRenderer.ts +0 -73
- package/src/renderers/ReactMjmlRenderer.ts +0 -94
- package/src/renderers/ReactRenderer.ts +0 -66
- package/src/renderers/TemplateRenderer.ts +0 -84
- package/src/renderers/VueMjmlRenderer.ts +0 -99
- package/src/renderers/VueRenderer.ts +0 -71
- package/src/renderers/mjml-templates.ts +0 -50
- package/src/transports/BaseTransport.ts +0 -148
- package/src/transports/LogTransport.ts +0 -55
- package/src/transports/MemoryTransport.ts +0 -55
- package/src/transports/SesTransport.ts +0 -129
- package/src/transports/SmtpTransport.ts +0 -184
- package/src/transports/Transport.ts +0 -45
- package/src/types.ts +0 -309
- package/src/webhooks/SendGridWebhookDriver.ts +0 -80
- package/src/webhooks/SesWebhookDriver.ts +0 -44
- package/tests/DevMailbox.test.ts +0 -54
- package/tests/FileMailboxStorage.test.ts +0 -56
- package/tests/MjmlLayout.test.ts +0 -28
- package/tests/MjmlRenderer.test.ts +0 -53
- package/tests/OrbitSignalWebhook.test.ts +0 -56
- package/tests/ReactMjmlRenderer.test.ts +0 -33
- package/tests/SendGridWebhookDriver.test.ts +0 -69
- package/tests/SesWebhookDriver.test.ts +0 -46
- package/tests/VueMjmlRenderer.test.ts +0 -35
- package/tests/dev-server.test.ts +0 -66
- package/tests/log-transport.test.ts +0 -21
- package/tests/mailable-extra.test.ts +0 -68
- package/tests/mailable.test.ts +0 -77
- package/tests/orbit-signal.test.ts +0 -43
- package/tests/renderers.test.ts +0 -58
- package/tests/template-renderer.test.ts +0 -24
- package/tests/transports.test.ts +0 -52
- package/tests/ui.test.ts +0 -37
- package/tsconfig.json +0 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,578 +1,91 @@
|
|
|
1
|
-
import { Queueable } from '@gravito/stream';
|
|
2
|
-
export { Queueable } from '@gravito/stream';
|
|
3
|
-
import { GravitoContext, GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
|
-
*
|
|
2
|
+
* OrbitSignal - The central Event Bus and Mail Service for Gravito.
|
|
7
3
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* This module provides the core infrastructure for sending emails and managing
|
|
5
|
+
* cross-module signals within the Gravito ecosystem. It supports multiple
|
|
6
|
+
* transport drivers, template rendering, and a robust development environment.
|
|
11
7
|
*
|
|
12
|
-
* @
|
|
13
|
-
* ```typescript
|
|
14
|
-
* class CustomTransport implements Transport {
|
|
15
|
-
* async send(message: Message): Promise<void> {
|
|
16
|
-
* // Implementation logic to deliver the message
|
|
17
|
-
* console.log(`Sending email to ${message.to[0].address}`);
|
|
18
|
-
* }
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* @public
|
|
23
|
-
*/
|
|
24
|
-
interface Transport {
|
|
25
|
-
/**
|
|
26
|
-
* Send the given message using the underlying transport mechanism.
|
|
27
|
-
*
|
|
28
|
-
* This method handles the actual communication with the delivery service.
|
|
29
|
-
* Implementations should handle connection management and protocol-specific logic.
|
|
30
|
-
*
|
|
31
|
-
* @param message - The finalized message object containing recipients, subject, and content.
|
|
32
|
-
* @returns A promise that resolves when the message has been successfully handed off to the transport.
|
|
33
|
-
* @throws {MailTransportError} If the delivery fails after all internal retry attempts.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
* const transport: Transport = new LogTransport();
|
|
38
|
-
* await transport.send({
|
|
39
|
-
* from: { address: 'sender@example.com' },
|
|
40
|
-
* to: [{ address: 'receiver@example.com' }],
|
|
41
|
-
* subject: 'Hello',
|
|
42
|
-
* html: '<p>World</p>'
|
|
43
|
-
* });
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
send(message: Message): Promise<void>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Interface for Webhook Drivers.
|
|
51
|
-
*/
|
|
52
|
-
interface WebhookDriver {
|
|
53
|
-
handle(c: GravitoContext): Promise<{
|
|
54
|
-
event: string;
|
|
55
|
-
payload: any;
|
|
56
|
-
}[] | null>;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Representation of an email address with optional display name.
|
|
61
|
-
*
|
|
62
|
-
* Defines the structure for email addresses used throughout the mail system.
|
|
63
|
-
* Supports both simple string addresses and formatted addresses with display names.
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```typescript
|
|
67
|
-
* // Simple address
|
|
68
|
-
* const addr1: Address = { address: 'user@example.com' }
|
|
69
|
-
*
|
|
70
|
-
* // Address with display name
|
|
71
|
-
* const addr2: Address = {
|
|
72
|
-
* name: 'John Doe',
|
|
73
|
-
* address: 'john@example.com'
|
|
74
|
-
* }
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
|
-
* @see {@link Envelope} For the email envelope structure
|
|
78
|
-
* @see {@link Message} For the complete message structure
|
|
79
|
-
*
|
|
80
|
-
* @public
|
|
81
|
-
* @since 3.0.0
|
|
82
|
-
*/
|
|
83
|
-
interface Address {
|
|
84
|
-
/** The display name of the recipient/sender, e.g., "John Doe". */
|
|
85
|
-
name?: string;
|
|
86
|
-
/** The actual email address string. */
|
|
87
|
-
address: string;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Configuration for an email attachment.
|
|
91
|
-
*
|
|
92
|
-
* Defines file attachments for email messages. Supports both regular attachments
|
|
93
|
-
* and inline attachments (e.g., embedded images referenced via Content-ID).
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* ```typescript
|
|
97
|
-
* // Regular file attachment
|
|
98
|
-
* const attachment: Attachment = {
|
|
99
|
-
* filename: 'document.pdf',
|
|
100
|
-
* content: Buffer.from('...'),
|
|
101
|
-
* contentType: 'application/pdf'
|
|
102
|
-
* }
|
|
103
|
-
*
|
|
104
|
-
* // Inline image attachment
|
|
105
|
-
* const inlineImage: Attachment = {
|
|
106
|
-
* filename: 'logo.png',
|
|
107
|
-
* content: Buffer.from('...'),
|
|
108
|
-
* contentType: 'image/png',
|
|
109
|
-
* cid: 'logo@example.com' // Reference in HTML: <img src="cid:logo@example.com">
|
|
110
|
-
* }
|
|
111
|
-
* ```
|
|
112
|
-
*
|
|
113
|
-
* @see {@link Envelope} For adding attachments to emails
|
|
114
|
-
*
|
|
115
|
-
* @public
|
|
116
|
-
* @since 3.0.0
|
|
8
|
+
* @packageDocumentation
|
|
117
9
|
*/
|
|
118
|
-
interface Attachment {
|
|
119
|
-
/** The filename of the attachment. */
|
|
120
|
-
filename: string;
|
|
121
|
-
/** The content of the attachment as a string or Buffer. */
|
|
122
|
-
content: string | Buffer;
|
|
123
|
-
/** Optional MIME type of the content. */
|
|
124
|
-
contentType?: string;
|
|
125
|
-
/** Optional Content-ID for referencing within HTML content (inline images). */
|
|
126
|
-
cid?: string;
|
|
127
|
-
/** Optional content encoding. */
|
|
128
|
-
encoding?: string;
|
|
129
|
-
}
|
|
130
10
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* Used during the construction phase of a Mailable. All fields are optional
|
|
134
|
-
* at this stage and will be validated when converting to a Message.
|
|
135
|
-
*
|
|
136
|
-
* @example
|
|
137
|
-
* ```typescript
|
|
138
|
-
* const envelope: Envelope = {
|
|
139
|
-
* from: { name: 'App', address: 'noreply@app.com' },
|
|
140
|
-
* to: [{ address: 'user@example.com' }],
|
|
141
|
-
* subject: 'Welcome!',
|
|
142
|
-
* priority: 'high',
|
|
143
|
-
* replyTo: { address: 'support@app.com' }
|
|
144
|
-
* }
|
|
145
|
-
* ```
|
|
11
|
+
* Queue-able interface from the stream package.
|
|
146
12
|
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
13
|
+
* Defines the contract for messages that can be queued for asynchronous processing,
|
|
14
|
+
* enabling email mailables to be dispatched to background workers.
|
|
149
15
|
*
|
|
16
|
+
* @see {@link Mailable} For messages that implement this interface
|
|
150
17
|
* @public
|
|
151
|
-
* @since 3.0.0
|
|
152
18
|
*/
|
|
153
|
-
|
|
154
|
-
/** The sender's address. */
|
|
155
|
-
from?: Address | undefined;
|
|
156
|
-
/** Primary recipients. */
|
|
157
|
-
to?: Address[] | undefined;
|
|
158
|
-
/** Carbon copy recipients. */
|
|
159
|
-
cc?: Address[] | undefined;
|
|
160
|
-
/** Blind carbon copy recipients. */
|
|
161
|
-
bcc?: Address[] | undefined;
|
|
162
|
-
/** Reply-to address. */
|
|
163
|
-
replyTo?: Address | undefined;
|
|
164
|
-
/** Email subject line. */
|
|
165
|
-
subject?: string | undefined;
|
|
166
|
-
/** Importance level of the email. */
|
|
167
|
-
priority?: 'high' | 'normal' | 'low' | undefined;
|
|
168
|
-
/** List of file attachments. */
|
|
169
|
-
attachments?: Attachment[] | undefined;
|
|
170
|
-
}
|
|
19
|
+
export type { Queueable } from '@gravito/stream';
|
|
171
20
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* Requires mandatory fields that were optional in the Envelope.
|
|
175
|
-
* This structure is passed to Transport implementations for actual delivery.
|
|
176
|
-
*
|
|
177
|
-
* @example
|
|
178
|
-
* ```typescript
|
|
179
|
-
* const message: Message = {
|
|
180
|
-
* from: { name: 'App', address: 'noreply@app.com' },
|
|
181
|
-
* to: [{ address: 'user@example.com' }],
|
|
182
|
-
* subject: 'Welcome to our service',
|
|
183
|
-
* html: '<h1>Welcome!</h1><p>Thanks for joining.</p>',
|
|
184
|
-
* text: 'Welcome! Thanks for joining.',
|
|
185
|
-
* priority: 'normal',
|
|
186
|
-
* headers: { 'X-Custom-Header': 'value' }
|
|
187
|
-
* }
|
|
188
|
-
* ```
|
|
21
|
+
* Development mailbox for capturing and previewing sent emails.
|
|
189
22
|
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
23
|
+
* Provides an in-memory storage mechanism for intercepting emails during development.
|
|
24
|
+
* Works with DevServer to display a preview UI at a configured endpoint (default: /__mail).
|
|
192
25
|
*
|
|
26
|
+
* @see {@link OrbitSignal} For development mode configuration
|
|
27
|
+
* @see {@link MailboxEntry} For mailbox data structure
|
|
193
28
|
* @public
|
|
194
|
-
* @since 3.0.0
|
|
195
29
|
*/
|
|
196
|
-
|
|
197
|
-
/** The mandatory sender's address. */
|
|
198
|
-
from: Address;
|
|
199
|
-
/** At least one recipient is required. */
|
|
200
|
-
to: Address[];
|
|
201
|
-
/** Mandatory subject. */
|
|
202
|
-
subject: string;
|
|
203
|
-
/** The rendered HTML body content. */
|
|
204
|
-
html: string;
|
|
205
|
-
/** Optional rendered plain text body content. */
|
|
206
|
-
text?: string;
|
|
207
|
-
/** Custom SMTP headers. */
|
|
208
|
-
headers?: Record<string, string>;
|
|
209
|
-
}
|
|
30
|
+
export { DevMailbox, type MailboxEntry } from './dev/DevMailbox';
|
|
210
31
|
/**
|
|
211
|
-
*
|
|
32
|
+
* Mail error codes and transport error class.
|
|
212
33
|
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
34
|
+
* Provides structured error information for mail delivery failures, including
|
|
35
|
+
* categorized error codes (CONNECTION_FAILED, AUTH_FAILED, RATE_LIMIT, etc.)
|
|
36
|
+
* and the MailTransportError exception class for programmatic error handling.
|
|
215
37
|
*
|
|
216
38
|
* @example
|
|
217
39
|
* ```typescript
|
|
218
|
-
* import {
|
|
40
|
+
* import { MailTransportError, MailErrorCode } from '@gravito/signal'
|
|
219
41
|
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
* viewsDir: './src/emails',
|
|
229
|
-
* devUiPrefix: '/__mail',
|
|
230
|
-
* translator: (key, replace, locale) => i18n.t(key, { ...replace, locale })
|
|
42
|
+
* try {
|
|
43
|
+
* await transport.send(message)
|
|
44
|
+
* } catch (error) {
|
|
45
|
+
* if (error instanceof MailTransportError) {
|
|
46
|
+
* if (error.code === MailErrorCode.RATE_LIMIT) {
|
|
47
|
+
* // Implement exponential backoff
|
|
48
|
+
* }
|
|
49
|
+
* }
|
|
231
50
|
* }
|
|
232
|
-
*
|
|
233
|
-
* const mail = new OrbitSignal(config)
|
|
234
51
|
* ```
|
|
235
52
|
*
|
|
236
|
-
* @see {@link
|
|
237
|
-
* @see {@link Transport} For available transport options
|
|
238
|
-
*
|
|
53
|
+
* @see {@link Transport} For implementations that throw these errors
|
|
239
54
|
* @public
|
|
240
|
-
* @since 3.0.0
|
|
241
|
-
*/
|
|
242
|
-
interface MailConfig {
|
|
243
|
-
/**
|
|
244
|
-
* Default sender address used if not specified in the Mailable.
|
|
245
|
-
*
|
|
246
|
-
* @example
|
|
247
|
-
* ```typescript
|
|
248
|
-
* from: { name: 'My App', address: 'noreply@myapp.com' }
|
|
249
|
-
* ```
|
|
250
|
-
*/
|
|
251
|
-
from?: Address;
|
|
252
|
-
/**
|
|
253
|
-
* The transport mechanism used to send emails (e.g., SMTP, SES, Log).
|
|
254
|
-
*
|
|
255
|
-
* @example
|
|
256
|
-
* ```typescript
|
|
257
|
-
* import { SmtpTransport } from '@gravito/signal'
|
|
258
|
-
* transport: new SmtpTransport({ host: 'smtp.example.com', port: 587 })
|
|
259
|
-
* ```
|
|
260
|
-
*/
|
|
261
|
-
transport?: Transport;
|
|
262
|
-
/**
|
|
263
|
-
* Enable development mode.
|
|
264
|
-
* When true, emails are intercepted by the DevMailbox instead of being sent.
|
|
265
|
-
*
|
|
266
|
-
* @default false
|
|
267
|
-
* @example
|
|
268
|
-
* ```typescript
|
|
269
|
-
* devMode: process.env.NODE_ENV === 'development'
|
|
270
|
-
* ```
|
|
271
|
-
*/
|
|
272
|
-
devMode?: boolean | undefined;
|
|
273
|
-
/**
|
|
274
|
-
* Directory where email templates are located for use with OrbitPrism.
|
|
275
|
-
*
|
|
276
|
-
* @default "src/emails"
|
|
277
|
-
* @example
|
|
278
|
-
* ```typescript
|
|
279
|
-
* viewsDir: './resources/views/emails'
|
|
280
|
-
* ```
|
|
281
|
-
*/
|
|
282
|
-
viewsDir?: string | undefined;
|
|
283
|
-
/**
|
|
284
|
-
* URL prefix for the Mail Dev UI.
|
|
285
|
-
*
|
|
286
|
-
* @default "/__mail"
|
|
287
|
-
* @example
|
|
288
|
-
* ```typescript
|
|
289
|
-
* devUiPrefix: '/dev/mailbox'
|
|
290
|
-
* ```
|
|
291
|
-
*/
|
|
292
|
-
devUiPrefix?: string | undefined;
|
|
293
|
-
/**
|
|
294
|
-
* Whether to allow access to the Mail Dev UI in production environments.
|
|
295
|
-
*
|
|
296
|
-
* @default false
|
|
297
|
-
* @example
|
|
298
|
-
* ```typescript
|
|
299
|
-
* devUiAllowInProduction: process.env.ALLOW_MAIL_UI === 'true'
|
|
300
|
-
* ```
|
|
301
|
-
*/
|
|
302
|
-
devUiAllowInProduction?: boolean | undefined;
|
|
303
|
-
/**
|
|
304
|
-
* Authorization gate for the Mail Dev UI.
|
|
305
|
-
* Should return true to allow access to the UI.
|
|
306
|
-
*
|
|
307
|
-
* @example
|
|
308
|
-
* ```typescript
|
|
309
|
-
* devUiGate: async (ctx) => {
|
|
310
|
-
* const user = await ctx.get('auth').user()
|
|
311
|
-
* return user?.role === 'admin'
|
|
312
|
-
* }
|
|
313
|
-
* ```
|
|
314
|
-
*/
|
|
315
|
-
devUiGate?: ((ctx: GravitoContext) => boolean | Promise<boolean>) | undefined;
|
|
316
|
-
/**
|
|
317
|
-
* Translation function for internationalization within emails.
|
|
318
|
-
*
|
|
319
|
-
* @example
|
|
320
|
-
* ```typescript
|
|
321
|
-
* translator: (key, replace, locale) => {
|
|
322
|
-
* return i18n.t(key, { ...replace, locale: locale || 'en' })
|
|
323
|
-
* }
|
|
324
|
-
* ```
|
|
325
|
-
*/
|
|
326
|
-
translator?: ((key: string, replace?: Record<string, unknown>, locale?: string) => string) | undefined;
|
|
327
|
-
/**
|
|
328
|
-
* URL prefix for Webhook endpoints.
|
|
329
|
-
*/
|
|
330
|
-
webhookPrefix?: string | undefined;
|
|
331
|
-
/**
|
|
332
|
-
* Dictionary of registered webhook drivers.
|
|
333
|
-
*/
|
|
334
|
-
webhookDrivers?: Record<string, WebhookDriver> | undefined;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Interface for DevMailbox storage engines.
|
|
339
|
-
*/
|
|
340
|
-
interface MailboxStorage {
|
|
341
|
-
/** Retrieve all entries. */
|
|
342
|
-
all(): Promise<MailboxEntry[]>;
|
|
343
|
-
/** Add a single entry. */
|
|
344
|
-
push(entry: MailboxEntry): Promise<void>;
|
|
345
|
-
/** Trim entries to a specific count. */
|
|
346
|
-
trim(max: number): Promise<void>;
|
|
347
|
-
clear(): Promise<void>;
|
|
348
|
-
delete?(id: string): Promise<boolean>;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Entry structure for messages stored in DevMailbox.
|
|
353
55
|
*/
|
|
354
|
-
|
|
355
|
-
/** Unique identifier for the entry. */
|
|
356
|
-
id: string;
|
|
357
|
-
/** The email envelope metadata. */
|
|
358
|
-
envelope: any;
|
|
359
|
-
/** The rendered HTML content. */
|
|
360
|
-
html: string;
|
|
361
|
-
/** Optional plain text content. */
|
|
362
|
-
text?: string;
|
|
363
|
-
/** Timestamp when the message was captured. */
|
|
364
|
-
sentAt: Date;
|
|
365
|
-
}
|
|
56
|
+
export { MailErrorCode, MailTransportError } from './errors';
|
|
366
57
|
/**
|
|
367
|
-
*
|
|
58
|
+
* Mail lifecycle event types and handlers.
|
|
368
59
|
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
60
|
+
* Provides event types and interfaces for subscribing to key moments in the
|
|
61
|
+
* email delivery process: beforeRender, afterRender, beforeSend, afterSend,
|
|
62
|
+
* sendFailed, and webhookReceived. Enables logging, analytics, and custom
|
|
63
|
+
* processing during mail service operations.
|
|
371
64
|
*
|
|
372
65
|
* @example
|
|
373
66
|
* ```typescript
|
|
374
|
-
*
|
|
375
|
-
* const mailbox = new DevMailbox()
|
|
376
|
-
*
|
|
377
|
-
* // Persistent file mailbox
|
|
378
|
-
* const storage = new FileMailboxStorage('./storage/mail')
|
|
379
|
-
* const persistentMailbox = new DevMailbox(100, storage)
|
|
380
|
-
* ```
|
|
67
|
+
* import { OrbitSignal, type MailEvent } from '@gravito/signal'
|
|
381
68
|
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
|
|
385
|
-
declare class DevMailbox {
|
|
386
|
-
private storage;
|
|
387
|
-
private _maxEntries;
|
|
388
|
-
/**
|
|
389
|
-
* Creates an instance of DevMailbox.
|
|
390
|
-
*
|
|
391
|
-
* @param maxEntries - Maximum number of emails to store (default: 50)
|
|
392
|
-
* @param storage - Optional custom storage engine (defaults to Memory)
|
|
393
|
-
*/
|
|
394
|
-
constructor(maxEntries?: number, storage?: MailboxStorage);
|
|
395
|
-
/**
|
|
396
|
-
* Adds a new message to the mailbox.
|
|
397
|
-
*
|
|
398
|
-
* If the mailbox exceeds the maximum capacity, the oldest messages are removed.
|
|
399
|
-
*/
|
|
400
|
-
add(message: Message): Promise<MailboxEntry>;
|
|
401
|
-
/**
|
|
402
|
-
* Sets the maximum number of emails to store.
|
|
403
|
-
*
|
|
404
|
-
* If the current mailbox exceeds the new capacity, the oldest messages are removed.
|
|
405
|
-
*/
|
|
406
|
-
setMaxEntries(count: number): Promise<void>;
|
|
407
|
-
/**
|
|
408
|
-
* Returns the maximum capacity of the mailbox.
|
|
409
|
-
*/
|
|
410
|
-
get maxEntries(): number;
|
|
411
|
-
/**
|
|
412
|
-
* Lists all messages in the mailbox.
|
|
413
|
-
*/
|
|
414
|
-
list(): Promise<MailboxEntry[]>;
|
|
415
|
-
/**
|
|
416
|
-
* Retrieves a specific message by ID.
|
|
417
|
-
*/
|
|
418
|
-
get(id: string): Promise<MailboxEntry | undefined>;
|
|
419
|
-
/**
|
|
420
|
-
* Deletes a specific message by ID.
|
|
421
|
-
*/
|
|
422
|
-
delete(id: string): Promise<boolean>;
|
|
423
|
-
/**
|
|
424
|
-
* Clears all messages from the mailbox.
|
|
425
|
-
*/
|
|
426
|
-
clear(): Promise<void>;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Mail transport error codes.
|
|
431
|
-
*
|
|
432
|
-
* Categorizes common failure modes in the mail delivery process to allow
|
|
433
|
-
* for programmatic handling (e.g., retries on rate limits).
|
|
434
|
-
*
|
|
435
|
-
* @public
|
|
436
|
-
* @since 3.1.0
|
|
437
|
-
*/
|
|
438
|
-
declare enum MailErrorCode {
|
|
439
|
-
/** Connection to mail server failed */
|
|
440
|
-
CONNECTION_FAILED = "CONNECTION_FAILED",
|
|
441
|
-
/** Authentication with mail server failed */
|
|
442
|
-
AUTH_FAILED = "AUTH_FAILED",
|
|
443
|
-
/** One or more recipients were rejected by the server */
|
|
444
|
-
RECIPIENT_REJECTED = "RECIPIENT_REJECTED",
|
|
445
|
-
/** The message was rejected by the server */
|
|
446
|
-
MESSAGE_REJECTED = "MESSAGE_REJECTED",
|
|
447
|
-
/** Rate limit exceeded */
|
|
448
|
-
RATE_LIMIT = "RATE_LIMIT",
|
|
449
|
-
/** Unknown or unclassified error */
|
|
450
|
-
UNKNOWN = "UNKNOWN"
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Error class for mail transport failures.
|
|
454
|
-
*
|
|
455
|
-
* Provides structured error information for mail sending failures,
|
|
456
|
-
* including error codes and original cause tracking for debugging.
|
|
457
|
-
*
|
|
458
|
-
* @example
|
|
459
|
-
* ```typescript
|
|
460
|
-
* throw new MailTransportError(
|
|
461
|
-
* 'Failed to connect to SMTP server',
|
|
462
|
-
* MailErrorCode.CONNECTION_FAILED,
|
|
463
|
-
* originalError
|
|
464
|
-
* )
|
|
465
|
-
* ```
|
|
466
|
-
*
|
|
467
|
-
* @public
|
|
468
|
-
* @since 3.1.0
|
|
469
|
-
*/
|
|
470
|
-
declare class MailTransportError extends Error {
|
|
471
|
-
readonly code: MailErrorCode;
|
|
472
|
-
readonly cause?: Error | undefined;
|
|
473
|
-
/**
|
|
474
|
-
* Create a new mail transport error.
|
|
475
|
-
*
|
|
476
|
-
* @param message - Human-readable error message
|
|
477
|
-
* @param code - Categorized error code
|
|
478
|
-
* @param cause - Original error that caused this failure
|
|
479
|
-
*
|
|
480
|
-
* @example
|
|
481
|
-
* ```typescript
|
|
482
|
-
* const error = new MailTransportError('Auth failed', MailErrorCode.AUTH_FAILED);
|
|
483
|
-
* ```
|
|
484
|
-
*/
|
|
485
|
-
constructor(message: string, code: MailErrorCode, cause?: Error | undefined);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Result of a content rendering operation.
|
|
490
|
-
*
|
|
491
|
-
* This interface defines the structure of the output produced by any renderer.
|
|
492
|
-
* It ensures consistency across different rendering strategies (HTML, React, Vue, etc.),
|
|
493
|
-
* providing both the final HTML for the email body and an optional plain text version
|
|
494
|
-
* for clients that do not support HTML.
|
|
495
|
-
*
|
|
496
|
-
* @example
|
|
497
|
-
* ```typescript
|
|
498
|
-
* const result: RenderResult = {
|
|
499
|
-
* html: '<html><body><h1>Hello</h1></body></html>',
|
|
500
|
-
* text: 'Hello'
|
|
501
|
-
* };
|
|
502
|
-
* ```
|
|
503
|
-
*
|
|
504
|
-
* @public
|
|
505
|
-
* @since 3.0.0
|
|
506
|
-
*/
|
|
507
|
-
interface RenderResult {
|
|
508
|
-
/**
|
|
509
|
-
* The rendered HTML string.
|
|
510
|
-
*
|
|
511
|
-
* This is the primary content used for the email body.
|
|
512
|
-
*/
|
|
513
|
-
html: string;
|
|
514
|
-
/**
|
|
515
|
-
* Optional rendered plain text string.
|
|
516
|
-
*
|
|
517
|
-
* Used as a fallback for email clients that cannot display HTML or for accessibility.
|
|
518
|
-
*/
|
|
519
|
-
text?: string;
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Interface for email content renderers.
|
|
523
|
-
*
|
|
524
|
-
* Renderers are responsible for transforming various input formats (raw HTML,
|
|
525
|
-
* templates, or UI components) into a standardized {@link RenderResult}.
|
|
526
|
-
* This abstraction allows the mail system to support multiple view engines
|
|
527
|
-
* and frameworks interchangeably.
|
|
69
|
+
* mail.on('afterSend', (event: MailEvent) => {
|
|
70
|
+
* console.log('Sent to:', event.message?.to[0].address)
|
|
71
|
+
* })
|
|
528
72
|
*
|
|
529
|
-
*
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
-
* async render(data: Record<string, unknown>): Promise<RenderResult> {
|
|
533
|
-
* return { html: `<div>${data.name}</div>`, text: String(data.name) };
|
|
534
|
-
* }
|
|
535
|
-
* }
|
|
73
|
+
* mail.on('sendFailed', (event: MailEvent) => {
|
|
74
|
+
* console.error('Failed:', event.error?.message)
|
|
75
|
+
* })
|
|
536
76
|
* ```
|
|
537
77
|
*
|
|
78
|
+
* @see {@link OrbitSignal} For event subscription API
|
|
538
79
|
* @public
|
|
539
|
-
* @since 3.0.0
|
|
540
80
|
*/
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Render the content into HTML and optionally plain text.
|
|
544
|
-
*
|
|
545
|
-
* This method performs the actual transformation of the source content
|
|
546
|
-
* using the provided data context.
|
|
547
|
-
*
|
|
548
|
-
* @param data - The data context for rendering.
|
|
549
|
-
* @returns A promise resolving to the rendered content.
|
|
550
|
-
* @throws {Error} If rendering fails due to syntax errors or missing dependencies.
|
|
551
|
-
*/
|
|
552
|
-
render(data: Record<string, unknown>): Promise<RenderResult>;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
type ComponentType = any;
|
|
81
|
+
export type { MailEvent, MailEventHandler, MailEventType } from './events';
|
|
556
82
|
/**
|
|
557
83
|
* Base class for all mailable messages.
|
|
558
84
|
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
* @architecture
|
|
564
|
-
* ```
|
|
565
|
-
* Mailable
|
|
566
|
-
* ├── Envelope (from, to, subject, cc, bcc, attachments)
|
|
567
|
-
* ├── Renderer (HtmlRenderer | TemplateRenderer | ReactRenderer | VueRenderer)
|
|
568
|
-
* └── Queueable (queue support interface)
|
|
569
|
-
* ```
|
|
570
|
-
*
|
|
571
|
-
* @lifecycle
|
|
572
|
-
* 1. Create Mailable subclass
|
|
573
|
-
* 2. Implement build() method to configure envelope and content
|
|
574
|
-
* 3. Call send() to send immediately, or queue() for background processing
|
|
575
|
-
* 4. OrbitSignal calls buildEnvelope() → renderContent() → transport.send()
|
|
85
|
+
* Provides a fluent API to build email envelopes and render content using
|
|
86
|
+
* multiple rendering engines (HTML, Prism templates, React, Vue). Supports
|
|
87
|
+
* background queuing via the Queueable interface and integration with the
|
|
88
|
+
* OrbitSignal service for sending.
|
|
576
89
|
*
|
|
577
90
|
* @example
|
|
578
91
|
* ```typescript
|
|
@@ -591,512 +104,59 @@ type ComponentType = any;
|
|
|
591
104
|
* }
|
|
592
105
|
* }
|
|
593
106
|
*
|
|
594
|
-
* // Send immediately
|
|
595
107
|
* await mail.send(new WelcomeEmail(user))
|
|
596
|
-
*
|
|
597
|
-
* // Queue for background processing
|
|
598
|
-
* await new WelcomeEmail(user).onQueue('emails').queue()
|
|
599
108
|
* ```
|
|
600
109
|
*
|
|
601
|
-
* @see {@link
|
|
602
|
-
* @see {@link
|
|
603
|
-
* @see {@link Envelope} Email metadata structure
|
|
604
|
-
* @see {@link Queueable} Queue integration interface
|
|
605
|
-
*
|
|
110
|
+
* @see {@link TypedMailable} For type-safe data passing
|
|
111
|
+
* @see {@link OrbitSignal} For sending integration
|
|
606
112
|
* @public
|
|
607
|
-
* @since 3.0.0
|
|
608
113
|
*/
|
|
609
|
-
|
|
610
|
-
protected envelope: Partial<Envelope>;
|
|
611
|
-
protected renderer?: Renderer;
|
|
612
|
-
private rendererResolver?;
|
|
613
|
-
protected renderData: Record<string, unknown>;
|
|
614
|
-
protected config?: MailConfig;
|
|
615
|
-
/**
|
|
616
|
-
* Set the sender address for the email.
|
|
617
|
-
*
|
|
618
|
-
* This defines the "From" field in the email envelope. If not called, the default
|
|
619
|
-
* sender from the mail configuration will be used.
|
|
620
|
-
*
|
|
621
|
-
* @param address - The email address or address object containing name and address.
|
|
622
|
-
* @returns The current mailable instance for chaining.
|
|
623
|
-
*
|
|
624
|
-
* @example
|
|
625
|
-
* ```typescript
|
|
626
|
-
* mailable.from('admin@example.com')
|
|
627
|
-
* mailable.from({ name: 'Support', address: 'support@example.com' })
|
|
628
|
-
* ```
|
|
629
|
-
*/
|
|
630
|
-
from(address: string | Address): this;
|
|
631
|
-
/**
|
|
632
|
-
* Set the primary recipient(s) for the email.
|
|
633
|
-
*
|
|
634
|
-
* Configures the "To" field. Supports single or multiple recipients in various formats.
|
|
635
|
-
*
|
|
636
|
-
* @param address - A single email string, an address object, or an array of either.
|
|
637
|
-
* @returns The current mailable instance for chaining.
|
|
638
|
-
*
|
|
639
|
-
* @example
|
|
640
|
-
* ```typescript
|
|
641
|
-
* mailable.to('user@example.com')
|
|
642
|
-
* mailable.to(['a@example.com', 'b@example.com'])
|
|
643
|
-
* mailable.to({ name: 'John', address: 'john@example.com' })
|
|
644
|
-
* ```
|
|
645
|
-
*/
|
|
646
|
-
to(address: string | Address | (string | Address)[]): this;
|
|
647
|
-
/**
|
|
648
|
-
* Set the carbon copy (CC) recipient(s).
|
|
649
|
-
*
|
|
650
|
-
* Adds recipients to the "Cc" field of the email.
|
|
651
|
-
*
|
|
652
|
-
* @param address - A single email string, an address object, or an array of either.
|
|
653
|
-
* @returns The current mailable instance for chaining.
|
|
654
|
-
*
|
|
655
|
-
* @example
|
|
656
|
-
* ```typescript
|
|
657
|
-
* mailable.cc('manager@example.com')
|
|
658
|
-
* ```
|
|
659
|
-
*/
|
|
660
|
-
cc(address: string | Address | (string | Address)[]): this;
|
|
661
|
-
/**
|
|
662
|
-
* Set the blind carbon copy (BCC) recipient(s).
|
|
663
|
-
*
|
|
664
|
-
* Adds recipients to the "Bcc" field. These recipients are hidden from others.
|
|
665
|
-
*
|
|
666
|
-
* @param address - A single email string, an address object, or an array of either.
|
|
667
|
-
* @returns The current mailable instance for chaining.
|
|
668
|
-
*
|
|
669
|
-
* @example
|
|
670
|
-
* ```typescript
|
|
671
|
-
* mailable.bcc('audit@example.com')
|
|
672
|
-
* ```
|
|
673
|
-
*/
|
|
674
|
-
bcc(address: string | Address | (string | Address)[]): this;
|
|
675
|
-
/**
|
|
676
|
-
* Set the reply-to address.
|
|
677
|
-
*
|
|
678
|
-
* Specifies where replies to this email should be directed.
|
|
679
|
-
*
|
|
680
|
-
* @param address - The email address or address object for replies.
|
|
681
|
-
* @returns The current mailable instance for chaining.
|
|
682
|
-
*
|
|
683
|
-
* @example
|
|
684
|
-
* ```typescript
|
|
685
|
-
* mailable.replyTo('no-reply@example.com')
|
|
686
|
-
* ```
|
|
687
|
-
*/
|
|
688
|
-
replyTo(address: string | Address): this;
|
|
689
|
-
/**
|
|
690
|
-
* Set the subject line for the email.
|
|
691
|
-
*
|
|
692
|
-
* Defines the text that appears in the recipient's inbox subject field.
|
|
693
|
-
*
|
|
694
|
-
* @param subject - The subject text.
|
|
695
|
-
* @returns The current mailable instance for chaining.
|
|
696
|
-
*
|
|
697
|
-
* @example
|
|
698
|
-
* ```typescript
|
|
699
|
-
* mailable.subject('Your Order Confirmation')
|
|
700
|
-
* ```
|
|
701
|
-
*/
|
|
702
|
-
subject(subject: string): this;
|
|
703
|
-
/**
|
|
704
|
-
* Set the email priority.
|
|
705
|
-
*
|
|
706
|
-
* Hints to the email client how urgent this message is.
|
|
707
|
-
*
|
|
708
|
-
* @param level - The priority level: 'high', 'normal', or 'low'.
|
|
709
|
-
* @returns The current mailable instance for chaining.
|
|
710
|
-
*
|
|
711
|
-
* @example
|
|
712
|
-
* ```typescript
|
|
713
|
-
* mailable.emailPriority('high')
|
|
714
|
-
* ```
|
|
715
|
-
*/
|
|
716
|
-
emailPriority(level: 'high' | 'normal' | 'low'): this;
|
|
717
|
-
/**
|
|
718
|
-
* Attach a file to the email.
|
|
719
|
-
*
|
|
720
|
-
* Adds a file attachment to the message. Can be called multiple times for multiple files.
|
|
721
|
-
*
|
|
722
|
-
* @param attachment - The attachment configuration including path, content, or filename.
|
|
723
|
-
* @returns The current mailable instance for chaining.
|
|
724
|
-
*
|
|
725
|
-
* @example
|
|
726
|
-
* ```typescript
|
|
727
|
-
* mailable.attach({
|
|
728
|
-
* filename: 'invoice.pdf',
|
|
729
|
-
* path: './storage/invoices/123.pdf'
|
|
730
|
-
* })
|
|
731
|
-
* ```
|
|
732
|
-
*/
|
|
733
|
-
attach(attachment: Attachment): this;
|
|
734
|
-
/**
|
|
735
|
-
* Set the content using a raw HTML string.
|
|
736
|
-
*
|
|
737
|
-
* Use this for simple emails where a full template engine is not required.
|
|
738
|
-
*
|
|
739
|
-
* @param content - The raw HTML content.
|
|
740
|
-
* @returns The current mailable instance for chaining.
|
|
741
|
-
*
|
|
742
|
-
* @example
|
|
743
|
-
* ```typescript
|
|
744
|
-
* mailable.html('<h1>Hello</h1><p>Welcome to our platform.</p>')
|
|
745
|
-
* ```
|
|
746
|
-
*/
|
|
747
|
-
html(content: string): this;
|
|
748
|
-
/**
|
|
749
|
-
* Set the content using an OrbitPrism template.
|
|
750
|
-
*
|
|
751
|
-
* Renders a template file with the provided data. This is the recommended way
|
|
752
|
-
* to build complex, data-driven emails.
|
|
753
|
-
*
|
|
754
|
-
* @param template - The template name or path relative to the configured views directory.
|
|
755
|
-
* @param data - The data object to be injected into the template.
|
|
756
|
-
* @returns The current mailable instance for chaining.
|
|
757
|
-
*
|
|
758
|
-
* @example
|
|
759
|
-
* ```typescript
|
|
760
|
-
* mailable.view('emails.welcome', { name: 'Alice' })
|
|
761
|
-
* ```
|
|
762
|
-
*/
|
|
763
|
-
view(template: string, data?: Record<string, unknown>): this;
|
|
764
|
-
/**
|
|
765
|
-
* Set the content using a React component.
|
|
766
|
-
*
|
|
767
|
-
* Leverages React's component model for email design. The renderer is loaded
|
|
768
|
-
* dynamically to keep the core package lightweight.
|
|
769
|
-
*
|
|
770
|
-
* @param component - The React component class or function.
|
|
771
|
-
* @param props - The properties to pass to the component.
|
|
772
|
-
* @param deps - Optional React/ReactDOMServer overrides for custom environments.
|
|
773
|
-
* @returns The current mailable instance for chaining.
|
|
774
|
-
*
|
|
775
|
-
* @example
|
|
776
|
-
* ```typescript
|
|
777
|
-
* mailable.react(WelcomeEmailComponent, { name: 'Alice' })
|
|
778
|
-
* ```
|
|
779
|
-
*/
|
|
780
|
-
react<P extends object>(component: ComponentType, props?: P, deps?: {
|
|
781
|
-
createElement?: (...args: any[]) => any;
|
|
782
|
-
renderToStaticMarkup?: (element: any) => string;
|
|
783
|
-
}): this;
|
|
784
|
-
/**
|
|
785
|
-
* Set the content using a Vue component.
|
|
786
|
-
*
|
|
787
|
-
* Leverages Vue's component model for email design. The renderer is loaded
|
|
788
|
-
* dynamically to keep the core package lightweight.
|
|
789
|
-
*
|
|
790
|
-
* @param component - The Vue component object.
|
|
791
|
-
* @param props - The properties to pass to the component.
|
|
792
|
-
* @param deps - Optional Vue/VueServerRenderer overrides for custom environments.
|
|
793
|
-
* @returns The current mailable instance for chaining.
|
|
794
|
-
*
|
|
795
|
-
* @example
|
|
796
|
-
* ```typescript
|
|
797
|
-
* mailable.vue(WelcomeEmailComponent, { name: 'Alice' })
|
|
798
|
-
* ```
|
|
799
|
-
*/
|
|
800
|
-
vue<P extends object>(component: ComponentType, props?: P, deps?: {
|
|
801
|
-
createSSRApp?: (...args: any[]) => any;
|
|
802
|
-
h?: (...args: any[]) => any;
|
|
803
|
-
renderToString?: (app: any) => Promise<string>;
|
|
804
|
-
}): this;
|
|
805
|
-
/**
|
|
806
|
-
* Set the content using an MJML markup string.
|
|
807
|
-
*
|
|
808
|
-
* MJML ensures responsive email compatibility across various clients.
|
|
809
|
-
*
|
|
810
|
-
* @param content - The MJML markup string or inner content.
|
|
811
|
-
* @param options - MJML transformation options.
|
|
812
|
-
* @param options.layout - Optional full MJML layout string. Use '{{content}}' as placeholder.
|
|
813
|
-
* @returns The current mailable instance for chaining.
|
|
814
|
-
*
|
|
815
|
-
* @example
|
|
816
|
-
* ```typescript
|
|
817
|
-
* mailable.mjml('<mj-text>Hello</mj-text>', {
|
|
818
|
-
* layout: '<mjml><mj-body>{{content}}</mj-body></mjml>'
|
|
819
|
-
* })
|
|
820
|
-
* ```
|
|
821
|
-
*/
|
|
822
|
-
mjml(content: string, options?: Record<string, any> & {
|
|
823
|
-
layout?: string;
|
|
824
|
-
}): this;
|
|
825
|
-
/**
|
|
826
|
-
* Set the content using a React component that outputs MJML.
|
|
827
|
-
*
|
|
828
|
-
* @param component - The React component.
|
|
829
|
-
* @param props - Component properties.
|
|
830
|
-
* @param options - MJML options.
|
|
831
|
-
* @returns The current mailable instance for chaining.
|
|
832
|
-
*/
|
|
833
|
-
mjmlReact<P extends object>(component: ComponentType, props?: P, options?: Record<string, any>): this;
|
|
834
|
-
/**
|
|
835
|
-
* Set the content using a Vue component that outputs MJML.
|
|
836
|
-
*
|
|
837
|
-
* @param component - The Vue component.
|
|
838
|
-
* @param props - Component properties.
|
|
839
|
-
* @param options - MJML options.
|
|
840
|
-
* @returns The current mailable instance for chaining.
|
|
841
|
-
*/
|
|
842
|
-
mjmlVue<P extends object>(component: ComponentType, props?: P, options?: Record<string, any>): this;
|
|
843
|
-
/**
|
|
844
|
-
* Configure the mailable's envelope and content.
|
|
845
|
-
*
|
|
846
|
-
* This abstract method must be implemented by subclasses to define the email's
|
|
847
|
-
* recipients, subject, and body using the fluent API.
|
|
848
|
-
*
|
|
849
|
-
* @returns The current mailable instance.
|
|
850
|
-
*
|
|
851
|
-
* @example
|
|
852
|
-
* ```typescript
|
|
853
|
-
* build() {
|
|
854
|
-
* return this.to('user@example.com').subject('Hi').html('...')
|
|
855
|
-
* }
|
|
856
|
-
* ```
|
|
857
|
-
*/
|
|
858
|
-
abstract build(): this;
|
|
859
|
-
/** The name of the queue to push this mailable to. */
|
|
860
|
-
queueName?: string;
|
|
861
|
-
/** The connection name for the queue. */
|
|
862
|
-
connectionName?: string;
|
|
863
|
-
/** Delay in seconds before the message is sent. */
|
|
864
|
-
delaySeconds?: number;
|
|
865
|
-
/** Priority of the message in the queue. */
|
|
866
|
-
priority?: number | string;
|
|
867
|
-
/**
|
|
868
|
-
* Set the target queue for background processing.
|
|
869
|
-
*
|
|
870
|
-
* @param queue - The name of the queue.
|
|
871
|
-
* @returns The current mailable instance for chaining.
|
|
872
|
-
*
|
|
873
|
-
* @example
|
|
874
|
-
* ```typescript
|
|
875
|
-
* mailable.onQueue('notifications')
|
|
876
|
-
* ```
|
|
877
|
-
*/
|
|
878
|
-
onQueue(queue: string): this;
|
|
879
|
-
/**
|
|
880
|
-
* Set the queue connection to be used.
|
|
881
|
-
*
|
|
882
|
-
* @param connection - The name of the connection (e.g., 'redis', 'sqs').
|
|
883
|
-
* @returns The current mailable instance for chaining.
|
|
884
|
-
*
|
|
885
|
-
* @example
|
|
886
|
-
* ```typescript
|
|
887
|
-
* mailable.onConnection('redis')
|
|
888
|
-
* ```
|
|
889
|
-
*/
|
|
890
|
-
onConnection(connection: string): this;
|
|
891
|
-
/**
|
|
892
|
-
* Set a delay for the queued message.
|
|
893
|
-
*
|
|
894
|
-
* The message will remain in the queue and only be processed after the delay.
|
|
895
|
-
*
|
|
896
|
-
* @param seconds - The delay in seconds.
|
|
897
|
-
* @returns The current mailable instance for chaining.
|
|
898
|
-
*
|
|
899
|
-
* @example
|
|
900
|
-
* ```typescript
|
|
901
|
-
* mailable.delay(3600) // Delay for 1 hour
|
|
902
|
-
* ```
|
|
903
|
-
*/
|
|
904
|
-
delay(seconds: number): this;
|
|
905
|
-
/**
|
|
906
|
-
* Set the priority for the queued message.
|
|
907
|
-
*
|
|
908
|
-
* Higher priority messages are typically processed before lower priority ones.
|
|
909
|
-
*
|
|
910
|
-
* @param priority - The priority value (numeric or string).
|
|
911
|
-
* @returns The current mailable instance for chaining.
|
|
912
|
-
*
|
|
913
|
-
* @example
|
|
914
|
-
* ```typescript
|
|
915
|
-
* mailable.withPriority(10)
|
|
916
|
-
* ```
|
|
917
|
-
*/
|
|
918
|
-
withPriority(priority: string | number): this;
|
|
919
|
-
/**
|
|
920
|
-
* Push the mailable onto the configured queue.
|
|
921
|
-
*
|
|
922
|
-
* Automatically resolves the mail service from the Gravito container and
|
|
923
|
-
* dispatches this mailable for background processing.
|
|
924
|
-
*
|
|
925
|
-
* @returns A promise that resolves when the mailable is queued.
|
|
926
|
-
*
|
|
927
|
-
* @example
|
|
928
|
-
* ```typescript
|
|
929
|
-
* await new WelcomeEmail(user).queue()
|
|
930
|
-
* ```
|
|
931
|
-
*/
|
|
932
|
-
queue(): Promise<void>;
|
|
933
|
-
protected currentLocale?: string;
|
|
934
|
-
protected translator?: (key: string, replace?: Record<string, unknown>, locale?: string) => string;
|
|
935
|
-
/**
|
|
936
|
-
* Set the locale for the email content.
|
|
937
|
-
*
|
|
938
|
-
* Used by the translator to resolve localized strings in templates or components.
|
|
939
|
-
*
|
|
940
|
-
* @param locale - The locale identifier (e.g., 'en-US', 'fr').
|
|
941
|
-
* @returns The current mailable instance for chaining.
|
|
942
|
-
*
|
|
943
|
-
* @example
|
|
944
|
-
* ```typescript
|
|
945
|
-
* mailable.locale('es')
|
|
946
|
-
* ```
|
|
947
|
-
*/
|
|
948
|
-
locale(locale: string): this;
|
|
949
|
-
/**
|
|
950
|
-
* Internal: Set the translator function (called by OrbitSignal)
|
|
951
|
-
* @internal
|
|
952
|
-
*/
|
|
953
|
-
setTranslator(translator: (key: string, replace?: Record<string, unknown>, locale?: string) => string): void;
|
|
954
|
-
/**
|
|
955
|
-
* Translate a key into a localized string.
|
|
956
|
-
*
|
|
957
|
-
* Uses the configured translator and current locale to resolve the key.
|
|
958
|
-
*
|
|
959
|
-
* @param key - The translation key.
|
|
960
|
-
* @param replace - Key-value pairs for string interpolation.
|
|
961
|
-
* @returns The translated string, or the key itself if no translator is available.
|
|
962
|
-
*
|
|
963
|
-
* @example
|
|
964
|
-
* ```typescript
|
|
965
|
-
* const text = mailable.t('messages.welcome', { name: 'Alice' })
|
|
966
|
-
* ```
|
|
967
|
-
*/
|
|
968
|
-
t(key: string, replace?: Record<string, unknown>): string;
|
|
969
|
-
/**
|
|
970
|
-
* Compile the final email envelope.
|
|
971
|
-
*
|
|
972
|
-
* Merges mailable-specific settings with global configuration defaults.
|
|
973
|
-
* This is called internally by the mail service before sending.
|
|
974
|
-
*
|
|
975
|
-
* @param configPromise - The mail configuration or a promise resolving to it.
|
|
976
|
-
* @returns The fully constructed envelope.
|
|
977
|
-
*
|
|
978
|
-
* @example
|
|
979
|
-
* ```typescript
|
|
980
|
-
* const envelope = await mailable.buildEnvelope(config)
|
|
981
|
-
* ```
|
|
982
|
-
*/
|
|
983
|
-
buildEnvelope(configPromise: MailConfig | Promise<MailConfig>): Promise<Envelope>;
|
|
984
|
-
/**
|
|
985
|
-
* Render the email content to HTML and plain text.
|
|
986
|
-
*
|
|
987
|
-
* Executes the chosen renderer (HTML, Template, React, or Vue) with the
|
|
988
|
-
* provided data and i18n helpers.
|
|
989
|
-
*
|
|
990
|
-
* @returns The rendered HTML and optional plain text content.
|
|
991
|
-
* @throws {Error} If no renderer has been specified.
|
|
992
|
-
*
|
|
993
|
-
* @example
|
|
994
|
-
* ```typescript
|
|
995
|
-
* const { html } = await mailable.renderContent()
|
|
996
|
-
* ```
|
|
997
|
-
*/
|
|
998
|
-
renderContent(): Promise<{
|
|
999
|
-
html: string;
|
|
1000
|
-
text?: string;
|
|
1001
|
-
}>;
|
|
1002
|
-
private normalizeAddressArray;
|
|
1003
|
-
}
|
|
1004
|
-
|
|
114
|
+
export { Mailable } from './Mailable';
|
|
1005
115
|
/**
|
|
1006
|
-
*
|
|
116
|
+
* Type-safe mailable base class with compile-time data validation.
|
|
1007
117
|
*
|
|
1008
|
-
*
|
|
1009
|
-
*
|
|
1010
|
-
*
|
|
1011
|
-
*
|
|
1012
|
-
*/
|
|
1013
|
-
type MailEventType = 'beforeSend' | 'afterSend' | 'sendFailed' | 'beforeRender' | 'afterRender' | 'webhookReceived';
|
|
1014
|
-
/**
|
|
1015
|
-
* Mail lifecycle event.
|
|
1016
|
-
*
|
|
1017
|
-
* Emitted at key points during email sending lifecycle.
|
|
1018
|
-
* Used for logging, analytics, or custom processing.
|
|
118
|
+
* Extends Mailable to provide generic type parameters for email data,
|
|
119
|
+
* ensuring template variables and component props are correctly typed
|
|
120
|
+
* and validated at build time. Improves developer experience and reduces
|
|
121
|
+
* runtime errors in complex email workflows.
|
|
1019
122
|
*
|
|
1020
123
|
* @example
|
|
1021
124
|
* ```typescript
|
|
1022
|
-
*
|
|
1023
|
-
* console.log('Email sent to:', event.message?.to)
|
|
1024
|
-
* })
|
|
1025
|
-
* ```
|
|
1026
|
-
*
|
|
1027
|
-
* @public
|
|
1028
|
-
* @since 3.1.0
|
|
1029
|
-
*/
|
|
1030
|
-
interface MailEvent {
|
|
1031
|
-
/** Type of event */
|
|
1032
|
-
type: MailEventType;
|
|
1033
|
-
/** Mailable instance that triggered the event */
|
|
1034
|
-
mailable: Mailable;
|
|
1035
|
-
/** Finalized message (available for send events) */
|
|
1036
|
-
message?: Message;
|
|
1037
|
-
/** Error that occurred (available for sendFailed event) */
|
|
1038
|
-
error?: Error;
|
|
1039
|
-
/** Timestamp when event occurred */
|
|
1040
|
-
timestamp: Date;
|
|
1041
|
-
/** Webhook payload (available for webhookReceived event) */
|
|
1042
|
-
webhook?: {
|
|
1043
|
-
driver: string;
|
|
1044
|
-
event: string;
|
|
1045
|
-
payload: any;
|
|
1046
|
-
};
|
|
1047
|
-
}
|
|
1048
|
-
/**
|
|
1049
|
-
* Mail event handler function.
|
|
125
|
+
* import { TypedMailable } from '@gravito/signal'
|
|
1050
126
|
*
|
|
1051
|
-
*
|
|
127
|
+
* interface WelcomeData {
|
|
128
|
+
* name: string
|
|
129
|
+
* activationUrl: string
|
|
130
|
+
* }
|
|
1052
131
|
*
|
|
1053
|
-
*
|
|
132
|
+
* class WelcomeEmail extends TypedMailable<WelcomeData> {
|
|
133
|
+
* protected data: WelcomeData
|
|
1054
134
|
*
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
135
|
+
* build() {
|
|
136
|
+
* return this
|
|
137
|
+
* .to(this.data.email)
|
|
138
|
+
* .view('emails/welcome', this.data)
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
1060
141
|
* ```
|
|
1061
142
|
*
|
|
143
|
+
* @see {@link Mailable} For base functionality
|
|
144
|
+
* @see {@link Renderer} For rendering engines
|
|
1062
145
|
* @public
|
|
1063
|
-
* @since 3.1.0
|
|
1064
146
|
*/
|
|
1065
|
-
|
|
1066
|
-
|
|
147
|
+
export { TypedMailable } from './TypedMailable';
|
|
1067
148
|
/**
|
|
1068
|
-
* OrbitSignal -
|
|
149
|
+
* OrbitSignal - The central email service orbit for Gravito.
|
|
1069
150
|
*
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
* Gravito's orbit system and queue infrastructure.
|
|
151
|
+
* A production-ready email service providing multi-transport support, automatic
|
|
152
|
+
* retry with exponential backoff, event-driven lifecycle hooks, and development
|
|
153
|
+
* tooling. Integrates seamlessly with Gravito's orbit system and queue infrastructure.
|
|
1074
154
|
*
|
|
1075
|
-
*
|
|
1076
|
-
*
|
|
1077
|
-
*
|
|
1078
|
-
* ├── Configuration (MailConfig)
|
|
1079
|
-
* │ ├── transport: Transport (SMTP, SES, Log, Memory)
|
|
1080
|
-
* │ ├── from: Default sender
|
|
1081
|
-
* │ ├── devMode: Development interception
|
|
1082
|
-
* │ └── translator: i18n support
|
|
1083
|
-
* ├── Lifecycle Events
|
|
1084
|
-
* │ ├── beforeRender → afterRender
|
|
1085
|
-
* │ ├── beforeSend → afterSend
|
|
1086
|
-
* │ └── sendFailed (on error)
|
|
1087
|
-
* ├── Transport Layer
|
|
1088
|
-
* │ ├── BaseTransport (retry, backoff)
|
|
1089
|
-
* │ ├── SmtpTransport (connection pooling)
|
|
1090
|
-
* │ ├── SesTransport (AWS SES)
|
|
1091
|
-
* │ ├── LogTransport (console output)
|
|
1092
|
-
* │ └── MemoryTransport (dev mode)
|
|
1093
|
-
* └── Dev Tools
|
|
1094
|
-
* ├── DevMailbox (in-memory storage)
|
|
1095
|
-
* └── DevServer (preview UI at /__mail)
|
|
1096
|
-
* ```
|
|
155
|
+
* Supports multiple transports (SMTP, AWS SES, Log, Memory) and rendering engines
|
|
156
|
+
* (HTML, Prism templates, React, Vue). In development mode, captures emails in an
|
|
157
|
+
* in-memory mailbox and displays a preview UI.
|
|
1097
158
|
*
|
|
1098
159
|
* @example
|
|
1099
|
-
* **Basic SMTP Configuration**
|
|
1100
160
|
* ```typescript
|
|
1101
161
|
* import { OrbitSignal, SmtpTransport } from '@gravito/signal'
|
|
1102
162
|
*
|
|
@@ -1106,1010 +166,379 @@ type MailEventHandler = (event: MailEvent) => void | Promise<void>;
|
|
|
1106
166
|
* port: 2525,
|
|
1107
167
|
* auth: { user: 'username', pass: 'password' }
|
|
1108
168
|
* }),
|
|
1109
|
-
* from: { name: 'My App', address: 'noreply@myapp.com' }
|
|
169
|
+
* from: { name: 'My App', address: 'noreply@myapp.com' },
|
|
170
|
+
* devMode: process.env.NODE_ENV === 'development'
|
|
1110
171
|
* })
|
|
1111
172
|
*
|
|
1112
173
|
* mail.install(core)
|
|
1113
174
|
* ```
|
|
1114
175
|
*
|
|
1115
176
|
* @example
|
|
1116
|
-
* **AWS SES with Retry Configuration**
|
|
1117
177
|
* ```typescript
|
|
1118
|
-
*
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1121
|
-
* transport: new SesTransport({
|
|
1122
|
-
* region: 'us-east-1',
|
|
1123
|
-
* retries: 3,
|
|
1124
|
-
* retryDelay: 1000,
|
|
1125
|
-
* retryMultiplier: 2
|
|
1126
|
-
* }),
|
|
1127
|
-
* from: { name: 'Production App', address: 'noreply@example.com' }
|
|
178
|
+
* // Sending with events
|
|
179
|
+
* mail.on('beforeSend', async (event) => {
|
|
180
|
+
* console.log('Sending to:', event.message?.to[0].address)
|
|
1128
181
|
* })
|
|
1129
|
-
* ```
|
|
1130
182
|
*
|
|
1131
|
-
*
|
|
1132
|
-
* **Development Mode with Preview UI**
|
|
1133
|
-
* ```typescript
|
|
1134
|
-
* const mail = new OrbitSignal({
|
|
1135
|
-
* devMode: process.env.NODE_ENV === 'development',
|
|
1136
|
-
* devUiPrefix: '/__mail',
|
|
1137
|
-
* from: { name: 'Dev App', address: 'dev@localhost' }
|
|
1138
|
-
* })
|
|
1139
|
-
*
|
|
1140
|
-
* // All emails intercepted to memory, view at http://localhost:3000/__mail
|
|
1141
|
-
* ```
|
|
1142
|
-
*
|
|
1143
|
-
* @example
|
|
1144
|
-
* **Event-Driven Analytics & Error Handling**
|
|
1145
|
-
* ```typescript
|
|
1146
|
-
* const mail = new OrbitSignal({ ... })
|
|
1147
|
-
*
|
|
1148
|
-
* // Track successful sends
|
|
1149
|
-
* mail.on('afterSend', async (event) => {
|
|
1150
|
-
* await analytics.track('email_sent', {
|
|
1151
|
-
* to: event.message?.to,
|
|
1152
|
-
* subject: event.message?.subject,
|
|
1153
|
-
* timestamp: event.timestamp
|
|
1154
|
-
* })
|
|
1155
|
-
* })
|
|
1156
|
-
*
|
|
1157
|
-
* // Log failures for monitoring
|
|
1158
|
-
* mail.on('sendFailed', async (event) => {
|
|
1159
|
-
* logger.error('Email send failed', {
|
|
1160
|
-
* error: event.error?.message,
|
|
1161
|
-
* mailable: event.mailable.constructor.name
|
|
1162
|
-
* })
|
|
1163
|
-
* await sentry.captureException(event.error)
|
|
1164
|
-
* })
|
|
1165
|
-
* ```
|
|
1166
|
-
*
|
|
1167
|
-
* @example
|
|
1168
|
-
* **SMTP with Connection Pooling**
|
|
1169
|
-
* ```typescript
|
|
1170
|
-
* const mail = new OrbitSignal({
|
|
1171
|
-
* transport: new SmtpTransport({
|
|
1172
|
-
* host: 'smtp.gmail.com',
|
|
1173
|
-
* port: 465,
|
|
1174
|
-
* secure: true,
|
|
1175
|
-
* auth: { user: 'user@gmail.com', pass: 'app-password' },
|
|
1176
|
-
* poolSize: 5,
|
|
1177
|
-
* maxIdleTime: 30000
|
|
1178
|
-
* })
|
|
1179
|
-
* })
|
|
1180
|
-
*
|
|
1181
|
-
* // Graceful shutdown
|
|
1182
|
-
* process.on('SIGTERM', async () => {
|
|
1183
|
-
* await mail.config.transport?.close?.()
|
|
1184
|
-
* })
|
|
183
|
+
* await mail.send(new WelcomeEmail(user))
|
|
1185
184
|
* ```
|
|
1186
185
|
*
|
|
1187
|
-
* @
|
|
1188
|
-
*
|
|
1189
|
-
*
|
|
1190
|
-
*
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
*
|
|
186
|
+
* @see {@link Mailable} For creating email messages
|
|
187
|
+
* @see {@link Transport} For custom transport implementations
|
|
188
|
+
* @see {@link MailEvent} For lifecycle event types
|
|
189
|
+
* @public
|
|
190
|
+
*/
|
|
191
|
+
export { OrbitSignal } from './OrbitSignal';
|
|
192
|
+
/**
|
|
193
|
+
* Raw HTML content renderer.
|
|
1195
194
|
*
|
|
1196
|
-
*
|
|
1197
|
-
*
|
|
1198
|
-
* ```
|
|
195
|
+
* Renders plain HTML strings as email content. Suitable for pre-rendered
|
|
196
|
+
* HTML or when using other templating libraries. Performs minimal processing.
|
|
1199
197
|
*
|
|
1200
198
|
* @example
|
|
1201
|
-
* **Queue Integration for Background Processing**
|
|
1202
199
|
* ```typescript
|
|
1203
|
-
*
|
|
1204
|
-
* const email = new WelcomeEmail(user)
|
|
1205
|
-
* .onQueue('emails')
|
|
1206
|
-
* .delay(60)
|
|
1207
|
-
*
|
|
1208
|
-
* await email.queue()
|
|
1209
|
-
* ```
|
|
200
|
+
* import { Mailable, HtmlRenderer } from '@gravito/signal'
|
|
1210
201
|
*
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1216
|
-
* } catch (error) {
|
|
1217
|
-
* if (error instanceof MailTransportError) {
|
|
1218
|
-
* switch (error.code) {
|
|
1219
|
-
* case MailErrorCode.RATE_LIMIT:
|
|
1220
|
-
* await queue.pushDelayed(email, 300)
|
|
1221
|
-
* break
|
|
1222
|
-
* case MailErrorCode.RECIPIENT_REJECTED:
|
|
1223
|
-
* await markUserEmailInvalid(user.id)
|
|
1224
|
-
* break
|
|
1225
|
-
* default:
|
|
1226
|
-
* throw error
|
|
1227
|
-
* }
|
|
202
|
+
* class RawHtmlEmail extends Mailable {
|
|
203
|
+
* build() {
|
|
204
|
+
* return this
|
|
205
|
+
* .to('user@example.com')
|
|
206
|
+
* .html('<h1>Hello</h1><p>This is HTML</p>')
|
|
1228
207
|
* }
|
|
1229
208
|
* }
|
|
1230
209
|
* ```
|
|
1231
210
|
*
|
|
1232
|
-
* @see {@link
|
|
1233
|
-
* @see {@link TypedMailable} Strongly-typed mailable with generic data
|
|
1234
|
-
* @see {@link Transport} Transport interface
|
|
1235
|
-
* @see {@link BaseTransport} Retry-enabled base transport
|
|
1236
|
-
* @see {@link MailConfig} Configuration interface
|
|
1237
|
-
* @see {@link MailEvent} Event types
|
|
1238
|
-
* @see {@link MailTransportError} Error handling
|
|
1239
|
-
*
|
|
1240
|
-
* @since 3.0.0
|
|
211
|
+
* @see {@link Renderer} For the renderer interface
|
|
1241
212
|
* @public
|
|
1242
213
|
*/
|
|
1243
|
-
|
|
1244
|
-
private config;
|
|
1245
|
-
private devMailbox?;
|
|
1246
|
-
private core?;
|
|
1247
|
-
private eventHandlers;
|
|
1248
|
-
constructor(config?: MailConfig);
|
|
1249
|
-
/**
|
|
1250
|
-
* Install the orbit into PlanetCore.
|
|
1251
|
-
*
|
|
1252
|
-
* Registers the mail service in the IoC container and sets up development
|
|
1253
|
-
* tools if enabled. It also injects the service into the GravitoContext
|
|
1254
|
-
* for easy access in route handlers.
|
|
1255
|
-
*
|
|
1256
|
-
* @param core - The PlanetCore instance to install into
|
|
1257
|
-
*
|
|
1258
|
-
* @example
|
|
1259
|
-
* ```typescript
|
|
1260
|
-
* const mail = new OrbitSignal(config);
|
|
1261
|
-
* mail.install(core);
|
|
1262
|
-
* ```
|
|
1263
|
-
*/
|
|
1264
|
-
install(core: PlanetCore): void;
|
|
1265
|
-
/**
|
|
1266
|
-
* Internal: Handle processed webhook.
|
|
1267
|
-
*/
|
|
1268
|
-
private handleWebhook;
|
|
1269
|
-
/**
|
|
1270
|
-
* Send a mailable instance immediately.
|
|
1271
|
-
*
|
|
1272
|
-
* Orchestrates the full email sending lifecycle: building the envelope,
|
|
1273
|
-
* rendering content, emitting events, and delivering via the configured transport.
|
|
1274
|
-
*
|
|
1275
|
-
* @param mailable - The email definition to send
|
|
1276
|
-
* @throws {Error} If mandatory fields (from, to) are missing or transport fails
|
|
1277
|
-
*
|
|
1278
|
-
* @example
|
|
1279
|
-
* ```typescript
|
|
1280
|
-
* await mail.send(new WelcomeEmail(user));
|
|
1281
|
-
* ```
|
|
1282
|
-
*/
|
|
1283
|
-
send(mailable: Mailable): Promise<void>;
|
|
1284
|
-
/**
|
|
1285
|
-
* Queue a mailable instance for background processing.
|
|
1286
|
-
*
|
|
1287
|
-
* Attempts to use the 'queue' service (OrbitStream) if available in the
|
|
1288
|
-
* container. Falls back to immediate sending if no queue service is found.
|
|
1289
|
-
*
|
|
1290
|
-
* @param mailable - The email definition to queue
|
|
1291
|
-
*
|
|
1292
|
-
* @example
|
|
1293
|
-
* ```typescript
|
|
1294
|
-
* await mail.queue(new WelcomeEmail(user));
|
|
1295
|
-
* ```
|
|
1296
|
-
*/
|
|
1297
|
-
queue(mailable: Mailable): Promise<void>;
|
|
1298
|
-
/**
|
|
1299
|
-
* Register an event handler.
|
|
1300
|
-
*
|
|
1301
|
-
* @description
|
|
1302
|
-
* Subscribe to mail lifecycle events for logging, analytics, or custom processing.
|
|
1303
|
-
*
|
|
1304
|
-
* @param event - The event type to listen for
|
|
1305
|
-
* @param handler - The handler function to execute
|
|
1306
|
-
* @returns This instance for method chaining
|
|
1307
|
-
*
|
|
1308
|
-
* @example
|
|
1309
|
-
* ```typescript
|
|
1310
|
-
* mail.on('afterSend', async (event) => {
|
|
1311
|
-
* await analytics.track('email_sent', {
|
|
1312
|
-
* to: event.message?.to,
|
|
1313
|
-
* subject: event.message?.subject
|
|
1314
|
-
* })
|
|
1315
|
-
* })
|
|
1316
|
-
* ```
|
|
1317
|
-
*
|
|
1318
|
-
* @public
|
|
1319
|
-
* @since 3.1.0
|
|
1320
|
-
*/
|
|
1321
|
-
on(event: MailEventType, handler: MailEventHandler): this;
|
|
1322
|
-
private emit;
|
|
1323
|
-
}
|
|
1324
|
-
declare module '@gravito/core' {
|
|
1325
|
-
interface GravitoVariables {
|
|
1326
|
-
/** Mail service for sending emails */
|
|
1327
|
-
mail?: OrbitSignal;
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
|
|
214
|
+
export { HtmlRenderer } from './renderers/HtmlRenderer';
|
|
1331
215
|
/**
|
|
1332
|
-
*
|
|
216
|
+
* MJML (Responsive Email Markup Language) template renderer.
|
|
1333
217
|
*
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1336
|
-
*
|
|
218
|
+
* Renders MJML template syntax and converts it to optimized, responsive HTML
|
|
219
|
+
* suitable for all email clients. MJML abstracts away CSS and media queries
|
|
220
|
+
* complexity while ensuring broad compatibility.
|
|
1337
221
|
*
|
|
1338
222
|
* @example
|
|
1339
223
|
* ```typescript
|
|
1340
|
-
*
|
|
1341
|
-
* const result = await renderer.render();
|
|
1342
|
-
* // result.html: '<h1>Hello</h1>'
|
|
1343
|
-
* // result.text: 'Hello'
|
|
1344
|
-
* ```
|
|
1345
|
-
*
|
|
1346
|
-
* @public
|
|
1347
|
-
* @since 3.0.0
|
|
1348
|
-
*/
|
|
1349
|
-
declare class HtmlRenderer implements Renderer {
|
|
1350
|
-
private content;
|
|
1351
|
-
/**
|
|
1352
|
-
* Creates an instance of HtmlRenderer.
|
|
1353
|
-
*
|
|
1354
|
-
* @param content - The raw HTML string to be rendered.
|
|
1355
|
-
*/
|
|
1356
|
-
constructor(content: string);
|
|
1357
|
-
/**
|
|
1358
|
-
* Returns the original HTML and a stripped plain text version.
|
|
1359
|
-
*
|
|
1360
|
-
* @returns A promise resolving to the rendered content.
|
|
1361
|
-
*/
|
|
1362
|
-
render(): Promise<RenderResult>;
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
/**
|
|
1366
|
-
* Renderer for MJML-based emails.
|
|
1367
|
-
*
|
|
1368
|
-
* MJML is a markup language designed to reduce the pain of coding a responsive email.
|
|
1369
|
-
* This renderer lazily loads the `mjml` package to keep the core lightweight.
|
|
224
|
+
* import { Mailable, MjmlRenderer } from '@gravito/signal'
|
|
1370
225
|
*
|
|
1371
|
-
*
|
|
1372
|
-
*
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
226
|
+
* class MjmlEmail extends Mailable {
|
|
227
|
+
* build() {
|
|
228
|
+
* return this
|
|
229
|
+
* .to('user@example.com')
|
|
230
|
+
* .view('emails/welcome.mjml', { name: 'Alice' })
|
|
231
|
+
* }
|
|
232
|
+
* }
|
|
1375
233
|
* ```
|
|
1376
234
|
*
|
|
235
|
+
* @see {@link ReactMjmlRenderer} For React components
|
|
236
|
+
* @see {@link VueMjmlRenderer} For Vue components
|
|
237
|
+
* @see {@link Renderer} For the renderer interface
|
|
1377
238
|
* @public
|
|
1378
|
-
* @since 1.1.0
|
|
1379
239
|
*/
|
|
1380
|
-
|
|
1381
|
-
private content;
|
|
1382
|
-
private options;
|
|
1383
|
-
private deps;
|
|
1384
|
-
/**
|
|
1385
|
-
* Creates an instance of MjmlRenderer.
|
|
1386
|
-
*
|
|
1387
|
-
* @param content - The MJML markup string to be rendered.
|
|
1388
|
-
* @param options - Optional MJML transformation options.
|
|
1389
|
-
* @param deps - Optional dependency injection for testing.
|
|
1390
|
-
*/
|
|
1391
|
-
constructor(content: string, options?: Record<string, any>, deps?: {
|
|
1392
|
-
mjml2html?: (mjml: string, options?: any) => any;
|
|
1393
|
-
});
|
|
1394
|
-
/**
|
|
1395
|
-
* Renders the MJML content to static HTML.
|
|
1396
|
-
*
|
|
1397
|
-
* This method performs a dynamic import of `mjml` to ensure it's only
|
|
1398
|
-
* loaded if this renderer is actually used.
|
|
1399
|
-
*
|
|
1400
|
-
* @returns A promise resolving to the rendered content.
|
|
1401
|
-
* @throws {Error} If MJML dependencies cannot be loaded or rendering fails.
|
|
1402
|
-
*/
|
|
1403
|
-
render(): Promise<RenderResult>;
|
|
1404
|
-
}
|
|
1405
|
-
|
|
240
|
+
export { MjmlRenderer } from './renderers/MjmlRenderer';
|
|
1406
241
|
/**
|
|
1407
|
-
*
|
|
1408
|
-
* Includes common head styles and responsive settings.
|
|
242
|
+
* Built-in MJML email templates and utilities.
|
|
1409
243
|
*
|
|
1410
|
-
*
|
|
1411
|
-
|
|
1412
|
-
declare const baseLayout: string;
|
|
1413
|
-
/**
|
|
1414
|
-
* A simple transactional component layout.
|
|
1415
|
-
*/
|
|
1416
|
-
declare const transactionLayout = "\n<mj-section background-color=\"#ffffff\" padding-top=\"0px\">\n <mj-column>\n {{content}}\n </mj-column>\n</mj-section>\n";
|
|
1417
|
-
|
|
1418
|
-
/**
|
|
1419
|
-
* Renderer for React component-based MJML emails.
|
|
244
|
+
* Pre-built responsive email template components and helpers for common
|
|
245
|
+
* use cases, reducing boilerplate when creating MJML-based emails.
|
|
1420
246
|
*
|
|
1421
|
-
*
|
|
1422
|
-
*
|
|
1423
|
-
*
|
|
1424
|
-
* @typeParam P - Props type for the React component.
|
|
247
|
+
* @see {@link MjmlRenderer} For MJML rendering
|
|
248
|
+
* @see {@link ReactMjmlRenderer} For React + MJML
|
|
1425
249
|
* @public
|
|
1426
|
-
* @since 1.1.0
|
|
1427
250
|
*/
|
|
1428
|
-
|
|
1429
|
-
private component;
|
|
1430
|
-
private props?;
|
|
1431
|
-
private options;
|
|
1432
|
-
private deps;
|
|
1433
|
-
/**
|
|
1434
|
-
* Creates an instance of ReactMjmlRenderer.
|
|
1435
|
-
*
|
|
1436
|
-
* @param component - The React component to render.
|
|
1437
|
-
* @param props - Initial props for the component.
|
|
1438
|
-
* @param options - Optional MJML transformation options.
|
|
1439
|
-
* @param deps - Optional dependency injection for testing.
|
|
1440
|
-
*/
|
|
1441
|
-
constructor(component: any, props?: P | undefined, options?: Record<string, any>, deps?: {
|
|
1442
|
-
createElement?: (...args: any[]) => any;
|
|
1443
|
-
renderToStaticMarkup?: (element: any) => string;
|
|
1444
|
-
mjml2html?: (mjml: string, options?: any) => any;
|
|
1445
|
-
});
|
|
1446
|
-
/**
|
|
1447
|
-
* Renders the React component to a static HTML string via MJML.
|
|
1448
|
-
*
|
|
1449
|
-
* @param data - Runtime data to be merged with initial props.
|
|
1450
|
-
* @returns A promise resolving to the rendered content.
|
|
1451
|
-
* @throws {Error} If MJML rendering fails.
|
|
1452
|
-
*/
|
|
1453
|
-
render(data: Record<string, unknown>): Promise<RenderResult>;
|
|
1454
|
-
}
|
|
1455
|
-
|
|
251
|
+
export * from './renderers/mjml-templates';
|
|
1456
252
|
/**
|
|
1457
|
-
*
|
|
253
|
+
* React component renderer with MJML support.
|
|
1458
254
|
*
|
|
1459
|
-
* Renders
|
|
1460
|
-
*
|
|
1461
|
-
*
|
|
255
|
+
* Renders React components as email content with MJML syntax support,
|
|
256
|
+
* enabling you to build emails using familiar React patterns while maintaining
|
|
257
|
+
* responsive email best practices.
|
|
1462
258
|
*
|
|
1463
259
|
* @example
|
|
1464
260
|
* ```typescript
|
|
1465
|
-
*
|
|
1466
|
-
*
|
|
261
|
+
* import { Mailable, ReactMjmlRenderer } from '@gravito/signal'
|
|
262
|
+
*
|
|
263
|
+
* const WelcomeComponent = ({ name }: { name: string }) => (
|
|
264
|
+
* <mjml>
|
|
265
|
+
* <mj-body>
|
|
266
|
+
* <mj-section>
|
|
267
|
+
* <mj-column><mj-text>Welcome, {name}!</mj-text></mj-column>
|
|
268
|
+
* </mj-section>
|
|
269
|
+
* </mj-body>
|
|
270
|
+
* </mjml>
|
|
271
|
+
* )
|
|
272
|
+
*
|
|
273
|
+
* class ReactEmail extends Mailable {
|
|
274
|
+
* build() {
|
|
275
|
+
* return this
|
|
276
|
+
* .to('user@example.com')
|
|
277
|
+
* .react(WelcomeComponent, { name: 'Alice' })
|
|
278
|
+
* }
|
|
279
|
+
* }
|
|
1467
280
|
* ```
|
|
1468
281
|
*
|
|
282
|
+
* @see {@link VueMjmlRenderer} For Vue component rendering
|
|
283
|
+
* @see {@link Renderer} For the renderer interface
|
|
1469
284
|
* @public
|
|
1470
|
-
* @since 3.0.0
|
|
1471
285
|
*/
|
|
1472
|
-
|
|
1473
|
-
private template;
|
|
1474
|
-
private viewsDir;
|
|
1475
|
-
private static engineCache;
|
|
1476
|
-
/**
|
|
1477
|
-
* Creates an instance of TemplateRenderer.
|
|
1478
|
-
*
|
|
1479
|
-
* @param templateName - The name of the template file (without extension).
|
|
1480
|
-
* @param viewsDir - The directory containing template files. Defaults to `src/emails`.
|
|
1481
|
-
*/
|
|
1482
|
-
constructor(templateName: string, viewsDir?: string);
|
|
1483
|
-
/**
|
|
1484
|
-
* Renders the template with the provided data.
|
|
1485
|
-
*
|
|
1486
|
-
* This method lazily loads `@gravito/prism` to ensure the core package
|
|
1487
|
-
* remains lightweight for users who don't need template rendering.
|
|
1488
|
-
*
|
|
1489
|
-
* @param data - The data context for template interpolation.
|
|
1490
|
-
* @returns A promise resolving to the rendered content.
|
|
1491
|
-
* @throws {Error} If the template engine fails to load or rendering fails.
|
|
1492
|
-
*/
|
|
1493
|
-
render(data: Record<string, unknown>): Promise<RenderResult>;
|
|
1494
|
-
/**
|
|
1495
|
-
* Clear template engine cache.
|
|
1496
|
-
*
|
|
1497
|
-
* Useful in development environments to force recompilation of templates
|
|
1498
|
-
* after they have been modified on disk.
|
|
1499
|
-
*
|
|
1500
|
-
* @example
|
|
1501
|
-
* ```typescript
|
|
1502
|
-
* TemplateRenderer.clearCache();
|
|
1503
|
-
* ```
|
|
1504
|
-
*
|
|
1505
|
-
* @public
|
|
1506
|
-
* @since 3.1.0
|
|
1507
|
-
*/
|
|
1508
|
-
static clearCache(): void;
|
|
1509
|
-
}
|
|
1510
|
-
|
|
286
|
+
export { ReactMjmlRenderer } from './renderers/ReactMjmlRenderer';
|
|
1511
287
|
/**
|
|
1512
|
-
* Renderer for
|
|
288
|
+
* Renderer abstractions for email content generation.
|
|
1513
289
|
*
|
|
1514
|
-
*
|
|
1515
|
-
*
|
|
290
|
+
* Defines the interface and return type for building custom content renderers,
|
|
291
|
+
* enabling support for additional templating engines beyond the built-in
|
|
292
|
+
* HTML, Prism, React, and Vue implementations.
|
|
1516
293
|
*
|
|
1517
|
-
* @
|
|
294
|
+
* @see {@link HtmlRenderer} For raw HTML content
|
|
295
|
+
* @see {@link TemplateRenderer} For Prism template rendering
|
|
296
|
+
* @see {@link ReactMjmlRenderer} For React component rendering
|
|
297
|
+
* @see {@link VueMjmlRenderer} For Vue component rendering
|
|
1518
298
|
* @public
|
|
1519
|
-
* @since 1.1.0
|
|
1520
299
|
*/
|
|
1521
|
-
|
|
1522
|
-
private component;
|
|
1523
|
-
private props?;
|
|
1524
|
-
private options;
|
|
1525
|
-
private deps;
|
|
1526
|
-
/**
|
|
1527
|
-
* Creates an instance of VueMjmlRenderer.
|
|
1528
|
-
*
|
|
1529
|
-
* @param component - The Vue component to render.
|
|
1530
|
-
* @param props - Initial props for the component.
|
|
1531
|
-
* @param options - Optional MJML transformation options.
|
|
1532
|
-
* @param deps - Optional dependency injection for testing.
|
|
1533
|
-
*/
|
|
1534
|
-
constructor(component: any, props?: P | undefined, options?: Record<string, any>, deps?: {
|
|
1535
|
-
createSSRApp?: (...args: any[]) => any;
|
|
1536
|
-
h?: (...args: any[]) => any;
|
|
1537
|
-
renderToString?: (app: any) => Promise<string>;
|
|
1538
|
-
mjml2html?: (mjml: string, options?: any) => any;
|
|
1539
|
-
});
|
|
1540
|
-
/**
|
|
1541
|
-
* Renders the Vue component to a static HTML string via MJML.
|
|
1542
|
-
*
|
|
1543
|
-
* @param data - Runtime data to be merged with initial props.
|
|
1544
|
-
* @returns A promise resolving to the rendered content.
|
|
1545
|
-
* @throws {Error} If MJML rendering fails.
|
|
1546
|
-
*/
|
|
1547
|
-
render(data: Record<string, unknown>): Promise<RenderResult>;
|
|
1548
|
-
}
|
|
1549
|
-
|
|
300
|
+
export type { Renderer, RenderResult } from './renderers/Renderer';
|
|
1550
301
|
/**
|
|
1551
|
-
*
|
|
302
|
+
* Prism templating engine renderer for email content.
|
|
1552
303
|
*
|
|
1553
|
-
*
|
|
1554
|
-
*
|
|
1555
|
-
*
|
|
1556
|
-
* components is correctly typed and validated at build time.
|
|
1557
|
-
*
|
|
1558
|
-
* @typeParam TData - The shape of data required by this mailable's template/component.
|
|
1559
|
-
* Must extend Record<string, unknown>.
|
|
304
|
+
* Renders Blade-style templates using the Prism template engine. Supports
|
|
305
|
+
* variables, control structures, and template inheritance for complex
|
|
306
|
+
* email layouts and components.
|
|
1560
307
|
*
|
|
1561
308
|
* @example
|
|
1562
309
|
* ```typescript
|
|
1563
|
-
* import {
|
|
1564
|
-
*
|
|
1565
|
-
* // Define the data interface
|
|
1566
|
-
* interface WelcomeData {
|
|
1567
|
-
* name: string
|
|
1568
|
-
* email: string
|
|
1569
|
-
* activationUrl: string
|
|
1570
|
-
* }
|
|
1571
|
-
*
|
|
1572
|
-
* // Create strongly-typed mailable
|
|
1573
|
-
* class WelcomeEmail extends TypedMailable<WelcomeData> {
|
|
1574
|
-
* protected data: WelcomeData
|
|
1575
|
-
*
|
|
1576
|
-
* constructor(data: WelcomeData) {
|
|
1577
|
-
* super()
|
|
1578
|
-
* this.data = data
|
|
1579
|
-
* }
|
|
310
|
+
* import { Mailable, TemplateRenderer } from '@gravito/signal'
|
|
1580
311
|
*
|
|
312
|
+
* class TemplateEmail extends Mailable {
|
|
1581
313
|
* build() {
|
|
1582
314
|
* return this
|
|
1583
|
-
* .to(
|
|
1584
|
-
* .
|
|
1585
|
-
* .view('emails/welcome', this.data) // Type-safe: compiler ensures WelcomeData matches template
|
|
315
|
+
* .to('user@example.com')
|
|
316
|
+
* .view('emails/welcome', { name: 'Alice' })
|
|
1586
317
|
* }
|
|
1587
318
|
* }
|
|
319
|
+
* ```
|
|
1588
320
|
*
|
|
1589
|
-
*
|
|
1590
|
-
*
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
*
|
|
321
|
+
* @see {@link Renderer} For the renderer interface
|
|
322
|
+
* @public
|
|
323
|
+
*/
|
|
324
|
+
export { TemplateRenderer } from './renderers/TemplateRenderer';
|
|
325
|
+
/**
|
|
326
|
+
* Vue component renderer with MJML support.
|
|
1595
327
|
*
|
|
1596
|
-
*
|
|
1597
|
-
*
|
|
328
|
+
* Renders Vue single-file components or templates as email content with MJML
|
|
329
|
+
* syntax support, enabling Vue developers to build emails using familiar
|
|
330
|
+
* patterns while maintaining responsive email best practices.
|
|
1598
331
|
*
|
|
1599
332
|
* @example
|
|
1600
333
|
* ```typescript
|
|
1601
|
-
*
|
|
1602
|
-
* interface InvoiceData {
|
|
1603
|
-
* invoiceNumber: string
|
|
1604
|
-
* amount: number
|
|
1605
|
-
* dueDate: Date
|
|
1606
|
-
* items: Array<{ name: string; price: number }>
|
|
1607
|
-
* }
|
|
1608
|
-
*
|
|
1609
|
-
* class InvoiceEmail extends TypedMailable<InvoiceData> {
|
|
1610
|
-
* protected data: InvoiceData
|
|
1611
|
-
*
|
|
1612
|
-
* constructor(data: InvoiceData) {
|
|
1613
|
-
* super()
|
|
1614
|
-
* this.data = data
|
|
1615
|
-
* }
|
|
334
|
+
* import { Mailable, VueMjmlRenderer } from '@gravito/signal'
|
|
1616
335
|
*
|
|
336
|
+
* class VueEmail extends Mailable {
|
|
1617
337
|
* build() {
|
|
1618
338
|
* return this
|
|
1619
|
-
* .to('
|
|
1620
|
-
* .
|
|
1621
|
-
* .react(InvoiceComponent, this.data) // Type-safe props
|
|
339
|
+
* .to('user@example.com')
|
|
340
|
+
* .vue('emails/welcome.vue', { name: 'Alice' })
|
|
1622
341
|
* }
|
|
1623
342
|
* }
|
|
1624
343
|
* ```
|
|
1625
344
|
*
|
|
1626
|
-
* @see {@link
|
|
1627
|
-
* @see {@link
|
|
1628
|
-
*
|
|
345
|
+
* @see {@link ReactMjmlRenderer} For React component rendering
|
|
346
|
+
* @see {@link Renderer} For the renderer interface
|
|
1629
347
|
* @public
|
|
1630
|
-
* @since 3.0.0
|
|
1631
348
|
*/
|
|
1632
|
-
|
|
1633
|
-
/**
|
|
1634
|
-
* The strongly-typed data for this mailable.
|
|
1635
|
-
*
|
|
1636
|
-
* This property holds the data that will be passed to the template or component
|
|
1637
|
-
* during rendering. By defining it as an abstract property with the generic
|
|
1638
|
-
* type TData, we force subclasses to provide a concrete, type-safe implementation.
|
|
1639
|
-
*
|
|
1640
|
-
* @protected
|
|
1641
|
-
*/
|
|
1642
|
-
protected abstract data: TData;
|
|
1643
|
-
}
|
|
1644
|
-
|
|
349
|
+
export { VueMjmlRenderer } from './renderers/VueMjmlRenderer';
|
|
1645
350
|
/**
|
|
1646
|
-
*
|
|
351
|
+
* Base transport class with automatic retry and backoff logic.
|
|
1647
352
|
*
|
|
1648
|
-
*
|
|
1649
|
-
*
|
|
353
|
+
* Provides common functionality for all transports, including exponential
|
|
354
|
+
* backoff retry strategy, connection management, and error handling.
|
|
355
|
+
* Extend this class to implement custom transport drivers.
|
|
1650
356
|
*
|
|
1651
357
|
* @example
|
|
1652
358
|
* ```typescript
|
|
1653
|
-
*
|
|
1654
|
-
*
|
|
1655
|
-
*
|
|
1656
|
-
*
|
|
1657
|
-
*
|
|
359
|
+
* import { BaseTransport, type TransportOptions } from '@gravito/signal'
|
|
360
|
+
*
|
|
361
|
+
* class CustomTransport extends BaseTransport {
|
|
362
|
+
* async send(message) {
|
|
363
|
+
* // Custom delivery logic
|
|
364
|
+
* }
|
|
365
|
+
* }
|
|
1658
366
|
* ```
|
|
1659
367
|
*
|
|
368
|
+
* @see {@link SmtpTransport} For production SMTP implementation
|
|
369
|
+
* @see {@link Transport} For the interface
|
|
1660
370
|
* @public
|
|
1661
371
|
*/
|
|
1662
|
-
|
|
1663
|
-
/**
|
|
1664
|
-
* Maximum number of retry attempts before giving up.
|
|
1665
|
-
* Set to 0 to disable retries.
|
|
1666
|
-
*/
|
|
1667
|
-
maxRetries?: number;
|
|
1668
|
-
/**
|
|
1669
|
-
* Initial delay in milliseconds before the first retry attempt.
|
|
1670
|
-
*/
|
|
1671
|
-
retryDelay?: number;
|
|
1672
|
-
/**
|
|
1673
|
-
* Multiplier applied to the delay after each failed attempt.
|
|
1674
|
-
* Used to implement exponential backoff to avoid overwhelming the service.
|
|
1675
|
-
*/
|
|
1676
|
-
backoffMultiplier?: number;
|
|
1677
|
-
}
|
|
372
|
+
export { BaseTransport, type TransportOptions } from './transports/BaseTransport';
|
|
1678
373
|
/**
|
|
1679
|
-
*
|
|
1680
|
-
*
|
|
1681
|
-
* This abstract class provides a robust foundation for all transport implementations by
|
|
1682
|
-
* handling transient failures through an exponential backoff retry strategy. It ensures
|
|
1683
|
-
* that temporary network issues or service rate limits do not immediately fail the email delivery.
|
|
374
|
+
* Console logging transport for development environments.
|
|
1684
375
|
*
|
|
1685
|
-
*
|
|
1686
|
-
*
|
|
1687
|
-
* 2. If it fails, wait for `retryDelay` milliseconds.
|
|
1688
|
-
* 3. Increment the delay by `backoffMultiplier` for the next attempt.
|
|
1689
|
-
* 4. Repeat until success or `maxRetries` is reached.
|
|
376
|
+
* Logs all emails to the console instead of sending them. Useful for
|
|
377
|
+
* local development and testing to avoid sending real emails to users.
|
|
1690
378
|
*
|
|
1691
379
|
* @example
|
|
1692
380
|
* ```typescript
|
|
1693
|
-
*
|
|
1694
|
-
* constructor() {
|
|
1695
|
-
* super({ maxRetries: 3, retryDelay: 1000 })
|
|
1696
|
-
* }
|
|
381
|
+
* import { LogTransport } from '@gravito/signal'
|
|
1697
382
|
*
|
|
1698
|
-
*
|
|
1699
|
-
*
|
|
1700
|
-
*
|
|
1701
|
-
*
|
|
1702
|
-
* }
|
|
383
|
+
* const mail = new OrbitSignal({
|
|
384
|
+
* transport: new LogTransport(),
|
|
385
|
+
* from: { address: 'dev@localhost' }
|
|
386
|
+
* })
|
|
1703
387
|
* ```
|
|
1704
388
|
*
|
|
389
|
+
* @see {@link MemoryTransport} For in-memory testing
|
|
1705
390
|
* @public
|
|
1706
391
|
*/
|
|
1707
|
-
|
|
1708
|
-
protected options: Required<TransportOptions>;
|
|
1709
|
-
/**
|
|
1710
|
-
* Initializes the transport with retry options.
|
|
1711
|
-
*
|
|
1712
|
-
* @param options - Configuration for the retry mechanism.
|
|
1713
|
-
*/
|
|
1714
|
-
constructor(options?: TransportOptions);
|
|
1715
|
-
/**
|
|
1716
|
-
* Orchestrates the message delivery with retry logic.
|
|
1717
|
-
*
|
|
1718
|
-
* This method wraps the concrete `doSend` implementation in a retry loop.
|
|
1719
|
-
* It tracks the last error encountered to provide context if all retries fail.
|
|
1720
|
-
*
|
|
1721
|
-
* @param message - The message to be delivered.
|
|
1722
|
-
* @returns A promise that resolves when the message is successfully sent.
|
|
1723
|
-
* @throws {MailTransportError} If the message cannot be sent after the maximum number of retries.
|
|
1724
|
-
*
|
|
1725
|
-
* @example
|
|
1726
|
-
* ```typescript
|
|
1727
|
-
* const transport = new SmtpTransport(config);
|
|
1728
|
-
* try {
|
|
1729
|
-
* await transport.send(message);
|
|
1730
|
-
* } catch (error) {
|
|
1731
|
-
* console.error('Failed to send email after retries', error);
|
|
1732
|
-
* }
|
|
1733
|
-
* ```
|
|
1734
|
-
*/
|
|
1735
|
-
send(message: Message): Promise<void>;
|
|
1736
|
-
/**
|
|
1737
|
-
* Actual transport implementation to be provided by subclasses.
|
|
1738
|
-
*
|
|
1739
|
-
* This method should contain the protocol-specific logic for delivering the message.
|
|
1740
|
-
* It will be automatically retried by the `send` method if it throws an error.
|
|
1741
|
-
*
|
|
1742
|
-
* @param message - The message to send.
|
|
1743
|
-
* @returns A promise that resolves when the delivery is successful.
|
|
1744
|
-
* @throws {Error} Any error encountered during delivery, which will trigger a retry.
|
|
1745
|
-
*/
|
|
1746
|
-
protected abstract doSend(message: Message): Promise<void>;
|
|
1747
|
-
/**
|
|
1748
|
-
* Utility method to pause execution for a given duration.
|
|
1749
|
-
*
|
|
1750
|
-
* @param ms - Milliseconds to sleep.
|
|
1751
|
-
* @returns A promise that resolves after the delay.
|
|
1752
|
-
*/
|
|
1753
|
-
private sleep;
|
|
1754
|
-
}
|
|
1755
|
-
|
|
392
|
+
export { LogTransport } from './transports/LogTransport';
|
|
1756
393
|
/**
|
|
1757
|
-
*
|
|
394
|
+
* In-memory transport for testing email workflows.
|
|
1758
395
|
*
|
|
1759
|
-
*
|
|
1760
|
-
*
|
|
1761
|
-
*
|
|
396
|
+
* Stores sent emails in memory without actual transmission. Perfect for
|
|
397
|
+
* unit tests and integration tests where email sending needs to be verified
|
|
398
|
+
* without external dependencies.
|
|
1762
399
|
*
|
|
1763
400
|
* @example
|
|
1764
401
|
* ```typescript
|
|
1765
|
-
* import {
|
|
1766
|
-
*
|
|
1767
|
-
* const transport = new
|
|
1768
|
-
*
|
|
1769
|
-
*
|
|
1770
|
-
*
|
|
1771
|
-
*
|
|
1772
|
-
*
|
|
1773
|
-
*
|
|
402
|
+
* import { MemoryTransport } from '@gravito/signal'
|
|
403
|
+
*
|
|
404
|
+
* const transport = new MemoryTransport()
|
|
405
|
+
* const mail = new OrbitSignal({
|
|
406
|
+
* transport,
|
|
407
|
+
* from: { address: 'test@example.com' }
|
|
408
|
+
* })
|
|
409
|
+
*
|
|
410
|
+
* await mail.send(email)
|
|
411
|
+
* assert.equal(transport.sentMessages.length, 1)
|
|
1774
412
|
* ```
|
|
1775
413
|
*
|
|
414
|
+
* @see {@link LogTransport} For development logging
|
|
1776
415
|
* @public
|
|
1777
416
|
*/
|
|
1778
|
-
|
|
1779
|
-
/**
|
|
1780
|
-
* Outputs the message details to the system console.
|
|
1781
|
-
*
|
|
1782
|
-
* Formats the email metadata (From, To, Subject) and content size into a readable
|
|
1783
|
-
* block in the console output.
|
|
1784
|
-
*
|
|
1785
|
-
* @param message - The message to log.
|
|
1786
|
-
* @returns A promise that resolves immediately after logging.
|
|
1787
|
-
*
|
|
1788
|
-
* @example
|
|
1789
|
-
* ```typescript
|
|
1790
|
-
* const transport = new LogTransport();
|
|
1791
|
-
* await transport.send(message);
|
|
1792
|
-
* // Console: 📧 [OrbitSignal] Email Sent (Simulated)...
|
|
1793
|
-
* ```
|
|
1794
|
-
*/
|
|
1795
|
-
send(message: Message): Promise<void>;
|
|
1796
|
-
}
|
|
1797
|
-
|
|
417
|
+
export { MemoryTransport } from './transports/MemoryTransport';
|
|
1798
418
|
/**
|
|
1799
|
-
*
|
|
419
|
+
* AWS SES email transport with automatic retry and rate limit handling.
|
|
1800
420
|
*
|
|
1801
|
-
*
|
|
1802
|
-
*
|
|
1803
|
-
*
|
|
421
|
+
* Delivers emails via Amazon Simple Email Service with built-in support
|
|
422
|
+
* for authentication, rate limiting awareness, and automatic retry with
|
|
423
|
+
* exponential backoff suitable for production AWS environments.
|
|
1804
424
|
*
|
|
1805
425
|
* @example
|
|
1806
426
|
* ```typescript
|
|
1807
|
-
* import {
|
|
1808
|
-
*
|
|
1809
|
-
* const mailbox = new DevMailbox();
|
|
1810
|
-
* const transport = new MemoryTransport(mailbox);
|
|
1811
|
-
* await transport.send(message);
|
|
427
|
+
* import { SesTransport } from '@gravito/signal'
|
|
1812
428
|
*
|
|
1813
|
-
*
|
|
429
|
+
* const mail = new OrbitSignal({
|
|
430
|
+
* transport: new SesTransport({
|
|
431
|
+
* region: 'us-east-1',
|
|
432
|
+
* retries: 3,
|
|
433
|
+
* retryDelay: 1000,
|
|
434
|
+
* retryMultiplier: 2
|
|
435
|
+
* }),
|
|
436
|
+
* from: { address: 'verified@example.com' }
|
|
437
|
+
* })
|
|
1814
438
|
* ```
|
|
1815
439
|
*
|
|
440
|
+
* @see {@link SmtpTransport} For SMTP alternative
|
|
441
|
+
* @see {@link SesWebhookDriver} For bounce/complaint handling
|
|
1816
442
|
* @public
|
|
1817
443
|
*/
|
|
1818
|
-
|
|
1819
|
-
private mailbox;
|
|
1820
|
-
/**
|
|
1821
|
-
* Creates a new MemoryTransport instance.
|
|
1822
|
-
*
|
|
1823
|
-
* @param mailbox - The in-memory storage where messages will be collected.
|
|
1824
|
-
*/
|
|
1825
|
-
constructor(mailbox: DevMailbox);
|
|
1826
|
-
/**
|
|
1827
|
-
* Stores the message in the associated mailbox.
|
|
1828
|
-
*
|
|
1829
|
-
* The message is added to the internal list of the `DevMailbox` instance,
|
|
1830
|
-
* making it available for retrieval by the Dev UI or test assertions.
|
|
1831
|
-
*
|
|
1832
|
-
* @param message - The message to store.
|
|
1833
|
-
* @returns A promise that resolves once the message is added to the mailbox.
|
|
1834
|
-
*
|
|
1835
|
-
* @example
|
|
1836
|
-
* ```typescript
|
|
1837
|
-
* await transport.send({
|
|
1838
|
-
* from: { address: 'dev@localhost' },
|
|
1839
|
-
* to: [{ address: 'test@example.com' }],
|
|
1840
|
-
* subject: 'Memory Test',
|
|
1841
|
-
* html: '<p>Stored in memory</p>'
|
|
1842
|
-
* });
|
|
1843
|
-
* ```
|
|
1844
|
-
*/
|
|
1845
|
-
send(message: Message): Promise<void>;
|
|
1846
|
-
}
|
|
1847
|
-
|
|
444
|
+
export { SesTransport } from './transports/SesTransport';
|
|
1848
445
|
/**
|
|
1849
|
-
*
|
|
446
|
+
* SMTP email transport with connection pooling and automatic retry.
|
|
1850
447
|
*
|
|
1851
|
-
*
|
|
1852
|
-
*
|
|
448
|
+
* Delivers emails via standard SMTP protocol with support for TLS/SSL,
|
|
449
|
+
* connection pooling, and automatic retry with exponential backoff.
|
|
450
|
+
* Compatible with any SMTP server (Gmail, Mailtrap, AWS SES SMTP, etc.).
|
|
1853
451
|
*
|
|
1854
452
|
* @example
|
|
1855
453
|
* ```typescript
|
|
1856
|
-
*
|
|
1857
|
-
*
|
|
1858
|
-
*
|
|
1859
|
-
*
|
|
1860
|
-
*
|
|
1861
|
-
*
|
|
454
|
+
* import { SmtpTransport } from '@gravito/signal'
|
|
455
|
+
*
|
|
456
|
+
* const mail = new OrbitSignal({
|
|
457
|
+
* transport: new SmtpTransport({
|
|
458
|
+
* host: 'smtp.mailtrap.io',
|
|
459
|
+
* port: 2525,
|
|
460
|
+
* auth: { user: 'username', pass: 'password' },
|
|
461
|
+
* poolSize: 10
|
|
462
|
+
* }),
|
|
463
|
+
* from: { address: 'noreply@example.com' }
|
|
464
|
+
* })
|
|
1862
465
|
* ```
|
|
1863
466
|
*
|
|
467
|
+
* @see {@link SesTransport} For AWS SES integration
|
|
468
|
+
* @see {@link BaseTransport} For base retry logic
|
|
1864
469
|
* @public
|
|
1865
470
|
*/
|
|
1866
|
-
|
|
1867
|
-
/** AWS region where the SES service is hosted (e.g., 'us-east-1'). */
|
|
1868
|
-
region: string;
|
|
1869
|
-
/** AWS access key ID. If omitted, the SDK will attempt to use default credential providers. */
|
|
1870
|
-
accessKeyId?: string;
|
|
1871
|
-
/** AWS secret access key. Required if accessKeyId is provided. */
|
|
1872
|
-
secretAccessKey?: string;
|
|
1873
|
-
}
|
|
471
|
+
export { SmtpTransport } from './transports/SmtpTransport';
|
|
1874
472
|
/**
|
|
1875
|
-
*
|
|
473
|
+
* Transport interface and implementations for email delivery.
|
|
1876
474
|
*
|
|
1877
|
-
*
|
|
1878
|
-
*
|
|
1879
|
-
*
|
|
1880
|
-
* includes automatic retry logic for transient API errors.
|
|
1881
|
-
*
|
|
1882
|
-
* @example
|
|
1883
|
-
* ```typescript
|
|
1884
|
-
* import { SesTransport } from '@gravito/signal';
|
|
1885
|
-
*
|
|
1886
|
-
* const transport = new SesTransport({
|
|
1887
|
-
* region: 'us-west-2'
|
|
1888
|
-
* });
|
|
1889
|
-
*
|
|
1890
|
-
* await transport.send(message);
|
|
1891
|
-
* ```
|
|
475
|
+
* Defines the contract for email delivery mechanisms and provides built-in
|
|
476
|
+
* transports: SmtpTransport (standard email servers), SesTransport (AWS SES),
|
|
477
|
+
* LogTransport (console output), and MemoryTransport (testing).
|
|
1892
478
|
*
|
|
479
|
+
* @see {@link SmtpTransport} For SMTP server integration
|
|
480
|
+
* @see {@link SesTransport} For AWS SES integration
|
|
481
|
+
* @see {@link LogTransport} For development logging
|
|
482
|
+
* @see {@link MemoryTransport} For testing
|
|
1893
483
|
* @public
|
|
1894
484
|
*/
|
|
1895
|
-
|
|
1896
|
-
private transporter;
|
|
1897
|
-
/**
|
|
1898
|
-
* Initializes the SES transport with the provided configuration.
|
|
1899
|
-
*
|
|
1900
|
-
* Configures the AWS SES client and wraps it in a nodemailer transporter
|
|
1901
|
-
* for consistent message handling.
|
|
1902
|
-
*
|
|
1903
|
-
* @param config - AWS SES connection and retry configuration.
|
|
1904
|
-
*/
|
|
1905
|
-
constructor(config: SesConfig);
|
|
1906
|
-
/**
|
|
1907
|
-
* Internal method to perform the actual SES delivery.
|
|
1908
|
-
*
|
|
1909
|
-
* Converts the generic `Message` object into a raw email format and sends it
|
|
1910
|
-
* via the SES `SendRawEmail` API.
|
|
1911
|
-
*
|
|
1912
|
-
* @param message - The message to deliver.
|
|
1913
|
-
* @returns A promise that resolves when SES accepts the message for delivery.
|
|
1914
|
-
* @throws {Error} If the SES API returns an error or connection fails.
|
|
1915
|
-
*/
|
|
1916
|
-
protected doSend(message: Message): Promise<void>;
|
|
1917
|
-
/**
|
|
1918
|
-
* Formats an Address object into a standard RFC 822 string.
|
|
1919
|
-
*
|
|
1920
|
-
* @param addr - The address object to format.
|
|
1921
|
-
* @returns A string in the format "Name <email@example.com>" or just "email@example.com".
|
|
1922
|
-
*/
|
|
1923
|
-
private formatAddress;
|
|
1924
|
-
}
|
|
1925
|
-
|
|
485
|
+
export type { Transport } from './transports/Transport';
|
|
1926
486
|
/**
|
|
1927
|
-
*
|
|
487
|
+
* Email message types and configuration interfaces.
|
|
1928
488
|
*
|
|
1929
|
-
*
|
|
1930
|
-
*
|
|
489
|
+
* Provides TypeScript interfaces for:
|
|
490
|
+
* - Address: Email address with optional display name
|
|
491
|
+
* - Attachment: File attachment configuration
|
|
492
|
+
* - Envelope: Complete email envelope (from, to, cc, bcc, etc.)
|
|
493
|
+
* - MailConfig: OrbitSignal configuration options
|
|
494
|
+
* - Message: Finalized message ready for transport
|
|
1931
495
|
*
|
|
1932
496
|
* @example
|
|
1933
497
|
* ```typescript
|
|
1934
|
-
*
|
|
1935
|
-
*
|
|
1936
|
-
*
|
|
1937
|
-
*
|
|
1938
|
-
*
|
|
1939
|
-
* }
|
|
498
|
+
* import type { Address, Attachment, Message, MailConfig } from '@gravito/signal'
|
|
499
|
+
*
|
|
500
|
+
* const config: MailConfig = {
|
|
501
|
+
* transport: new SmtpTransport({ ... }),
|
|
502
|
+
* from: { name: 'App', address: 'noreply@app.com' }
|
|
503
|
+
* }
|
|
1940
504
|
* ```
|
|
1941
505
|
*
|
|
1942
506
|
* @public
|
|
1943
507
|
*/
|
|
1944
|
-
|
|
1945
|
-
/** SMTP server hostname or IP address. */
|
|
1946
|
-
host: string;
|
|
1947
|
-
/** SMTP server port (typically 25, 465, or 587). */
|
|
1948
|
-
port: number;
|
|
1949
|
-
/** Whether to use a secure TLS/SSL connection. Should be true for port 465. */
|
|
1950
|
-
secure?: boolean;
|
|
1951
|
-
/** Authentication credentials for the SMTP server. */
|
|
1952
|
-
auth?: {
|
|
1953
|
-
/** SMTP username. */
|
|
1954
|
-
user: string;
|
|
1955
|
-
/** SMTP password. */
|
|
1956
|
-
pass: string;
|
|
1957
|
-
};
|
|
1958
|
-
/** TLS specific options for the connection. */
|
|
1959
|
-
tls?: {
|
|
1960
|
-
/** Whether to reject unauthorized certificates (useful for self-signed certs). */
|
|
1961
|
-
rejectUnauthorized?: boolean;
|
|
1962
|
-
/** Specific cipher suite to use for the connection. */
|
|
1963
|
-
ciphers?: string;
|
|
1964
|
-
};
|
|
1965
|
-
/** Number of concurrent connections to maintain in the pool. */
|
|
1966
|
-
poolSize?: number;
|
|
1967
|
-
/** Maximum time in milliseconds a connection can remain idle before being closed. */
|
|
1968
|
-
maxIdleTime?: number;
|
|
1969
|
-
}
|
|
508
|
+
export type { Address, Attachment, Envelope, MailConfig, Message, } from './types';
|
|
1970
509
|
/**
|
|
1971
|
-
*
|
|
510
|
+
* SendGrid webhook driver for handling bounce and complaint events.
|
|
1972
511
|
*
|
|
1973
|
-
*
|
|
1974
|
-
*
|
|
1975
|
-
* for connection pooling to improve performance when sending multiple emails.
|
|
1976
|
-
* It inherits automatic retry logic from `BaseTransport`.
|
|
512
|
+
* Processes webhook notifications from SendGrid (bounces, complaints, etc.)
|
|
513
|
+
* and converts them into standardized mail events for logging and analytics.
|
|
1977
514
|
*
|
|
1978
515
|
* @example
|
|
1979
516
|
* ```typescript
|
|
1980
|
-
* import {
|
|
1981
|
-
*
|
|
1982
|
-
* const transport = new SmtpTransport({
|
|
1983
|
-
* host: 'smtp.example.com',
|
|
1984
|
-
* port: 587,
|
|
1985
|
-
* auth: { user: 'user', pass: 'pass' }
|
|
1986
|
-
* });
|
|
517
|
+
* import { SendGridWebhookDriver } from '@gravito/signal'
|
|
1987
518
|
*
|
|
1988
|
-
*
|
|
519
|
+
* const driver = new SendGridWebhookDriver()
|
|
520
|
+
* mail.registerWebhookDriver('sendgrid', driver)
|
|
1989
521
|
* ```
|
|
1990
522
|
*
|
|
523
|
+
* @see {@link SesWebhookDriver} For AWS SES webhooks
|
|
1991
524
|
* @public
|
|
1992
525
|
*/
|
|
1993
|
-
|
|
1994
|
-
private transporter;
|
|
1995
|
-
/**
|
|
1996
|
-
* Initializes the SMTP transport with the provided configuration.
|
|
1997
|
-
*
|
|
1998
|
-
* Sets up the underlying nodemailer transporter with connection pooling enabled.
|
|
1999
|
-
*
|
|
2000
|
-
* @param config - SMTP connection and retry configuration.
|
|
2001
|
-
*/
|
|
2002
|
-
constructor(config: SmtpConfig);
|
|
2003
|
-
/**
|
|
2004
|
-
* Internal method to perform the actual SMTP delivery.
|
|
2005
|
-
*
|
|
2006
|
-
* Maps the generic `Message` object to the format expected by nodemailer.
|
|
2007
|
-
*
|
|
2008
|
-
* @param message - The message to deliver.
|
|
2009
|
-
* @returns A promise that resolves when the SMTP server accepts the message.
|
|
2010
|
-
* @throws {Error} If the SMTP server rejects the message or connection fails.
|
|
2011
|
-
*/
|
|
2012
|
-
protected doSend(message: Message): Promise<void>;
|
|
2013
|
-
/**
|
|
2014
|
-
* Gracefully shuts down the transport and closes all pooled connections.
|
|
2015
|
-
*
|
|
2016
|
-
* This should be called during application shutdown to ensure no resources are leaked.
|
|
2017
|
-
*
|
|
2018
|
-
* @returns A promise that resolves when all connections are closed.
|
|
2019
|
-
*
|
|
2020
|
-
* @example
|
|
2021
|
-
* ```typescript
|
|
2022
|
-
* await transport.close();
|
|
2023
|
-
* ```
|
|
2024
|
-
*/
|
|
2025
|
-
close(): Promise<void>;
|
|
2026
|
-
/**
|
|
2027
|
-
* Verifies the SMTP connection and authentication.
|
|
2028
|
-
*
|
|
2029
|
-
* Useful for health checks or validating configuration during startup.
|
|
2030
|
-
*
|
|
2031
|
-
* @returns A promise that resolves to true if the connection is valid, false otherwise.
|
|
2032
|
-
*
|
|
2033
|
-
* @example
|
|
2034
|
-
* ```typescript
|
|
2035
|
-
* const isValid = await transport.verify();
|
|
2036
|
-
* if (!isValid) throw new Error('SMTP configuration is invalid');
|
|
2037
|
-
* ```
|
|
2038
|
-
*/
|
|
2039
|
-
verify(): Promise<boolean>;
|
|
2040
|
-
/**
|
|
2041
|
-
* Formats an Address object into a standard RFC 822 string.
|
|
2042
|
-
*
|
|
2043
|
-
* @param addr - The address object to format.
|
|
2044
|
-
* @returns A string in the format "Name <email@example.com>" or just "email@example.com".
|
|
2045
|
-
*/
|
|
2046
|
-
private formatAddress;
|
|
2047
|
-
}
|
|
2048
|
-
|
|
526
|
+
export { type SendGridWebhookConfig, SendGridWebhookDriver } from './webhooks/SendGridWebhookDriver';
|
|
2049
527
|
/**
|
|
2050
|
-
*
|
|
2051
|
-
*/
|
|
2052
|
-
interface SendGridWebhookConfig {
|
|
2053
|
-
/**
|
|
2054
|
-
* Public key or Verification Secret for signature validation.
|
|
2055
|
-
* If provided, all requests will be validated.
|
|
2056
|
-
*/
|
|
2057
|
-
publicKey?: string;
|
|
2058
|
-
}
|
|
2059
|
-
/**
|
|
2060
|
-
* SendGrid Webhook Driver.
|
|
528
|
+
* AWS SES webhook driver for handling bounce and complaint events.
|
|
2061
529
|
*
|
|
2062
|
-
*
|
|
530
|
+
* Processes SNS notifications from AWS SES (bounces, complaints, etc.)
|
|
531
|
+
* and converts them into standardized mail events for logging and analytics.
|
|
2063
532
|
*
|
|
2064
|
-
* @
|
|
2065
|
-
*
|
|
2066
|
-
* @
|
|
2067
|
-
*/
|
|
2068
|
-
declare class SendGridWebhookDriver implements WebhookDriver {
|
|
2069
|
-
private config;
|
|
2070
|
-
constructor(config?: SendGridWebhookConfig);
|
|
2071
|
-
/**
|
|
2072
|
-
* Handles the SendGrid webhook request.
|
|
2073
|
-
*/
|
|
2074
|
-
handle(c: GravitoContext): Promise<{
|
|
2075
|
-
event: string;
|
|
2076
|
-
payload: any;
|
|
2077
|
-
}[] | null>;
|
|
2078
|
-
/**
|
|
2079
|
-
* Verifies the SendGrid webhook signature.
|
|
2080
|
-
*
|
|
2081
|
-
* @param payload - Raw request body string.
|
|
2082
|
-
* @param signature - Signature from X-Twilio-Email-Event-Webhook-Signature header.
|
|
2083
|
-
* @param timestamp - Timestamp from X-Twilio-Email-Event-Webhook-Timestamp header.
|
|
2084
|
-
* @returns True if signature is valid.
|
|
2085
|
-
*
|
|
2086
|
-
* @remarks
|
|
2087
|
-
* Real SendGrid validation uses Elliptic Curve (ECDSA).
|
|
2088
|
-
* This is a placeholder for the logic structure.
|
|
2089
|
-
*/
|
|
2090
|
-
private verifySignature;
|
|
2091
|
-
}
|
|
2092
|
-
|
|
2093
|
-
/**
|
|
2094
|
-
* AWS SES Webhook Driver.
|
|
533
|
+
* @example
|
|
534
|
+
* ```typescript
|
|
535
|
+
* import { SesWebhookDriver } from '@gravito/signal'
|
|
2095
536
|
*
|
|
2096
|
-
*
|
|
537
|
+
* const driver = new SesWebhookDriver()
|
|
538
|
+
* mail.registerWebhookDriver('ses', driver)
|
|
539
|
+
* ```
|
|
2097
540
|
*
|
|
2098
|
-
* @see
|
|
541
|
+
* @see {@link SendGridWebhookDriver} For SendGrid webhooks
|
|
2099
542
|
* @public
|
|
2100
|
-
* @since 1.1.0
|
|
2101
543
|
*/
|
|
2102
|
-
|
|
2103
|
-
/**
|
|
2104
|
-
* Handles the AWS SES/SNS webhook request.
|
|
2105
|
-
*
|
|
2106
|
-
* @param c - The Gravito request context.
|
|
2107
|
-
* @returns Array of processed events or null if ignored.
|
|
2108
|
-
*/
|
|
2109
|
-
handle(c: GravitoContext): Promise<{
|
|
2110
|
-
event: string;
|
|
2111
|
-
payload: any;
|
|
2112
|
-
}[] | null>;
|
|
2113
|
-
}
|
|
2114
|
-
|
|
2115
|
-
export { type Address, type Attachment, BaseTransport, DevMailbox, type Envelope, HtmlRenderer, LogTransport, type MailConfig, MailErrorCode, type MailEvent, type MailEventHandler, type MailEventType, MailTransportError, Mailable, type MailboxEntry, MemoryTransport, type Message, MjmlRenderer, OrbitSignal, ReactMjmlRenderer, type RenderResult, type Renderer, type SendGridWebhookConfig, SendGridWebhookDriver, SesTransport, SesWebhookDriver, SmtpTransport, TemplateRenderer, type Transport, type TransportOptions, TypedMailable, VueMjmlRenderer, baseLayout, transactionLayout };
|
|
544
|
+
export { SesWebhookDriver } from './webhooks/SesWebhookDriver';
|