@groundbrick/email-service 1.1.3 → 1.1.4
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/EmailService.d.ts +24 -0
- package/dist/EmailService.d.ts.map +1 -0
- package/dist/EmailService.js +32 -0
- package/dist/EmailService.js.map +1 -0
- package/dist/EmailServiceFactory.d.ts +5 -0
- package/dist/EmailServiceFactory.d.ts.map +1 -0
- package/dist/EmailServiceFactory.js +21 -0
- package/dist/EmailServiceFactory.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/IEmailProvider.d.ts +103 -0
- package/dist/interfaces/IEmailProvider.d.ts.map +1 -0
- package/dist/interfaces/IEmailProvider.js +11 -0
- package/dist/interfaces/IEmailProvider.js.map +1 -0
- package/dist/providers/GatewayApiEmailProvider.d.ts +41 -0
- package/dist/providers/GatewayApiEmailProvider.d.ts.map +1 -0
- package/dist/providers/GatewayApiEmailProvider.js +270 -0
- package/dist/providers/GatewayApiEmailProvider.js.map +1 -0
- package/dist/providers/MockEmailProvider.d.ts +49 -0
- package/dist/providers/MockEmailProvider.d.ts.map +1 -0
- package/dist/providers/MockEmailProvider.js +194 -0
- package/dist/providers/MockEmailProvider.js.map +1 -0
- package/dist/providers/RedirectEmailProvider.d.ts +28 -0
- package/dist/providers/RedirectEmailProvider.d.ts.map +1 -0
- package/dist/providers/RedirectEmailProvider.js +108 -0
- package/dist/providers/RedirectEmailProvider.js.map +1 -0
- package/dist/providers/SweegoEmailProvider.d.ts +36 -0
- package/dist/providers/SweegoEmailProvider.d.ts.map +1 -0
- package/dist/providers/SweegoEmailProvider.js +379 -0
- package/dist/providers/SweegoEmailProvider.js.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/index.js.map +1 -0
- package/package.json +8 -9
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { EmailStatus } from '../interfaces/IEmailProvider.js';
|
|
2
|
+
export class MockEmailProvider {
|
|
3
|
+
simulateDelay;
|
|
4
|
+
simulateFailures;
|
|
5
|
+
defaultFrom;
|
|
6
|
+
sentEmails = new Map();
|
|
7
|
+
messageIdCounter = 1;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.simulateDelay = config.simulateDelay || 0;
|
|
10
|
+
this.simulateFailures = config.simulateFailures || false;
|
|
11
|
+
this.defaultFrom = config.defaultFrom;
|
|
12
|
+
}
|
|
13
|
+
async send(message) {
|
|
14
|
+
// Simulate network delay
|
|
15
|
+
if (this.simulateDelay > 0) {
|
|
16
|
+
await this.delay(this.simulateDelay);
|
|
17
|
+
}
|
|
18
|
+
// Simulate random failures (10% chance)
|
|
19
|
+
if (this.simulateFailures && Math.random() < 0.1) {
|
|
20
|
+
return {
|
|
21
|
+
success: false,
|
|
22
|
+
status: EmailStatus.FAILED,
|
|
23
|
+
timestamp: new Date(),
|
|
24
|
+
error: 'Simulated failure'
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// Generate message ID
|
|
28
|
+
const messageId = `mock-${this.messageIdCounter++}-${Date.now()}`;
|
|
29
|
+
// Store sent email
|
|
30
|
+
const sentEmail = {
|
|
31
|
+
id: messageId,
|
|
32
|
+
message,
|
|
33
|
+
sentAt: new Date(),
|
|
34
|
+
status: EmailStatus.DELIVERED
|
|
35
|
+
};
|
|
36
|
+
this.sentEmails.set(messageId, sentEmail);
|
|
37
|
+
// Log email (useful for debugging)
|
|
38
|
+
this.logEmail(messageId, message);
|
|
39
|
+
return {
|
|
40
|
+
success: true,
|
|
41
|
+
messageId,
|
|
42
|
+
status: EmailStatus.DELIVERED,
|
|
43
|
+
timestamp: new Date(),
|
|
44
|
+
providerResponse: { mock: true, stored: true }
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async getDeliveryReport(messageId) {
|
|
48
|
+
const sentEmail = this.sentEmails.get(messageId);
|
|
49
|
+
if (!sentEmail) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const recipient = Array.isArray(sentEmail.message.to)
|
|
53
|
+
? sentEmail.message.to[0].address
|
|
54
|
+
: sentEmail.message.to.address;
|
|
55
|
+
return {
|
|
56
|
+
messageId,
|
|
57
|
+
status: sentEmail.status,
|
|
58
|
+
timestamp: sentEmail.sentAt,
|
|
59
|
+
recipient,
|
|
60
|
+
providerData: { mock: true }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
validateWebhook(payload, signature, _options) {
|
|
64
|
+
// Mock provider doesn't validate webhooks
|
|
65
|
+
return {
|
|
66
|
+
isValid: false,
|
|
67
|
+
error: 'Mock provider does not support webhooks'
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get all sent emails (useful for testing)
|
|
72
|
+
*/
|
|
73
|
+
getSentEmails() {
|
|
74
|
+
return Array.from(this.sentEmails.values());
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Clear all sent emails (useful for testing)
|
|
78
|
+
*/
|
|
79
|
+
clearSentEmails() {
|
|
80
|
+
this.sentEmails.clear();
|
|
81
|
+
this.messageIdCounter = 1;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get a specific sent email by ID (useful for testing)
|
|
85
|
+
*/
|
|
86
|
+
getSentEmail(messageId) {
|
|
87
|
+
return this.sentEmails.get(messageId);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Log email to console (only in development)
|
|
91
|
+
*/
|
|
92
|
+
logEmail(messageId, message) {
|
|
93
|
+
const recipients = Array.isArray(message.to)
|
|
94
|
+
? message.to.map(t => t.address).join(', ')
|
|
95
|
+
: message.to.address;
|
|
96
|
+
console.log('\n' + '='.repeat(80));
|
|
97
|
+
console.log('📧 MOCK EMAIL SENT');
|
|
98
|
+
console.log('='.repeat(80));
|
|
99
|
+
console.log(`Message ID: ${messageId}`);
|
|
100
|
+
console.log(`From: ${message.from?.address || this.defaultFrom.address}`);
|
|
101
|
+
console.log(`To: ${recipients}`);
|
|
102
|
+
if (message.cc && message.cc.length > 0) {
|
|
103
|
+
console.log(`CC: ${message.cc.map(c => c.address).join(', ')}`);
|
|
104
|
+
}
|
|
105
|
+
if (message.bcc && message.bcc.length > 0) {
|
|
106
|
+
console.log(`BCC: ${message.bcc.map(b => b.address).join(', ')}`);
|
|
107
|
+
}
|
|
108
|
+
console.log(`Subject: ${message.subject}`);
|
|
109
|
+
console.log('-'.repeat(80));
|
|
110
|
+
if (message.html) {
|
|
111
|
+
// Extract plain text from HTML for better readability
|
|
112
|
+
const plainText = this.htmlToPlainText(message.html);
|
|
113
|
+
console.log('📄 EMAIL CONTENT (Plain Text):');
|
|
114
|
+
console.log(plainText);
|
|
115
|
+
// Try to extract 2FA code if present
|
|
116
|
+
const code = this.extract2FACode(message.html);
|
|
117
|
+
if (code) {
|
|
118
|
+
console.log('\n' + '🔑 '.repeat(20));
|
|
119
|
+
console.log(`🔐 2FA CODE DETECTED: ${code}`);
|
|
120
|
+
console.log('🔑 '.repeat(20));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else if (message.text) {
|
|
124
|
+
console.log('📄 EMAIL CONTENT:');
|
|
125
|
+
console.log(message.text);
|
|
126
|
+
// Try to extract 2FA code from text
|
|
127
|
+
const code = this.extract2FACode(message.text);
|
|
128
|
+
if (code) {
|
|
129
|
+
console.log('\n' + '🔑 '.repeat(20));
|
|
130
|
+
console.log(`🔐 2FA CODE DETECTED: ${code}`);
|
|
131
|
+
console.log('🔑 '.repeat(20));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (message.attachments && message.attachments.length > 0) {
|
|
135
|
+
console.log(`\n📎 Attachments: ${message.attachments.length} file(s)`);
|
|
136
|
+
message.attachments.forEach((att, i) => {
|
|
137
|
+
console.log(` ${i + 1}. ${att.filename} (${att.contentType})`);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
console.log('='.repeat(80) + '\n');
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Convert HTML to plain text (basic implementation)
|
|
144
|
+
*/
|
|
145
|
+
htmlToPlainText(html) {
|
|
146
|
+
return html
|
|
147
|
+
// Remove scripts and styles
|
|
148
|
+
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
|
149
|
+
.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '')
|
|
150
|
+
// Replace block elements with newlines
|
|
151
|
+
.replace(/<\/?(div|p|br|h[1-6]|li|tr)[^>]*>/gi, '\n')
|
|
152
|
+
// Remove all other HTML tags
|
|
153
|
+
.replace(/<[^>]+>/g, '')
|
|
154
|
+
// Decode HTML entities
|
|
155
|
+
.replace(/ /g, ' ')
|
|
156
|
+
.replace(/&/g, '&')
|
|
157
|
+
.replace(/</g, '<')
|
|
158
|
+
.replace(/>/g, '>')
|
|
159
|
+
.replace(/"/g, '"')
|
|
160
|
+
// Clean up whitespace
|
|
161
|
+
.replace(/\n\s*\n/g, '\n\n')
|
|
162
|
+
.trim();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Extract 2FA/verification code from email content
|
|
166
|
+
* Looks for 6-digit codes commonly used in 2FA
|
|
167
|
+
*/
|
|
168
|
+
extract2FACode(content) {
|
|
169
|
+
// Try to find 6-digit code in common patterns
|
|
170
|
+
const patterns = [
|
|
171
|
+
/\b(\d{6})\b/, // Simple 6 digits
|
|
172
|
+
/code.*?(\d{6})/i, // "code: 123456"
|
|
173
|
+
/verification.*?(\d{6})/i, // "verification code: 123456"
|
|
174
|
+
/login.*?code.*?(\d{6})/i, // "login code: 123456"
|
|
175
|
+
/<div[^>]*>(\d{6})<\/div>/i, // In a div
|
|
176
|
+
/font-size:\s*32px[^>]*>(\d{6})</i, // Large font (common for codes)
|
|
177
|
+
/letter-spacing[^>]*>(\d{6})</i // Letter-spaced (common for codes)
|
|
178
|
+
];
|
|
179
|
+
for (const pattern of patterns) {
|
|
180
|
+
const match = content.match(pattern);
|
|
181
|
+
if (match && match[1]) {
|
|
182
|
+
return match[1];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Simple delay helper
|
|
189
|
+
*/
|
|
190
|
+
delay(ms) {
|
|
191
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=MockEmailProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockEmailProvider.js","sourceRoot":"","sources":["../../src/providers/MockEmailProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IEmailProvider, EmailMessage, EmailResult, DeliveryReport, WebhookValidationResult, RedirectEmailConfig, WebhookValidationOptions } from '../interfaces/IEmailProvider.js';
|
|
2
|
+
/**
|
|
3
|
+
* RedirectEmailProvider wraps another provider and redirects all emails to a specific address.
|
|
4
|
+
* Useful for development/testing to prevent accidentally sending emails to real users.
|
|
5
|
+
*/
|
|
6
|
+
export declare class RedirectEmailProvider implements IEmailProvider {
|
|
7
|
+
private redirectTo;
|
|
8
|
+
private defaultFrom;
|
|
9
|
+
private addOriginalToSubject;
|
|
10
|
+
private baseProvider;
|
|
11
|
+
constructor(config: RedirectEmailConfig);
|
|
12
|
+
send(message: EmailMessage): Promise<EmailResult>;
|
|
13
|
+
getDeliveryReport(messageId: string): Promise<DeliveryReport | null>;
|
|
14
|
+
validateWebhook(payload: any, signature?: string, options?: WebhookValidationOptions): WebhookValidationResult;
|
|
15
|
+
/**
|
|
16
|
+
* Extract all original recipients from the message
|
|
17
|
+
*/
|
|
18
|
+
private getOriginalRecipients;
|
|
19
|
+
/**
|
|
20
|
+
* Add a notice to the email body about the redirection
|
|
21
|
+
*/
|
|
22
|
+
private addRedirectNotice;
|
|
23
|
+
/**
|
|
24
|
+
* Simple HTML escape for security
|
|
25
|
+
*/
|
|
26
|
+
private escapeHtml;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=RedirectEmailProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedirectEmailProvider.d.ts","sourceRoot":"","sources":["../../src/providers/RedirectEmailProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EAEnB,wBAAwB,EAC3B,MAAM,iCAAiC,CAAC;AAGzC;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IACxD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,oBAAoB,CAAU;IACtC,OAAO,CAAC,YAAY,CAAiB;gBAEzB,MAAM,EAAE,mBAAmB;IAWjC,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA4BjD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAI1E,eAAe,CACX,OAAO,EAAE,GAAG,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,wBAAwB,GACnC,uBAAuB;IAI1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;OAEG;IACH,OAAO,CAAC,UAAU;CAUrB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { MockEmailProvider } from './MockEmailProvider.js';
|
|
2
|
+
/**
|
|
3
|
+
* RedirectEmailProvider wraps another provider and redirects all emails to a specific address.
|
|
4
|
+
* Useful for development/testing to prevent accidentally sending emails to real users.
|
|
5
|
+
*/
|
|
6
|
+
export class RedirectEmailProvider {
|
|
7
|
+
redirectTo;
|
|
8
|
+
defaultFrom;
|
|
9
|
+
addOriginalToSubject;
|
|
10
|
+
baseProvider;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.redirectTo = config.redirectTo;
|
|
13
|
+
this.defaultFrom = config.defaultFrom;
|
|
14
|
+
this.addOriginalToSubject = config.addOriginalToSubject ?? true;
|
|
15
|
+
// Use provided base provider or default to MockEmailProvider
|
|
16
|
+
this.baseProvider = config.baseProvider || new MockEmailProvider({
|
|
17
|
+
defaultFrom: config.defaultFrom
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async send(message) {
|
|
21
|
+
// Build list of original recipients for logging
|
|
22
|
+
const originalRecipients = this.getOriginalRecipients(message);
|
|
23
|
+
// Create modified message that redirects to the configured address
|
|
24
|
+
const redirectedMessage = {
|
|
25
|
+
...message,
|
|
26
|
+
to: { address: this.redirectTo },
|
|
27
|
+
cc: undefined, // Clear CC
|
|
28
|
+
bcc: undefined, // Clear BCC
|
|
29
|
+
subject: this.addOriginalToSubject
|
|
30
|
+
? `[REDIRECTED] ${message.subject} (Original: ${originalRecipients})`
|
|
31
|
+
: message.subject
|
|
32
|
+
};
|
|
33
|
+
// Add original recipients info to the email body
|
|
34
|
+
if (message.html) {
|
|
35
|
+
redirectedMessage.html = this.addRedirectNotice(message.html, originalRecipients, 'html');
|
|
36
|
+
}
|
|
37
|
+
if (message.text) {
|
|
38
|
+
redirectedMessage.text = this.addRedirectNotice(message.text, originalRecipients, 'text');
|
|
39
|
+
}
|
|
40
|
+
// Send via base provider
|
|
41
|
+
return this.baseProvider.send(redirectedMessage);
|
|
42
|
+
}
|
|
43
|
+
async getDeliveryReport(messageId) {
|
|
44
|
+
return this.baseProvider.getDeliveryReport(messageId);
|
|
45
|
+
}
|
|
46
|
+
validateWebhook(payload, signature, options) {
|
|
47
|
+
return this.baseProvider.validateWebhook(payload, signature, options);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Extract all original recipients from the message
|
|
51
|
+
*/
|
|
52
|
+
getOriginalRecipients(message) {
|
|
53
|
+
const recipients = [];
|
|
54
|
+
// Add 'to' recipients
|
|
55
|
+
const toAddresses = Array.isArray(message.to) ? message.to : [message.to];
|
|
56
|
+
recipients.push(...toAddresses.map(addr => addr.address));
|
|
57
|
+
// Add CC recipients
|
|
58
|
+
if (message.cc && message.cc.length > 0) {
|
|
59
|
+
recipients.push(...message.cc.map(addr => `CC: ${addr.address}`));
|
|
60
|
+
}
|
|
61
|
+
// Add BCC recipients
|
|
62
|
+
if (message.bcc && message.bcc.length > 0) {
|
|
63
|
+
recipients.push(...message.bcc.map(addr => `BCC: ${addr.address}`));
|
|
64
|
+
}
|
|
65
|
+
return recipients.join(', ');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Add a notice to the email body about the redirection
|
|
69
|
+
*/
|
|
70
|
+
addRedirectNotice(content, originalRecipients, type) {
|
|
71
|
+
const notice = type === 'html'
|
|
72
|
+
? `
|
|
73
|
+
<div style="background-color: #fff3cd; border: 1px solid #ffc107; padding: 15px; margin-bottom: 20px; border-radius: 5px;">
|
|
74
|
+
<strong>⚠️ EMAIL REDIRECTED (Development Mode)</strong><br>
|
|
75
|
+
<p style="margin: 5px 0 0 0;">
|
|
76
|
+
This email was redirected from the original recipients:<br>
|
|
77
|
+
<strong>${this.escapeHtml(originalRecipients)}</strong>
|
|
78
|
+
</p>
|
|
79
|
+
</div>
|
|
80
|
+
${content}
|
|
81
|
+
`
|
|
82
|
+
: `
|
|
83
|
+
========================================
|
|
84
|
+
⚠️ EMAIL REDIRECTED (Development Mode)
|
|
85
|
+
========================================
|
|
86
|
+
This email was redirected from the original recipients:
|
|
87
|
+
${originalRecipients}
|
|
88
|
+
========================================
|
|
89
|
+
|
|
90
|
+
${content}
|
|
91
|
+
`;
|
|
92
|
+
return notice;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Simple HTML escape for security
|
|
96
|
+
*/
|
|
97
|
+
escapeHtml(text) {
|
|
98
|
+
const map = {
|
|
99
|
+
'&': '&',
|
|
100
|
+
'<': '<',
|
|
101
|
+
'>': '>',
|
|
102
|
+
'"': '"',
|
|
103
|
+
"'": '''
|
|
104
|
+
};
|
|
105
|
+
return text.replace(/[&<>"']/g, char => map[char]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=RedirectEmailProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedirectEmailProvider.js","sourceRoot":"","sources":["../../src/providers/RedirectEmailProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { IEmailProvider, EmailMessage, EmailResult, DeliveryReport, WebhookValidationResult, WebhookValidationOptions, SweegoEmailConfig } from '../interfaces/IEmailProvider.js';
|
|
2
|
+
export declare class SweegoEmailProvider implements IEmailProvider {
|
|
3
|
+
private readonly config;
|
|
4
|
+
private readonly apiKey?;
|
|
5
|
+
private readonly accessToken?;
|
|
6
|
+
private readonly baseUrl;
|
|
7
|
+
private readonly providerSlug;
|
|
8
|
+
private readonly defaultFrom;
|
|
9
|
+
private readonly channel;
|
|
10
|
+
private readonly clientId?;
|
|
11
|
+
private readonly webhookSecret?;
|
|
12
|
+
constructor(config: SweegoEmailConfig);
|
|
13
|
+
send(message: EmailMessage): Promise<EmailResult>;
|
|
14
|
+
getDeliveryReport(messageId: string): Promise<DeliveryReport | null>;
|
|
15
|
+
validateWebhook(payload: any, signature?: string, options?: WebhookValidationOptions): WebhookValidationResult;
|
|
16
|
+
private applyMetadata;
|
|
17
|
+
private applyContent;
|
|
18
|
+
private applyAttachments;
|
|
19
|
+
private encodeAttachmentContent;
|
|
20
|
+
private normalizeRecipients;
|
|
21
|
+
private normalizeAddress;
|
|
22
|
+
private extractSweegoMetadata;
|
|
23
|
+
private buildHeaders;
|
|
24
|
+
private extractSweegoIds;
|
|
25
|
+
private mapProviderStatus;
|
|
26
|
+
private mapWebhookPayload;
|
|
27
|
+
private extractSweegoUid;
|
|
28
|
+
private parseTimestamp;
|
|
29
|
+
private normalizeBaseUrl;
|
|
30
|
+
private safeParseResponse;
|
|
31
|
+
private extractProviderError;
|
|
32
|
+
private normalizeHeaders;
|
|
33
|
+
private stringifyPayload;
|
|
34
|
+
private parseWebhookSecret;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=SweegoEmailProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SweegoEmailProvider.d.ts","sourceRoot":"","sources":["../../src/providers/SweegoEmailProvider.ts"],"names":[],"mappings":"AACA,OAAO,EACH,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EAIpB,MAAM,iCAAiC,CAAC;AAmBzC,qBAAa,mBAAoB,YAAW,cAAc;IAU1C,OAAO,CAAC,QAAQ,CAAC,MAAM;IATnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;gBAEX,MAAM,EAAE,iBAAiB;IAgBhD,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA0EjD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAgC1E,eAAe,CACX,OAAO,EAAE,GAAG,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,wBAAwB,GACnC,uBAAuB;IAsC1B,OAAO,CAAC,aAAa;IAwCrB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,YAAY;IAsBpB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,kBAAkB;CAW7B"}
|