@visulima/email 1.0.0-alpha.1 → 1.0.0-alpha.10

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.
Files changed (148) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/LICENSE.md +6 -6
  3. package/README.md +408 -72
  4. package/dist/crypto/index.js +1 -1
  5. package/dist/draft-mail-message.d.ts +13 -0
  6. package/dist/index.d.ts +3 -16
  7. package/dist/index.js +1 -1
  8. package/dist/mail-message.d.ts +425 -0
  9. package/dist/mail.d.ts +124 -275
  10. package/dist/packem_shared/{DkimSigner-Z8D4Il10.js → DkimSigner-pFd4c3fZ.js} +1 -1
  11. package/dist/packem_shared/EmailError-C4nx6TgJ.js +1 -0
  12. package/dist/packem_shared/Mail-CmvJ5iZg.js +1 -0
  13. package/dist/packem_shared/MailMessage-B76GPBBA.js +1 -0
  14. package/dist/packem_shared/{RequiredOptionError-CevW3u2K.js → RequiredOptionError-BeTzeno6.js} +1 -1
  15. package/dist/packem_shared/{SmimeSigner-02aXVi90.js → SmimeSigner-CObA4jzT.js} +1 -1
  16. package/dist/packem_shared/ahaSendProvider-CBqIPxEd.js +1 -0
  17. package/dist/packem_shared/{attachment-processor-2rHmfa7j.js → attachment-processor-E18l3TW_.js} +1 -1
  18. package/dist/packem_shared/{awsSesProvider-CkuFOzb0.js → awsSesProvider-BPRp4yoX.js} +6 -6
  19. package/dist/packem_shared/azureProvider-m8hC1YG8.js +1 -0
  20. package/dist/packem_shared/brevoProvider-D9c9c-Ef.js +1 -0
  21. package/dist/packem_shared/build-mime-message-BzDR2Zv-.js +2 -0
  22. package/dist/packem_shared/create-logger-BiWdqFNg.js +1 -0
  23. package/dist/packem_shared/failoverProvider-uP2Wpi5x.js +1 -0
  24. package/dist/packem_shared/{generateBoundary-CZ8kJuY6.js → generate-boundary-Cx8nXYS0.js} +1 -1
  25. package/dist/packem_shared/{generateMessageId-11Ls5JsR.js → generate-message-id-D4uA8gkj.js} +1 -1
  26. package/dist/packem_shared/headers-to-record-Qo124ImV.js +1 -0
  27. package/dist/packem_shared/httpProvider-DAZnfgDh.js +1 -0
  28. package/dist/packem_shared/infobipProvider-pP3a1I1z.js +1 -0
  29. package/dist/packem_shared/{mailCrabProvider-BEwRjB3F.js → mailCrabProvider-Ccm6HIsr.js} +1 -1
  30. package/dist/packem_shared/mailPaceProvider-BdpdKp7S.js +1 -0
  31. package/dist/packem_shared/mailerSendProvider-BPJ4RzsE.js +1 -0
  32. package/dist/packem_shared/mailgunProvider-CwvMTsc_.js +1 -0
  33. package/dist/packem_shared/mailjetProvider-CUJMsFSY.js +1 -0
  34. package/dist/packem_shared/mailomatProvider-B_l5QnwN.js +1 -0
  35. package/dist/packem_shared/mailtrapProvider-CmICY2yv.js +1 -0
  36. package/dist/packem_shared/{makeRequest-DwxHX0xo.js → make-request-sA_-JKm0.js} +1 -1
  37. package/dist/packem_shared/mandrillProvider-Dj4vhxjz.js +1 -0
  38. package/dist/packem_shared/mockProvider-UiTviqTp.js +1 -0
  39. package/dist/packem_shared/nodemailerProvider-BqG5vYka.js +1 -0
  40. package/dist/packem_shared/opentelemetryProvider-1uJuHIQ5.js +1 -0
  41. package/dist/packem_shared/plunkProvider-DMdTroUj.js +1 -0
  42. package/dist/packem_shared/postalProvider-DG2rY0mt.js +1 -0
  43. package/dist/packem_shared/postmarkProvider-DaR-sY5P.js +1 -0
  44. package/dist/packem_shared/provider-base-8LBAorjm.js +1 -0
  45. package/dist/packem_shared/resendProvider-998actWK.js +1 -0
  46. package/dist/packem_shared/roundRobinProvider-DroogcP0.js +1 -0
  47. package/dist/packem_shared/scalewayProvider-BWUCBzur.js +1 -0
  48. package/dist/packem_shared/sendGridProvider-D82muNhj.js +1 -0
  49. package/dist/packem_shared/smtpProvider-DzSgmGjo.js +23 -0
  50. package/dist/packem_shared/sweegoProvider-dOP4zYOR.js +1 -0
  51. package/dist/packem_shared/validate-email-options-DfJ7llf8.js +1 -0
  52. package/dist/packem_shared/zeptomailProvider-BWyoNPZH.js +1 -0
  53. package/dist/providers/ahasend/index.js +1 -1
  54. package/dist/providers/aws-ses/index.js +1 -1
  55. package/dist/providers/azure/index.js +1 -1
  56. package/dist/providers/brevo/index.js +1 -1
  57. package/dist/providers/brevo/types.d.ts +10 -3
  58. package/dist/providers/failover/index.js +1 -1
  59. package/dist/providers/http/index.js +1 -1
  60. package/dist/providers/infobip/index.js +1 -1
  61. package/dist/providers/mailcrab/index.js +1 -1
  62. package/dist/providers/mailersend/index.js +1 -1
  63. package/dist/providers/mailgun/index.js +1 -1
  64. package/dist/providers/mailjet/index.js +1 -1
  65. package/dist/providers/mailomat/index.js +1 -1
  66. package/dist/providers/mailpace/index.js +1 -1
  67. package/dist/providers/mailtrap/index.js +1 -1
  68. package/dist/providers/mandrill/index.js +1 -1
  69. package/dist/providers/mock/index.js +1 -1
  70. package/dist/providers/nodemailer/index.js +1 -1
  71. package/dist/providers/opentelemetry/index.js +1 -1
  72. package/dist/providers/plunk/index.js +1 -1
  73. package/dist/providers/postal/index.js +1 -1
  74. package/dist/providers/postmark/index.js +1 -1
  75. package/dist/providers/resend/index.js +1 -1
  76. package/dist/providers/roundrobin/index.js +1 -1
  77. package/dist/providers/scaleway/index.js +1 -1
  78. package/dist/providers/sendgrid/index.js +1 -1
  79. package/dist/providers/smtp/index.js +1 -1
  80. package/dist/providers/sweego/index.js +1 -1
  81. package/dist/providers/zeptomail/index.js +1 -1
  82. package/dist/template-engines/handlebars.js +1 -1
  83. package/dist/template-engines/html-to-text.js +1 -1
  84. package/dist/template-engines/mjml.js +1 -1
  85. package/dist/template-engines/react-email.js +1 -1
  86. package/dist/template-engines/vue-email.js +1 -1
  87. package/dist/types.d.ts +18 -0
  88. package/dist/utils/cache.d.ts +54 -0
  89. package/dist/utils/cache.js +1 -0
  90. package/dist/utils/create-logger.d.ts +2 -4
  91. package/dist/utils/format-email-address.js +1 -0
  92. package/dist/utils/normalize-email-aliases.d.ts +22 -0
  93. package/dist/utils/normalize-email-aliases.js +1 -0
  94. package/dist/utils/parse-address.js +1 -0
  95. package/dist/utils/validation/check-mx-records.d.ts +42 -0
  96. package/dist/utils/validation/check-mx-records.js +1 -0
  97. package/dist/utils/validation/disposable-email-domains.d.ts +13 -0
  98. package/dist/utils/validation/disposable-email-domains.js +1 -0
  99. package/dist/utils/validation/role-accounts.d.ts +21 -0
  100. package/dist/utils/validation/role-accounts.js +1 -0
  101. package/dist/utils/{validate-email-options.d.ts → validation/validate-email-options.d.ts} +1 -1
  102. package/dist/utils/validation/verify-email.d.ts +47 -0
  103. package/dist/utils/validation/verify-email.js +1 -0
  104. package/dist/utils/validation/verify-smtp.d.ts +39 -0
  105. package/dist/utils/validation/verify-smtp.js +4 -0
  106. package/package.json +49 -3
  107. package/dist/packem_shared/EmailError-zm2ffVav.js +0 -1
  108. package/dist/packem_shared/MailMessage-Hdgowmvi.js +0 -1
  109. package/dist/packem_shared/ahaSendProvider-NUD_kwyT.js +0 -1
  110. package/dist/packem_shared/azureProvider-Ckdrpmw9.js +0 -1
  111. package/dist/packem_shared/brevoProvider-CB3IYW4n.js +0 -1
  112. package/dist/packem_shared/buildMimeMessage-BPtd0pno.js +0 -2
  113. package/dist/packem_shared/comparePriority-BfiwjVsV.js +0 -1
  114. package/dist/packem_shared/createLogger-DlElSVQP.js +0 -1
  115. package/dist/packem_shared/failoverProvider-sam9n1AG.js +0 -1
  116. package/dist/packem_shared/formatEmailAddress-CHeME3Vk.js +0 -1
  117. package/dist/packem_shared/formatEmailAddresses-UegVOe5A.js +0 -1
  118. package/dist/packem_shared/headersToRecord-BKUTr40L.js +0 -1
  119. package/dist/packem_shared/httpProvider-BhN0RrK-.js +0 -1
  120. package/dist/packem_shared/infobipProvider-D8vYTHV4.js +0 -1
  121. package/dist/packem_shared/isPortAvailable-5kfsfo8u.js +0 -1
  122. package/dist/packem_shared/mailPaceProvider-C47Izgaj.js +0 -1
  123. package/dist/packem_shared/mailerSendProvider-C4uAo-fc.js +0 -1
  124. package/dist/packem_shared/mailgunProvider-B7upu_OV.js +0 -1
  125. package/dist/packem_shared/mailjetProvider-ReErm08u.js +0 -1
  126. package/dist/packem_shared/mailomatProvider-OlCT_O2i.js +0 -1
  127. package/dist/packem_shared/mailtrapProvider-hVMV3h6r.js +0 -1
  128. package/dist/packem_shared/mandrillProvider-DdnbkHZI.js +0 -1
  129. package/dist/packem_shared/mockProvider-BDWZJpea.js +0 -1
  130. package/dist/packem_shared/nodemailerProvider-BV21eRGX.js +0 -1
  131. package/dist/packem_shared/opentelemetryProvider-kAz62mKm.js +0 -1
  132. package/dist/packem_shared/parseAddress-CATTKGe_.js +0 -1
  133. package/dist/packem_shared/plunkProvider-Bs6K51lT.js +0 -1
  134. package/dist/packem_shared/postalProvider-Bcsxp-z6.js +0 -1
  135. package/dist/packem_shared/postmarkProvider-BUq3wuYD.js +0 -1
  136. package/dist/packem_shared/provider-base-_hbWXBdK.js +0 -1
  137. package/dist/packem_shared/resendProvider-D-_HQpN_.js +0 -1
  138. package/dist/packem_shared/retry-D1MBqS49.js +0 -1
  139. package/dist/packem_shared/roundRobinProvider-CejLM1rZ.js +0 -1
  140. package/dist/packem_shared/scalewayProvider-1n6ePiGl.js +0 -1
  141. package/dist/packem_shared/sendGridProvider-B1T62dyX.js +0 -1
  142. package/dist/packem_shared/smtpProvider-CcAoRrkt.js +0 -23
  143. package/dist/packem_shared/sweegoProvider-CxFmEUh6.js +0 -1
  144. package/dist/packem_shared/validateEmailOptions-BzlJECG5.js +0 -1
  145. package/dist/packem_shared/zeptomailProvider-CWYQPAJk.js +0 -1
  146. package/dist/utils/compare-priority.d.ts +0 -16
  147. /package/dist/utils/{validate-email.d.ts → validation/validate-email.d.ts} +0 -0
  148. /package/dist/{packem_shared/validateEmail-BkVdVioP.js → utils/validation/validate-email.js} +0 -0
@@ -12,11 +12,17 @@ export interface BrevoConfig extends BaseConfig {
12
12
  * Defaults to: https://api.brevo.com/v3
13
13
  */
14
14
  endpoint?: string;
15
+ /**
16
+ * Enable hard validation for replyTo addresses.
17
+ * If true, arrays will be rejected. If false, the first address from an array will be used.
18
+ * Defaults to: false
19
+ */
20
+ hardValidation?: boolean;
15
21
  }
16
22
  /**
17
23
  * Brevo-specific email options
18
24
  */
19
- export interface BrevoEmailOptions extends EmailOptions {
25
+ export interface BrevoEmailOptions extends Omit<EmailOptions, "replyTo"> {
20
26
  /**
21
27
  * Batch ID for batch sending
22
28
  */
@@ -26,9 +32,10 @@ export interface BrevoEmailOptions extends EmailOptions {
26
32
  */
27
33
  headers?: Record<string, string>;
28
34
  /**
29
- * Reply-to email address (can override base replyTo)
35
+ * Reply-to email address (can override base replyTo).
36
+ * Only one address is allowed. If an array is provided and hardValidation is false, the first address will be used.
30
37
  */
31
- replyTo?: EmailAddress;
38
+ replyTo?: EmailAddress | EmailAddress[];
32
39
  /**
33
40
  * Scheduled date/time
34
41
  * - If string: ISO 8601 format (e.g., "2025-01-15T10:00:00Z")
@@ -1 +1 @@
1
- import{default as o}from"../../packem_shared/failoverProvider-sam9n1AG.js";export{o as failoverProvider};
1
+ import{default as o}from"../../packem_shared/failoverProvider-uP2Wpi5x.js";export{o as failoverProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../packem_shared/httpProvider-BhN0RrK-.js";export{e as httpProvider};
1
+ import{default as e}from"../../packem_shared/httpProvider-DAZnfgDh.js";export{e as httpProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../packem_shared/infobipProvider-D8vYTHV4.js";export{e as infobipProvider};
1
+ import{default as e}from"../../packem_shared/infobipProvider-pP3a1I1z.js";export{e as infobipProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../packem_shared/mailCrabProvider-BEwRjB3F.js";export{e as mailCrabProvider};
1
+ import{default as e}from"../../packem_shared/mailCrabProvider-Ccm6HIsr.js";export{e as mailCrabProvider};
@@ -1 +1 @@
1
- import{default as a}from"../../packem_shared/mailerSendProvider-C4uAo-fc.js";export{a as mailerSendProvider};
1
+ import{default as a}from"../../packem_shared/mailerSendProvider-BPJ4RzsE.js";export{a as mailerSendProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../packem_shared/mailgunProvider-B7upu_OV.js";export{e as mailgunProvider};
1
+ import{default as e}from"../../packem_shared/mailgunProvider-CwvMTsc_.js";export{e as mailgunProvider};
@@ -1 +1 @@
1
- import{default as a}from"../../packem_shared/mailjetProvider-ReErm08u.js";export{a as mailjetProvider};
1
+ import{default as a}from"../../packem_shared/mailjetProvider-CUJMsFSY.js";export{a as mailjetProvider};
@@ -1 +1 @@
1
- import{default as r}from"../../packem_shared/mailomatProvider-OlCT_O2i.js";export{r as mailomatProvider};
1
+ import{default as r}from"../../packem_shared/mailomatProvider-B_l5QnwN.js";export{r as mailomatProvider};
@@ -1 +1 @@
1
- import{default as r}from"../../packem_shared/mailPaceProvider-C47Izgaj.js";export{r as mailPaceProvider};
1
+ import{default as r}from"../../packem_shared/mailPaceProvider-BdpdKp7S.js";export{r as mailPaceProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../packem_shared/mailtrapProvider-hVMV3h6r.js";export{e as mailtrapProvider};
1
+ import{default as e}from"../../packem_shared/mailtrapProvider-CmICY2yv.js";export{e as mailtrapProvider};
@@ -1 +1 @@
1
- import{default as d}from"../../packem_shared/mandrillProvider-DdnbkHZI.js";export{d as mandrillProvider};
1
+ import{default as d}from"../../packem_shared/mandrillProvider-Dj4vhxjz.js";export{d as mandrillProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../packem_shared/mockProvider-BDWZJpea.js";export{e as mockProvider};
1
+ import{default as e}from"../../packem_shared/mockProvider-UiTviqTp.js";export{e as mockProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../packem_shared/nodemailerProvider-BV21eRGX.js";export{o as nodemailerProvider};
1
+ import{default as o}from"../../packem_shared/nodemailerProvider-BqG5vYka.js";export{o as nodemailerProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../packem_shared/opentelemetryProvider-kAz62mKm.js";export{o as opentelemetryProvider};
1
+ import{default as o}from"../../packem_shared/opentelemetryProvider-1uJuHIQ5.js";export{o as opentelemetryProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../packem_shared/plunkProvider-Bs6K51lT.js";export{o as plunkProvider};
1
+ import{default as o}from"../../packem_shared/plunkProvider-DMdTroUj.js";export{o as plunkProvider};
@@ -1 +1 @@
1
- import{default as a}from"../../packem_shared/postalProvider-Bcsxp-z6.js";export{a as postalProvider};
1
+ import{default as a}from"../../packem_shared/postalProvider-DG2rY0mt.js";export{a as postalProvider};
@@ -1 +1 @@
1
- import{default as a}from"../../packem_shared/postmarkProvider-BUq3wuYD.js";export{a as postmarkProvider};
1
+ import{default as a}from"../../packem_shared/postmarkProvider-DaR-sY5P.js";export{a as postmarkProvider};
@@ -1 +1 @@
1
- import{default as d}from"../../packem_shared/resendProvider-D-_HQpN_.js";export{d as resendProvider};
1
+ import{default as d}from"../../packem_shared/resendProvider-998actWK.js";export{d as resendProvider};
@@ -1 +1 @@
1
- import{default as d}from"../../packem_shared/roundRobinProvider-CejLM1rZ.js";export{d as roundRobinProvider};
1
+ import{default as d}from"../../packem_shared/roundRobinProvider-DroogcP0.js";export{d as roundRobinProvider};
@@ -1 +1 @@
1
- import{default as r}from"../../packem_shared/scalewayProvider-1n6ePiGl.js";export{r as scalewayProvider};
1
+ import{default as r}from"../../packem_shared/scalewayProvider-BWUCBzur.js";export{r as scalewayProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../packem_shared/sendGridProvider-B1T62dyX.js";export{e as sendGridProvider};
1
+ import{default as e}from"../../packem_shared/sendGridProvider-D82muNhj.js";export{e as sendGridProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../packem_shared/smtpProvider-CcAoRrkt.js";export{o as smtpProvider};
1
+ import{default as o}from"../../packem_shared/smtpProvider-DzSgmGjo.js";export{o as smtpProvider};
@@ -1 +1 @@
1
- import{default as r}from"../../packem_shared/sweegoProvider-CxFmEUh6.js";export{r as sweegoProvider};
1
+ import{default as r}from"../../packem_shared/sweegoProvider-dOP4zYOR.js";export{r as sweegoProvider};
@@ -1 +1 @@
1
- import{default as r}from"../../packem_shared/zeptomailProvider-CWYQPAJk.js";export{r as zeptomailProvider};
1
+ import{default as r}from"../../packem_shared/zeptomailProvider-BWyoNPZH.js";export{r as zeptomailProvider};
@@ -1 +1 @@
1
- var i=Object.defineProperty;var d=(a,r)=>i(a,"name",{value:r,configurable:!0});import t from"handlebars";import s from"../packem_shared/EmailError-zm2ffVav.js";var o=Object.defineProperty,l=d((a,r)=>o(a,"name",{value:r,configurable:!0}),"s");const p=l((a,r,e)=>{try{if(typeof a!="string")throw new TypeError("Handlebars template must be a string");return t.compile(a,e)(r||{})}catch(n){throw n instanceof Error&&n.message.includes("Cannot find module")?new s("handlebars","Handlebars is not installed. Please install it: pnpm add handlebars",{cause:n}):new s("handlebars",`Failed to render Handlebars template: ${n.message}`,{cause:n})}},"renderHandlebars"),u=l((a,r)=>{try{t.registerHelper(a,r)}catch(e){throw e instanceof Error&&e.message.includes("Cannot find module")?new s("handlebars","Handlebars is not installed. Please install it: pnpm add handlebars",{cause:e}):e}},"registerHandlebarsHelper"),h=l((a,r)=>{try{t.registerPartial(a,r)}catch(e){throw e instanceof Error&&e.message.includes("Cannot find module")?new s("handlebars","Handlebars is not installed. Please install it: pnpm add handlebars",{cause:e}):e}},"registerHandlebarsPartial");export{u as registerHandlebarsHelper,h as registerHandlebarsPartial,p as renderHandlebars};
1
+ var i=Object.defineProperty;var d=(a,r)=>i(a,"name",{value:r,configurable:!0});import t from"handlebars";import s from"../packem_shared/EmailError-C4nx6TgJ.js";var o=Object.defineProperty,l=d((a,r)=>o(a,"name",{value:r,configurable:!0}),"s");const p=l((a,r,e)=>{try{if(typeof a!="string")throw new TypeError("Handlebars template must be a string");return t.compile(a,e)(r||{})}catch(n){throw n instanceof Error&&n.message.includes("Cannot find module")?new s("handlebars","Handlebars is not installed. Please install it: pnpm add handlebars",{cause:n}):new s("handlebars",`Failed to render Handlebars template: ${n.message}`,{cause:n})}},"renderHandlebars"),u=l((a,r)=>{try{t.registerHelper(a,r)}catch(e){throw e instanceof Error&&e.message.includes("Cannot find module")?new s("handlebars","Handlebars is not installed. Please install it: pnpm add handlebars",{cause:e}):e}},"registerHandlebarsHelper"),h=l((a,r)=>{try{t.registerPartial(a,r)}catch(e){throw e instanceof Error&&e.message.includes("Cannot find module")?new s("handlebars","Handlebars is not installed. Please install it: pnpm add handlebars",{cause:e}):e}},"registerHandlebarsPartial");export{u as registerHandlebarsHelper,h as registerHandlebarsPartial,p as renderHandlebars};
@@ -1 +1 @@
1
- var n=Object.defineProperty;var o=(t,e)=>n(t,"name",{value:e,configurable:!0});import{convert as a}from"html-to-text";import l from"../packem_shared/EmailError-zm2ffVav.js";var s=Object.defineProperty,i=o((t,e)=>s(t,"name",{value:e,configurable:!0}),"o");const p=i((t,e)=>{try{return a(t,{longWordSplit:e?.longWordSplit,preserveNewlines:e?.preserveNewlines??!1,selectors:e?.selectors,wordwrap:e?.wordwrap??80})}catch(r){throw r instanceof Error&&r.message.includes("Cannot find module")?new l("html-to-text","html-to-text is not installed. Please install it: pnpm add html-to-text",{cause:r}):new l("html-to-text",`Failed to convert HTML to text: ${r.message}`,{cause:r})}},"htmlToText");export{p as default};
1
+ var n=Object.defineProperty;var o=(t,e)=>n(t,"name",{value:e,configurable:!0});import{convert as a}from"html-to-text";import l from"../packem_shared/EmailError-C4nx6TgJ.js";var s=Object.defineProperty,i=o((t,e)=>s(t,"name",{value:e,configurable:!0}),"o");const p=i((t,e)=>{try{return a(t,{longWordSplit:e?.longWordSplit,preserveNewlines:e?.preserveNewlines??!1,selectors:e?.selectors,wordwrap:e?.wordwrap??80})}catch(r){throw r instanceof Error&&r.message.includes("Cannot find module")?new l("html-to-text","html-to-text is not installed. Please install it: pnpm add html-to-text",{cause:r}):new l("html-to-text",`Failed to convert HTML to text: ${r.message}`,{cause:r})}},"htmlToText");export{p as default};
@@ -1 +1 @@
1
- var i=Object.defineProperty;var a=(t,o)=>i(t,"name",{value:o,configurable:!0});import l from"mjml";import r from"../packem_shared/EmailError-zm2ffVav.js";var f=Object.defineProperty,d=a((t,o)=>f(t,"name",{value:o,configurable:!0}),"o");const v=d((t,o,n)=>{try{if(typeof t!="string")throw new TypeError("MJML template must be a string");const e=l(t,{beautify:n?.beautify??!1,fonts:n?.fonts,keepComments:n?.keepComments??!0,minify:n?.minify??!1,validationLevel:n?.validationLevel??"soft"});if(e.errors&&e.errors.length>0){const s=e.errors.map(m=>m.message).join("; ");throw new r("mjml",`MJML validation errors: ${s}`)}return e.html}catch(e){throw e instanceof Error&&e.message.includes("Cannot find module")?new r("mjml","MJML is not installed. Please install it: pnpm add mjml",{cause:e}):e instanceof r?e:new r("mjml",`Failed to render MJML: ${e.message}`,{cause:e})}},"mjml");export{v as default};
1
+ var i=Object.defineProperty;var a=(t,o)=>i(t,"name",{value:o,configurable:!0});import l from"mjml";import r from"../packem_shared/EmailError-C4nx6TgJ.js";var f=Object.defineProperty,d=a((t,o)=>f(t,"name",{value:o,configurable:!0}),"o");const v=d((t,o,n)=>{try{if(typeof t!="string")throw new TypeError("MJML template must be a string");const e=l(t,{beautify:n?.beautify??!1,fonts:n?.fonts,keepComments:n?.keepComments??!0,minify:n?.minify??!1,validationLevel:n?.validationLevel??"soft"});if(e.errors&&e.errors.length>0){const s=e.errors.map(m=>m.message).join("; ");throw new r("mjml",`MJML validation errors: ${s}`)}return e.html}catch(e){throw e instanceof Error&&e.message.includes("Cannot find module")?new r("mjml","MJML is not installed. Please install it: pnpm add mjml",{cause:e}):e instanceof r?e:new r("mjml",`Failed to render MJML: ${e.message}`,{cause:e})}},"mjml");export{v as default};
@@ -1 +1 @@
1
- var l=Object.defineProperty;var n=(e,t)=>l(e,"name",{value:t,configurable:!0});import{render as c}from"@react-email/render";import i from"../packem_shared/EmailError-zm2ffVav.js";var o=Object.defineProperty,m=n((e,t)=>o(e,"name",{value:t,configurable:!0}),"t");const u=m(async(e,t,r)=>{try{return await c(e,{plainText:r?.plainText,pretty:r?.pretty})}catch(a){throw a instanceof Error&&a.message.includes("Cannot find module")?new i("react-email","@react-email/render is not installed. Please install it: pnpm add @react-email/render",{cause:a}):new i("react-email",`Failed to render React Email component: ${a.message}`,{cause:a})}},"reactEmail");export{u as default};
1
+ var l=Object.defineProperty;var n=(e,t)=>l(e,"name",{value:t,configurable:!0});import{render as c}from"@react-email/render";import i from"../packem_shared/EmailError-C4nx6TgJ.js";var o=Object.defineProperty,m=n((e,t)=>o(e,"name",{value:t,configurable:!0}),"t");const u=m(async(e,t,r)=>{try{return await c(e,{plainText:r?.plainText,pretty:r?.pretty})}catch(a){throw a instanceof Error&&a.message.includes("Cannot find module")?new i("react-email","@react-email/render is not installed. Please install it: pnpm add @react-email/render",{cause:a}):new i("react-email",`Failed to render React Email component: ${a.message}`,{cause:a})}},"reactEmail");export{u as default};
@@ -1 +1 @@
1
- var l=Object.defineProperty;var r=(e,a)=>l(e,"name",{value:a,configurable:!0});import{render as o}from"@vue-email/render";import i from"../packem_shared/EmailError-zm2ffVav.js";var m=Object.defineProperty,s=r((e,a)=>m(e,"name",{value:a,configurable:!0}),"a");const c=s(async(e,a,n)=>{try{return await o(e,a??{},{htmlToTextOptions:n?.htmlToTextOptions,plainText:n?.plainText,pretty:n?.pretty})}catch(t){throw t instanceof Error&&t.message.includes("Cannot find module")?new i("vue-email","@vue-email/render is not installed. Please install it: pnpm add @vue-email/render",{cause:t}):new i("vue-email",`Failed to render Vue Email component: ${t.message}`,{cause:t})}},"vueEmail");export{c as default};
1
+ var l=Object.defineProperty;var r=(e,a)=>l(e,"name",{value:a,configurable:!0});import{render as o}from"@vue-email/render";import i from"../packem_shared/EmailError-C4nx6TgJ.js";var m=Object.defineProperty,s=r((e,a)=>m(e,"name",{value:a,configurable:!0}),"a");const c=s(async(e,a,n)=>{try{return await o(e,a??{},{htmlToTextOptions:n?.htmlToTextOptions,plainText:n?.plainText,pretty:n?.pretty})}catch(t){throw t instanceof Error&&t.message.includes("Cannot find module")?new i("vue-email","@vue-email/render is not installed. Please install it: pnpm add @vue-email/render",{cause:t}):new i("vue-email",`Failed to render Vue Email component: ${t.message}`,{cause:t})}},"vueEmail");export{c as default};
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-C4nx6TgJ.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};
@@ -1,4 +1,4 @@
1
- import type { EmailOptions } from "../types.d.ts";
1
+ import type { EmailOptions } from "../../types.d.ts";
2
2
  /**
3
3
  * Validates email options and returns any validation errors.
4
4
  * @param options The email options to validate.
@@ -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};