@stacksjs/email 0.69.2 → 0.70.0

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/dist/base.d.ts ADDED
@@ -0,0 +1,130 @@
1
+ import type { EmailDriver, EmailDriverConfig, EmailMessage, EmailResult, RenderOptions } from '@stacksjs/types';
2
+
3
+ export declare abstract class BaseEmailDriver implements EmailDriver {
4
+ public abstract name: string
5
+ protected config: Required<EmailDriverConfig>
6
+
7
+ constructor(config?: EmailDriverConfig) {
8
+ this.config = {
9
+ maxRetries: config?.maxRetries || 3,
10
+ retryTimeout: config?.retryTimeout || 1000,
11
+ ...config,
12
+ }
13
+ }
14
+
15
+ public configure(config: EmailDriverConfig): void {
16
+ this.config = { ...this.config, ...config }
17
+ }
18
+
19
+ public abstract send(message: EmailMessage, options?: RenderOptions): Promise<EmailResult>
20
+
21
+ protected validateMessage(message: EmailMessage): boolean {
22
+ if (!message.from?.address) {
23
+ throw new Error('Email sender address is required')
24
+ }
25
+
26
+ if (!message.to || (Array.isArray(message.to) && message.to.length === 0)) {
27
+ throw new Error('At least one recipient is required')
28
+ }
29
+
30
+ if (!message.subject) {
31
+ throw new Error('Email subject is required')
32
+ }
33
+
34
+ return true
35
+ }
36
+
37
+ protected formatAddresses(addresses: string | string[] | EmailAddress[] | undefined): string[] {
38
+ if (!addresses)
39
+ return []
40
+
41
+ if (typeof addresses === 'string') {
42
+ return [addresses]
43
+ }
44
+
45
+ return addresses.map((addr) => {
46
+ if (typeof addr === 'string')
47
+ return addr
48
+ return addr.name ? `${addr.name} <${addr.address}>` : addr.address
49
+ })
50
+ }
51
+
52
+ protected async handleError(error: unknown, message: EmailMessage): Promise<EmailResult> {
53
+ const err = error instanceof Error ? error : new Error(String(error))
54
+
55
+ log.error(`[${this.name}] Email sending failed`, {
56
+ error: err.message,
57
+ stack: err.stack,
58
+ to: message.to,
59
+ subject: message.subject,
60
+ })
61
+
62
+ let result: EmailResult = {
63
+ message: `Email sending failed: ${err.message}`,
64
+ success: false,
65
+ provider: this.name,
66
+ }
67
+
68
+ if (message.onError) {
69
+ const customResult = message.onError(err)
70
+ const handlerResult = customResult instanceof Promise
71
+ ? await customResult
72
+ : customResult
73
+
74
+ result = {
75
+ ...result,
76
+ ...handlerResult,
77
+ success: false,
78
+ provider: this.name,
79
+ }
80
+ }
81
+
82
+ return result
83
+ }
84
+
85
+ protected async handleSuccess(message: EmailMessage, messageId?: string): Promise<EmailResult> {
86
+ let result: EmailResult = {
87
+ message: 'Email sent successfully',
88
+ success: true,
89
+ provider: this.name,
90
+ messageId,
91
+ }
92
+
93
+ try {
94
+ if (message.handle) {
95
+ const customResult = message.handle()
96
+ const handlerResult = customResult instanceof Promise
97
+ ? await customResult
98
+ : customResult
99
+
100
+ result = {
101
+ ...result,
102
+ ...handlerResult,
103
+ success: true,
104
+ provider: this.name,
105
+ messageId,
106
+ }
107
+ }
108
+
109
+ if (message.onSuccess) {
110
+ const successResult = message.onSuccess()
111
+ const handlerResult = successResult instanceof Promise
112
+ ? await successResult
113
+ : successResult
114
+
115
+ result = {
116
+ ...result,
117
+ ...handlerResult,
118
+ success: true,
119
+ provider: this.name,
120
+ messageId,
121
+ }
122
+ }
123
+ }
124
+ catch (error) {
125
+ return this.handleError(error, message)
126
+ }
127
+
128
+ return result
129
+ }
130
+ }
@@ -0,0 +1,2 @@
1
+ declare const driver: unknown;
2
+ export declare const mail: Mail;
package/dist/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export * as ses from './ses'
1
+ export * from './drivers'
2
+ export * from './email'
3
+ export * from './types'