@visulima/email 1.0.0-alpha.1 → 1.0.0-alpha.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.
- package/CHANGELOG.md +31 -0
- package/README.md +377 -60
- package/dist/crypto/index.js +1 -1
- package/dist/draft-mail-message.d.ts +13 -0
- package/dist/index.d.ts +3 -16
- package/dist/index.js +1 -1
- package/dist/mail-message.d.ts +425 -0
- package/dist/mail.d.ts +124 -275
- package/dist/packem_shared/{DkimSigner-Z8D4Il10.js → DkimSigner-pFd4c3fZ.js} +1 -1
- package/dist/packem_shared/Mail-6Bltpy_p.js +1 -0
- package/dist/packem_shared/MailMessage-B76GPBBA.js +1 -0
- package/dist/packem_shared/{SmimeSigner-02aXVi90.js → SmimeSigner-CObA4jzT.js} +1 -1
- package/dist/packem_shared/ahaSendProvider-DlFKEQ6D.js +1 -0
- package/dist/packem_shared/{awsSesProvider-CkuFOzb0.js → awsSesProvider-Ba-eVJxZ.js} +6 -6
- package/dist/packem_shared/azureProvider-CQYAkgVF.js +1 -0
- package/dist/packem_shared/brevoProvider-5p6jjiK9.js +1 -0
- package/dist/packem_shared/build-mime-message-IYaUqqPJ.js +2 -0
- package/dist/packem_shared/create-logger-BiWdqFNg.js +1 -0
- package/dist/packem_shared/failoverProvider-CAHQQueo.js +1 -0
- package/dist/packem_shared/{generateBoundary-CZ8kJuY6.js → generate-boundary-Cx8nXYS0.js} +1 -1
- package/dist/packem_shared/{generateMessageId-11Ls5JsR.js → generate-message-id-D4uA8gkj.js} +1 -1
- package/dist/packem_shared/headers-to-record-Qo124ImV.js +1 -0
- package/dist/packem_shared/httpProvider-CZD6LZX3.js +1 -0
- package/dist/packem_shared/infobipProvider-CtLwrUaP.js +1 -0
- package/dist/packem_shared/{mailCrabProvider-BEwRjB3F.js → mailCrabProvider-CM_CFDca.js} +1 -1
- package/dist/packem_shared/mailPaceProvider-B6yKvh6z.js +1 -0
- package/dist/packem_shared/mailerSendProvider-CeeIXFnW.js +1 -0
- package/dist/packem_shared/mailgunProvider-mmjKzouh.js +1 -0
- package/dist/packem_shared/mailjetProvider-DwN6i0VA.js +1 -0
- package/dist/packem_shared/mailomatProvider-DMQmjKHT.js +1 -0
- package/dist/packem_shared/mailtrapProvider-BN3UBEQw.js +1 -0
- package/dist/packem_shared/{makeRequest-DwxHX0xo.js → make-request-BDzF9W9D.js} +1 -1
- package/dist/packem_shared/mandrillProvider-370y7CLu.js +1 -0
- package/dist/packem_shared/mockProvider-DN5ZwutD.js +1 -0
- package/dist/packem_shared/nodemailerProvider-_w8QXMU-.js +1 -0
- package/dist/packem_shared/opentelemetryProvider-C_ZXOLSd.js +1 -0
- package/dist/packem_shared/plunkProvider-DfJumQ4U.js +1 -0
- package/dist/packem_shared/postalProvider-Bavx2FcH.js +1 -0
- package/dist/packem_shared/postmarkProvider-DFC0uvjO.js +1 -0
- package/dist/packem_shared/provider-base-Cmzx6BTO.js +1 -0
- package/dist/packem_shared/resendProvider-CfqU7UdE.js +1 -0
- package/dist/packem_shared/roundRobinProvider-1WQnuKR8.js +1 -0
- package/dist/packem_shared/scalewayProvider-be1HPimL.js +1 -0
- package/dist/packem_shared/sendGridProvider-BVI1sq3n.js +1 -0
- package/dist/packem_shared/smtpProvider-BV-ufR53.js +23 -0
- package/dist/packem_shared/sweegoProvider-7419CSAq.js +1 -0
- package/dist/packem_shared/validate-email-options-DfJ7llf8.js +1 -0
- package/dist/packem_shared/zeptomailProvider-C2lh0Xmo.js +1 -0
- package/dist/providers/ahasend/index.js +1 -1
- package/dist/providers/aws-ses/index.js +1 -1
- package/dist/providers/azure/index.js +1 -1
- package/dist/providers/brevo/index.js +1 -1
- package/dist/providers/brevo/types.d.ts +10 -3
- package/dist/providers/failover/index.js +1 -1
- package/dist/providers/http/index.js +1 -1
- package/dist/providers/infobip/index.js +1 -1
- package/dist/providers/mailcrab/index.js +1 -1
- package/dist/providers/mailersend/index.js +1 -1
- package/dist/providers/mailgun/index.js +1 -1
- package/dist/providers/mailjet/index.js +1 -1
- package/dist/providers/mailomat/index.js +1 -1
- package/dist/providers/mailpace/index.js +1 -1
- package/dist/providers/mailtrap/index.js +1 -1
- package/dist/providers/mandrill/index.js +1 -1
- package/dist/providers/mock/index.js +1 -1
- package/dist/providers/nodemailer/index.js +1 -1
- package/dist/providers/opentelemetry/index.js +1 -1
- package/dist/providers/plunk/index.js +1 -1
- package/dist/providers/postal/index.js +1 -1
- package/dist/providers/postmark/index.js +1 -1
- package/dist/providers/resend/index.js +1 -1
- package/dist/providers/roundrobin/index.js +1 -1
- package/dist/providers/scaleway/index.js +1 -1
- package/dist/providers/sendgrid/index.js +1 -1
- package/dist/providers/smtp/index.js +1 -1
- package/dist/providers/sweego/index.js +1 -1
- package/dist/providers/zeptomail/index.js +1 -1
- package/dist/types.d.ts +18 -0
- package/dist/utils/cache.d.ts +54 -0
- package/dist/utils/cache.js +1 -0
- package/dist/utils/create-logger.d.ts +2 -4
- package/dist/utils/format-email-address.js +1 -0
- package/dist/utils/normalize-email-aliases.d.ts +22 -0
- package/dist/utils/normalize-email-aliases.js +1 -0
- package/dist/utils/parse-address.js +1 -0
- package/dist/utils/validation/check-mx-records.d.ts +42 -0
- package/dist/utils/validation/check-mx-records.js +1 -0
- package/dist/utils/validation/disposable-email-domains.d.ts +13 -0
- package/dist/utils/validation/disposable-email-domains.js +1 -0
- package/dist/utils/validation/role-accounts.d.ts +21 -0
- package/dist/utils/validation/role-accounts.js +1 -0
- package/dist/utils/{validate-email-options.d.ts → validation/validate-email-options.d.ts} +1 -1
- package/dist/utils/validation/verify-email.d.ts +47 -0
- package/dist/utils/validation/verify-email.js +1 -0
- package/dist/utils/validation/verify-smtp.d.ts +39 -0
- package/dist/utils/validation/verify-smtp.js +4 -0
- package/package.json +47 -1
- package/dist/packem_shared/MailMessage-Hdgowmvi.js +0 -1
- package/dist/packem_shared/ahaSendProvider-NUD_kwyT.js +0 -1
- package/dist/packem_shared/azureProvider-Ckdrpmw9.js +0 -1
- package/dist/packem_shared/brevoProvider-CB3IYW4n.js +0 -1
- package/dist/packem_shared/buildMimeMessage-BPtd0pno.js +0 -2
- package/dist/packem_shared/comparePriority-BfiwjVsV.js +0 -1
- package/dist/packem_shared/createLogger-DlElSVQP.js +0 -1
- package/dist/packem_shared/failoverProvider-sam9n1AG.js +0 -1
- package/dist/packem_shared/formatEmailAddress-CHeME3Vk.js +0 -1
- package/dist/packem_shared/formatEmailAddresses-UegVOe5A.js +0 -1
- package/dist/packem_shared/headersToRecord-BKUTr40L.js +0 -1
- package/dist/packem_shared/httpProvider-BhN0RrK-.js +0 -1
- package/dist/packem_shared/infobipProvider-D8vYTHV4.js +0 -1
- package/dist/packem_shared/isPortAvailable-5kfsfo8u.js +0 -1
- package/dist/packem_shared/mailPaceProvider-C47Izgaj.js +0 -1
- package/dist/packem_shared/mailerSendProvider-C4uAo-fc.js +0 -1
- package/dist/packem_shared/mailgunProvider-B7upu_OV.js +0 -1
- package/dist/packem_shared/mailjetProvider-ReErm08u.js +0 -1
- package/dist/packem_shared/mailomatProvider-OlCT_O2i.js +0 -1
- package/dist/packem_shared/mailtrapProvider-hVMV3h6r.js +0 -1
- package/dist/packem_shared/mandrillProvider-DdnbkHZI.js +0 -1
- package/dist/packem_shared/mockProvider-BDWZJpea.js +0 -1
- package/dist/packem_shared/nodemailerProvider-BV21eRGX.js +0 -1
- package/dist/packem_shared/opentelemetryProvider-kAz62mKm.js +0 -1
- package/dist/packem_shared/parseAddress-CATTKGe_.js +0 -1
- package/dist/packem_shared/plunkProvider-Bs6K51lT.js +0 -1
- package/dist/packem_shared/postalProvider-Bcsxp-z6.js +0 -1
- package/dist/packem_shared/postmarkProvider-BUq3wuYD.js +0 -1
- package/dist/packem_shared/provider-base-_hbWXBdK.js +0 -1
- package/dist/packem_shared/resendProvider-D-_HQpN_.js +0 -1
- package/dist/packem_shared/retry-D1MBqS49.js +0 -1
- package/dist/packem_shared/roundRobinProvider-CejLM1rZ.js +0 -1
- package/dist/packem_shared/scalewayProvider-1n6ePiGl.js +0 -1
- package/dist/packem_shared/sendGridProvider-B1T62dyX.js +0 -1
- package/dist/packem_shared/smtpProvider-CcAoRrkt.js +0 -23
- package/dist/packem_shared/sweegoProvider-CxFmEUh6.js +0 -1
- package/dist/packem_shared/validateEmailOptions-BzlJECG5.js +0 -1
- package/dist/packem_shared/zeptomailProvider-CWYQPAJk.js +0 -1
- package/dist/utils/compare-priority.d.ts +0 -16
- /package/dist/utils/{validate-email.d.ts → validation/validate-email.d.ts} +0 -0
- /package/dist/{packem_shared/validateEmail-BkVdVioP.js → utils/validation/validate-email.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as o}from"../../packem_shared/plunkProvider-
|
|
1
|
+
import{default as o}from"../../packem_shared/plunkProvider-DfJumQ4U.js";export{o as plunkProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as a}from"../../packem_shared/postalProvider-
|
|
1
|
+
import{default as a}from"../../packem_shared/postalProvider-Bavx2FcH.js";export{a as postalProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as a}from"../../packem_shared/postmarkProvider-
|
|
1
|
+
import{default as a}from"../../packem_shared/postmarkProvider-DFC0uvjO.js";export{a as postmarkProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as d}from"../../packem_shared/resendProvider-
|
|
1
|
+
import{default as d}from"../../packem_shared/resendProvider-CfqU7UdE.js";export{d as resendProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as d}from"../../packem_shared/roundRobinProvider-
|
|
1
|
+
import{default as d}from"../../packem_shared/roundRobinProvider-1WQnuKR8.js";export{d as roundRobinProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as r}from"../../packem_shared/scalewayProvider-
|
|
1
|
+
import{default as r}from"../../packem_shared/scalewayProvider-be1HPimL.js";export{r as scalewayProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as e}from"../../packem_shared/sendGridProvider-
|
|
1
|
+
import{default as e}from"../../packem_shared/sendGridProvider-BVI1sq3n.js";export{e as sendGridProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as o}from"../../packem_shared/smtpProvider-
|
|
1
|
+
import{default as o}from"../../packem_shared/smtpProvider-BV-ufR53.js";export{o as smtpProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as r}from"../../packem_shared/sweegoProvider-
|
|
1
|
+
import{default as r}from"../../packem_shared/sweegoProvider-7419CSAq.js";export{r as sweegoProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as r}from"../../packem_shared/zeptomailProvider-
|
|
1
|
+
import{default as r}from"../../packem_shared/zeptomailProvider-C2lh0Xmo.js";export{r as zeptomailProvider};
|
package/dist/types.d.ts
CHANGED
|
@@ -109,6 +109,19 @@ export type ImmutableHeaders = Omit<Headers, "append" | "delete" | "set">;
|
|
|
109
109
|
* Email headers can be either a plain object or an ImmutableHeaders instance
|
|
110
110
|
*/
|
|
111
111
|
export type EmailHeaders = Record<string, string> | ImmutableHeaders;
|
|
112
|
+
/**
|
|
113
|
+
* Options for calendar event attachments
|
|
114
|
+
*/
|
|
115
|
+
export interface CalendarEventOptions {
|
|
116
|
+
/**
|
|
117
|
+
* Alternative text for the calendar event
|
|
118
|
+
*/
|
|
119
|
+
alternativeText?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Method for the calendar event (e.g., 'REQUEST', 'CANCEL', 'REPLY')
|
|
122
|
+
*/
|
|
123
|
+
method?: string;
|
|
124
|
+
}
|
|
112
125
|
/**
|
|
113
126
|
* Common email options that all providers support
|
|
114
127
|
*/
|
|
@@ -119,6 +132,11 @@ export interface EmailOptions {
|
|
|
119
132
|
from: EmailAddress;
|
|
120
133
|
headers?: EmailHeaders;
|
|
121
134
|
html?: string;
|
|
135
|
+
icalEvent?: CalendarEventOptions & {
|
|
136
|
+
content?: string;
|
|
137
|
+
href?: string;
|
|
138
|
+
path?: string;
|
|
139
|
+
};
|
|
122
140
|
priority?: Priority;
|
|
123
141
|
replyTo?: EmailAddress;
|
|
124
142
|
subject: string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic cache interface for caching any type of data.
|
|
3
|
+
* Implementations can use in-memory cache, LRU cache, Redis, etc.
|
|
4
|
+
*/
|
|
5
|
+
export interface Cache<T = unknown> {
|
|
6
|
+
/**
|
|
7
|
+
* Clears all cached entries.
|
|
8
|
+
*/
|
|
9
|
+
clear: () => Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Deletes a cached entry.
|
|
12
|
+
* @param key The cache key.
|
|
13
|
+
*/
|
|
14
|
+
delete: (key: string) => Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Gets a cached value.
|
|
17
|
+
* @param key The cache key.
|
|
18
|
+
* @returns The cached value or undefined if not found or expired.
|
|
19
|
+
*/
|
|
20
|
+
get: (key: string) => Promise<T | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* Sets a cached value.
|
|
23
|
+
* @param key The cache key.
|
|
24
|
+
* @param value The value to cache.
|
|
25
|
+
* @param ttl Time-to-live in milliseconds.
|
|
26
|
+
*/
|
|
27
|
+
set: (key: string, value: T, ttl: number) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Options for creating an in-memory cache.
|
|
31
|
+
*/
|
|
32
|
+
export interface InMemoryCacheOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Maximum number of entries in the cache.
|
|
35
|
+
* @default 500
|
|
36
|
+
*/
|
|
37
|
+
max?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Default TTL in milliseconds for entries.
|
|
40
|
+
* @default 3600000 (1 hour)
|
|
41
|
+
*/
|
|
42
|
+
ttl?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Default in-memory cache implementation using LRU cache.
|
|
46
|
+
*/
|
|
47
|
+
export declare class InMemoryCache<T extends object = Record<string, unknown>> implements Cache<T> {
|
|
48
|
+
private readonly cache;
|
|
49
|
+
constructor(options?: InMemoryCacheOptions);
|
|
50
|
+
clear: () => Promise<void>;
|
|
51
|
+
delete: (key: string) => Promise<void>;
|
|
52
|
+
get: (key: string) => Promise<T | undefined>;
|
|
53
|
+
set: (key: string, value: T, ttl: number) => Promise<void>;
|
|
54
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var h=Object.defineProperty;var r=(c,e)=>h(c,"name",{value:e,configurable:!0});import{LRUCache as n}from"lru-cache";var l=Object.defineProperty,t=r((c,e)=>l(c,"name",{value:e,configurable:!0}),"t");class m{static{r(this,"InMemoryCache")}static{t(this,"InMemoryCache")}cache;constructor(e={}){const{max:a=500,ttl:s=36e5}=e;this.cache=new n({max:a,ttl:s})}clear=t(async()=>{this.cache.clear()},"clear");delete=t(async e=>{this.cache.delete(e)},"delete");get=t(async e=>this.cache.get(e),"get");set=t(async(e,a,s)=>{this.cache.set(e,a,{ttl:s})},"set")}export{m as InMemoryCache};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Logger interface with debug, error, info, and warn methods.
|
|
3
3
|
*/
|
|
4
|
-
type Logger = {
|
|
4
|
+
export type Logger = {
|
|
5
5
|
debug: (message: string, ...args: unknown[]) => void;
|
|
6
6
|
error: (message: string, ...args: unknown[]) => void;
|
|
7
7
|
info: (message: string, ...args: unknown[]) => void;
|
|
@@ -13,6 +13,4 @@ type Logger = {
|
|
|
13
13
|
* @param logger Optional Console instance. If provided, logs will be displayed with prefixes. If not provided, returns a no-op logger.
|
|
14
14
|
* @returns A logger instance with debug, error, info, and warn methods.
|
|
15
15
|
*/
|
|
16
|
-
declare const createLogger: (providerName: string, logger?: Console) => Logger;
|
|
17
|
-
export type { Logger };
|
|
18
|
-
export default createLogger;
|
|
16
|
+
export declare const createLogger: (providerName: string, logger?: Console) => Logger;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var m=Object.defineProperty;var r=(e,a)=>m(e,"name",{value:a,configurable:!0});import o from"../packem_shared/EmailError-zm2ffVav.js";import{s as l}from"../packem_shared/sanitize-header-wWav-Scu.js";import t from"./validation/validate-email.js";var i=Object.defineProperty,n=r((e,a)=>i(e,"name",{value:a,configurable:!0}),"m");const p=n(e=>{if(!t(e.email))throw new o("email",`Invalid email address: ${e.email}`);return e.name?`${l(e.name)} <${e.email}>`:e.email},"formatEmailAddress");export{p as default};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes email aliases for supported email providers.
|
|
3
|
+
* For example: example@gmail.com and example+another@gmail.com point to the same email address.
|
|
4
|
+
* This function normalizes aliases to their canonical form.
|
|
5
|
+
*
|
|
6
|
+
* Supported providers:
|
|
7
|
+
* - Gmail: Removes dots and plus aliases (example+test@gmail.com → example@gmail.com)
|
|
8
|
+
* - Yahoo, Outlook, Hotmail, Live, MSN, iCloud, ProtonMail, Zoho, FastMail, Mail.com, GMX: Removes plus aliases only
|
|
9
|
+
* @param email The email address to normalize.
|
|
10
|
+
* @returns The normalized email address, or the original email if not supported or invalid.
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { normalizeEmailAliases } from "@visulima/email/utils/normalize-email-aliases";
|
|
14
|
+
*
|
|
15
|
+
* normalizeEmailAliases("example+test@gmail.com"); // "example@gmail.com"
|
|
16
|
+
* normalizeEmailAliases("ex.ample@gmail.com"); // "example@gmail.com"
|
|
17
|
+
* normalizeEmailAliases("user+tag@yahoo.com"); // "user@yahoo.com"
|
|
18
|
+
* normalizeEmailAliases("user@example.com"); // "user@example.com" (unchanged)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare const normalizeEmailAliases: (email: string) => string;
|
|
22
|
+
export default normalizeEmailAliases;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=Object.defineProperty;var l=(o,e)=>a(o,"name",{value:e,configurable:!0});var g=Object.defineProperty,u=l((o,e)=>g(o,"name",{value:e,configurable:!0}),"m");const c=new Map([["fastmail.com",{domain:"fastmail.com",ignoreDots:!1,ignorePlus:!0}],["gmail.com",{domain:"gmail.com",ignoreDots:!0,ignorePlus:!0}],["gmx.com",{domain:"gmx.com",ignoreDots:!1,ignorePlus:!0}],["gmx.de",{domain:"gmx.de",ignoreDots:!1,ignorePlus:!0}],["gmx.net",{domain:"gmx.net",ignoreDots:!1,ignorePlus:!0}],["hotmail.com",{domain:"hotmail.com",ignoreDots:!1,ignorePlus:!0}],["icloud.com",{domain:"icloud.com",ignoreDots:!1,ignorePlus:!0}],["live.com",{domain:"live.com",ignoreDots:!1,ignorePlus:!0}],["mail.com",{domain:"mail.com",ignoreDots:!1,ignorePlus:!0}],["msn.com",{domain:"msn.com",ignoreDots:!1,ignorePlus:!0}],["outlook.com",{domain:"outlook.com",ignoreDots:!1,ignorePlus:!0}],["protonmail.com",{domain:"protonmail.com",ignoreDots:!1,ignorePlus:!0}],["yahoo.com",{domain:"yahoo.com",ignoreDots:!1,ignorePlus:!0}],["zoho.com",{domain:"zoho.com",ignoreDots:!1,ignorePlus:!0}]]),d=u(o=>{if(!o||typeof o!="string")return o;const e=o.trim().toLowerCase(),n=e.indexOf("@");if(n===-1||n===0||n===e.length-1)return o;const m=e.slice(0,n),r=e.slice(n+1);if(!m||!r)return o;const t=c.get(r);if(!t)return e;let i=m;if(t.ignorePlus){const s=i.indexOf("+");s!==-1&&(i=i.slice(0,s))}return t.ignoreDots&&(i=i.replaceAll(".","")),`${i}@${r}`},"normalizeEmailAliases");export{d as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var m=Object.defineProperty;var o=(t,e)=>m(t,"name",{value:e,configurable:!0});import d from"./validation/validate-email.js";var h=Object.defineProperty,c=o((t,e)=>h(t,"name",{value:e,configurable:!0}),"l");const g=c(t=>{const e=t.replace(/^"(.+)"$/,"$1");return!(!e||e.length===0||e.includes("..")||e.startsWith(".")||e.endsWith("."))},"isValidLocalPart"),a=c(t=>{const e=t.indexOf("@[");if(e>0&&t.endsWith("]")){const n=t.length-1,l=t.slice(e+2,n);if(l.includes("@["))return!1;const i=t.slice(0,e),s=l;return!s||s.trim().length===0||s.includes("]")?!1:i?g(i):!1}if(t.includes("@[")&&!t.includes("]"))return!1;const r=t.match(/^"((?:[^"\\]|\\.)+)"@(.+)$/);if(r&&r[2]){const n=r[2];return n.startsWith("[")?!1:d(`test@${n}`)}return d(t)},"isValidEmailFormat"),$=c(t=>{if(!t||typeof t!="string")return;const e=t.trim();if(!e)return;const r=e.lastIndexOf("<"),n=e.lastIndexOf(">");if(r!==-1&&n>r){const i=e.slice(0,r).trim(),s=e.slice(r+1,n).trim();if(s&&a(s)){if(i){const f=i.replace(/^"(.+)"$/,"$1");return{email:s,name:f}}return{email:s}}}const l=e.match(/^<([^>]+)>$/);if(l&&l[1]){const i=l[1].trim();return a(i)?{email:i}:void 0}if(!(e.includes("]")&&!e.includes("@["))&&!(e.includes('"')&&!e.startsWith('"')&&e.indexOf('"')<e.indexOf("@"))){if(e.startsWith('"')){let i=1,s=!1;for(;i<e.length;)if(e[i]==="\\"&&i+1<e.length)i+=2;else if(e[i]==='"'){if(i+1<e.length&&e[i+1]==="@"){s=!0;break}i+=1}else i+=1;if(!s&&e.includes("@")){const f=e.indexOf("@"),u=e.slice(1).indexOf('"');if(u===-1||f<u+1)return}}if(a(e))return{email:e}}},"parseAddress");export{$ as default};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Cache } from "../cache.d.ts";
|
|
2
|
+
export type { Cache, InMemoryCache } from "../cache.d.ts";
|
|
3
|
+
/**
|
|
4
|
+
* MX record information.
|
|
5
|
+
*/
|
|
6
|
+
export interface MxRecord {
|
|
7
|
+
exchange: string;
|
|
8
|
+
priority: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Result of MX record check.
|
|
12
|
+
*/
|
|
13
|
+
export interface MxCheckResult {
|
|
14
|
+
error?: string;
|
|
15
|
+
records?: MxRecord[];
|
|
16
|
+
valid: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Options for MX record checking.
|
|
20
|
+
*/
|
|
21
|
+
export interface MxCheckOptions {
|
|
22
|
+
cache?: Cache<MxCheckResult>;
|
|
23
|
+
ttl?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Checks MX records for a domain.
|
|
27
|
+
* @param domain The domain to check MX records for.
|
|
28
|
+
* @param options Options for MX record checking, including caching.
|
|
29
|
+
* @returns Result containing MX records or error.
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { checkMxRecords } from "@visulima/email/validation/check-mx-records";
|
|
33
|
+
* import { InMemoryCache } from "@visulima/email/utils/cache";
|
|
34
|
+
*
|
|
35
|
+
* const cache = new InMemoryCache();
|
|
36
|
+
* const result = await checkMxRecords("example.com", { cache });
|
|
37
|
+
* if (result.valid) {
|
|
38
|
+
* console.log("MX records:", result.records);
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare const checkMxRecords: (domain: string, options?: MxCheckOptions) => Promise<MxCheckResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var d=Object.defineProperty;var n=(r,e)=>d(r,"name",{value:e,configurable:!0});import{createRequire as l}from"node:module";const u=l(import.meta.url),c=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,p=n(r=>{if(typeof c<"u"&&c.versions&&c.versions.node){const[e,o]=c.versions.node.split(".").map(Number);if(e>22||e===22&&o>=3||e===20&&o>=16)return c.getBuiltinModule(r)}return u(r)},"__cjs_getBuiltinModule"),{resolveMx:h}=p("node:dns/promises");var f=Object.defineProperty,g=n((r,e)=>f(r,"name",{value:e,configurable:!0}),"h");const v=g(async(r,e={})=>{const o=e.ttl??36e5;if(e.cache){const t=await e.cache.get(r);if(t!==void 0)return t}try{const t=(await h(r)).map(i=>({exchange:i.exchange,priority:i.priority})),s={records:t.toSorted((i,a)=>i.priority-a.priority),valid:t.length>0};return e.cache&&await e.cache.set(r,s,o),s}catch(t){const s={error:t instanceof Error?t.message:String(t),valid:!1};return e.cache&&await e.cache.set(r,s,o),s}},"checkMxRecords");export{v as checkMxRecords};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports all functionality from @visulima/disposable-email-domains.
|
|
3
|
+
* This provides access to disposable email domain checking utilities.
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { isDisposableEmail, isDisposableDomain, getDomainList } from "\@visulima/email/validation/disposable-email-domains";
|
|
7
|
+
*
|
|
8
|
+
* if (isDisposableEmail("user@mailinator.com")) {
|
|
9
|
+
* console.log("Disposable email detected!");
|
|
10
|
+
* }
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export * from "@visulima/disposable-email-domains";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"@visulima/disposable-email-domains";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common role account prefixes that indicate non-personal email addresses.
|
|
3
|
+
* Includes RFC 2142 standard role accounts and common business/operational prefixes.
|
|
4
|
+
*/
|
|
5
|
+
declare const ROLE_ACCOUNT_PREFIXES: Set<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Checks if an email address is a role account (non-personal).
|
|
8
|
+
* @param email The email address to check.
|
|
9
|
+
* @param customPrefixes Optional set of additional role account prefixes.
|
|
10
|
+
* @returns True if the email is a role account, false otherwise.
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { isRoleAccount } from "@visulima/email/validation/role-accounts";
|
|
14
|
+
*
|
|
15
|
+
* if (isRoleAccount("noreply@example.com")) {
|
|
16
|
+
* console.log("This is a role account");
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare const isRoleAccount: (email: string, customPrefixes?: Set<string>) => boolean;
|
|
21
|
+
export { ROLE_ACCOUNT_PREFIXES };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var l=Object.defineProperty;var u=(e,r)=>l(e,"name",{value:r,configurable:!0});var p=Object.defineProperty,i=u((e,r)=>p(e,"name",{value:r,configurable:!0}),"n");const m=new Set(["abuse","accounts","admin","adminhelp","administrator","adminoffice","adminteam","affiliates","alarms","alert","alternative","analytics","anonymous","archive","audit","automated","autoreply","backoffice","backup","batch","billing","board","bot","bounce","bug","bugreport","build","careers","cert","chapter","chatbot","ci","compliance","contact","continuousintegration","cron","csirt","customer-care","customercare","customerservice","customersupport","cvs","daemon","default","demo","deploy","deployment","dev","development","devops","digest","director","dnsadmin","docs","donotreply","enquiry","errors","events","executive","faculty","failover","feed","feedback","finance","forensics","ftp","git","guardian","guest","help","helpdesk","helpsec","hostmaster","hr","incident","incidents","indexer","info","ingest","inquiry","issues","it","jobs","legal","list","list-request","log","logistics","logs","maildaemon","mailer-daemon","malicious","management","manager","marketing","media","membership","metrics","mod","moderator","mods","monitor","network","news","newsletter","no-reply","noc","noreply","notifications","notify","operations","operator","owner","owners","parent","partners","patches","payments","phish","phishing","pipeline","post","postmaster","pr","press","privacy","procurement","qa","recruitment","redundancy","registrar","releases","reminder","reminders","reply","report","reports","request","resource","root","sales","scheduler","secondary","secops","secretariat","secretary","security","server","service","spam","spamreport","staff","standby","student","subscribe","subscriptions","summaries","supervisor","supplychain","support","supportteam","svn","sync","sysadmin","system","system-alert","system-msg","team","tech","techsupport","temp","tertiary","test","threat","threats","tracker","trial","unknown","unsubscribe","update","updates","usenet","usergroup","uucp","volunteer","vuln","vulnerability","webinars","webmaster","www"]),o=i((e,r)=>m.has(e)||(r?.has(e)??!1),"checkRolePrefix"),d=i((e,r)=>{if(e.length<2)return!1;const t=["-",".","_"];for(const s of t){const n=`${e[0]}${s}${e[1]}`;if(o(n,r))return!0}return!1},"checkCombinedParts"),f=i((e,r)=>{for(const t of e)if(!o(t,r))return!1;return!0},"checkAllPartsAreRoleAccounts"),h=i((e,r)=>{if(!e||typeof e!="string")return!1;const t=e.toLowerCase().trim(),s=t.indexOf("@");if(s===-1||s===0)return!1;const n=t.slice(0,s);if(o(n,r))return!0;const a=n.split(/[+._-]/);if(a.length===1){const c=a[0];return c===void 0?!1:o(c,r)}return d(a,r)?!0:f(a,r)},"isRoleAccount");export{m as ROLE_ACCOUNT_PREFIXES,h as isRoleAccount};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SmtpVerificationOptions } from "./verify-smtp.d.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Options for comprehensive email verification.
|
|
4
|
+
*/
|
|
5
|
+
export interface EmailVerificationOptions extends SmtpVerificationOptions {
|
|
6
|
+
checkDisposable?: boolean;
|
|
7
|
+
checkMx?: boolean;
|
|
8
|
+
checkRoleAccount?: boolean;
|
|
9
|
+
checkSmtp?: boolean;
|
|
10
|
+
customDisposableDomains?: Set<string>;
|
|
11
|
+
customRolePrefixes?: Set<string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Result of comprehensive email verification.
|
|
15
|
+
*/
|
|
16
|
+
export interface EmailVerificationResult {
|
|
17
|
+
disposable?: boolean;
|
|
18
|
+
errors: string[];
|
|
19
|
+
formatValid: boolean;
|
|
20
|
+
mxValid?: boolean;
|
|
21
|
+
roleAccount?: boolean;
|
|
22
|
+
smtpValid?: boolean;
|
|
23
|
+
valid: boolean;
|
|
24
|
+
warnings: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Comprehensive email verification combining multiple checks.
|
|
28
|
+
* @param email The email address to verify.
|
|
29
|
+
* @param options Verification options.
|
|
30
|
+
* @returns Detailed verification result.
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { verifyEmail } from "@visulima/email/validation/verify-email";
|
|
34
|
+
*
|
|
35
|
+
* const result = await verifyEmail("user@example.com", {
|
|
36
|
+
* checkDisposable: true,
|
|
37
|
+
* checkRoleAccount: true,
|
|
38
|
+
* checkMx: true,
|
|
39
|
+
* checkSmtp: false
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* if (result.valid) {
|
|
43
|
+
* console.log("Email is valid!");
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const verifyEmail: (email: string, options?: EmailVerificationOptions) => Promise<EmailVerificationResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var V=Object.defineProperty;var f=(e,r)=>V(e,"name",{value:r,configurable:!0});import{checkMxRecords as y}from"./check-mx-records.js";import{isRoleAccount as k}from"./role-accounts.js";import w from"./validate-email.js";import{verifySmtp as E}from"./verify-smtp.js";import{isDisposableEmail as A}from"@visulima/disposable-email-domains";var D=Object.defineProperty,M=f((e,r)=>D(e,"name",{value:r,configurable:!0}),"f");const N=M(async(e,r={})=>{const{checkDisposable:p=!0,checkMx:d=!0,checkRoleAccount:u=!0,checkSmtp:h=!1,customDisposableDomains:v,customRolePrefixes:b,...g}=r,c=w(e),a=[],i=[];if(!c)return a.push("Invalid email format"),{errors:a,formatValid:!1,valid:!1,warnings:i};let s,l,m,n;if(p)try{s=A(e,v),s&&i.push("Email is from a disposable email service")}catch{}if(u&&(l=k(e,b),l&&i.push("Email appears to be a role account (non-personal)")),d){const o=e.split("@")[1];if(!o)return a.push("Invalid email format: missing domain"),{disposable:s,errors:a,formatValid:!1,mxValid:!1,roleAccount:l,valid:!1,warnings:i};const t=await y(o,{cache:r.cache});m=t.valid,t.valid||a.push(t.error||"No valid MX records found")}if(h){const o=await E(e,{...g,cache:r.cache,smtpCache:r.smtpCache});n=o.valid,!o.valid&&o.error&&a.push(`SMTP verification failed: ${o.error}`)}const x=c&&a.length===0;return{disposable:s,errors:a,formatValid:c,mxValid:m,roleAccount:l,smtpValid:n,valid:x,warnings:i}},"verifyEmail");export{N as verifyEmail};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Cache } from "../cache.d.ts";
|
|
2
|
+
import type { MxCheckResult, MxRecord } from "./check-mx-records.d.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Options for SMTP verification.
|
|
5
|
+
*/
|
|
6
|
+
export interface SmtpVerificationOptions {
|
|
7
|
+
cache?: Cache<MxCheckResult>;
|
|
8
|
+
fromEmail?: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
smtpCache?: Cache<SmtpVerificationResult>;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
ttl?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Detailed result of SMTP verification attempt.
|
|
16
|
+
*/
|
|
17
|
+
export interface SmtpVerificationResult {
|
|
18
|
+
error?: string;
|
|
19
|
+
mxRecords?: MxRecord[];
|
|
20
|
+
smtpResponse?: string;
|
|
21
|
+
valid: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Verifies an email address by checking MX records and attempting SMTP verification.
|
|
25
|
+
* Note: Many mail servers block SMTP verification to prevent email harvesting.
|
|
26
|
+
* @param email The email address to verify.
|
|
27
|
+
* @param options Verification options.
|
|
28
|
+
* @returns Result containing verification status.
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { verifySmtp } from "@visulima/email/validation/verify-smtp";
|
|
32
|
+
*
|
|
33
|
+
* const result = await verifySmtp("user@example.com", {
|
|
34
|
+
* timeout: 5000,
|
|
35
|
+
* fromEmail: "test@example.com"
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const verifySmtp: (email: string, options?: SmtpVerificationOptions) => Promise<SmtpVerificationResult>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var j=Object.defineProperty;var R=(t,e)=>j(t,"name",{value:e,configurable:!0});import{createRequire as S}from"node:module";import{checkMxRecords as C}from"./check-mx-records.js";const $=S(import.meta.url),u=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,O=R(t=>{if(typeof u<"u"&&u.versions&&u.versions.node){const[e,d]=u.versions.node.split(".").map(Number);if(e>22||e===22&&d>=3||e===20&&d>=16)return u.getBuiltinModule(t)}return $(t)},"__cjs_getBuiltinModule"),{Socket:P}=O("node:net");var E=Object.defineProperty,p=R((t,e)=>E(t,"name",{value:e,configurable:!0}),"n");const A=p(async(t,e={})=>{const{fromEmail:d="test@example.com",port:x=25,timeout:M=5e3,ttl:_=36e5}=e;if(!t||typeof t!="string")return{error:"Invalid email address",valid:!1};const l=t.toLowerCase().trim(),h=l.indexOf("@");if(h===-1||h===l.length-1)return{error:"Invalid email format",valid:!1};const{smtpCache:c}=e,g=`smtp:${l}:${d}:${x}`;if(c){const n=await c.get(g);if(n!==void 0)return n}const w=l.slice(h+1),W=e.cache,r=await C(w,{cache:W});if(!r.valid||!r.records||r.records.length===0){const n={error:r.error||"No MX records found",mxRecords:r.records,valid:!1};return c&&await c.set(g,n,_),n}const y=r.records[0];return new Promise(n=>{const o=new P;let v="",s="connected";const m=p(()=>{o.removeAllListeners(),o.destroy()},"cleanup"),f=p(a=>{c&&c.set(g,a,_).catch(()=>{}),n(a)},"cacheAndResolve"),T=p(a=>{m(),f({error:a.message,mxRecords:r.records,valid:!1})},"onError"),b=p(()=>{m(),f({error:"SMTP connection timeout",mxRecords:r.records,valid:!1})},"onTimeout");o.setTimeout(M),o.on("error",T),o.on("timeout",b),o.on("data",a=>{v+=a.toString();const i=v.slice(-3);s==="connected"&&(i.startsWith("220")||i.startsWith("250"))?(s="helo",o.write(`HELO ${w}\r
|
|
2
|
+
`)):s==="helo"&&i.startsWith("250")?(s="mail-from",o.write(`MAIL FROM:<${d}>\r
|
|
3
|
+
`)):s==="mail-from"&&i.startsWith("250")?(s="rcpt-to",o.write(`RCPT TO:<${l}>\r
|
|
4
|
+
`)):s==="rcpt-to"&&i.startsWith("250")?(m(),f({mxRecords:r.records,smtpResponse:v,valid:!0})):s==="rcpt-to"&&(i.startsWith("550")||i.startsWith("551")||i.startsWith("553"))&&(m(),f({error:"Email address does not exist",mxRecords:r.records,smtpResponse:v,valid:!1}))}),y?o.connect(x,y.exchange):(m(),f({error:"No MX record available",mxRecords:r.records,valid:!1}))})},"verifySmtp");export{A as verifySmtp};
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/email",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.2",
|
|
4
4
|
"description": "A comprehensive email library with multi-provider support, crypto utilities, and template engines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visulima",
|
|
7
7
|
"email",
|
|
8
8
|
"mail",
|
|
9
|
+
"better-mail",
|
|
9
10
|
"smtp",
|
|
10
11
|
"resend",
|
|
11
12
|
"aws-ses",
|
|
@@ -39,6 +40,8 @@
|
|
|
39
40
|
"encryption",
|
|
40
41
|
"signing",
|
|
41
42
|
"crypto",
|
|
43
|
+
"disposable-email",
|
|
44
|
+
"disposable-email-domains",
|
|
42
45
|
"handlebars",
|
|
43
46
|
"mjml",
|
|
44
47
|
"react-email",
|
|
@@ -212,6 +215,46 @@
|
|
|
212
215
|
"types": "./dist/providers/sweego/index.d.ts",
|
|
213
216
|
"default": "./dist/providers/sweego/index.js"
|
|
214
217
|
},
|
|
218
|
+
"./utils/parse-address": {
|
|
219
|
+
"types": "./dist/utils/parse-address.d.ts",
|
|
220
|
+
"default": "./dist/utils/parse-address.js"
|
|
221
|
+
},
|
|
222
|
+
"./utils/format-email-address": {
|
|
223
|
+
"types": "./dist/utils/format-email-address.d.ts",
|
|
224
|
+
"default": "./dist/utils/format-email-address.js"
|
|
225
|
+
},
|
|
226
|
+
"./utils/cache": {
|
|
227
|
+
"types": "./dist/utils/cache.d.ts",
|
|
228
|
+
"default": "./dist/utils/cache.js"
|
|
229
|
+
},
|
|
230
|
+
"./validation/disposable-email-domains": {
|
|
231
|
+
"types": "./dist/utils/validation/disposable-email-domains.d.ts",
|
|
232
|
+
"default": "./dist/utils/validation/disposable-email-domains.js"
|
|
233
|
+
},
|
|
234
|
+
"./validation/validate-email": {
|
|
235
|
+
"types": "./dist/utils/validation/validate-email.d.ts",
|
|
236
|
+
"default": "./dist/utils/validation/validate-email.js"
|
|
237
|
+
},
|
|
238
|
+
"./validation/check-mx-records": {
|
|
239
|
+
"types": "./dist/utils/validation/check-mx-records.d.ts",
|
|
240
|
+
"default": "./dist/utils/validation/check-mx-records.js"
|
|
241
|
+
},
|
|
242
|
+
"./validation/role-accounts": {
|
|
243
|
+
"types": "./dist/utils/validation/role-accounts.d.ts",
|
|
244
|
+
"default": "./dist/utils/validation/role-accounts.js"
|
|
245
|
+
},
|
|
246
|
+
"./validation/verify-smtp": {
|
|
247
|
+
"types": "./dist/utils/validation/verify-smtp.d.ts",
|
|
248
|
+
"default": "./dist/utils/validation/verify-smtp.js"
|
|
249
|
+
},
|
|
250
|
+
"./validation/verify-email": {
|
|
251
|
+
"types": "./dist/utils/validation/verify-email.d.ts",
|
|
252
|
+
"default": "./dist/utils/validation/verify-email.js"
|
|
253
|
+
},
|
|
254
|
+
"./utils/normalize-email-aliases": {
|
|
255
|
+
"types": "./dist/utils/normalize-email-aliases.d.ts",
|
|
256
|
+
"default": "./dist/utils/normalize-email-aliases.js"
|
|
257
|
+
},
|
|
215
258
|
"./package.json": "./package.json"
|
|
216
259
|
},
|
|
217
260
|
"files": [
|
|
@@ -220,7 +263,10 @@
|
|
|
220
263
|
"CHANGELOG.md"
|
|
221
264
|
],
|
|
222
265
|
"dependencies": {
|
|
266
|
+
"@visulima/disposable-email-domains": "1.0.0-alpha.1",
|
|
223
267
|
"html-to-text": "^9.0.5",
|
|
268
|
+
"ical-generator": "^9.0.0",
|
|
269
|
+
"lru-cache": "^11.2.2",
|
|
224
270
|
"mime": "^4.1.0"
|
|
225
271
|
},
|
|
226
272
|
"peerDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var x=Object.defineProperty;var h=(o,e)=>x(o,"name",{value:e,configurable:!0});import{createRequire as v}from"node:module";import{readFileAsBuffer as b,detectMimeType as u,generateContentId as A}from"./detectMimeType-S8WRsNtY.js";import w from"../template-engines/html-to-text.js";import T from"./createLogger-DlElSVQP.js";import j from"./headersToRecord-BKUTr40L.js";const E=v(import.meta.url),l=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,M=h(o=>{if(typeof l<"u"&&l.versions&&l.versions.node){const[e,t]=l.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return l.getBuiltinModule(o)}return E(o)},"__cjs_getBuiltinModule"),{basename:y}=M("node:path");var C=Object.defineProperty,d=h((o,e)=>C(o,"name",{value:e,configurable:!0}),"g");const p=d(o=>Array.isArray(o)?o.map(e=>typeof e=="string"?{email:e}:e):typeof o=="string"?[{email:o}]:[o],"normalizeAddresses"),f=d((o,e,t)=>{e.success&&e.data?o&&o.info("Email sent successfully",{messageId:e.data.messageId,provider:e.data.provider}):o&&o.error("Email send failed",{error:e.error,provider:t})},"logSendResult");class I{static{h(this,"MailMessage")}static{d(this,"MailMessage")}fromAddress;toAddresses=[];ccAddresses=[];bccAddresses=[];subjectText="";textContent;autoTextEnabled=!0;htmlContent;headers={};attachments=[];replyToAddress;priorityValue;tagsValue=[];provider;signer;encrypter;logger;from(e){return this.fromAddress=typeof e=="string"?{email:e}:e,this}to(e){return this.toAddresses.push(...p(e)),this}cc(e){return this.ccAddresses.push(...p(e)),this}bcc(e){return this.bccAddresses.push(...p(e)),this}subject(e){return this.subjectText=e,this}text(e){return this.textContent=e,this}html(e){return this.htmlContent=e,this}header(e,t){return this.headers[e]=t,this}setHeaders(e){const t=j(e);return Object.assign(this.headers,t),this}async attachFromPath(e,t){try{const s=await b(e),i=t?.filename||y(e)||"attachment",r=t?.contentType||u(i);this.attachments.push({cid:t?.cid,content:s,contentDisposition:t?.contentDisposition||"attachment",contentType:r,encoding:t?.encoding,filename:i,headers:t?.headers}),this.logger&&this.logger.debug(`Attachment added from path: ${e}`,{contentType:r,filename:i})}catch(s){throw this.logger&&this.logger.error(`Failed to attach file from path: ${e}`,s),s}return this}attachData(e,t){const s=t.contentType||u(t.filename);return this.attachments.push({cid:t.cid,content:e,contentDisposition:t.contentDisposition||"attachment",contentType:s,encoding:t.encoding,filename:t.filename,headers:t.headers}),this.logger&&this.logger.debug("Attachment added from data",{contentType:s,filename:t.filename}),this}async embedFromPath(e,t){try{const s=await b(e),i=t?.filename||y(e)||"inline",r=t?.contentType||u(i),n=A(i);return this.attachments.push({cid:n,content:s,contentDisposition:"inline",contentType:r,filename:i}),this.logger&&this.logger.debug(`Inline attachment embedded from path: ${e}`,{cid:n,contentType:r,filename:i}),n}catch(s){throw this.logger&&this.logger.error(`Failed to embed file from path: ${e}`,s),s}}embedData(e,t,s){const i=s?.contentType||u(t),r=A(t);return this.attachments.push({cid:r,content:e,contentDisposition:"inline",contentType:i,filename:t}),this.logger&&this.logger.debug("Inline attachment embedded from data",{cid:r,contentType:i,filename:t}),r}replyTo(e){return this.replyToAddress=typeof e=="string"?{email:e}:e,this}priority(e){return this.priorityValue=e,this}tags(e){return this.tagsValue=Array.isArray(e)?e:[e],this}mailer(e){return this.provider=e,this}sign(e){return this.signer=e,this.logger&&this.logger.debug("Email signer configured"),this}encrypt(e){return this.encrypter=e,this.logger&&this.logger.debug("Email encrypter configured"),this}setLogger(e){return this.logger=T("MailMessage",e),this}async view(e,t,s,i){try{const r=i?.autoText!==!1;this.autoTextEnabled=r,this.logger&&this.logger.debug("Rendering template",{autoText:r});const n=await e(t,s,i);this.html(n),r&&n&&this.tryAutoGenerateText(n),this.logger&&this.logger.debug("Template rendered successfully")}catch(r){throw this.logger&&this.logger.error("Failed to render template",r),new Error(`Failed to render template: ${r.message}`)}return this}async viewText(e,t,s,i){try{this.logger&&this.logger.debug("Rendering text template");const r=await e(t,s,i);if(typeof r=="string")this.text(r),this.logger&&this.logger.debug("Text template rendered successfully");else throw new TypeError("Text renderer must return a string")}catch(r){throw this.logger&&this.logger.error("Failed to render text template",r),new Error(`Failed to render text template: ${r.message}`)}return this}async build(){if(this.logger&&this.logger.debug("Building email message"),this.fromAddress||this.throwAndLogError("From address is required","Build failed: from address is required"),this.toAddresses.length===0&&this.throwAndLogError("At least one recipient is required","Build failed: at least one recipient is required"),this.subjectText||this.throwAndLogError("Subject is required","Build failed: subject is required"),this.htmlContent&&!this.textContent&&this.autoTextEnabled)try{this.textContent=w(this.htmlContent),this.logger&&this.logger.debug("Auto-generated text content from HTML")}catch{this.logger&&this.logger.debug("Failed to convert HTML to text; proceeding without text content.")}!this.textContent&&!this.htmlContent&&this.throwAndLogError("Either text or html content is required","Build failed: either text or html content is required");let e={from:this.fromAddress,html:this.htmlContent,subject:this.subjectText,text:this.textContent,to:this.toAddresses.length===1?this.toAddresses[0]:this.toAddresses};return this.ccAddresses.length>0&&(e.cc=this.ccAddresses.length===1?this.ccAddresses[0]:this.ccAddresses),this.bccAddresses.length>0&&(e.bcc=this.bccAddresses.length===1?this.bccAddresses[0]:this.bccAddresses),Object.keys(this.headers).length>0&&(e.headers=this.headers),this.attachments.length>0&&(e.attachments=this.attachments,this.logger&&this.logger.debug(`Email includes ${this.attachments.length} attachment(s)`)),this.replyToAddress&&(e.replyTo=this.replyToAddress),this.priorityValue&&(e.priority=this.priorityValue),this.tagsValue.length>0&&(e.tags=this.tagsValue),this.signer&&(this.logger&&this.logger.debug("Signing email message"),e=await this.signer.sign(e),this.logger&&this.logger.debug("Email message signed successfully")),this.encrypter&&(this.logger&&this.logger.debug("Encrypting email message"),e=await this.encrypter.encrypt(e),this.logger&&this.logger.debug("Email message encrypted successfully")),this.logger&&this.logger.debug("Email message built successfully",{bcc:this.bccAddresses.length,cc:this.ccAddresses.length,hasHtml:!!this.htmlContent,hasText:!!this.textContent,to:this.toAddresses.length}),e}async send(){this.provider||this.throwAndLogError("No provider configured. Use mailer() method to set a provider.","Send failed: no provider configured"),this.logger&&this.logger.debug("Sending email",{subject:this.subjectText,to:this.toAddresses.length});const e=await this.build(),t=await this.provider.sendEmail(e);return f(this.logger,t,this.provider.name||"unknown"),t}tryAutoGenerateText(e){try{const t=w(e);t&&!this.textContent&&this.text(t),this.logger&&this.logger.debug("Auto-generated text content from HTML template")}catch(t){this.logger&&this.logger.warn("Failed to auto-generate text from HTML template",t)}}throwAndLogError(e,t){const s=new Error(e);throw this.logger&&this.logger.error(t||e),s}}class m{static{h(this,"Mail")}static{d(this,"Mail")}static extractErrorMessages(e){return e instanceof Error?[e.message]:[String(e||"Unknown error")]}provider;logger;loggerInstance;constructor(e){this.provider=e}setLogger(e){return this.loggerInstance=e,this.logger=T("Mail",e),this}message(){this.logger&&this.logger.debug("Creating new mail message");const e=new I;return e.mailer(this.provider),this.loggerInstance&&e.setLogger(this.loggerInstance),e}async send(e){this.logger&&this.logger.debug("Sending mailable instance");const t=await e.build(),s=await this.provider.sendEmail(t);return f(this.logger,s,this.provider.name||"unknown"),s}async sendEmail(e){this.logger&&this.logger.debug("Sending email with options",{subject:e.subject,to:Array.isArray(e.to)?e.to.length:1});const t=await this.provider.sendEmail(e);return f(this.logger,t,this.provider.name||"unknown"),t}async*sendMany(e,t){const s=this.provider.name;let i=0,r=0,n=0;this.logger&&this.logger.debug("Starting batch email send",{provider:s});for await(const c of e){if(t?.signal?.aborted){this.logger&&this.logger.warn("Batch send operation was aborted",{failed:n,processed:i,successful:r}),yield{errorMessages:["Send operation was aborted"],provider:s,successful:!1};return}i+=1;try{const g="build"in c&&typeof c.build=="function"?await c.build():c;this.logger&&this.logger.debug(`Sending email ${i}`,{subject:g.subject,to:Array.isArray(g.to)?g.to.length:1});const a=await this.provider.sendEmail(g);a.success&&a.data?(r+=1,this.logger&&this.logger.debug(`Email ${i} sent successfully`,{messageId:a.data.messageId}),yield{messageId:a.data.messageId,provider:a.data.provider||s,response:a.data.response,successful:!0,timestamp:a.data.timestamp}):(n+=1,this.logger&&this.logger.error(`Email ${i} send failed`,{error:a.error}),yield{errorMessages:m.extractErrorMessages(a.error),provider:s,successful:!1})}catch(g){n+=1,this.logger&&this.logger.error(`Email ${i} send failed with exception`,g),yield{errorMessages:m.extractErrorMessages(g),provider:s,successful:!1}}}this.logger&&this.logger.info("Batch email send completed",{failed:n,successful:r,total:i})}}const _=d(o=>new m(o),"createMail");export{m as Mail,I as MailMessage,_ as createMail};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var P=Object.defineProperty;var y=(i,r)=>P(i,"name",{value:r,configurable:!0});import{createRequire as $}from"node:module";import c from"./EmailError-zm2ffVav.js";import S from"./RequiredOptionError-CevW3u2K.js";import _ from"./generateMessageId-11Ls5JsR.js";import E from"./headersToRecord-BKUTr40L.js";import{makeRequest as f}from"./makeRequest-DwxHX0xo.js";import b from"./retry-D1MBqS49.js";import z from"./validateEmailOptions-BzlJECG5.js";import{defineProvider as k}from"./defineProvider-B9rSklAJ.js";import{c as q,h as w,P as K}from"./provider-base-_hbWXBdK.js";import{f as p,a as B}from"./address-formatter-Cm_E_ZMa.js";const I=$(import.meta.url),m=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,T=y(i=>{if(typeof m<"u"&&m.versions&&m.versions.node){const[r,u]=m.versions.node.split(".").map(Number);if(r>22||r===22&&u>=3||r===20&&u>=16)return m.getBuiltinModule(i)}return I(i)},"__cjs_getBuiltinModule"),{Buffer:j}=T("node:buffer"),s="ahasend",C="https://api.ahasend.com",x=3e4,G=3,W=k((i={})=>{if(!i.apiKey)throw new S(s,"apiKey");const r={apiKey:i.apiKey,debug:i.debug||!1,endpoint:i.endpoint||C,retries:i.retries||G,timeout:i.timeout||x,...i.logger&&{logger:i.logger}},u=new K,n=q(s,i.logger);return{features:{attachments:!0,batchSending:!0,customHeaders:!0,html:!0,replyTo:!0,scheduling:!1,tagging:!0,templates:!0,tracking:!0},async getEmail(e){try{if(!e)return{error:new c(s,"Email ID is required to retrieve email details"),success:!1};await this.initialize();const o={Authorization:`Bearer ${r.apiKey}`,"Content-Type":"application/json"};n.debug("Retrieving email details",{id:e});const t=await b(async()=>f(`${r.endpoint}/emails/${e}`,{headers:o,method:"GET",timeout:r.timeout}),r.retries);return t.success?(n.debug("Email details retrieved successfully"),{data:t.data?.body,success:!0}):(n.debug("API request failed when retrieving email",t.error),{error:new c(s,`Failed to retrieve email: ${t.error instanceof Error?t.error.message:"Unknown error"}`,{cause:t.error}),success:!1})}catch(o){return{error:w(s,"retrieve email",o,n),success:!1}}},async initialize(){await u.ensureInitialized(async()=>{if(!await this.isAvailable())throw new c(s,"AhaSend API not available or invalid API key");n.debug("Provider initialized successfully")},s)},async isAvailable(){try{return n.debug("Checking AhaSend API availability"),!!(await f(`${r.endpoint}/v2/ping`,{headers:{Authorization:`Bearer ${r.apiKey}`,"Content-Type":"application/json"},method:"GET",timeout:r.timeout})).success}catch(e){return n.debug("Error checking availability:",e),!1}},name:s,options:r,async sendEmail(e){try{const o=z(e);if(o.length>0)return{error:new c(s,`Invalid email options: ${o.join(", ")}`),success:!1};await this.initialize();const t={from:{email:e.from.email,name:e.from.name},subject:e.subject,to:p(e.to)};if(e.html&&(t.html=e.html),e.text&&(t.text=e.text),e.cc&&(t.cc=p(e.cc)),e.bcc&&(t.bcc=p(e.bcc)),e.replyTo&&(t.replyTo=B(e.replyTo)),e.templateId&&(t.templateId=e.templateId,e.templateVariables&&(t.templateVariables=e.templateVariables)),e.tags&&e.tags.length>0&&(t.tags=e.tags),e.headers){const a=E(e.headers);t.headers=a}e.attachments&&e.attachments.length>0&&(t.attachments=await Promise.all(e.attachments.map(async a=>{let d;if(a.content)if(typeof a.content=="string")d=a.content;else if(a.content instanceof Promise){const A=await a.content;d=j.from(A).toString("base64")}else d=a.content.toString("base64");else if(a.raw)d=typeof a.raw=="string"?a.raw:a.raw.toString("base64");else throw new c(s,`Attachment ${a.filename} has no content`);return{content:d,contentType:a.contentType||"application/octet-stream",filename:a.filename,...a.cid&&{cid:a.cid}}}))),n.debug("Sending email via AhaSend API",{subject:t.subject,to:t.to});const v={Authorization:`Bearer ${r.apiKey}`,"Content-Type":"application/json"},l=await b(async()=>f(`${r.endpoint}/send`,{headers:v,method:"POST",timeout:r.timeout},JSON.stringify(t)),r.retries);if(!l.success)return n.debug("API request failed when sending email",l.error),{error:l.error||new c(s,"Failed to send email"),success:!1};const g=l.data?.body,h=g?.messageId||g?.id||_();return n.debug("Email sent successfully",{messageId:h}),{data:{messageId:h,provider:s,response:l.data,sent:!0,timestamp:new Date},success:!0}}catch(o){return{error:w(s,"send email",o,n),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{W as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var k=Object.defineProperty;var w=(n,l)=>k(n,"name",{value:l,configurable:!0});import{createRequire as z}from"node:module";import u from"./EmailError-zm2ffVav.js";import v from"./RequiredOptionError-CevW3u2K.js";import P from"./generateMessageId-11Ls5JsR.js";import j from"./headersToRecord-BKUTr40L.js";import{makeRequest as h}from"./makeRequest-DwxHX0xo.js";import T from"./retry-D1MBqS49.js";import _ from"./validateEmailOptions-BzlJECG5.js";import{defineProvider as B}from"./defineProvider-B9rSklAJ.js";import{j as y,k as C}from"./address-formatter-Cm_E_ZMa.js";import{c as E,P as q,h as S}from"./provider-base-_hbWXBdK.js";const $=z(import.meta.url),f=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,I=w(n=>{if(typeof f<"u"&&f.versions&&f.versions.node){const[l,t]=f.versions.node.split(".").map(Number);if(l>22||l===22&&t>=3||l===20&&t>=16)return f.getBuiltinModule(n)}return $(n)},"__cjs_getBuiltinModule"),{Buffer:p}=I("node:buffer"),s="azure",x=3e4,O=3,V=B((n={})=>{if(!n.region)throw new v(s,"region");if(!n.connectionString&&!n.accessToken)throw new v(s,"connectionString or accessToken");const l=n.endpoint||`https://${n.region}.communication.azure.com`,t={debug:n.debug||!1,endpoint:l,region:n.region,retries:n.retries||O,timeout:n.timeout||x,...n.connectionString&&{connectionString:n.connectionString},...n.accessToken&&{accessToken:n.accessToken},...n.logger&&{logger:n.logger}},g=new q,o=E(s,n.logger);return{features:{attachments:!0,batchSending:!1,customHeaders:!0,html:!0,replyTo:!0,scheduling:!1,tagging:!1,templates:!0,tracking:!1},async getEmail(e){try{if(!e)return{error:new u(s,"Email ID is required to retrieve email details"),success:!1};await g.ensureInitialized(()=>this.initialize(),s);const a={"Content-Type":"application/json"};if(t.accessToken)a.Authorization=`Bearer ${t.accessToken}`;else if(t.connectionString){const c=t.connectionString.match(/endpoint=([^;]+);accesskey=([^;]+)/);c&&(a.Authorization=`Bearer ${c[2]}`)}o.debug("Retrieving email details",{id:e});const r=await T(async()=>h(`${t.endpoint}/emails/${e}`,{headers:a,method:"GET",timeout:t.timeout}),t.retries);return r.success?(o.debug("Email details retrieved successfully"),{data:r.data?.body,success:!0}):(o.debug("API request failed when retrieving email",r.error),{error:new u(s,`Failed to retrieve email: ${r.error instanceof Error?r.error.message:"Unknown error"}`,{cause:r.error}),success:!1})}catch(a){return{error:S(s,"retrieve email",a,o),success:!1}}},async initialize(){await g.ensureInitialized(async()=>{if(!await this.isAvailable())throw new u(s,"Azure Communication Services API not available or invalid credentials");o.debug("Provider initialized successfully")},s)},async isAvailable(){try{const e={"Content-Type":"application/json"};if(t.accessToken)e.Authorization=`Bearer ${t.accessToken}`;else if(t.connectionString){const c=t.connectionString.match(/endpoint=([^;]+);accesskey=([^;]+)/);if(c)e.Authorization=`Bearer ${c[2]}`;else return!1}else return!1;o.debug("Checking Azure Communication Services API availability");const a=await h(`${t.endpoint}/emails:send`,{headers:e,method:"POST",timeout:t.timeout},JSON.stringify({}));if(a.success)return!0;const r=a.data?.statusCode;return r===401||r===403?!1:r===400}catch(e){if(o.debug("Error checking availability:",e),e instanceof Error){const a=e.message;if(a.includes("401")||a.includes("403"))return!1}return!1}},name:s,options:t,async sendEmail(e){try{const a=_(e);if(a.length>0)return{error:new u(s,`Invalid email options: ${a.join(", ")}`),success:!1};await g.ensureInitialized(()=>this.initialize(),s);const r={content:{subject:e.subject},recipients:{to:y(e.to)},senderAddress:e.from.email};if(e.html&&(r.content.html=e.html),e.text&&(r.content.plainText=e.text),e.cc&&(r.recipients.cc=y(e.cc)),e.bcc&&(r.recipients.bcc=y(e.bcc)),e.replyTo&&(r.replyTo=C(e.replyTo).email),e.importance&&(r.importance=e.importance),e.headers){const i=j(e.headers);r.headers=i}e.attachments&&e.attachments.length>0&&(r.attachments=await Promise.all(e.attachments.map(async i=>{let d;if(i.content)if(typeof i.content=="string")d=p.from(i.content,"utf8").toString("base64");else if(i.content&&typeof i.content.then=="function"){const A=await i.content;d=p.from(A).toString("base64")}else d=i.content.toString("base64");else if(i.raw)d=typeof i.raw=="string"?p.from(i.raw,"utf8").toString("base64"):i.raw.toString("base64");else throw new u(s,`Attachment ${i.filename} has no content`);return{contentInBase64:d,contentType:i.contentType||"application/octet-stream",name:i.filename}}))),o.debug("Sending email via Azure Communication Services API",{subject:r.content.subject,to:r.recipients.to});const c={"Content-Type":"application/json"};if(t.accessToken)c.Authorization=`Bearer ${t.accessToken}`;else if(t.connectionString){const i=t.connectionString.match(/endpoint=([^;]+);accesskey=([^;]+)/);if(i)c.Authorization=`Bearer ${i[2]}`;else return{error:new u(s,"Invalid connection string format"),success:!1}}const m=await T(async()=>h(`${t.endpoint}/emails:send`,{headers:c,method:"POST",timeout:t.timeout},JSON.stringify(r)),t.retries);if(!m.success)return o.debug("API request failed when sending email",m.error),{error:m.error||new u(s,"Failed to send email"),success:!1};const b=m.data?.body?.messageId||P();return o.debug("Email sent successfully",{messageId:b}),{data:{messageId:b,provider:s,response:m.data,sent:!0,timestamp:new Date},success:!0}}catch(a){return{error:S(s,"send email",a,o),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{V as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var P=Object.defineProperty;var h=(o,a)=>P(o,"name",{value:a,configurable:!0});import{createRequire as A}from"node:module";import d from"./EmailError-zm2ffVav.js";import S from"./RequiredOptionError-CevW3u2K.js";import _ from"./generateMessageId-11Ls5JsR.js";import k from"./headersToRecord-BKUTr40L.js";import{makeRequest as p}from"./makeRequest-DwxHX0xo.js";import y from"./retry-D1MBqS49.js";import E from"./validateEmailOptions-BzlJECG5.js";import{defineProvider as $}from"./defineProvider-B9rSklAJ.js";import{c as B,P as q,h as b}from"./provider-base-_hbWXBdK.js";import{f,a as v}from"./address-formatter-Cm_E_ZMa.js";const j=A(import.meta.url),m=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,T=h(o=>{if(typeof m<"u"&&m.versions&&m.versions.node){const[a,c]=m.versions.node.split(".").map(Number);if(a>22||a===22&&c>=3||a===20&&c>=16)return m.getBuiltinModule(o)}return j(o)},"__cjs_getBuiltinModule"),{Buffer:C}=T("node:buffer"),i="brevo",z="https://api.brevo.com/v3",K=3e4,x=3,V=$((o={})=>{if(!o.apiKey)throw new S(i,"apiKey");const a={apiKey:o.apiKey,debug:o.debug||!1,endpoint:o.endpoint||z,retries:o.retries||x,timeout:o.timeout||K,...o.logger&&{logger:o.logger}},c=new q,n=B(i,o.logger);return{endpoint:a.endpoint,features:{attachments:!0,batchSending:!0,customHeaders:!0,html:!0,replyTo:!0,scheduling:!0,tagging:!0,templates:!0,tracking:!0},async getEmail(e){try{if(!e)return{error:new d(i,"Email ID is required to retrieve email details"),success:!1};await c.ensureInitialized(()=>this.initialize(),i);const r={"api-key":a.apiKey,"Content-Type":"application/json"};n.debug("Retrieving email details",{id:e});const t=await y(async()=>p(`${a.endpoint}/smtp/emails/${e}`,{headers:r,method:"GET",timeout:a.timeout}),a.retries);return t.success?(n.debug("Email details retrieved successfully"),{data:t.data?.body,success:!0}):(n.debug("API request failed when retrieving email",t.error),{error:new d(i,`Failed to retrieve email: ${t.error instanceof Error?t.error.message:"Unknown error"}`,{cause:t.error}),success:!1})}catch(r){return{error:b(i,"retrieve email",r,n),success:!1}}},async initialize(){await c.ensureInitialized(async()=>{if(!await this.isAvailable())throw new d(i,"Brevo API not available or invalid API key");n.debug("Provider initialized successfully")},i)},async isAvailable(){try{const e={"api-key":a.apiKey,"Content-Type":"application/json"};n.debug("Checking Brevo API availability");const r=await p(`${a.endpoint}/account`,{headers:e,method:"GET",timeout:a.timeout});return n.debug("Brevo API availability check response:",{error:r.error instanceof Error?r.error.message:void 0,statusCode:r.data?.statusCode,success:r.success}),!!(r.success&&r.data&&typeof r.data=="object"&&"statusCode"in r.data&&typeof r.data.statusCode=="number"&&r.data.statusCode>=200&&r.data.statusCode<300)}catch(e){return n.debug("Error checking availability:",e),!1}},name:i,options:a,async sendEmail(e){try{const r=E(e);if(r.length>0)return{error:new d(i,`Invalid email options: ${r.join(", ")}`),success:!1};await c.ensureInitialized(()=>this.initialize(),i);const t={sender:v(e.from),subject:e.subject,to:f(e.to)};if(e.html&&(t.htmlContent=e.html),e.text&&(t.textContent=e.text),e.cc&&(t.cc=f(e.cc)),e.bcc&&(t.bcc=f(e.bcc)),e.replyTo&&(t.replyTo=v(e.replyTo)),e.templateId&&(t.templateId=e.templateId,e.templateParams&&(t.params=e.templateParams)),e.tags&&e.tags.length>0&&(t.tags=e.tags),e.scheduledAt){const s=typeof e.scheduledAt=="number"?new Date(e.scheduledAt*1e3).toISOString():e.scheduledAt;t.scheduledAt=s}if(e.batchId&&(t.batchId=e.batchId),e.headers){const s=k(e.headers);t.headers=s}e.attachments&&e.attachments.length>0&&(t.attachment=await Promise.all(e.attachments.map(async s=>{let u;if(s.content)if(typeof s.content=="string")u=s.content;else if(s.content instanceof Promise){const I=await s.content;u=C.from(I).toString("base64")}else u=s.content.toString("base64");else if(s.raw)u=typeof s.raw=="string"?s.raw:s.raw.toString("base64");else throw new d(i,`Attachment ${s.filename} has no content`);return{content:u,name:s.filename,...s.contentType&&{type:s.contentType}}}))),n.debug("Sending email via Brevo API",{subject:t.subject,to:t.to});const w={"api-key":a.apiKey,"Content-Type":"application/json"},l=await y(async()=>p(`${a.endpoint}/smtp/email`,{headers:w,method:"POST",timeout:a.timeout},JSON.stringify(t)),a.retries);if(!l.success)return n.debug("API request failed when sending email",l.error),{error:l.error||new d(i,"Failed to send email"),success:!1};const g=l.data?.body?.messageId||_();return n.debug("Email sent successfully",{messageId:g}),{data:{messageId:g,provider:i,response:l.data,sent:!0,timestamp:new Date},success:!0}}catch(r){return{error:b(i,"send email",r,n),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{V as default};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var v=Object.defineProperty;var p=(e,o)=>v(e,"name",{value:o,configurable:!0});import C from"./EmailError-zm2ffVav.js";import d from"./formatEmailAddress-CHeME3Vk.js";import l from"./formatEmailAddresses-UegVOe5A.js";import w from"./generateBoundary-CZ8kJuY6.js";import x from"./headersToRecord-BKUTr40L.js";import{s as h,a as b}from"./sanitize-header-wWav-Scu.js";var B=Object.defineProperty,E=p((e,o)=>B(e,"name",{value:o,configurable:!0}),"b");const m=globalThis.Buffer!==void 0,g=E(e=>{if(typeof e=="string"){if(m)return Buffer.from(e,"utf8").toString("base64");const t=new TextEncoder().encode(e);let r="";const a=8192;for(let s=0;s<t.length;s+=a){const f=t.subarray(s,Math.min(s+a,t.length));r+=String.fromCharCode.apply(void 0,f)}return btoa(r)}if(m&&e instanceof Buffer)return e.toString("base64");const o=e instanceof Uint8Array?e:new Uint8Array(e);if(m)return Buffer.from(o).toString("base64");let n="";const c=8192;for(let t=0;t<o.length;t+=c){const r=o.subarray(t,Math.min(t+c,o.length));n+=String.fromCharCode.apply(void 0,r)}return btoa(n)},"toBase64");var M=Object.defineProperty,j=p((e,o)=>M(e,"name",{value:o,configurable:!0}),"h");const S=globalThis.Buffer!==void 0,I=j(async e=>{const o=w(),n=[`From: ${d(e.from)}`,`To: ${l(e.to)}`];if(e.cc&&n.push(`Cc: ${l(e.cc)}`),e.bcc&&n.push(`Bcc: ${l(e.bcc)}`),e.replyTo&&n.push(`Reply-To: ${d(e.replyTo)}`),n.push(`Subject: ${h(e.subject)}`,"MIME-Version: 1.0"),e.headers){const c=x(e.headers);Object.entries(c).forEach(([t,r])=>{const a=b(t),s=h(r);n.push(`${a}: ${s}`)})}if(n.push(`Content-Type: multipart/mixed; boundary="${o}"`,""),e.text&&n.push(`--${o}`,"Content-Type: text/plain; charset=UTF-8","Content-Transfer-Encoding: 7bit","",e.text,""),e.html&&n.push(`--${o}`,"Content-Type: text/html; charset=UTF-8","Content-Transfer-Encoding: 7bit","",e.html,""),e.attachments&&e.attachments.length>0){const c=await Promise.all(e.attachments.map(async t=>{let r;if(t.raw!==void 0)r=t.raw;else{if(t.content===void 0)throw new C("attachment",`Attachment '${t.filename}' must have content, raw, or be resolved from path/href before building MIME message`);r=t.content instanceof Promise?await t.content:t.content}return{...t,resolvedContent:r}}));for(const t of c){n.push(`--${o}`);const r=t.contentType||"application/octet-stream",a=h(t.filename);n.push(`Content-Type: ${r}; name="${a}"`);const s=t.contentDisposition||"attachment";n.push(`Content-Disposition: ${s}; filename="${a}"`),t.cid&&n.push(`Content-ID: <${t.cid}>`),t.headers&&Object.entries(t.headers).forEach(([u,$])=>{const y=b(u),T=h($);n.push(`${y}: ${T}`)});const f=t.encoding||"base64";n.push(`Content-Transfer-Encoding: ${f}`,"");const i=t.resolvedContent;if(f==="base64")n.push(g(i));else if(f==="7bit"||f==="8bit")if(typeof i=="string")n.push(i);else if(S&&i instanceof Buffer)n.push(i.toString("utf8"));else{const u=new TextDecoder;n.push(u.decode(i))}else n.push(g(i));n.push("")}}return n.push(`--${o}--`),n.join(`\r
|
|
2
|
-
`)},"buildMimeMessage");export{I as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var r=Object.defineProperty;var o=(e,a)=>r(e,"name",{value:a,configurable:!0});var t=Object.defineProperty,i=o((e,a)=>t(e,"name",{value:a,configurable:!0}),"t");const h=i((e,a)=>e===a?0:e==="high"?-1:a==="high"||e==="low"?1:-1,"comparePriority");export{h as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var $=Object.defineProperty;var u=(e,r)=>$(e,"name",{value:r,configurable:!0});var f=Object.defineProperty,n=u((e,r)=>f(e,"name",{value:r,configurable:!0}),"s");const b=n((e,r)=>{const t=n(()=>{},"noop");return r?{debug:n((o,...a)=>{r.log(`[${e}] ${o}`,...a)},"debug"),error:n((o,...a)=>{r.error(`[${e}] ${o}`,...a)},"error"),info:n((o,...a)=>{r.info(`[${e}] ${o}`,...a)},"info"),warn:n((o,...a)=>{r.warn(`[${e}] ${o}`,...a)},"warn")}:{debug:t,error:t,info:t,warn:t}},"createLogger");export{b as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var w=Object.defineProperty;var b=(e,l)=>w(e,"name",{value:l,configurable:!0});import u from"./EmailError-zm2ffVav.js";import $ from"./RequiredOptionError-CevW3u2K.js";import A from"./generateMessageId-11Ls5JsR.js";import{defineProvider as E}from"./defineProvider-B9rSklAJ.js";import z from"./createLogger-DlElSVQP.js";var P=Object.defineProperty,p=b((e,l)=>P(e,"name",{value:l,configurable:!0}),"v");const k=p(e=>typeof e=="function","isProviderFactory"),F=p(e=>e!==null&&typeof e=="object"&&"sendEmail"in e&&"initialize"in e&&"isAvailable"in e,"isProvider"),o="failover",C=E((e={})=>{if(!e.mailers||e.mailers.length===0)throw new $(o,"mailers");const l={debug:e.debug||!1,mailers:e.mailers,retryAfter:e.retryAfter??60};let h=!1;const t=[],s=z(o,e.logger);let g;const m=p(async()=>g||(g=(async()=>{t.length=0;for(const a of l.mailers)try{let r;if(k(a))r=a({});else if(F(a))r=a;else{s.debug(`Skipping invalid mailer: ${a}`);continue}try{await r.initialize(),t.push(r),s.debug(`Initialized provider: ${r.name||"unknown"}`)}catch(c){s.debug(`Failed to initialize provider ${r.name||"unknown"}:`,c)}}catch(r){s.debug("Error processing mailer:",r)}if(t.length===0)throw new u(o,"No providers could be initialized")})(),g),"initializeProviders");return{features:{attachments:!0,batchSending:!1,customHeaders:!0,html:!0,replyTo:!0,scheduling:!1,tagging:!1,templates:!1,tracking:!1},async initialize(){if(!h)try{await m(),h=!0,s.debug(`Failover provider initialized with ${t.length} provider(s)`)}catch(a){throw new u(o,`Failed to initialize: ${a.message}`,{cause:a})}},async isAvailable(){try{t.length===0&&await m();for(const a of t)try{if(await a.isAvailable())return!0}catch{}return!1}catch{return!1}},name:o,options:l,async sendEmail(a){try{if(t.length===0&&await m(),t.length===0)return{error:new u(o,"No providers available"),success:!1};const r=[];let c;for(let n=0;n<t.length;n+=1){const f=t[n];if(!f)continue;const d=f.name||`provider-${n+1}`;s.debug(`Attempting to send email via ${d} (${n+1}/${t.length})`);try{if(!await f.isAvailable()){s.debug(`Provider ${d} is not available, skipping`),r.push(new u(o,`Provider ${d} is not available`));continue}const i=await f.sendEmail(a);if(i.success&&i.data)return s.debug(`Email sent successfully via ${d}`),{data:{...i.data,messageId:i.data.messageId||A(),provider:`${o}(${d})`},success:!0};if(i.error){c=i.error,r.push(i.error);const v=i.error instanceof Error?i.error.message:String(i.error);s.debug(`Failed to send via ${d}:`,v)}}catch(i){c=i instanceof Error?i:new Error(String(i)),r.push(c);const v=c instanceof Error?c.message:String(c);s.debug(`Exception sending via ${d}:`,v)}n<t.length-1&&l.retryAfter>0&&(s.debug(`Waiting ${l.retryAfter}ms before trying next provider`),await new Promise(i=>{setTimeout(()=>{i()},l.retryAfter)}))}const y=r.map(n=>n instanceof Error?n.message:String(n)).join("; ");return{error:new u(o,`All providers failed. Errors: ${y}`,{cause:c}),success:!1}}catch(r){return{error:new u(o,`Failed to send email: ${r.message}`,{cause:r}),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{C as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var m=Object.defineProperty;var r=(e,a)=>m(e,"name",{value:a,configurable:!0});import o from"./EmailError-zm2ffVav.js";import{s as l}from"./sanitize-header-wWav-Scu.js";import t from"./validateEmail-BkVdVioP.js";var i=Object.defineProperty,n=r((e,a)=>i(e,"name",{value:a,configurable:!0}),"m");const p=n(e=>{if(!t(e.email))throw new o("email",`Invalid email address: ${e.email}`);return e.name?`${l(e.name)} <${e.email}>`:e.email},"formatEmailAddress");export{p as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var t=Object.defineProperty;var r=(a,e)=>t(a,"name",{value:e,configurable:!0});import o from"./formatEmailAddress-CHeME3Vk.js";var m=Object.defineProperty,i=r((a,e)=>m(a,"name",{value:e,configurable:!0}),"m");const n=i(a=>Array.isArray(a)?a.map(e=>o(e)).join(", "):o(a),"formatEmailAddresses");export{n as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var o=Object.defineProperty;var a=(e,r)=>o(e,"name",{value:r,configurable:!0});var c=Object.defineProperty,f=a((e,r)=>c(e,"name",{value:r,configurable:!0}),"t");const u=f(e=>{if(!(e instanceof Headers))return e;const r={};return e.forEach((t,n)=>{r[n]=t}),r},"headersToRecord");export{u as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var v=Object.defineProperty;var p=(r,a)=>v(r,"name",{value:a,configurable:!0});import d from"./EmailError-zm2ffVav.js";import A from"./RequiredOptionError-CevW3u2K.js";import j from"./generateMessageId-11Ls5JsR.js";import{makeRequest as u}from"./makeRequest-DwxHX0xo.js";import O from"./validateEmailOptions-BzlJECG5.js";import{defineProvider as P}from"./defineProvider-B9rSklAJ.js";var C=Object.defineProperty,h=p((r,a)=>C(r,"name",{value:a,configurable:!0}),"f");const n="http",I="POST",f=3e4,z=P((r={})=>{if(!r.endpoint)throw new A(n,"endpoint");const a={apiKey:r.apiKey||"",endpoint:r.endpoint,headers:r.headers||{},method:r.method||I},m=h(()=>{const e={"Content-Type":"application/json",...a.headers};return a.apiKey&&(e.Authorization=`Bearer ${a.apiKey}`),e},"getStandardHeaders"),y=h(e=>{const t={from:e.from.email,from_name:e.from.name,html:e.html,subject:e.subject,text:e.text,to:Array.isArray(e.to)?e.to.map(s=>s.email):e.to.email};return e.cc&&(t.cc=Array.isArray(e.cc)?e.cc.map(s=>s.email):e.cc.email),e.bcc&&(t.bcc=Array.isArray(e.bcc)?e.bcc.map(s=>s.email):e.bcc.email),e.customParams&&Object.assign(t,e.customParams),t},"formatRequest");let l=!1;return{features:{attachments:!1,batchSending:!1,customHeaders:!0,html:!0,replyTo:!1,scheduling:!1,tagging:!1,templates:!1,tracking:!1},async initialize(){if(!l){if(!await this.isAvailable())throw new d(n,"API endpoint not available");l=!0}},async isAvailable(){try{return!!(await u(a.endpoint,{headers:m(),method:"OPTIONS",timeout:f})).success}catch(e){if(e instanceof Error){const t=e.message;if(t.includes("401")||t.includes("403"))return!1}return!1}},name:n,options:a,async sendEmail(e){try{const t=O(e);if(t.length>0)return{error:new d(n,`Invalid email options: ${t.join(", ")}`),success:!1};l||await this.initialize();const s=m();e.headers&&Object.assign(s,e.headers);const b=y(e),g=e.endpointOverride||a.endpoint,w=e.methodOverride||a.method,o=await u(g,{headers:s,method:w,timeout:f},JSON.stringify(b));if(!o.success)return{error:new d(n,`Failed to send email: ${o.error?.message||"Unknown error"}`,{cause:o.error}),success:!1};let c;const i=o.data?.body;return i&&typeof i=="object"&&(c=i.id||i.messageId||i.data&&typeof i.data=="object"&&(i.data.id||i.data.messageId)),c||(c=j()),{data:{messageId:c,provider:n,response:o.data?.body,sent:!0,timestamp:new Date},success:!0}}catch(t){return{error:new d(n,`Failed to send email: ${t.message}`,{cause:t}),success:!1}}},async validateCredentials(){try{const e=await u(a.endpoint,{headers:m(),method:"GET",timeout:f});return!!(e.data&&typeof e.data=="object"&&"statusCode"in e.data&&typeof e.data.statusCode=="number"&&e.data.statusCode>=200&&e.data.statusCode<300)}catch{return!1}}}});export{z as default};
|