@skoolite/notify-hub 0.1.0 → 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/dist/index.d.mts +48 -13
- package/dist/index.d.ts +48 -13
- package/dist/index.js +210 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +210 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -337,20 +337,15 @@ interface MetaWhatsAppConfig {
|
|
|
337
337
|
webhookVerifyToken?: string;
|
|
338
338
|
}
|
|
339
339
|
/**
|
|
340
|
-
*
|
|
340
|
+
* Resend email provider configuration
|
|
341
341
|
*/
|
|
342
|
-
interface
|
|
343
|
-
/**
|
|
344
|
-
|
|
345
|
-
/** Default from address */
|
|
342
|
+
interface ResendConfig {
|
|
343
|
+
/** Resend API key */
|
|
344
|
+
apiKey: string;
|
|
345
|
+
/** Default from address (must be verified domain) */
|
|
346
346
|
fromAddress: string;
|
|
347
347
|
/** Default from name */
|
|
348
348
|
fromName?: string;
|
|
349
|
-
/** AWS credentials (optional, will use default credential chain) */
|
|
350
|
-
credentials?: {
|
|
351
|
-
accessKeyId: string;
|
|
352
|
-
secretAccessKey: string;
|
|
353
|
-
};
|
|
354
349
|
}
|
|
355
350
|
/**
|
|
356
351
|
* Provider-specific configuration union
|
|
@@ -373,8 +368,8 @@ type WhatsAppProviderConfig = {
|
|
|
373
368
|
instance: WhatsAppProvider;
|
|
374
369
|
};
|
|
375
370
|
type EmailProviderConfig = {
|
|
376
|
-
provider: '
|
|
377
|
-
config:
|
|
371
|
+
provider: 'resend';
|
|
372
|
+
config: ResendConfig;
|
|
378
373
|
} | {
|
|
379
374
|
provider: 'custom';
|
|
380
375
|
instance: EmailProvider;
|
|
@@ -825,6 +820,46 @@ declare class MetaWhatsAppProvider implements WhatsAppProvider {
|
|
|
825
820
|
destroy(): Promise<void>;
|
|
826
821
|
}
|
|
827
822
|
|
|
823
|
+
/**
|
|
824
|
+
* Resend email provider implementation
|
|
825
|
+
* @see https://resend.com/docs/api-reference/emails/send-email
|
|
826
|
+
*/
|
|
827
|
+
declare class ResendEmailProvider implements EmailProvider {
|
|
828
|
+
readonly name = "resend";
|
|
829
|
+
private readonly config;
|
|
830
|
+
private readonly logger?;
|
|
831
|
+
private readonly retryConfig;
|
|
832
|
+
private readonly baseUrl;
|
|
833
|
+
constructor(config: ResendConfig, options?: {
|
|
834
|
+
logger?: Logger;
|
|
835
|
+
retryConfig?: RetryConfig;
|
|
836
|
+
});
|
|
837
|
+
/**
|
|
838
|
+
* Initialize the provider (no-op for Resend, uses REST API)
|
|
839
|
+
*/
|
|
840
|
+
initialize(): Promise<void>;
|
|
841
|
+
/**
|
|
842
|
+
* Build the "from" field with optional name
|
|
843
|
+
*/
|
|
844
|
+
private buildFrom;
|
|
845
|
+
/**
|
|
846
|
+
* Send an email
|
|
847
|
+
*/
|
|
848
|
+
send(to: string, email: EmailMessage, options?: EmailOptions): Promise<SendResult>;
|
|
849
|
+
/**
|
|
850
|
+
* Send bulk emails using Resend batch API
|
|
851
|
+
*/
|
|
852
|
+
sendBulk(messages: EmailMessageWithRecipient[], options?: BulkOptions): Promise<BulkResult>;
|
|
853
|
+
/**
|
|
854
|
+
* Basic email validation
|
|
855
|
+
*/
|
|
856
|
+
private isValidEmail;
|
|
857
|
+
/**
|
|
858
|
+
* Cleanup resources
|
|
859
|
+
*/
|
|
860
|
+
destroy(): Promise<void>;
|
|
861
|
+
}
|
|
862
|
+
|
|
828
863
|
/**
|
|
829
864
|
* Twilio webhook payload for message status updates
|
|
830
865
|
*/
|
|
@@ -1077,4 +1112,4 @@ declare function getPakistanNetwork(phone: string): 'jazz' | 'telenor' | 'zong'
|
|
|
1077
1112
|
*/
|
|
1078
1113
|
declare function routeByPrefix(phone: string, routing: Record<string, 'primary' | 'fallback'>): 'primary' | 'fallback';
|
|
1079
1114
|
|
|
1080
|
-
export { BaseLocalSmsProvider, type BaseProvider, type BulkOptions, type BulkResult, type BulkSummary, type Channel, type Cost, DEFAULT_RETRY_CONFIG, type EmailAttachment, type EmailMessage, type EmailMessageWithRecipient, type EmailOptions, type EmailProvider, type EmailProviderConfig, type IncomingMessageEvent, JazzSmsProvider, type LocalSmsConfig, type Logger, type MessageStatus, type MetaWhatsAppConfig, MetaWhatsAppProvider, type Notification, type NotifyError, NotifyHub, type NotifyHubConfig, type RateLimitConfig, type
|
|
1115
|
+
export { BaseLocalSmsProvider, type BaseProvider, type BulkOptions, type BulkResult, type BulkSummary, type Channel, type Cost, DEFAULT_RETRY_CONFIG, type EmailAttachment, type EmailMessage, type EmailMessageWithRecipient, type EmailOptions, type EmailProvider, type EmailProviderConfig, type IncomingMessageEvent, JazzSmsProvider, type LocalSmsConfig, type Logger, type MessageStatus, type MetaWhatsAppConfig, MetaWhatsAppProvider, type Notification, type NotifyError, NotifyHub, type NotifyHubConfig, type RateLimitConfig, type ResendConfig, ResendEmailProvider, type RetryConfig, type RoutingConfig, type SendResult, type SmsChannelConfig, type SmsMessage, type SmsOptions, type SmsProvider, type SmsProviderConfig, type StatusWebhookEvent, TelenorSmsProvider, type TwilioConfig, TwilioSmsProvider, TwilioWebhookHandler, type WebhookEvent, type WebhookHandler, type WhatsAppMessage, type WhatsAppOptions, type WhatsAppProvider, type WhatsAppProviderConfig, type WhatsAppTemplate, type WhatsAppTemplateButton, type WhatsAppTemplateHeader, WhatsAppWebhookHandler, ZongSmsProvider, calculateBackoff, cleanPhoneNumber, createNotifyError, createTwilioWebhookHandler, createWhatsAppWebhookHandler, getCallingCode, getCountryCode, getPakistanNetwork, isCountry, isPakistanMobile, isRetriableError, routeByPrefix, toE164, validatePhoneNumber, withRetry };
|
package/dist/index.d.ts
CHANGED
|
@@ -337,20 +337,15 @@ interface MetaWhatsAppConfig {
|
|
|
337
337
|
webhookVerifyToken?: string;
|
|
338
338
|
}
|
|
339
339
|
/**
|
|
340
|
-
*
|
|
340
|
+
* Resend email provider configuration
|
|
341
341
|
*/
|
|
342
|
-
interface
|
|
343
|
-
/**
|
|
344
|
-
|
|
345
|
-
/** Default from address */
|
|
342
|
+
interface ResendConfig {
|
|
343
|
+
/** Resend API key */
|
|
344
|
+
apiKey: string;
|
|
345
|
+
/** Default from address (must be verified domain) */
|
|
346
346
|
fromAddress: string;
|
|
347
347
|
/** Default from name */
|
|
348
348
|
fromName?: string;
|
|
349
|
-
/** AWS credentials (optional, will use default credential chain) */
|
|
350
|
-
credentials?: {
|
|
351
|
-
accessKeyId: string;
|
|
352
|
-
secretAccessKey: string;
|
|
353
|
-
};
|
|
354
349
|
}
|
|
355
350
|
/**
|
|
356
351
|
* Provider-specific configuration union
|
|
@@ -373,8 +368,8 @@ type WhatsAppProviderConfig = {
|
|
|
373
368
|
instance: WhatsAppProvider;
|
|
374
369
|
};
|
|
375
370
|
type EmailProviderConfig = {
|
|
376
|
-
provider: '
|
|
377
|
-
config:
|
|
371
|
+
provider: 'resend';
|
|
372
|
+
config: ResendConfig;
|
|
378
373
|
} | {
|
|
379
374
|
provider: 'custom';
|
|
380
375
|
instance: EmailProvider;
|
|
@@ -825,6 +820,46 @@ declare class MetaWhatsAppProvider implements WhatsAppProvider {
|
|
|
825
820
|
destroy(): Promise<void>;
|
|
826
821
|
}
|
|
827
822
|
|
|
823
|
+
/**
|
|
824
|
+
* Resend email provider implementation
|
|
825
|
+
* @see https://resend.com/docs/api-reference/emails/send-email
|
|
826
|
+
*/
|
|
827
|
+
declare class ResendEmailProvider implements EmailProvider {
|
|
828
|
+
readonly name = "resend";
|
|
829
|
+
private readonly config;
|
|
830
|
+
private readonly logger?;
|
|
831
|
+
private readonly retryConfig;
|
|
832
|
+
private readonly baseUrl;
|
|
833
|
+
constructor(config: ResendConfig, options?: {
|
|
834
|
+
logger?: Logger;
|
|
835
|
+
retryConfig?: RetryConfig;
|
|
836
|
+
});
|
|
837
|
+
/**
|
|
838
|
+
* Initialize the provider (no-op for Resend, uses REST API)
|
|
839
|
+
*/
|
|
840
|
+
initialize(): Promise<void>;
|
|
841
|
+
/**
|
|
842
|
+
* Build the "from" field with optional name
|
|
843
|
+
*/
|
|
844
|
+
private buildFrom;
|
|
845
|
+
/**
|
|
846
|
+
* Send an email
|
|
847
|
+
*/
|
|
848
|
+
send(to: string, email: EmailMessage, options?: EmailOptions): Promise<SendResult>;
|
|
849
|
+
/**
|
|
850
|
+
* Send bulk emails using Resend batch API
|
|
851
|
+
*/
|
|
852
|
+
sendBulk(messages: EmailMessageWithRecipient[], options?: BulkOptions): Promise<BulkResult>;
|
|
853
|
+
/**
|
|
854
|
+
* Basic email validation
|
|
855
|
+
*/
|
|
856
|
+
private isValidEmail;
|
|
857
|
+
/**
|
|
858
|
+
* Cleanup resources
|
|
859
|
+
*/
|
|
860
|
+
destroy(): Promise<void>;
|
|
861
|
+
}
|
|
862
|
+
|
|
828
863
|
/**
|
|
829
864
|
* Twilio webhook payload for message status updates
|
|
830
865
|
*/
|
|
@@ -1077,4 +1112,4 @@ declare function getPakistanNetwork(phone: string): 'jazz' | 'telenor' | 'zong'
|
|
|
1077
1112
|
*/
|
|
1078
1113
|
declare function routeByPrefix(phone: string, routing: Record<string, 'primary' | 'fallback'>): 'primary' | 'fallback';
|
|
1079
1114
|
|
|
1080
|
-
export { BaseLocalSmsProvider, type BaseProvider, type BulkOptions, type BulkResult, type BulkSummary, type Channel, type Cost, DEFAULT_RETRY_CONFIG, type EmailAttachment, type EmailMessage, type EmailMessageWithRecipient, type EmailOptions, type EmailProvider, type EmailProviderConfig, type IncomingMessageEvent, JazzSmsProvider, type LocalSmsConfig, type Logger, type MessageStatus, type MetaWhatsAppConfig, MetaWhatsAppProvider, type Notification, type NotifyError, NotifyHub, type NotifyHubConfig, type RateLimitConfig, type
|
|
1115
|
+
export { BaseLocalSmsProvider, type BaseProvider, type BulkOptions, type BulkResult, type BulkSummary, type Channel, type Cost, DEFAULT_RETRY_CONFIG, type EmailAttachment, type EmailMessage, type EmailMessageWithRecipient, type EmailOptions, type EmailProvider, type EmailProviderConfig, type IncomingMessageEvent, JazzSmsProvider, type LocalSmsConfig, type Logger, type MessageStatus, type MetaWhatsAppConfig, MetaWhatsAppProvider, type Notification, type NotifyError, NotifyHub, type NotifyHubConfig, type RateLimitConfig, type ResendConfig, ResendEmailProvider, type RetryConfig, type RoutingConfig, type SendResult, type SmsChannelConfig, type SmsMessage, type SmsOptions, type SmsProvider, type SmsProviderConfig, type StatusWebhookEvent, TelenorSmsProvider, type TwilioConfig, TwilioSmsProvider, TwilioWebhookHandler, type WebhookEvent, type WebhookHandler, type WhatsAppMessage, type WhatsAppOptions, type WhatsAppProvider, type WhatsAppProviderConfig, type WhatsAppTemplate, type WhatsAppTemplateButton, type WhatsAppTemplateHeader, WhatsAppWebhookHandler, ZongSmsProvider, calculateBackoff, cleanPhoneNumber, createNotifyError, createTwilioWebhookHandler, createWhatsAppWebhookHandler, getCallingCode, getCountryCode, getPakistanNetwork, isCountry, isPakistanMobile, isRetriableError, routeByPrefix, toE164, validatePhoneNumber, withRetry };
|
package/dist/index.js
CHANGED
|
@@ -975,6 +975,207 @@ var MetaWhatsAppProvider = class {
|
|
|
975
975
|
}
|
|
976
976
|
};
|
|
977
977
|
|
|
978
|
+
// src/providers/email/resend.provider.ts
|
|
979
|
+
var ResendEmailProvider = class {
|
|
980
|
+
name = "resend";
|
|
981
|
+
config;
|
|
982
|
+
logger;
|
|
983
|
+
retryConfig;
|
|
984
|
+
baseUrl = "https://api.resend.com";
|
|
985
|
+
constructor(config, options) {
|
|
986
|
+
this.config = config;
|
|
987
|
+
this.logger = options?.logger;
|
|
988
|
+
this.retryConfig = options?.retryConfig ?? DEFAULT_RETRY_CONFIG;
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Initialize the provider (no-op for Resend, uses REST API)
|
|
992
|
+
*/
|
|
993
|
+
async initialize() {
|
|
994
|
+
this.logger?.debug("ResendEmailProvider initialized");
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Build the "from" field with optional name
|
|
998
|
+
*/
|
|
999
|
+
buildFrom(options) {
|
|
1000
|
+
const name = options?.fromName ?? this.config.fromName;
|
|
1001
|
+
const address = options?.from ?? this.config.fromAddress;
|
|
1002
|
+
if (name) {
|
|
1003
|
+
return `${name} <${address}>`;
|
|
1004
|
+
}
|
|
1005
|
+
return address;
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Send an email
|
|
1009
|
+
*/
|
|
1010
|
+
async send(to, email, options) {
|
|
1011
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
1012
|
+
if (!this.isValidEmail(to)) {
|
|
1013
|
+
return {
|
|
1014
|
+
success: false,
|
|
1015
|
+
channel: "email",
|
|
1016
|
+
status: "failed",
|
|
1017
|
+
provider: this.name,
|
|
1018
|
+
error: {
|
|
1019
|
+
code: "INVALID_EMAIL",
|
|
1020
|
+
message: `Invalid email address: ${to}`,
|
|
1021
|
+
retriable: false
|
|
1022
|
+
},
|
|
1023
|
+
timestamp,
|
|
1024
|
+
metadata: options?.metadata
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
if (!email.body && !email.html) {
|
|
1028
|
+
return {
|
|
1029
|
+
success: false,
|
|
1030
|
+
channel: "email",
|
|
1031
|
+
status: "failed",
|
|
1032
|
+
provider: this.name,
|
|
1033
|
+
error: {
|
|
1034
|
+
code: "INVALID_EMAIL_CONTENT",
|
|
1035
|
+
message: "Email must have either body or html content",
|
|
1036
|
+
retriable: false
|
|
1037
|
+
},
|
|
1038
|
+
timestamp,
|
|
1039
|
+
metadata: options?.metadata
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
this.logger?.debug(`Sending email to ${to}`);
|
|
1043
|
+
const result = await withRetry(
|
|
1044
|
+
async () => {
|
|
1045
|
+
const payload = {
|
|
1046
|
+
from: this.buildFrom(options),
|
|
1047
|
+
to: [to],
|
|
1048
|
+
subject: email.subject
|
|
1049
|
+
};
|
|
1050
|
+
if (email.html) {
|
|
1051
|
+
payload.html = email.html;
|
|
1052
|
+
}
|
|
1053
|
+
if (email.body) {
|
|
1054
|
+
payload.text = email.body;
|
|
1055
|
+
}
|
|
1056
|
+
if (options?.replyTo) {
|
|
1057
|
+
payload.reply_to = options.replyTo;
|
|
1058
|
+
}
|
|
1059
|
+
if (options?.cc?.length) {
|
|
1060
|
+
payload.cc = options.cc;
|
|
1061
|
+
}
|
|
1062
|
+
if (options?.bcc?.length) {
|
|
1063
|
+
payload.bcc = options.bcc;
|
|
1064
|
+
}
|
|
1065
|
+
if (email.attachments?.length) {
|
|
1066
|
+
payload.attachments = email.attachments.map((att) => ({
|
|
1067
|
+
filename: att.filename,
|
|
1068
|
+
content: typeof att.content === "string" ? att.content : att.content.toString("base64"),
|
|
1069
|
+
content_type: att.contentType
|
|
1070
|
+
}));
|
|
1071
|
+
}
|
|
1072
|
+
const response = await fetch(`${this.baseUrl}/emails`, {
|
|
1073
|
+
method: "POST",
|
|
1074
|
+
headers: {
|
|
1075
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
1076
|
+
"Content-Type": "application/json"
|
|
1077
|
+
},
|
|
1078
|
+
body: JSON.stringify(payload)
|
|
1079
|
+
});
|
|
1080
|
+
if (!response.ok) {
|
|
1081
|
+
const errorData = await response.json();
|
|
1082
|
+
const error = new Error(errorData.message);
|
|
1083
|
+
error.statusCode = response.status;
|
|
1084
|
+
throw error;
|
|
1085
|
+
}
|
|
1086
|
+
return await response.json();
|
|
1087
|
+
},
|
|
1088
|
+
this.retryConfig
|
|
1089
|
+
);
|
|
1090
|
+
if (result.success && result.value) {
|
|
1091
|
+
this.logger?.info(`Email sent successfully: ${result.value.id}`);
|
|
1092
|
+
return {
|
|
1093
|
+
success: true,
|
|
1094
|
+
messageId: result.value.id,
|
|
1095
|
+
channel: "email",
|
|
1096
|
+
status: "sent",
|
|
1097
|
+
provider: this.name,
|
|
1098
|
+
timestamp,
|
|
1099
|
+
metadata: options?.metadata
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
this.logger?.error(`Email send failed: ${result.error?.message}`);
|
|
1103
|
+
return {
|
|
1104
|
+
success: false,
|
|
1105
|
+
channel: "email",
|
|
1106
|
+
status: "failed",
|
|
1107
|
+
provider: this.name,
|
|
1108
|
+
error: createNotifyError(result.error, "RESEND_ERROR"),
|
|
1109
|
+
timestamp,
|
|
1110
|
+
metadata: options?.metadata
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
/**
|
|
1114
|
+
* Send bulk emails using Resend batch API
|
|
1115
|
+
*/
|
|
1116
|
+
async sendBulk(messages, options) {
|
|
1117
|
+
const startTime = Date.now();
|
|
1118
|
+
const results = [];
|
|
1119
|
+
let sent = 0;
|
|
1120
|
+
let failed = 0;
|
|
1121
|
+
const batchSize = Math.min(options?.concurrency ?? 100, 100);
|
|
1122
|
+
for (let i = 0; i < messages.length; i += batchSize) {
|
|
1123
|
+
const batch = messages.slice(i, i + batchSize);
|
|
1124
|
+
const batchResults = await Promise.all(
|
|
1125
|
+
batch.map(
|
|
1126
|
+
(msg) => this.send(msg.to, msg, { metadata: msg.metadata })
|
|
1127
|
+
)
|
|
1128
|
+
);
|
|
1129
|
+
for (const result of batchResults) {
|
|
1130
|
+
results.push(result);
|
|
1131
|
+
if (result.success) {
|
|
1132
|
+
sent++;
|
|
1133
|
+
} else {
|
|
1134
|
+
failed++;
|
|
1135
|
+
if (options?.stopOnError) {
|
|
1136
|
+
return {
|
|
1137
|
+
results,
|
|
1138
|
+
summary: {
|
|
1139
|
+
total: messages.length,
|
|
1140
|
+
sent,
|
|
1141
|
+
failed,
|
|
1142
|
+
durationMs: Date.now() - startTime
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
options?.onProgress?.(sent + failed, messages.length);
|
|
1149
|
+
if (i + batchSize < messages.length && options?.rateLimit) {
|
|
1150
|
+
const delayMs = Math.ceil(1e3 / options.rateLimit.messagesPerSecond) * batchSize;
|
|
1151
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
return {
|
|
1155
|
+
results,
|
|
1156
|
+
summary: {
|
|
1157
|
+
total: messages.length,
|
|
1158
|
+
sent,
|
|
1159
|
+
failed,
|
|
1160
|
+
durationMs: Date.now() - startTime
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Basic email validation
|
|
1166
|
+
*/
|
|
1167
|
+
isValidEmail(email) {
|
|
1168
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1169
|
+
return emailRegex.test(email);
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Cleanup resources
|
|
1173
|
+
*/
|
|
1174
|
+
async destroy() {
|
|
1175
|
+
this.logger?.debug("ResendEmailProvider destroyed");
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
|
|
978
1179
|
// src/notify-hub.ts
|
|
979
1180
|
var noopLogger = {
|
|
980
1181
|
debug: () => void 0,
|
|
@@ -1096,8 +1297,14 @@ var NotifyHub = class {
|
|
|
1096
1297
|
if (config.provider === "custom" && config.instance) {
|
|
1097
1298
|
return config.instance;
|
|
1098
1299
|
}
|
|
1099
|
-
if (config.provider === "
|
|
1100
|
-
|
|
1300
|
+
if (config.provider === "resend") {
|
|
1301
|
+
const resendConfig = config.config;
|
|
1302
|
+
const provider = new ResendEmailProvider(resendConfig, {
|
|
1303
|
+
logger: this.logger,
|
|
1304
|
+
retryConfig: this.retryConfig
|
|
1305
|
+
});
|
|
1306
|
+
await provider.initialize();
|
|
1307
|
+
return provider;
|
|
1101
1308
|
}
|
|
1102
1309
|
throw new Error(`Unknown email provider: ${config.provider}`);
|
|
1103
1310
|
}
|
|
@@ -1668,6 +1875,7 @@ exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
|
|
|
1668
1875
|
exports.JazzSmsProvider = JazzSmsProvider;
|
|
1669
1876
|
exports.MetaWhatsAppProvider = MetaWhatsAppProvider;
|
|
1670
1877
|
exports.NotifyHub = NotifyHub;
|
|
1878
|
+
exports.ResendEmailProvider = ResendEmailProvider;
|
|
1671
1879
|
exports.TelenorSmsProvider = TelenorSmsProvider;
|
|
1672
1880
|
exports.TwilioSmsProvider = TwilioSmsProvider;
|
|
1673
1881
|
exports.TwilioWebhookHandler = TwilioWebhookHandler;
|