@bernierllc/email-sender 0.2.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/LICENSE +7 -0
- package/README.md +430 -0
- package/dist/core/email-sender.d.ts +71 -0
- package/dist/core/email-sender.d.ts.map +1 -0
- package/dist/core/email-sender.js +125 -0
- package/dist/core/email-sender.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/base.d.ts +63 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +132 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/mailgun.d.ts +40 -0
- package/dist/providers/mailgun.d.ts.map +1 -0
- package/dist/providers/mailgun.js +525 -0
- package/dist/providers/mailgun.js.map +1 -0
- package/dist/providers/postmark.d.ts +37 -0
- package/dist/providers/postmark.d.ts.map +1 -0
- package/dist/providers/postmark.js +482 -0
- package/dist/providers/postmark.js.map +1 -0
- package/dist/providers/sendgrid.d.ts +80 -0
- package/dist/providers/sendgrid.d.ts.map +1 -0
- package/dist/providers/sendgrid.js +407 -0
- package/dist/providers/sendgrid.js.map +1 -0
- package/dist/providers/ses.d.ts +38 -0
- package/dist/providers/ses.d.ts.map +1 -0
- package/dist/providers/ses.js +404 -0
- package/dist/providers/ses.js.map +1 -0
- package/dist/providers/smtp.d.ts +61 -0
- package/dist/providers/smtp.d.ts.map +1 -0
- package/dist/providers/smtp.js +201 -0
- package/dist/providers/smtp.js.map +1 -0
- package/dist/types/index.d.ts +99 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SesProvider = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* AWS SES Email Provider
|
|
13
|
+
* Handles email sending through Amazon Simple Email Service
|
|
14
|
+
*/
|
|
15
|
+
const base_1 = require("./base");
|
|
16
|
+
class SesProvider extends base_1.EmailProvider {
|
|
17
|
+
constructor(config) {
|
|
18
|
+
super(config);
|
|
19
|
+
this.initializeClient();
|
|
20
|
+
}
|
|
21
|
+
initializeClient() {
|
|
22
|
+
try {
|
|
23
|
+
// Dynamically import AWS SDK to avoid bundling issues
|
|
24
|
+
const AWS = require('aws-sdk');
|
|
25
|
+
this.sesClient = new AWS.SES({
|
|
26
|
+
accessKeyId: this.config.apiKey,
|
|
27
|
+
secretAccessKey: this.config.secretKey,
|
|
28
|
+
region: this.config.region,
|
|
29
|
+
endpoint: this.config.endpoint,
|
|
30
|
+
apiVersion: '2010-12-01'
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
throw new Error(`Failed to initialize AWS SES client: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async sendEmail(message) {
|
|
38
|
+
try {
|
|
39
|
+
const sesMessage = this.convertToSesMessage(message);
|
|
40
|
+
const params = {
|
|
41
|
+
...sesMessage,
|
|
42
|
+
ConfigurationSetName: this.config.sandbox ? 'sandbox' : undefined
|
|
43
|
+
};
|
|
44
|
+
const result = await this.sesClient.sendEmail(params).promise();
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
messageId: result.MessageId,
|
|
48
|
+
providerResponse: result,
|
|
49
|
+
metadata: {
|
|
50
|
+
provider: 'ses',
|
|
51
|
+
region: this.config.region,
|
|
52
|
+
timestamp: new Date().toISOString()
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
errorMessage: this.formatSesError(error),
|
|
60
|
+
providerResponse: error,
|
|
61
|
+
metadata: {
|
|
62
|
+
provider: 'ses',
|
|
63
|
+
region: this.config.region,
|
|
64
|
+
timestamp: new Date().toISOString()
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async sendBatch(emails) {
|
|
70
|
+
try {
|
|
71
|
+
const batchSize = Math.min(emails.length, this.getCapabilities().maxBatchSize);
|
|
72
|
+
const results = [];
|
|
73
|
+
// Process emails in batches
|
|
74
|
+
for (let i = 0; i < emails.length; i += batchSize) {
|
|
75
|
+
const batch = emails.slice(i, i + batchSize);
|
|
76
|
+
const batchResults = await this.sendBatchChunk(batch);
|
|
77
|
+
results.push(...batchResults);
|
|
78
|
+
}
|
|
79
|
+
return results;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
// If batch fails, return individual error results
|
|
83
|
+
return emails.map(() => ({
|
|
84
|
+
success: false,
|
|
85
|
+
errorMessage: this.formatSesError(error),
|
|
86
|
+
metadata: {
|
|
87
|
+
provider: 'ses',
|
|
88
|
+
region: this.config.region,
|
|
89
|
+
timestamp: new Date().toISOString()
|
|
90
|
+
}
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async sendBatchChunk(emails) {
|
|
95
|
+
try {
|
|
96
|
+
const batchRequests = emails.map(email => ({
|
|
97
|
+
Id: `email-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
98
|
+
...this.convertToSesMessage(email)
|
|
99
|
+
}));
|
|
100
|
+
const params = {
|
|
101
|
+
Source: this.config.fromEmail,
|
|
102
|
+
Destinations: batchRequests
|
|
103
|
+
};
|
|
104
|
+
const result = await this.sesClient.sendBulkTemplatedEmail(params).promise();
|
|
105
|
+
return batchRequests.map((_, index) => {
|
|
106
|
+
const status = result.Status[index];
|
|
107
|
+
return {
|
|
108
|
+
success: status.Status === 'Success',
|
|
109
|
+
messageId: status.MessageId,
|
|
110
|
+
errorMessage: status.Status === 'Failed' ? status.Error : undefined,
|
|
111
|
+
providerResponse: status,
|
|
112
|
+
metadata: {
|
|
113
|
+
provider: 'ses',
|
|
114
|
+
region: this.config.region,
|
|
115
|
+
timestamp: new Date().toISOString()
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return emails.map(() => ({
|
|
122
|
+
success: false,
|
|
123
|
+
errorMessage: this.formatSesError(error),
|
|
124
|
+
metadata: {
|
|
125
|
+
provider: 'ses',
|
|
126
|
+
region: this.config.region,
|
|
127
|
+
timestamp: new Date().toISOString()
|
|
128
|
+
}
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async sendTemplateEmail(templateId, toEmail, variables) {
|
|
133
|
+
try {
|
|
134
|
+
const params = {
|
|
135
|
+
Source: this.config.fromEmail,
|
|
136
|
+
Destination: {
|
|
137
|
+
ToAddresses: [toEmail]
|
|
138
|
+
},
|
|
139
|
+
Template: templateId,
|
|
140
|
+
TemplateData: JSON.stringify(variables)
|
|
141
|
+
};
|
|
142
|
+
const result = await this.sesClient.sendTemplatedEmail(params).promise();
|
|
143
|
+
return {
|
|
144
|
+
success: true,
|
|
145
|
+
messageId: result.MessageId,
|
|
146
|
+
providerResponse: result,
|
|
147
|
+
metadata: {
|
|
148
|
+
provider: 'ses',
|
|
149
|
+
region: this.config.region,
|
|
150
|
+
templateId,
|
|
151
|
+
timestamp: new Date().toISOString()
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
errorMessage: this.formatSesError(error),
|
|
159
|
+
providerResponse: error,
|
|
160
|
+
metadata: {
|
|
161
|
+
provider: 'ses',
|
|
162
|
+
region: this.config.region,
|
|
163
|
+
templateId,
|
|
164
|
+
timestamp: new Date().toISOString()
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async createTemplate(template) {
|
|
170
|
+
try {
|
|
171
|
+
const params = {
|
|
172
|
+
Template: {
|
|
173
|
+
TemplateName: template.name,
|
|
174
|
+
SubjectPart: template.subject,
|
|
175
|
+
HtmlPart: template.htmlContent,
|
|
176
|
+
TextPart: template.textContent
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
await this.sesClient.createTemplate(params).promise();
|
|
180
|
+
return template.name; // SES uses template name as ID
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
throw new Error(`Failed to create SES template: ${this.formatSesError(error)}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async updateTemplate(template) {
|
|
187
|
+
try {
|
|
188
|
+
const params = {
|
|
189
|
+
Template: {
|
|
190
|
+
TemplateName: template.id,
|
|
191
|
+
SubjectPart: template.subject,
|
|
192
|
+
HtmlPart: template.htmlContent,
|
|
193
|
+
TextPart: template.textContent
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
await this.sesClient.updateTemplate(params).promise();
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
throw new Error(`Failed to update SES template: ${this.formatSesError(error)}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async deleteTemplate(templateId) {
|
|
203
|
+
try {
|
|
204
|
+
const params = {
|
|
205
|
+
TemplateName: templateId
|
|
206
|
+
};
|
|
207
|
+
await this.sesClient.deleteTemplate(params).promise();
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
throw new Error(`Failed to delete SES template: ${this.formatSesError(error)}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async getTemplate(templateId) {
|
|
214
|
+
try {
|
|
215
|
+
const params = {
|
|
216
|
+
TemplateName: templateId
|
|
217
|
+
};
|
|
218
|
+
const result = await this.sesClient.getTemplate(params).promise();
|
|
219
|
+
const template = result.Template;
|
|
220
|
+
return {
|
|
221
|
+
id: template.TemplateName,
|
|
222
|
+
name: template.TemplateName,
|
|
223
|
+
subject: template.SubjectPart,
|
|
224
|
+
htmlContent: template.HtmlPart,
|
|
225
|
+
textContent: template.TextPart,
|
|
226
|
+
variables: [], // SES doesn't provide variable list
|
|
227
|
+
createdAt: new Date(), // SES doesn't provide creation date
|
|
228
|
+
updatedAt: new Date() // SES doesn't provide update date
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
if (error.code === 'TemplateDoesNotExist') {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
throw new Error(`Failed to get SES template: ${this.formatSesError(error)}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async listTemplates() {
|
|
239
|
+
try {
|
|
240
|
+
const result = await this.sesClient.listTemplates().promise();
|
|
241
|
+
const templates = [];
|
|
242
|
+
for (const template of result.TemplatesMetadata || []) {
|
|
243
|
+
const fullTemplate = await this.getTemplate(template.Name);
|
|
244
|
+
if (fullTemplate) {
|
|
245
|
+
templates.push(fullTemplate);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return templates;
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
throw new Error(`Failed to list SES templates: ${this.formatSesError(error)}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async getDeliveryStatus(messageId) {
|
|
255
|
+
try {
|
|
256
|
+
// SES doesn't provide direct delivery status via API
|
|
257
|
+
// This would typically be handled via SNS notifications
|
|
258
|
+
return {
|
|
259
|
+
messageId,
|
|
260
|
+
status: 'sent', // Default status
|
|
261
|
+
metadata: {
|
|
262
|
+
provider: 'ses',
|
|
263
|
+
region: this.config.region
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async processWebhook(_payload, _signature) {
|
|
272
|
+
// SES uses SNS for webhooks, not direct webhooks
|
|
273
|
+
// This would need to be implemented based on SNS message format
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
async testConnection() {
|
|
277
|
+
try {
|
|
278
|
+
// Test by getting sending statistics
|
|
279
|
+
await this.sesClient.getSendStatistics().promise();
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
validateConfiguration() {
|
|
287
|
+
const errors = [];
|
|
288
|
+
const warnings = [];
|
|
289
|
+
if (!this.config.apiKey) {
|
|
290
|
+
errors.push('AWS Access Key ID is required');
|
|
291
|
+
}
|
|
292
|
+
if (!this.config.secretKey) {
|
|
293
|
+
errors.push('AWS Secret Access Key is required');
|
|
294
|
+
}
|
|
295
|
+
if (!this.config.region) {
|
|
296
|
+
errors.push('AWS region is required');
|
|
297
|
+
}
|
|
298
|
+
if (!this.config.fromEmail) {
|
|
299
|
+
errors.push('From email is required');
|
|
300
|
+
}
|
|
301
|
+
if (this.config.sandbox) {
|
|
302
|
+
warnings.push('SES sandbox mode is enabled - emails can only be sent to verified addresses');
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
isValid: errors.length === 0,
|
|
306
|
+
errors,
|
|
307
|
+
warnings
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
validateEmailMessage(message) {
|
|
311
|
+
const errors = [];
|
|
312
|
+
const warnings = [];
|
|
313
|
+
if (!message.toEmail) {
|
|
314
|
+
errors.push('Recipient email is required');
|
|
315
|
+
}
|
|
316
|
+
else if (!this.isValidEmail(message.toEmail)) {
|
|
317
|
+
errors.push('Invalid recipient email format');
|
|
318
|
+
}
|
|
319
|
+
if (!message.subject) {
|
|
320
|
+
errors.push('Email subject is required');
|
|
321
|
+
}
|
|
322
|
+
if (!message.htmlContent && !message.textContent) {
|
|
323
|
+
errors.push('Either HTML or text content is required');
|
|
324
|
+
}
|
|
325
|
+
if (message.attachments && message.attachments.length > 0) {
|
|
326
|
+
warnings.push('SES has limited attachment support - consider using S3 for large files');
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
isValid: errors.length === 0,
|
|
330
|
+
errors,
|
|
331
|
+
warnings
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
getCapabilities() {
|
|
335
|
+
return {
|
|
336
|
+
supportsBatch: true,
|
|
337
|
+
supportsTemplates: true,
|
|
338
|
+
supportsWebhooks: false, // SES uses SNS for notifications
|
|
339
|
+
supportsAttachments: true,
|
|
340
|
+
supportsDeliveryTracking: true,
|
|
341
|
+
maxBatchSize: 50,
|
|
342
|
+
maxAttachmentSize: 10 * 1024 * 1024 // 10MB
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
convertToSesMessage(message) {
|
|
346
|
+
const sesMessage = {
|
|
347
|
+
Source: message.fromEmail || this.config.fromEmail,
|
|
348
|
+
Destination: {
|
|
349
|
+
ToAddresses: [message.toEmail]
|
|
350
|
+
},
|
|
351
|
+
Message: {
|
|
352
|
+
Subject: {
|
|
353
|
+
Data: message.subject,
|
|
354
|
+
Charset: 'UTF-8'
|
|
355
|
+
},
|
|
356
|
+
Body: {}
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
if (message.htmlContent) {
|
|
360
|
+
sesMessage.Message.Body.Html = {
|
|
361
|
+
Data: message.htmlContent,
|
|
362
|
+
Charset: 'UTF-8'
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
if (message.textContent) {
|
|
366
|
+
sesMessage.Message.Body.Text = {
|
|
367
|
+
Data: message.textContent,
|
|
368
|
+
Charset: 'UTF-8'
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
if (message.replyTo) {
|
|
372
|
+
sesMessage.ReplyToAddresses = [message.replyTo];
|
|
373
|
+
}
|
|
374
|
+
if (message.headers) {
|
|
375
|
+
// Convert headers to SES tags
|
|
376
|
+
sesMessage.Tags = Object.entries(message.headers).map(([key, value]) => ({
|
|
377
|
+
Name: key,
|
|
378
|
+
Value: value
|
|
379
|
+
}));
|
|
380
|
+
}
|
|
381
|
+
return sesMessage;
|
|
382
|
+
}
|
|
383
|
+
formatSesError(error) {
|
|
384
|
+
if (error.code) {
|
|
385
|
+
switch (error.code) {
|
|
386
|
+
case 'MessageRejected':
|
|
387
|
+
return 'Message rejected by SES';
|
|
388
|
+
case 'MailFromDomainNotVerified':
|
|
389
|
+
return 'From domain is not verified in SES';
|
|
390
|
+
case 'ConfigurationSetDoesNotExist':
|
|
391
|
+
return 'Configuration set does not exist';
|
|
392
|
+
case 'TemplateDoesNotExist':
|
|
393
|
+
return 'Template does not exist';
|
|
394
|
+
case 'InvalidParameterValue':
|
|
395
|
+
return 'Invalid parameter value provided';
|
|
396
|
+
default:
|
|
397
|
+
return `SES Error (${error.code}): ${error.message || 'Unknown error'}`;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return error.message || 'Unknown SES error';
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
exports.SesProvider = SesProvider;
|
|
404
|
+
//# sourceMappingURL=ses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ses.js","sourceRoot":"","sources":["../../src/providers/ses.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { EmailProvider } from './base';
|
|
2
|
+
import { EmailMessage, SendResult, DeliveryStatus, WebhookEvent, EmailProviderConfig } from '../types';
|
|
3
|
+
export declare class SmtpProvider extends EmailProvider {
|
|
4
|
+
private transporter;
|
|
5
|
+
constructor(config: EmailProviderConfig);
|
|
6
|
+
/**
|
|
7
|
+
* Initialize the nodemailer transporter
|
|
8
|
+
*/
|
|
9
|
+
private initializeTransporter;
|
|
10
|
+
/**
|
|
11
|
+
* Send a single email
|
|
12
|
+
*/
|
|
13
|
+
sendEmail(email: EmailMessage): Promise<SendResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Send multiple emails
|
|
16
|
+
*/
|
|
17
|
+
sendBatch(emails: EmailMessage[]): Promise<SendResult[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Get delivery status for a message
|
|
20
|
+
* Note: SMTP doesn't provide delivery tracking by default
|
|
21
|
+
*/
|
|
22
|
+
getDeliveryStatus(_messageId: string): Promise<DeliveryStatus | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Process webhook events from the provider
|
|
25
|
+
* Note: SMTP doesn't support webhooks by default
|
|
26
|
+
*/
|
|
27
|
+
processWebhook(_payload: any, _signature: string): Promise<WebhookEvent[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Override capabilities for SMTP
|
|
30
|
+
*/
|
|
31
|
+
getCapabilities(): {
|
|
32
|
+
supportsBatch: boolean;
|
|
33
|
+
supportsTemplates: boolean;
|
|
34
|
+
supportsWebhooks: boolean;
|
|
35
|
+
supportsAttachments: boolean;
|
|
36
|
+
supportsDeliveryTracking: boolean;
|
|
37
|
+
maxBatchSize: number;
|
|
38
|
+
maxAttachmentSize: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Test the SMTP connection
|
|
42
|
+
*/
|
|
43
|
+
testConnection(): Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Format from address
|
|
46
|
+
*/
|
|
47
|
+
private formatFromAddress;
|
|
48
|
+
/**
|
|
49
|
+
* Format to address
|
|
50
|
+
*/
|
|
51
|
+
private formatToAddress;
|
|
52
|
+
/**
|
|
53
|
+
* Override configuration validation for SMTP
|
|
54
|
+
*/
|
|
55
|
+
validateConfiguration(): {
|
|
56
|
+
isValid: boolean;
|
|
57
|
+
errors: string[];
|
|
58
|
+
warnings: string[];
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=smtp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smtp.d.ts","sourceRoot":"","sources":["../../src/providers/smtp.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEvG,qBAAa,YAAa,SAAQ,aAAa;IAC7C,OAAO,CAAC,WAAW,CAAuC;gBAE9C,MAAM,EAAE,mBAAmB;IAKvC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkB7B;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IA0DzD;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAW9D;;;OAGG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAK3E;;;OAGG;IACG,cAAc,CAAC,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAKhF;;OAEG;IACM,eAAe;;;;;;;;;IAYxB;;OAEG;IACY,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAajD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACM,qBAAqB;;;;;CA0B/B"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.SmtpProvider = void 0;
|
|
14
|
+
/**
|
|
15
|
+
* SMTP Email Provider implementation using nodemailer
|
|
16
|
+
*/
|
|
17
|
+
const nodemailer_1 = __importDefault(require("nodemailer"));
|
|
18
|
+
const base_1 = require("./base");
|
|
19
|
+
class SmtpProvider extends base_1.EmailProvider {
|
|
20
|
+
constructor(config) {
|
|
21
|
+
super(config);
|
|
22
|
+
this.transporter = null;
|
|
23
|
+
this.initializeTransporter();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the nodemailer transporter
|
|
27
|
+
*/
|
|
28
|
+
initializeTransporter() {
|
|
29
|
+
if (this.config.provider !== 'smtp') {
|
|
30
|
+
throw new Error('SmtpProvider requires provider to be "smtp"');
|
|
31
|
+
}
|
|
32
|
+
const smtpConfig = {
|
|
33
|
+
host: this.config.host,
|
|
34
|
+
port: this.config.port,
|
|
35
|
+
secure: this.config.secure ?? false,
|
|
36
|
+
auth: {
|
|
37
|
+
user: this.config.username,
|
|
38
|
+
pass: this.config.password,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
this.transporter = nodemailer_1.default.createTransport(smtpConfig);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Send a single email
|
|
45
|
+
*/
|
|
46
|
+
async sendEmail(email) {
|
|
47
|
+
try {
|
|
48
|
+
// Validate email message
|
|
49
|
+
const validation = this.validateEmailMessage(email);
|
|
50
|
+
if (!validation.isValid) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
errorMessage: `Email validation failed: ${validation.errors.join(', ')}`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (!this.transporter) {
|
|
57
|
+
throw new Error('SMTP transporter not initialized');
|
|
58
|
+
}
|
|
59
|
+
// Prepare nodemailer options
|
|
60
|
+
const mailOptions = {
|
|
61
|
+
from: this.formatFromAddress(email.fromEmail, email.fromName),
|
|
62
|
+
to: this.formatToAddress(email.toEmail, email.toName),
|
|
63
|
+
subject: email.subject,
|
|
64
|
+
html: email.htmlContent,
|
|
65
|
+
text: email.textContent,
|
|
66
|
+
replyTo: email.replyTo,
|
|
67
|
+
headers: email.headers,
|
|
68
|
+
};
|
|
69
|
+
// Add attachments if present
|
|
70
|
+
if (email.attachments && email.attachments.length > 0) {
|
|
71
|
+
mailOptions.attachments = email.attachments.map(attachment => ({
|
|
72
|
+
filename: attachment.filename,
|
|
73
|
+
content: Buffer.from(attachment.content, 'base64'),
|
|
74
|
+
contentType: attachment.contentType,
|
|
75
|
+
contentDisposition: attachment.disposition,
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
// Send email
|
|
79
|
+
const result = await this.transporter.sendMail(mailOptions);
|
|
80
|
+
return {
|
|
81
|
+
success: true,
|
|
82
|
+
messageId: result.messageId,
|
|
83
|
+
providerResponse: result,
|
|
84
|
+
metadata: {
|
|
85
|
+
accepted: result.accepted,
|
|
86
|
+
rejected: result.rejected,
|
|
87
|
+
response: result.response,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
success: false,
|
|
94
|
+
errorMessage: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
95
|
+
providerResponse: error,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Send multiple emails
|
|
101
|
+
*/
|
|
102
|
+
async sendBatch(emails) {
|
|
103
|
+
const results = [];
|
|
104
|
+
for (const email of emails) {
|
|
105
|
+
const result = await this.sendEmail(email);
|
|
106
|
+
results.push(result);
|
|
107
|
+
}
|
|
108
|
+
return results;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get delivery status for a message
|
|
112
|
+
* Note: SMTP doesn't provide delivery tracking by default
|
|
113
|
+
*/
|
|
114
|
+
async getDeliveryStatus(_messageId) {
|
|
115
|
+
// SMTP doesn't provide delivery tracking
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Process webhook events from the provider
|
|
120
|
+
* Note: SMTP doesn't support webhooks by default
|
|
121
|
+
*/
|
|
122
|
+
async processWebhook(_payload, _signature) {
|
|
123
|
+
// SMTP doesn't support webhooks
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Override capabilities for SMTP
|
|
128
|
+
*/
|
|
129
|
+
getCapabilities() {
|
|
130
|
+
return {
|
|
131
|
+
supportsBatch: true,
|
|
132
|
+
supportsTemplates: false,
|
|
133
|
+
supportsWebhooks: false,
|
|
134
|
+
supportsAttachments: true,
|
|
135
|
+
supportsDeliveryTracking: false,
|
|
136
|
+
maxBatchSize: 100,
|
|
137
|
+
maxAttachmentSize: 25 * 1024 * 1024, // 25MB
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Test the SMTP connection
|
|
142
|
+
*/
|
|
143
|
+
async testConnection() {
|
|
144
|
+
try {
|
|
145
|
+
if (!this.transporter) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
await this.transporter.verify();
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Format from address
|
|
157
|
+
*/
|
|
158
|
+
formatFromAddress(email, name) {
|
|
159
|
+
const fromEmail = email || this.config.fromEmail;
|
|
160
|
+
const fromName = name || this.config.fromName;
|
|
161
|
+
if (fromName) {
|
|
162
|
+
return `"${fromName}" <${fromEmail}>`;
|
|
163
|
+
}
|
|
164
|
+
return fromEmail;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Format to address
|
|
168
|
+
*/
|
|
169
|
+
formatToAddress(email, name) {
|
|
170
|
+
if (name) {
|
|
171
|
+
return `"${name}" <${email}>`;
|
|
172
|
+
}
|
|
173
|
+
return email;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Override configuration validation for SMTP
|
|
177
|
+
*/
|
|
178
|
+
validateConfiguration() {
|
|
179
|
+
const errors = [];
|
|
180
|
+
const warnings = [];
|
|
181
|
+
if (!this.config.host) {
|
|
182
|
+
errors.push('SMTP host is required');
|
|
183
|
+
}
|
|
184
|
+
if (!this.config.port) {
|
|
185
|
+
errors.push('SMTP port is required');
|
|
186
|
+
}
|
|
187
|
+
if (this.config.username && !this.config.password) {
|
|
188
|
+
warnings.push('SMTP username provided but no password');
|
|
189
|
+
}
|
|
190
|
+
if (this.config.password && !this.config.username) {
|
|
191
|
+
warnings.push('SMTP password provided but no username');
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
isValid: errors.length === 0,
|
|
195
|
+
errors,
|
|
196
|
+
warnings,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
exports.SmtpProvider = SmtpProvider;
|
|
201
|
+
//# sourceMappingURL=smtp.js.map
|