@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.
Files changed (124) hide show
  1. package/README.md +26 -15
  2. package/dist/Mailable.d.ts +453 -0
  3. package/dist/OrbitSignal.d.ts +267 -0
  4. package/{src/Queueable.ts → dist/Queueable.d.ts} +1 -1
  5. package/{src/TypedMailable.ts → dist/TypedMailable.d.ts} +12 -13
  6. package/dist/dev/DevMailbox.d.ts +79 -0
  7. package/dist/dev/DevServer.d.ts +39 -0
  8. package/dist/dev/storage/FileMailboxStorage.d.ts +16 -0
  9. package/dist/dev/storage/MailboxStorage.d.ts +14 -0
  10. package/dist/dev/storage/MemoryMailboxStorage.d.ts +13 -0
  11. package/dist/dev/ui/mailbox.d.ts +11 -0
  12. package/dist/dev/ui/preview.d.ts +11 -0
  13. package/dist/dev/ui/shared.d.ts +15 -0
  14. package/dist/errors.d.ts +58 -0
  15. package/{src/events.ts → dist/events.d.ts} +20 -29
  16. package/dist/{lib-HJTRWKU5.mjs → index.cjs} +4687 -10983
  17. package/dist/index.d.ts +303 -1874
  18. package/dist/index.js +317 -45939
  19. package/dist/index.mjs +59748 -27
  20. package/dist/renderers/HtmlRenderer.d.ts +34 -0
  21. package/dist/renderers/MjmlRenderer.d.ts +41 -0
  22. package/dist/renderers/ReactMjmlRenderer.d.ts +38 -0
  23. package/dist/renderers/ReactRenderer.d.ts +46 -0
  24. package/{src/renderers/Renderer.ts → dist/renderers/Renderer.d.ts} +23 -24
  25. package/dist/renderers/TemplateRenderer.d.ts +55 -0
  26. package/dist/renderers/VueMjmlRenderer.d.ts +39 -0
  27. package/dist/renderers/VueRenderer.d.ts +47 -0
  28. package/dist/renderers/mjml-templates.d.ts +11 -0
  29. package/dist/transports/BaseTransport.d.ts +111 -0
  30. package/dist/transports/LogTransport.d.ts +42 -0
  31. package/dist/transports/MemoryTransport.d.ts +51 -0
  32. package/dist/transports/SesTransport.d.ts +79 -0
  33. package/dist/transports/SmtpTransport.d.ts +124 -0
  34. package/dist/transports/Transport.d.ts +44 -0
  35. package/dist/types.d.ts +294 -0
  36. package/{src/utils/html.ts → dist/utils/html.d.ts} +1 -15
  37. package/dist/webhooks/SendGridWebhookDriver.d.ts +45 -0
  38. package/dist/webhooks/SesWebhookDriver.d.ts +23 -0
  39. package/package.json +20 -8
  40. package/CHANGELOG.md +0 -74
  41. package/dist/MjmlRenderer-IUH663FT.mjs +0 -8
  42. package/dist/ReactMjmlRenderer-C3P5YO5L.mjs +0 -8
  43. package/dist/ReactRenderer-24SQ4KRU.mjs +0 -27
  44. package/dist/ReactRenderer-2JFLRVST.mjs +0 -45
  45. package/dist/ReactRenderer-CMCAOEPH.mjs +0 -28
  46. package/dist/ReactRenderer-KYNA4WKE.mjs +0 -28
  47. package/dist/ReactRenderer-LYEOSYFS.mjs +0 -28
  48. package/dist/ReactRenderer-V54CUUEI.mjs +0 -45
  49. package/dist/VueMjmlRenderer-4F4CXHDB.mjs +0 -8
  50. package/dist/VueMjmlRenderer-5WZR4CQG.mjs +0 -8
  51. package/dist/VueMjmlRenderer-U5YMWI44.mjs +0 -8
  52. package/dist/VueRenderer-3YBRQXME.mjs +0 -48
  53. package/dist/VueRenderer-46JGXTJ2.mjs +0 -48
  54. package/dist/VueRenderer-5KWD4R3C.mjs +0 -48
  55. package/dist/VueRenderer-C23U4O5E.mjs +0 -48
  56. package/dist/VueRenderer-DWTCD2RF.mjs +0 -31
  57. package/dist/VueRenderer-IIR5SYTM.mjs +0 -31
  58. package/dist/VueRenderer-LEVDFLHP.mjs +0 -31
  59. package/dist/VueRenderer-RNHSCCRI.mjs +0 -48
  60. package/dist/VueRenderer-SUP66ISX.mjs +0 -29
  61. package/dist/chunk-3WOR3XSL.mjs +0 -82
  62. package/dist/chunk-DBFIVHHG.mjs +0 -79
  63. package/dist/chunk-EBO3CZXG.mjs +0 -15
  64. package/dist/chunk-HEBXNMVQ.mjs +0 -48
  65. package/dist/chunk-KB7IDDBT.mjs +0 -82
  66. package/dist/chunk-LZL5UUPC.mjs +0 -82
  67. package/dist/chunk-W6LXIJKK.mjs +0 -57
  68. package/dist/chunk-XBIVBJS2.mjs +0 -8
  69. package/dist/index.d.mts +0 -2115
  70. package/dist/server-renderer-4IM3P5XZ.mjs +0 -37183
  71. package/dist/server-renderer-4W4FI7YG.mjs +0 -37269
  72. package/dist/server-renderer-7KWFSTPV.mjs +0 -37193
  73. package/dist/server-renderer-S5FPSTJ2.mjs +0 -37183
  74. package/dist/server-renderer-X5LUFVWT.mjs +0 -37193
  75. package/doc/OPTIMIZATION_PLAN.md +0 -496
  76. package/scripts/check-coverage.ts +0 -64
  77. package/src/Mailable.ts +0 -674
  78. package/src/OrbitSignal.ts +0 -451
  79. package/src/dev/DevMailbox.ts +0 -146
  80. package/src/dev/DevServer.ts +0 -192
  81. package/src/dev/storage/FileMailboxStorage.ts +0 -66
  82. package/src/dev/storage/MailboxStorage.ts +0 -15
  83. package/src/dev/storage/MemoryMailboxStorage.ts +0 -36
  84. package/src/dev/ui/mailbox.ts +0 -77
  85. package/src/dev/ui/preview.ts +0 -103
  86. package/src/dev/ui/shared.ts +0 -60
  87. package/src/errors.ts +0 -69
  88. package/src/index.ts +0 -41
  89. package/src/renderers/HtmlRenderer.ts +0 -41
  90. package/src/renderers/MjmlRenderer.ts +0 -73
  91. package/src/renderers/ReactMjmlRenderer.ts +0 -94
  92. package/src/renderers/ReactRenderer.ts +0 -66
  93. package/src/renderers/TemplateRenderer.ts +0 -84
  94. package/src/renderers/VueMjmlRenderer.ts +0 -99
  95. package/src/renderers/VueRenderer.ts +0 -71
  96. package/src/renderers/mjml-templates.ts +0 -50
  97. package/src/transports/BaseTransport.ts +0 -148
  98. package/src/transports/LogTransport.ts +0 -55
  99. package/src/transports/MemoryTransport.ts +0 -55
  100. package/src/transports/SesTransport.ts +0 -129
  101. package/src/transports/SmtpTransport.ts +0 -184
  102. package/src/transports/Transport.ts +0 -45
  103. package/src/types.ts +0 -309
  104. package/src/webhooks/SendGridWebhookDriver.ts +0 -80
  105. package/src/webhooks/SesWebhookDriver.ts +0 -44
  106. package/tests/DevMailbox.test.ts +0 -54
  107. package/tests/FileMailboxStorage.test.ts +0 -56
  108. package/tests/MjmlLayout.test.ts +0 -28
  109. package/tests/MjmlRenderer.test.ts +0 -53
  110. package/tests/OrbitSignalWebhook.test.ts +0 -56
  111. package/tests/ReactMjmlRenderer.test.ts +0 -33
  112. package/tests/SendGridWebhookDriver.test.ts +0 -69
  113. package/tests/SesWebhookDriver.test.ts +0 -46
  114. package/tests/VueMjmlRenderer.test.ts +0 -35
  115. package/tests/dev-server.test.ts +0 -66
  116. package/tests/log-transport.test.ts +0 -21
  117. package/tests/mailable-extra.test.ts +0 -68
  118. package/tests/mailable.test.ts +0 -77
  119. package/tests/orbit-signal.test.ts +0 -43
  120. package/tests/renderers.test.ts +0 -58
  121. package/tests/template-renderer.test.ts +0 -24
  122. package/tests/transports.test.ts +0 -52
  123. package/tests/ui.test.ts +0 -37
  124. package/tsconfig.json +0 -14
@@ -0,0 +1,267 @@
1
+ import type { GravitoOrbit, PlanetCore } from '@gravito/core';
2
+ import type { MailEventHandler, MailEventType } from './events';
3
+ import type { Mailable } from './Mailable';
4
+ import type { MailConfig } from './types';
5
+ /**
6
+ * OrbitSignal - Mail service orbit for Gravito framework.
7
+ *
8
+ * @description
9
+ * A production-ready email service providing multi-transport support, automatic retry,
10
+ * event-driven lifecycle hooks, and development tooling. Integrates seamlessly with
11
+ * Gravito's orbit system and queue infrastructure.
12
+ *
13
+ * @architecture
14
+ * ```
15
+ * OrbitSignal
16
+ * ├── Configuration (MailConfig)
17
+ * │ ├── transport: Transport (SMTP, SES, Log, Memory)
18
+ * │ ├── from: Default sender
19
+ * │ ├── devMode: Development interception
20
+ * │ └── translator: i18n support
21
+ * ├── Lifecycle Events
22
+ * │ ├── beforeRender → afterRender
23
+ * │ ├── beforeSend → afterSend
24
+ * │ └── sendFailed (on error)
25
+ * ├── Transport Layer
26
+ * │ ├── BaseTransport (retry, backoff)
27
+ * │ ├── SmtpTransport (connection pooling)
28
+ * │ ├── SesTransport (AWS SES)
29
+ * │ ├── LogTransport (console output)
30
+ * │ └── MemoryTransport (dev mode)
31
+ * └── Dev Tools
32
+ * ├── DevMailbox (in-memory storage)
33
+ * └── DevServer (preview UI at /__mail)
34
+ * ```
35
+ *
36
+ * @example
37
+ * **Basic SMTP Configuration**
38
+ * ```typescript
39
+ * import { OrbitSignal, SmtpTransport } from '@gravito/signal'
40
+ *
41
+ * const mail = new OrbitSignal({
42
+ * transport: new SmtpTransport({
43
+ * host: 'smtp.mailtrap.io',
44
+ * port: 2525,
45
+ * auth: { user: 'username', pass: 'password' }
46
+ * }),
47
+ * from: { name: 'My App', address: 'noreply@myapp.com' }
48
+ * })
49
+ *
50
+ * mail.install(core)
51
+ * ```
52
+ *
53
+ * @example
54
+ * **AWS SES with Retry Configuration**
55
+ * ```typescript
56
+ * import { OrbitSignal, SesTransport } from '@gravito/signal'
57
+ *
58
+ * const mail = new OrbitSignal({
59
+ * transport: new SesTransport({
60
+ * region: 'us-east-1',
61
+ * retries: 3,
62
+ * retryDelay: 1000,
63
+ * retryMultiplier: 2
64
+ * }),
65
+ * from: { name: 'Production App', address: 'noreply@example.com' }
66
+ * })
67
+ * ```
68
+ *
69
+ * @example
70
+ * **Development Mode with Preview UI**
71
+ * ```typescript
72
+ * const mail = new OrbitSignal({
73
+ * devMode: process.env.NODE_ENV === 'development',
74
+ * devUiPrefix: '/__mail',
75
+ * from: { name: 'Dev App', address: 'dev@localhost' }
76
+ * })
77
+ *
78
+ * // All emails intercepted to memory, view at http://localhost:3000/__mail
79
+ * ```
80
+ *
81
+ * @example
82
+ * **Event-Driven Analytics & Error Handling**
83
+ * ```typescript
84
+ * const mail = new OrbitSignal({ ... })
85
+ *
86
+ * // Track successful sends
87
+ * mail.on('afterSend', async (event) => {
88
+ * await analytics.track('email_sent', {
89
+ * to: event.message?.to,
90
+ * subject: event.message?.subject,
91
+ * timestamp: event.timestamp
92
+ * })
93
+ * })
94
+ *
95
+ * // Log failures for monitoring
96
+ * mail.on('sendFailed', async (event) => {
97
+ * logger.error('Email send failed', {
98
+ * error: event.error?.message,
99
+ * mailable: event.mailable.constructor.name
100
+ * })
101
+ * await sentry.captureException(event.error)
102
+ * })
103
+ * ```
104
+ *
105
+ * @example
106
+ * **SMTP with Connection Pooling**
107
+ * ```typescript
108
+ * const mail = new OrbitSignal({
109
+ * transport: new SmtpTransport({
110
+ * host: 'smtp.gmail.com',
111
+ * port: 465,
112
+ * secure: true,
113
+ * auth: { user: 'user@gmail.com', pass: 'app-password' },
114
+ * poolSize: 5,
115
+ * maxIdleTime: 30000
116
+ * })
117
+ * })
118
+ *
119
+ * // Graceful shutdown
120
+ * process.on('SIGTERM', async () => {
121
+ * await mail.config.transport?.close?.()
122
+ * })
123
+ * ```
124
+ *
125
+ * @example
126
+ * **Usage in Route Handlers**
127
+ * ```typescript
128
+ * // Injected automatically into GravitoContext
129
+ * app.post('/register', async (c) => {
130
+ * const user = await createUser(c.req.json())
131
+ *
132
+ * await c.get('mail').send(new WelcomeEmail(user))
133
+ *
134
+ * return c.json({ success: true })
135
+ * })
136
+ * ```
137
+ *
138
+ * @example
139
+ * **Queue Integration for Background Processing**
140
+ * ```typescript
141
+ * // Requires @gravito/stream
142
+ * const email = new WelcomeEmail(user)
143
+ * .onQueue('emails')
144
+ * .delay(60)
145
+ *
146
+ * await email.queue()
147
+ * ```
148
+ *
149
+ * @example
150
+ * **Error Handling Best Practices**
151
+ * ```typescript
152
+ * try {
153
+ * await mail.send(new InvoiceEmail(order))
154
+ * } catch (error) {
155
+ * if (error instanceof MailTransportError) {
156
+ * switch (error.code) {
157
+ * case MailErrorCode.RATE_LIMIT:
158
+ * await queue.pushDelayed(email, 300)
159
+ * break
160
+ * case MailErrorCode.RECIPIENT_REJECTED:
161
+ * await markUserEmailInvalid(user.id)
162
+ * break
163
+ * default:
164
+ * throw error
165
+ * }
166
+ * }
167
+ * }
168
+ * ```
169
+ *
170
+ * @see {@link Mailable} Base class for email definitions
171
+ * @see {@link TypedMailable} Strongly-typed mailable with generic data
172
+ * @see {@link Transport} Transport interface
173
+ * @see {@link BaseTransport} Retry-enabled base transport
174
+ * @see {@link MailConfig} Configuration interface
175
+ * @see {@link MailEvent} Event types
176
+ * @see {@link MailTransportError} Error handling
177
+ *
178
+ * @since 3.0.0
179
+ * @public
180
+ */
181
+ export declare class OrbitSignal implements GravitoOrbit {
182
+ private config;
183
+ private devMailbox?;
184
+ private core?;
185
+ private eventHandlers;
186
+ constructor(config?: MailConfig);
187
+ /**
188
+ * Install the orbit into PlanetCore.
189
+ *
190
+ * Registers the mail service in the IoC container and sets up development
191
+ * tools if enabled. It also injects the service into the GravitoContext
192
+ * for easy access in route handlers.
193
+ *
194
+ * @param core - The PlanetCore instance to install into
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * const mail = new OrbitSignal(config);
199
+ * mail.install(core);
200
+ * ```
201
+ */
202
+ install(core: PlanetCore): void;
203
+ /**
204
+ * Internal: Handle processed webhook.
205
+ */
206
+ private handleWebhook;
207
+ /**
208
+ * Send a mailable instance immediately.
209
+ *
210
+ * Orchestrates the full email sending lifecycle: building the envelope,
211
+ * rendering content, emitting events, and delivering via the configured transport.
212
+ *
213
+ * @param mailable - The email definition to send
214
+ * @throws {Error} If mandatory fields (from, to) are missing or transport fails
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * await mail.send(new WelcomeEmail(user));
219
+ * ```
220
+ */
221
+ send(mailable: Mailable): Promise<void>;
222
+ /**
223
+ * Queue a mailable instance for background processing.
224
+ *
225
+ * Attempts to use the 'queue' service (OrbitStream) if available in the
226
+ * container. Falls back to immediate sending if no queue service is found.
227
+ *
228
+ * @param mailable - The email definition to queue
229
+ *
230
+ * @example
231
+ * ```typescript
232
+ * await mail.queue(new WelcomeEmail(user));
233
+ * ```
234
+ */
235
+ queue(mailable: Mailable): Promise<void>;
236
+ /**
237
+ * Register an event handler.
238
+ *
239
+ * @description
240
+ * Subscribe to mail lifecycle events for logging, analytics, or custom processing.
241
+ *
242
+ * @param event - The event type to listen for
243
+ * @param handler - The handler function to execute
244
+ * @returns This instance for method chaining
245
+ *
246
+ * @example
247
+ * ```typescript
248
+ * mail.on('afterSend', async (event) => {
249
+ * await analytics.track('email_sent', {
250
+ * to: event.message?.to,
251
+ * subject: event.message?.subject
252
+ * })
253
+ * })
254
+ * ```
255
+ *
256
+ * @public
257
+ * @since 3.1.0
258
+ */
259
+ on(event: MailEventType, handler: MailEventHandler): this;
260
+ private emit;
261
+ }
262
+ declare module '@gravito/core' {
263
+ interface GravitoVariables {
264
+ /** Mail service for sending emails */
265
+ mail?: OrbitSignal;
266
+ }
267
+ }
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * @deprecated Use `import type { Queueable } from '@gravito/stream'`
8
8
  */
9
- export type { Queueable } from '@gravito/stream'
9
+ export type { Queueable } from '@gravito/stream';
@@ -1,5 +1,4 @@
1
- import { Mailable } from './Mailable'
2
-
1
+ import { Mailable } from './Mailable';
3
2
  /**
4
3
  * Abstract base class for strongly-typed Mailable messages.
5
4
  *
@@ -82,15 +81,15 @@ import { Mailable } from './Mailable'
82
81
  * @public
83
82
  * @since 3.0.0
84
83
  */
85
- export abstract class TypedMailable<TData extends Record<string, unknown>> extends Mailable {
86
- /**
87
- * The strongly-typed data for this mailable.
88
- *
89
- * This property holds the data that will be passed to the template or component
90
- * during rendering. By defining it as an abstract property with the generic
91
- * type TData, we force subclasses to provide a concrete, type-safe implementation.
92
- *
93
- * @protected
94
- */
95
- protected abstract data: TData
84
+ export declare abstract class TypedMailable<TData extends Record<string, unknown>> extends Mailable {
85
+ /**
86
+ * The strongly-typed data for this mailable.
87
+ *
88
+ * This property holds the data that will be passed to the template or component
89
+ * during rendering. By defining it as an abstract property with the generic
90
+ * type TData, we force subclasses to provide a concrete, type-safe implementation.
91
+ *
92
+ * @protected
93
+ */
94
+ protected abstract data: TData;
96
95
  }
@@ -0,0 +1,79 @@
1
+ import type { Message } from '../types';
2
+ import type { MailboxStorage } from './storage/MailboxStorage';
3
+ /**
4
+ * Entry structure for messages stored in DevMailbox.
5
+ */
6
+ export interface MailboxEntry {
7
+ /** Unique identifier for the entry. */
8
+ id: string;
9
+ /** The email envelope metadata. */
10
+ envelope: any;
11
+ /** The rendered HTML content. */
12
+ html: string;
13
+ /** Optional plain text content. */
14
+ text?: string;
15
+ /** Timestamp when the message was captured. */
16
+ sentAt: Date;
17
+ }
18
+ /**
19
+ * Capture and store emails during development for preview and testing.
20
+ *
21
+ * Supports different storage engines (Memory, FileSystem) and implements
22
+ * capacity limits via a Ring Buffer strategy.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Default memory mailbox
27
+ * const mailbox = new DevMailbox()
28
+ *
29
+ * // Persistent file mailbox
30
+ * const storage = new FileMailboxStorage('./storage/mail')
31
+ * const persistentMailbox = new DevMailbox(100, storage)
32
+ * ```
33
+ *
34
+ * @since 3.0.0
35
+ * @public
36
+ */
37
+ export declare class DevMailbox {
38
+ private storage;
39
+ private _maxEntries;
40
+ /**
41
+ * Creates an instance of DevMailbox.
42
+ *
43
+ * @param maxEntries - Maximum number of emails to store (default: 50)
44
+ * @param storage - Optional custom storage engine (defaults to Memory)
45
+ */
46
+ constructor(maxEntries?: number, storage?: MailboxStorage);
47
+ /**
48
+ * Adds a new message to the mailbox.
49
+ *
50
+ * If the mailbox exceeds the maximum capacity, the oldest messages are removed.
51
+ */
52
+ add(message: Message): Promise<MailboxEntry>;
53
+ /**
54
+ * Sets the maximum number of emails to store.
55
+ *
56
+ * If the current mailbox exceeds the new capacity, the oldest messages are removed.
57
+ */
58
+ setMaxEntries(count: number): Promise<void>;
59
+ /**
60
+ * Returns the maximum capacity of the mailbox.
61
+ */
62
+ get maxEntries(): number;
63
+ /**
64
+ * Lists all messages in the mailbox.
65
+ */
66
+ list(): Promise<MailboxEntry[]>;
67
+ /**
68
+ * Retrieves a specific message by ID.
69
+ */
70
+ get(id: string): Promise<MailboxEntry | undefined>;
71
+ /**
72
+ * Deletes a specific message by ID.
73
+ */
74
+ delete(id: string): Promise<boolean>;
75
+ /**
76
+ * Clears all messages from the mailbox.
77
+ */
78
+ clear(): Promise<void>;
79
+ }
@@ -0,0 +1,39 @@
1
+ import type { GravitoContext, PlanetCore } from '@gravito/core';
2
+ import type { DevMailbox } from './DevMailbox';
3
+ /**
4
+ * Configuration options for the development mail server.
5
+ *
6
+ * @public
7
+ */
8
+ export type DevServerOptions = {
9
+ /** Allow access in production environment (use with caution) */
10
+ allowInProduction?: boolean;
11
+ /** Custom gate function to control access to the dev UI */
12
+ gate?: (c: GravitoContext) => boolean | Promise<boolean>;
13
+ };
14
+ /**
15
+ * Development mail server for previewing captured emails.
16
+ *
17
+ * Provides a web UI at the configured base path (default: `/__mail`)
18
+ * to view, preview, and manage emails captured during development.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const mailbox = new DevMailbox()
23
+ * const devServer = new DevServer(mailbox, '/__mail', {
24
+ * gate: (c) => c.get('user')?.isAdmin
25
+ * })
26
+ * devServer.register(core)
27
+ * ```
28
+ *
29
+ * @since 3.0.0
30
+ * @public
31
+ */
32
+ export declare class DevServer {
33
+ private mailbox;
34
+ private base;
35
+ private options?;
36
+ constructor(mailbox: DevMailbox, base?: string, options?: DevServerOptions);
37
+ private canAccess;
38
+ register(core: PlanetCore): void;
39
+ }
@@ -0,0 +1,16 @@
1
+ import type { MailboxEntry } from '../DevMailbox';
2
+ import type { MailboxStorage } from './MailboxStorage';
3
+ /**
4
+ * File-based storage for DevMailbox (Persistence).
5
+ * Stores emails as JSON in a specified directory.
6
+ */
7
+ export declare class FileMailboxStorage implements MailboxStorage {
8
+ private filePath;
9
+ constructor(storageDir: string);
10
+ all(): Promise<MailboxEntry[]>;
11
+ push(entry: MailboxEntry): Promise<void>;
12
+ trim(max: number): Promise<void>;
13
+ clear(): Promise<void>;
14
+ delete(id: string): Promise<boolean>;
15
+ private save;
16
+ }
@@ -0,0 +1,14 @@
1
+ import type { MailboxEntry } from '../DevMailbox';
2
+ /**
3
+ * Interface for DevMailbox storage engines.
4
+ */
5
+ export interface MailboxStorage {
6
+ /** Retrieve all entries. */
7
+ all(): Promise<MailboxEntry[]>;
8
+ /** Add a single entry. */
9
+ push(entry: MailboxEntry): Promise<void>;
10
+ /** Trim entries to a specific count. */
11
+ trim(max: number): Promise<void>;
12
+ clear(): Promise<void>;
13
+ delete?(id: string): Promise<boolean>;
14
+ }
@@ -0,0 +1,13 @@
1
+ import type { MailboxEntry } from '../DevMailbox';
2
+ import type { MailboxStorage } from './MailboxStorage';
3
+ /**
4
+ * Memory-based storage for DevMailbox (Default).
5
+ */
6
+ export declare class MemoryMailboxStorage implements MailboxStorage {
7
+ private entries;
8
+ all(): Promise<MailboxEntry[]>;
9
+ push(entry: MailboxEntry): Promise<void>;
10
+ trim(max: number): Promise<void>;
11
+ clear(): Promise<void>;
12
+ delete(id: string): Promise<boolean>;
13
+ }
@@ -0,0 +1,11 @@
1
+ import type { MailboxEntry } from '../DevMailbox';
2
+ /**
3
+ * Generates the HTML for the mailbox list view.
4
+ *
5
+ * @param entries - Array of mailbox entries to display
6
+ * @param prefix - Base URL prefix for the dev server
7
+ * @returns HTML string for the mailbox UI
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function getMailboxHtml(entries: MailboxEntry[], prefix: string): string;
@@ -0,0 +1,11 @@
1
+ import type { MailboxEntry } from '../DevMailbox';
2
+ /**
3
+ * Generates the HTML for the email preview page.
4
+ *
5
+ * @param entry - Mailbox entry to preview
6
+ * @param prefix - Base URL prefix for the dev server
7
+ * @returns HTML string for the preview UI
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function getPreviewHtml(entry: MailboxEntry, prefix: string): string;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * CSS styles for the development mail UI.
3
+ * @internal
4
+ */
5
+ export declare const styles = "\n:root {\n --primary: #6366f1;\n --primary-dark: #4f46e5;\n --bg-dark: #0f172a;\n --bg-card: #1e293b;\n --text: #f1f5f9;\n --text-muted: #94a3b8;\n --border: #334155;\n --danger: #ef4444;\n}\nbody { background: var(--bg-dark); color: var(--text); font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 20px; }\n.container { max-width: 1000px; margin: 0 auto; }\n.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }\n.title { font-size: 24px; font-weight: bold; display: flex; align-items: center; gap: 10px; }\n.card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }\n.btn { background: var(--border); color: var(--text); border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; text-decoration: none; font-size: 14px; transition: 0.2s; }\n.btn:hover { background: var(--bg-card-hover); }\n.btn-primary { background: var(--primary); color: white; }\n.btn-primary:hover { background: var(--primary-dark); }\n.btn-danger { background: var(--danger); color: white; }\n.list-item { padding: 16px; border-bottom: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px; text-decoration: none; color: inherit; transition: background 0.2s; }\n.list-item:last-child { border-bottom: none; }\n.list-item:hover { background: #334155; }\n.meta { display: flex; justify-content: space-between; font-size: 14px; color: var(--text-muted); }\n.subject { font-weight: 600; font-size: 16px; }\n.from { color: #cbd5e1; }\n.badge { background: #475569; padding: 2px 6px; border-radius: 4px; font-size: 12px; }\n.badge-high { background: #dc2626; color: white; }\n.empty { padding: 40px; text-align: center; color: var(--text-muted); }\n";
6
+ /**
7
+ * HTML layout wrapper for dev mail UI pages.
8
+ *
9
+ * @param title - Page title
10
+ * @param content - HTML content to inject
11
+ * @returns Complete HTML document
12
+ *
13
+ * @internal
14
+ */
15
+ export declare const layout: (title: string, content: string) => string;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Mail transport error codes.
3
+ *
4
+ * Categorizes common failure modes in the mail delivery process to allow
5
+ * for programmatic handling (e.g., retries on rate limits).
6
+ *
7
+ * @public
8
+ * @since 3.1.0
9
+ */
10
+ export declare enum MailErrorCode {
11
+ /** Connection to mail server failed */
12
+ CONNECTION_FAILED = "CONNECTION_FAILED",
13
+ /** Authentication with mail server failed */
14
+ AUTH_FAILED = "AUTH_FAILED",
15
+ /** One or more recipients were rejected by the server */
16
+ RECIPIENT_REJECTED = "RECIPIENT_REJECTED",
17
+ /** The message was rejected by the server */
18
+ MESSAGE_REJECTED = "MESSAGE_REJECTED",
19
+ /** Rate limit exceeded */
20
+ RATE_LIMIT = "RATE_LIMIT",
21
+ /** Unknown or unclassified error */
22
+ UNKNOWN = "UNKNOWN"
23
+ }
24
+ /**
25
+ * Error class for mail transport failures.
26
+ *
27
+ * Provides structured error information for mail sending failures,
28
+ * including error codes and original cause tracking for debugging.
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * throw new MailTransportError(
33
+ * 'Failed to connect to SMTP server',
34
+ * MailErrorCode.CONNECTION_FAILED,
35
+ * originalError
36
+ * )
37
+ * ```
38
+ *
39
+ * @public
40
+ * @since 3.1.0
41
+ */
42
+ export declare class MailTransportError extends Error {
43
+ readonly code: MailErrorCode;
44
+ readonly cause?: Error;
45
+ /**
46
+ * Create a new mail transport error.
47
+ *
48
+ * @param message - Human-readable error message
49
+ * @param code - Categorized error code
50
+ * @param cause - Original error that caused this failure
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const error = new MailTransportError('Auth failed', MailErrorCode.AUTH_FAILED);
55
+ * ```
56
+ */
57
+ constructor(message: string, code: MailErrorCode, cause?: Error);
58
+ }
@@ -1,6 +1,5 @@
1
- import type { Mailable } from './Mailable'
2
- import type { Message } from './types'
3
-
1
+ import type { Mailable } from './Mailable';
2
+ import type { Message } from './types';
4
3
  /**
5
4
  * Mail event types.
6
5
  *
@@ -9,14 +8,7 @@ import type { Message } from './types'
9
8
  * @public
10
9
  * @since 3.1.0
11
10
  */
12
- export type MailEventType =
13
- | 'beforeSend'
14
- | 'afterSend'
15
- | 'sendFailed'
16
- | 'beforeRender'
17
- | 'afterRender'
18
- | 'webhookReceived'
19
-
11
+ export type MailEventType = 'beforeSend' | 'afterSend' | 'sendFailed' | 'beforeRender' | 'afterRender' | 'webhookReceived';
20
12
  /**
21
13
  * Mail lifecycle event.
22
14
  *
@@ -34,24 +26,23 @@ export type MailEventType =
34
26
  * @since 3.1.0
35
27
  */
36
28
  export interface MailEvent {
37
- /** Type of event */
38
- type: MailEventType
39
- /** Mailable instance that triggered the event */
40
- mailable: Mailable
41
- /** Finalized message (available for send events) */
42
- message?: Message
43
- /** Error that occurred (available for sendFailed event) */
44
- error?: Error
45
- /** Timestamp when event occurred */
46
- timestamp: Date
47
- /** Webhook payload (available for webhookReceived event) */
48
- webhook?: {
49
- driver: string
50
- event: string
51
- payload: any
52
- }
29
+ /** Type of event */
30
+ type: MailEventType;
31
+ /** Mailable instance that triggered the event */
32
+ mailable: Mailable;
33
+ /** Finalized message (available for send events) */
34
+ message?: Message;
35
+ /** Error that occurred (available for sendFailed event) */
36
+ error?: Error;
37
+ /** Timestamp when event occurred */
38
+ timestamp: Date;
39
+ /** Webhook payload (available for webhookReceived event) */
40
+ webhook?: {
41
+ driver: string;
42
+ event: string;
43
+ payload: any;
44
+ };
53
45
  }
54
-
55
46
  /**
56
47
  * Mail event handler function.
57
48
  *
@@ -69,4 +60,4 @@ export interface MailEvent {
69
60
  * @public
70
61
  * @since 3.1.0
71
62
  */
72
- export type MailEventHandler = (event: MailEvent) => void | Promise<void>
63
+ export type MailEventHandler = (event: MailEvent) => void | Promise<void>;