sently 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +86 -98
  3. package/dist/adapters/bun.js +1 -1
  4. package/dist/adapters/bun.js.map +1 -1
  5. package/dist/adapters/cf.d.ts +2 -2
  6. package/dist/adapters/cf.js +2 -2
  7. package/dist/adapters/cf.js.map +2 -2
  8. package/dist/adapters/deno.d.ts +2 -2
  9. package/dist/adapters/deno.js +1 -1
  10. package/dist/adapters/deno.js.map +1 -1
  11. package/dist/adapters/node.js +1 -1
  12. package/dist/adapters/node.js.map +1 -1
  13. package/dist/auth/oauth2.js +1 -1
  14. package/dist/{chunk-qnz9z0d4.js → chunk-4mvp3b85.js} +2 -2
  15. package/dist/chunk-4mvp3b85.js.map +10 -0
  16. package/dist/chunk-74rha3ac.js +4 -0
  17. package/dist/chunk-74rha3ac.js.map +10 -0
  18. package/dist/{chunk-n601jhpd.js → chunk-a1c87hn1.js} +2 -2
  19. package/dist/chunk-a1c87hn1.js.map +10 -0
  20. package/dist/chunk-cvrbfke9.js +13 -0
  21. package/dist/{chunk-w3fnjh04.js.map → chunk-cvrbfke9.js.map} +2 -2
  22. package/dist/{chunk-wzdcz88x.js → chunk-d5rwm3br.js} +2 -2
  23. package/dist/{chunk-wzdcz88x.js.map → chunk-d5rwm3br.js.map} +1 -1
  24. package/dist/{chunk-y4qxdyqn.js → chunk-gh5n759p.js} +3 -3
  25. package/dist/{chunk-y4qxdyqn.js.map → chunk-gh5n759p.js.map} +1 -1
  26. package/dist/{chunk-y72qggqf.js → chunk-gkkv7yqm.js} +2 -2
  27. package/dist/{chunk-y72qggqf.js.map → chunk-gkkv7yqm.js.map} +1 -1
  28. package/dist/chunk-ka6t8g77.js +4 -0
  29. package/dist/chunk-ka6t8g77.js.map +11 -0
  30. package/dist/{chunk-tfxje74k.js → chunk-kebhy657.js} +2 -2
  31. package/dist/{chunk-tfxje74k.js.map → chunk-kebhy657.js.map} +1 -1
  32. package/dist/{chunk-rszb1n1d.js → chunk-keksa6fx.js} +2 -2
  33. package/dist/{chunk-rszb1n1d.js.map → chunk-keksa6fx.js.map} +1 -1
  34. package/dist/{chunk-z7j2n9k8.js → chunk-r7ee9tk7.js} +2 -2
  35. package/dist/{chunk-z7j2n9k8.js.map → chunk-r7ee9tk7.js.map} +1 -1
  36. package/dist/{chunk-348wndn3.js → chunk-rm78s1ek.js} +2 -2
  37. package/dist/{chunk-348wndn3.js.map → chunk-rm78s1ek.js.map} +1 -1
  38. package/dist/core/errors.d.ts +1 -1
  39. package/dist/core/errors.js +2 -2
  40. package/dist/core/errors.js.map +1 -1
  41. package/dist/core/smtp.js +2 -2
  42. package/dist/core/smtp.js.map +1 -1
  43. package/dist/core/types.d.ts +4 -8
  44. package/dist/detect.d.ts +1 -7
  45. package/dist/detect.js +2 -2
  46. package/dist/detect.js.map +3 -4
  47. package/dist/dkim.js +2 -2
  48. package/dist/dkim.js.map +1 -1
  49. package/dist/idempotency.js +2 -2
  50. package/dist/idempotency.js.map +2 -2
  51. package/dist/index.d.ts +12 -98
  52. package/dist/index.js +4 -98
  53. package/dist/mailer.js +2 -2
  54. package/dist/mailer.js.map +1 -1
  55. package/dist/plugins/react.js +2 -2
  56. package/dist/plugins/react.js.map +1 -1
  57. package/dist/plugins/template.js +1 -1
  58. package/dist/pool/pool.js +2 -2
  59. package/dist/pool/pool.js.map +1 -1
  60. package/dist/smtp-mailer.d.ts +23 -0
  61. package/dist/smtp-mailer.js +3 -0
  62. package/dist/smtp-mailer.js.map +10 -0
  63. package/dist/transports/brevo.js +2 -2
  64. package/dist/transports/brevo.js.map +2 -2
  65. package/dist/transports/mailgun.js +2 -2
  66. package/dist/transports/mailgun.js.map +3 -3
  67. package/dist/transports/postmark.js +2 -2
  68. package/dist/transports/postmark.js.map +3 -3
  69. package/dist/transports/preview.js +2 -2
  70. package/dist/transports/preview.js.map +1 -1
  71. package/dist/transports/resend.js +2 -2
  72. package/dist/transports/resend.js.map +2 -2
  73. package/dist/transports/retry.js +2 -2
  74. package/dist/transports/retry.js.map +4 -3
  75. package/dist/transports/sendgrid.js +2 -2
  76. package/dist/transports/sendgrid.js.map +2 -2
  77. package/dist/transports/ses.js +2 -2
  78. package/dist/transports/ses.js.map +2 -2
  79. package/dist/transports/smtp.d.ts +1 -0
  80. package/dist/transports/smtp.js +2 -2
  81. package/dist/transports/smtp.js.map +1 -1
  82. package/dist/webhooks/brevo.js +1 -1
  83. package/dist/webhooks/mailgun.js +1 -1
  84. package/dist/webhooks/postmark.js +1 -1
  85. package/dist/webhooks/resend.js +1 -1
  86. package/dist/webhooks/sendgrid.js +1 -1
  87. package/dist/webhooks/ses.js +1 -1
  88. package/dist/webhooks/timing-safe-equal.js +1 -1
  89. package/package.json +5 -1
  90. package/dist/chunk-3y1tr1vt.js +0 -4
  91. package/dist/chunk-3y1tr1vt.js.map +0 -11
  92. package/dist/chunk-n601jhpd.js.map +0 -10
  93. package/dist/chunk-qnz9z0d4.js.map +0 -10
  94. package/dist/chunk-t0en64h9.js +0 -4
  95. package/dist/chunk-t0en64h9.js.map +0 -10
  96. package/dist/chunk-w3fnjh04.js +0 -13
@@ -1,3 +1,3 @@
1
- import{d as F,e as u,f as G,g as H}from"../chunk-q8k3m6qe.js";import"../chunk-rszb1n1d.js";var K={delivered:"delivered",hard_bounce:"bounced",hardBounce:"bounced",soft_bounce:"bounced",soft_bounced:"bounced",softBounce:"bounced",blocked:"bounced",invalid:"bounced",invalid_email:"bounced",deferred:"deferred",spam:"complained",opened:"opened",unique_opened:"opened",uniqueOpened:"opened",click:"clicked",clicked:"clicked",unique_click:"clicked",uniqueClicked:"clicked",sent:"unknown",request:"unknown",unsubscribe:"complained",unsubscribed:"complained"};function L(f){return u(f.ts_event)??u(f.ts)??u(f.date_event)??u(f.date)??u(f.ts_epoch!==void 0?Number(f.ts_epoch):void 0)}function Q(f){if(typeof f["message-id"]==="string")return f["message-id"];if(typeof f.messageId==="string")return f.messageId;return}function U(f){return G(f).flatMap((x)=>{if(typeof x!=="object"||x===null)return[];let q=x,J=typeof q.event==="string"?q.event:"",C=L(q),D=Q(q);return[H({provider:"brevo",type:F(J,K),...D!==void 0?{messageId:D}:{},...typeof q.email==="string"?{recipient:q.email}:{},...C!==void 0?{timestamp:C}:{},raw:x})]})}export{U as parse};
1
+ import{d as F,e as u,f as G,g as H}from"../chunk-q8k3m6qe.js";import"../chunk-keksa6fx.js";var K={delivered:"delivered",hard_bounce:"bounced",hardBounce:"bounced",soft_bounce:"bounced",soft_bounced:"bounced",softBounce:"bounced",blocked:"bounced",invalid:"bounced",invalid_email:"bounced",deferred:"deferred",spam:"complained",opened:"opened",unique_opened:"opened",uniqueOpened:"opened",click:"clicked",clicked:"clicked",unique_click:"clicked",uniqueClicked:"clicked",sent:"unknown",request:"unknown",unsubscribe:"complained",unsubscribed:"complained"};function L(f){return u(f.ts_event)??u(f.ts)??u(f.date_event)??u(f.date)??u(f.ts_epoch!==void 0?Number(f.ts_epoch):void 0)}function Q(f){if(typeof f["message-id"]==="string")return f["message-id"];if(typeof f.messageId==="string")return f.messageId;return}function U(f){return G(f).flatMap((x)=>{if(typeof x!=="object"||x===null)return[];let q=x,J=typeof q.event==="string"?q.event:"",C=L(q),D=Q(q);return[H({provider:"brevo",type:F(J,K),...D!==void 0?{messageId:D}:{},...typeof q.email==="string"?{recipient:q.email}:{},...C!==void 0?{timestamp:C}:{},raw:x})]})}export{U as parse};
2
2
 
3
3
  //# debugId=916BC5D0AADEB5C764756E2164756E21
@@ -1,3 +1,3 @@
1
- import{a as G,c as H}from"../chunk-pqp843mh.js";import{d as Y,e as Z,g as $}from"../chunk-q8k3m6qe.js";import"../chunk-rszb1n1d.js";var R={accepted:"unknown",delivered:"delivered",rejected:"bounced",complained:"complained",opened:"opened",clicked:"clicked",stored:"unknown",unsubscribed:"unknown"};function U(z){let J=typeof z.event==="string"?z.event:"";if(J==="failed")return z.severity==="temporary"?"deferred":"bounced";return Y(J,R)}function b(z){if(!z)return;let J=z.headers;if(typeof J==="object"&&J!==null){let C=J["message-id"];if(typeof C==="string")return C}return typeof z["message-id"]==="string"?z["message-id"]:void 0}function N(z){if(typeof z!=="object"||z===null)return[];let J=z,C=typeof J["event-data"]==="object"&&J["event-data"]!==null?J["event-data"]:J,O=typeof C.message==="object"&&C.message!==null?C.message:void 0,Q=b(O),W=Z(C.timestamp);return[$({provider:"mailgun",type:U(C),...Q!==void 0?{messageId:Q}:{},...typeof C.recipient==="string"?{recipient:C.recipient}:{},...W!==void 0?{timestamp:W}:{},raw:z})]}async function q(z,J,C,O){let Q=await crypto.subtle.importKey("raw",new TextEncoder().encode(O),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),W=new TextEncoder().encode(z+J),L=await crypto.subtle.sign("HMAC",Q,W),P=new Uint8Array(L),X=H(C);if(X===null)return!1;return G(P,X)}async function S(z,J){if(typeof z!=="object"||z===null)return!1;let C=z.signature;if(typeof C!=="object"||C===null)return!1;let O=C;if(typeof O.timestamp!=="string"||typeof O.token!=="string"||typeof O.signature!=="string")return!1;return q(O.timestamp,O.token,O.signature,J)}export{q as verifySignature,S as verifyPayload,N as parse};
1
+ import{a as G,c as H}from"../chunk-pqp843mh.js";import{d as Y,e as Z,g as $}from"../chunk-q8k3m6qe.js";import"../chunk-keksa6fx.js";var R={accepted:"unknown",delivered:"delivered",rejected:"bounced",complained:"complained",opened:"opened",clicked:"clicked",stored:"unknown",unsubscribed:"unknown"};function U(z){let J=typeof z.event==="string"?z.event:"";if(J==="failed")return z.severity==="temporary"?"deferred":"bounced";return Y(J,R)}function b(z){if(!z)return;let J=z.headers;if(typeof J==="object"&&J!==null){let C=J["message-id"];if(typeof C==="string")return C}return typeof z["message-id"]==="string"?z["message-id"]:void 0}function N(z){if(typeof z!=="object"||z===null)return[];let J=z,C=typeof J["event-data"]==="object"&&J["event-data"]!==null?J["event-data"]:J,O=typeof C.message==="object"&&C.message!==null?C.message:void 0,Q=b(O),W=Z(C.timestamp);return[$({provider:"mailgun",type:U(C),...Q!==void 0?{messageId:Q}:{},...typeof C.recipient==="string"?{recipient:C.recipient}:{},...W!==void 0?{timestamp:W}:{},raw:z})]}async function q(z,J,C,O){let Q=await crypto.subtle.importKey("raw",new TextEncoder().encode(O),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),W=new TextEncoder().encode(z+J),L=await crypto.subtle.sign("HMAC",Q,W),P=new Uint8Array(L),X=H(C);if(X===null)return!1;return G(P,X)}async function S(z,J){if(typeof z!=="object"||z===null)return!1;let C=z.signature;if(typeof C!=="object"||C===null)return!1;let O=C;if(typeof O.timestamp!=="string"||typeof O.token!=="string"||typeof O.signature!=="string")return!1;return q(O.timestamp,O.token,O.signature,J)}export{q as verifySignature,S as verifyPayload,N as parse};
2
2
 
3
3
  //# debugId=7FB21CD9E29B4FE264756E2164756E21
@@ -1,3 +1,3 @@
1
- import{d as u,e as q,g as x}from"../chunk-q8k3m6qe.js";import"../chunk-rszb1n1d.js";var C={Delivery:"delivered",Bounce:"bounced",SpamComplaint:"complained",Open:"opened",Click:"clicked",SubscriptionChange:"unknown",Inbound:"unknown"};function F(g){if(typeof g!=="object"||g===null)return[];let f=g,B=typeof f.RecordType==="string"?f.RecordType:"";return[x({provider:"postmark",type:u(B,C),...typeof f.MessageID==="string"?{messageId:f.MessageID}:{},...typeof f.Recipient==="string"?{recipient:f.Recipient}:typeof f.Email==="string"?{recipient:f.Email}:{},...q(f.DeliveredAt??f.BouncedAt??f.ReceivedAt??f.ChangedAt)!==void 0?{timestamp:q(f.DeliveredAt??f.BouncedAt??f.ReceivedAt??f.ChangedAt)}:{},raw:g})]}export{F as parse};
1
+ import{d as u,e as q,g as x}from"../chunk-q8k3m6qe.js";import"../chunk-keksa6fx.js";var C={Delivery:"delivered",Bounce:"bounced",SpamComplaint:"complained",Open:"opened",Click:"clicked",SubscriptionChange:"unknown",Inbound:"unknown"};function F(g){if(typeof g!=="object"||g===null)return[];let f=g,B=typeof f.RecordType==="string"?f.RecordType:"";return[x({provider:"postmark",type:u(B,C),...typeof f.MessageID==="string"?{messageId:f.MessageID}:{},...typeof f.Recipient==="string"?{recipient:f.Recipient}:typeof f.Email==="string"?{recipient:f.Email}:{},...q(f.DeliveredAt??f.BouncedAt??f.ReceivedAt??f.ChangedAt)!==void 0?{timestamp:q(f.DeliveredAt??f.BouncedAt??f.ReceivedAt??f.ChangedAt)}:{},raw:g})]}export{F as parse};
2
2
 
3
3
  //# debugId=7CD05BB54D484C3864756E2164756E21
@@ -1,3 +1,3 @@
1
- import{a as $,b as A}from"../chunk-pqp843mh.js";import{d as X,e as Y,g as Z}from"../chunk-q8k3m6qe.js";import"../chunk-rszb1n1d.js";var j={"email.sent":"unknown","email.scheduled":"unknown","email.delivered":"delivered","email.delivery_delayed":"deferred","email.bounced":"bounced","email.failed":"bounced","email.complained":"complained","email.opened":"opened","email.clicked":"clicked","email.received":"unknown","email.suppressed":"unknown"};function k(G){let F=G.startsWith("whsec_")?G.slice(6):G,K=atob(F),J=new Uint8Array(K.length);for(let z=0;z<K.length;z++)J[z]=K.charCodeAt(z);return J.buffer}function H(G){if(typeof G!=="object"||G===null)return[];let F=G,K=typeof F.type==="string"?F.type:"",J=typeof F.data==="object"&&F.data!==null?F.data:{},z=J.to,L=Array.isArray(z)?typeof z[0]==="string"?z[0]:void 0:typeof z==="string"?z:void 0,O=Y(F.created_at??J.created_at);return[Z({provider:"resend",type:X(K,j),...typeof J.email_id==="string"?{messageId:J.email_id}:{},...L!==void 0?{recipient:L}:{},...O!==void 0?{timestamp:O}:{},raw:G})]}async function I(G,F,K){let J=F["svix-id"],z=F["svix-timestamp"],L=F["svix-signature"];if(!J||!z||!L)return!1;let O=`${J}.${z}.${G}`,D=await crypto.subtle.importKey("raw",k(K),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),M=await crypto.subtle.sign("HMAC",D,new TextEncoder().encode(O)),P=new Uint8Array(M);for(let W of L.split(" ")){let Q=W.split(",",2)[1];if(Q===void 0)continue;let U=A(Q);if(U===null)continue;if($(P,U))return!0}return!1}export{I as verifySignature,H as parse};
1
+ import{a as $,b as A}from"../chunk-pqp843mh.js";import{d as X,e as Y,g as Z}from"../chunk-q8k3m6qe.js";import"../chunk-keksa6fx.js";var j={"email.sent":"unknown","email.scheduled":"unknown","email.delivered":"delivered","email.delivery_delayed":"deferred","email.bounced":"bounced","email.failed":"bounced","email.complained":"complained","email.opened":"opened","email.clicked":"clicked","email.received":"unknown","email.suppressed":"unknown"};function k(G){let F=G.startsWith("whsec_")?G.slice(6):G,K=atob(F),J=new Uint8Array(K.length);for(let z=0;z<K.length;z++)J[z]=K.charCodeAt(z);return J.buffer}function H(G){if(typeof G!=="object"||G===null)return[];let F=G,K=typeof F.type==="string"?F.type:"",J=typeof F.data==="object"&&F.data!==null?F.data:{},z=J.to,L=Array.isArray(z)?typeof z[0]==="string"?z[0]:void 0:typeof z==="string"?z:void 0,O=Y(F.created_at??J.created_at);return[Z({provider:"resend",type:X(K,j),...typeof J.email_id==="string"?{messageId:J.email_id}:{},...L!==void 0?{recipient:L}:{},...O!==void 0?{timestamp:O}:{},raw:G})]}async function I(G,F,K){let J=F["svix-id"],z=F["svix-timestamp"],L=F["svix-signature"];if(!J||!z||!L)return!1;let O=`${J}.${z}.${G}`,D=await crypto.subtle.importKey("raw",k(K),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),M=await crypto.subtle.sign("HMAC",D,new TextEncoder().encode(O)),P=new Uint8Array(M);for(let W of L.split(" ")){let Q=W.split(",",2)[1];if(Q===void 0)continue;let U=A(Q);if(U===null)continue;if($(P,U))return!0}return!1}export{I as verifySignature,H as parse};
2
2
 
3
3
  //# debugId=2EA62D07463E258664756E2164756E21
@@ -1,3 +1,3 @@
1
- import{d as w,e as x,f as B,g as C}from"../chunk-q8k3m6qe.js";import"../chunk-rszb1n1d.js";var F={processed:"unknown",delivered:"delivered",deferred:"deferred",bounce:"bounced",dropped:"bounced",spamreport:"complained",unsubscribe:"complained",group_unsubscribe:"complained",group_resubscribe:"unknown",open:"opened",click:"clicked"};function H(q){let g=typeof q.event==="string"?q.event:"";if(g==="bounce"&&q.type==="blocked")return"deferred";return w(g,F)}function K(q){return B(q).flatMap((g)=>{if(typeof g!=="object"||g===null)return[];let f=g,u=x(f.timestamp);return[C({provider:"sendgrid",type:H(f),...typeof f.sg_message_id==="string"?{messageId:f.sg_message_id}:typeof f["smtp-id"]==="string"?{messageId:f["smtp-id"]}:{},...typeof f.email==="string"?{recipient:f.email}:{},...u!==void 0?{timestamp:u}:{},raw:g})]})}export{K as parse};
1
+ import{d as w,e as x,f as B,g as C}from"../chunk-q8k3m6qe.js";import"../chunk-keksa6fx.js";var F={processed:"unknown",delivered:"delivered",deferred:"deferred",bounce:"bounced",dropped:"bounced",spamreport:"complained",unsubscribe:"complained",group_unsubscribe:"complained",group_resubscribe:"unknown",open:"opened",click:"clicked"};function H(q){let g=typeof q.event==="string"?q.event:"";if(g==="bounce"&&q.type==="blocked")return"deferred";return w(g,F)}function K(q){return B(q).flatMap((g)=>{if(typeof g!=="object"||g===null)return[];let f=g,u=x(f.timestamp);return[C({provider:"sendgrid",type:H(f),...typeof f.sg_message_id==="string"?{messageId:f.sg_message_id}:typeof f["smtp-id"]==="string"?{messageId:f["smtp-id"]}:{},...typeof f.email==="string"?{recipient:f.email}:{},...u!==void 0?{timestamp:u}:{},raw:g})]})}export{K as parse};
2
2
 
3
3
  //# debugId=D4C7DDEE719D449764756E2164756E21
@@ -1,3 +1,3 @@
1
- import{d as Q,e as U,g as X}from"../chunk-q8k3m6qe.js";import"../chunk-rszb1n1d.js";var $={Delivery:"delivered",Bounce:"bounced",Complaint:"complained",Open:"opened",Click:"clicked",DeliveryDelay:"deferred",Send:"unknown",Reject:"bounced","Rendering Failure":"bounced",Subscription:"unknown"};function h(q){if(typeof q.eventType==="string")return q.eventType;if(typeof q.notificationType==="string")return q.notificationType;return""}function j(q){let J=typeof q.delivery==="object"&&q.delivery!==null?q.delivery:void 0;if(J&&Array.isArray(J.recipients)&&typeof J.recipients[0]==="string")return J.recipients[0];let K=typeof q.bounce==="object"&&q.bounce!==null?q.bounce:void 0;if(K&&Array.isArray(K.bouncedRecipients)){let I=K.bouncedRecipients[0];if(typeof I==="object"&&I!==null&&typeof I.emailAddress==="string")return I.emailAddress}let B=typeof q.complaint==="object"&&q.complaint!==null?q.complaint:void 0;if(B&&Array.isArray(B.complainedRecipients)){let I=B.complainedRecipients[0];if(typeof I==="object"&&I!==null&&typeof I.emailAddress==="string")return I.emailAddress}let G=typeof q.mail==="object"&&q.mail!==null?q.mail:void 0;if(Array.isArray(G?.destination)&&typeof G.destination[0]==="string")return G.destination[0];return}function w(q){let J=h(q),K=typeof q.mail==="object"&&q.mail!==null?q.mail:void 0,B=typeof q.bounce==="object"&&q.bounce!==null?q.bounce:void 0,G=typeof q.complaint==="object"&&q.complaint!==null?q.complaint:void 0,I=typeof q.open==="object"&&q.open!==null?q.open:void 0,Y=typeof q.click==="object"&&q.click!==null?q.click:void 0,Z=typeof q.deliveryDelay==="object"&&q.deliveryDelay!==null?q.deliveryDelay:void 0,L=j(q),O=U(q.timestamp??B?.timestamp??G?.timestamp??I?.timestamp??Y?.timestamp??Z?.timestamp??K?.timestamp);return[X({provider:"ses",type:Q(J,$),...typeof K?.messageId==="string"?{messageId:K.messageId}:{},...L!==void 0?{recipient:L}:{},...O!==void 0?{timestamp:O}:{},raw:q})]}function z(q){if(typeof q!=="object"||q===null)return[];let J=q,K=typeof J.Type==="string"?J.Type:"";if(K==="SubscriptionConfirmation")return[];if(K!=="Notification")return[];let B=J.Message,G;if(typeof B==="string")try{G=JSON.parse(B)}catch{return[{provider:"ses",type:"unknown",raw:q}]}else if(typeof B==="object"&&B!==null)G=B;else return[];if(typeof G!=="object"||G===null)return[{provider:"ses",type:"unknown",raw:q}];return w(G)}export{z as parse};
1
+ import{d as Q,e as U,g as X}from"../chunk-q8k3m6qe.js";import"../chunk-keksa6fx.js";var $={Delivery:"delivered",Bounce:"bounced",Complaint:"complained",Open:"opened",Click:"clicked",DeliveryDelay:"deferred",Send:"unknown",Reject:"bounced","Rendering Failure":"bounced",Subscription:"unknown"};function h(q){if(typeof q.eventType==="string")return q.eventType;if(typeof q.notificationType==="string")return q.notificationType;return""}function j(q){let J=typeof q.delivery==="object"&&q.delivery!==null?q.delivery:void 0;if(J&&Array.isArray(J.recipients)&&typeof J.recipients[0]==="string")return J.recipients[0];let K=typeof q.bounce==="object"&&q.bounce!==null?q.bounce:void 0;if(K&&Array.isArray(K.bouncedRecipients)){let I=K.bouncedRecipients[0];if(typeof I==="object"&&I!==null&&typeof I.emailAddress==="string")return I.emailAddress}let B=typeof q.complaint==="object"&&q.complaint!==null?q.complaint:void 0;if(B&&Array.isArray(B.complainedRecipients)){let I=B.complainedRecipients[0];if(typeof I==="object"&&I!==null&&typeof I.emailAddress==="string")return I.emailAddress}let G=typeof q.mail==="object"&&q.mail!==null?q.mail:void 0;if(Array.isArray(G?.destination)&&typeof G.destination[0]==="string")return G.destination[0];return}function w(q){let J=h(q),K=typeof q.mail==="object"&&q.mail!==null?q.mail:void 0,B=typeof q.bounce==="object"&&q.bounce!==null?q.bounce:void 0,G=typeof q.complaint==="object"&&q.complaint!==null?q.complaint:void 0,I=typeof q.open==="object"&&q.open!==null?q.open:void 0,Y=typeof q.click==="object"&&q.click!==null?q.click:void 0,Z=typeof q.deliveryDelay==="object"&&q.deliveryDelay!==null?q.deliveryDelay:void 0,L=j(q),O=U(q.timestamp??B?.timestamp??G?.timestamp??I?.timestamp??Y?.timestamp??Z?.timestamp??K?.timestamp);return[X({provider:"ses",type:Q(J,$),...typeof K?.messageId==="string"?{messageId:K.messageId}:{},...L!==void 0?{recipient:L}:{},...O!==void 0?{timestamp:O}:{},raw:q})]}function z(q){if(typeof q!=="object"||q===null)return[];let J=q,K=typeof J.Type==="string"?J.Type:"";if(K==="SubscriptionConfirmation")return[];if(K!=="Notification")return[];let B=J.Message,G;if(typeof B==="string")try{G=JSON.parse(B)}catch{return[{provider:"ses",type:"unknown",raw:q}]}else if(typeof B==="object"&&B!==null)G=B;else return[];if(typeof G!=="object"||G===null)return[{provider:"ses",type:"unknown",raw:q}];return w(G)}export{z as parse};
2
2
 
3
3
  //# debugId=C5FC4A2C6082819B64756E2164756E21
@@ -1,3 +1,3 @@
1
- import{a,b,c}from"../chunk-pqp843mh.js";import"../chunk-rszb1n1d.js";export{a as timingSafeEqual,c as decodeHexBytes,b as decodeBase64Bytes};
1
+ import{a,b,c}from"../chunk-pqp843mh.js";import"../chunk-keksa6fx.js";export{a as timingSafeEqual,c as decodeHexBytes,b as decodeBase64Bytes};
2
2
 
3
3
  //# debugId=CA7D50FE7388E14864756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sently",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Runtime-agnostic email library for Node.js, Bun, Deno, and Cloudflare Workers. ESM-native Nodemailer alternative with zero dependencies.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -158,6 +158,10 @@
158
158
  "import": "./dist/mailer.js",
159
159
  "types": "./dist/mailer.d.ts"
160
160
  },
161
+ "./smtp": {
162
+ "import": "./dist/smtp-mailer.js",
163
+ "types": "./dist/smtp-mailer.d.ts"
164
+ },
161
165
  "./dkim": {
162
166
  "import": "./dist/dkim.js",
163
167
  "types": "./dist/dkim.d.ts"
@@ -1,4 +0,0 @@
1
- import{v as I}from"./chunk-t0en64h9.js";import{w as M}from"./chunk-tfxje74k.js";import{A as R}from"./chunk-y4qxdyqn.js";async function j(B,G){if(!G||G.length===0)return B;let K=B;for(let Y of G)K=await Y(K);return K}async function k(B){return new q(B.transport,B.plugins??[],B.hooks)}function D(B){return B.attachments!==void 0&&B.attachments.length>0}function f(B){let G=B.constructor.name;if(G==="Object")return"custom";if(G.endsWith("Transport"))return G.slice(0,-9).toLowerCase();return G.toLowerCase()||"unknown"}function C(B,G){return{...B.messageId!==void 0?{messageId:B.messageId}:{},to:R(B.to),subject:B.subject,provider:f(G)}}async function T(B,...G){if(B===void 0)return;try{await B(...G)}catch(K){if(!(typeof process<"u"&&process.env?.NODE_ENV==="production"))console.warn("[sently] Mailer hook threw; send continues:",K)}}class q{transport;plugins;hooks;constructor(B,G=[],K){this.transport=B;this.plugins=G;this.hooks=K}async send(B){let G=await j(B,this.plugins),K=C(G,this.transport);if(await T(this.hooks?.onSend,K),this.hooks?.onRetry!==void 0&&this.transport instanceof I)this.transport.setMailerOnRetry((Y,Z)=>{T(this.hooks?.onRetry,K,Y,Z)});try{let Y=await this.transport.send(G),Z={...K,messageId:Y.messageId};return await T(this.hooks?.onSuccess,Z,Y),Y}catch(Y){throw await T(this.hooks?.onError,K,Y),Y}finally{if(this.transport instanceof I)this.transport.setMailerOnRetry(void 0)}}async processMessage(B){return j(B,this.plugins)}async sendBulk(B,G){if(B.length===0)return{total:0,sent:0,failed:0,results:[]};let K=Array(B.length),Y=G?.stopOnError??!1,Z=!1,S=async(_,$,Q,V)=>{if(K[$]={status:"sent",result:Q},V!==void 0&&this.hooks!==void 0){let W=C(V,this.transport);await T(this.hooks.onSend,W),await T(this.hooks.onSuccess,{...W,messageId:Q.messageId},Q)}G?.onSuccess?.(_,$,Q)},L=async(_,$,Q,V)=>{if(K[$]={status:"failed",error:Q},V!==void 0&&this.hooks!==void 0){let W=C(V,this.transport);await T(this.hooks.onSend,W),await T(this.hooks.onError,W,Q)}if(G?.onError?.(_,$,Q),Y)Z=!0};if(this.transport.sendBatch){let _=[],$=[];for(let[Q,V]of B.entries())if(D(V))$.push({index:Q,message:V});else _.push({index:Q,message:V});if(_.length>0&&!Z){let Q=this.transport.batchMax??_.length,V=G?.rateDelta??2,W=V>0?new M(V,G?.rateLimit??1000,G?.now):null;for(let A=0;A<_.length&&!Z;A+=Q){let X=_.slice(A,A+Q);if(W)await W.acquire();try{let w=await Promise.all(X.map(({message:J})=>this.processMessage(J))),U=await this.transport.sendBatch(w);for(let J=0;J<X.length;J++){let z=X[J],P=w[J],F=U[J];if(F===void 0)await L(z.message,z.index,Error("Batch response missing result for message"),P);else if(F.batchError!==void 0)await L(z.message,z.index,F.batchError,P);else await S(z.message,z.index,F,P)}}catch(w){let U=await Promise.all(X.map(({message:J})=>this.processMessage(J)));for(let J=0;J<X.length;J++){if(Z)break;let z=X[J];await L(z.message,z.index,w,U[J])}}}}if($.length>0&&!Z){let Q=G?.concurrency??1,V=[...$],W=0;await new Promise((A)=>{let X=()=>{if(V.length===0&&W===0||Z)A()},w=()=>{if(V.length===0||Z){X();return}let U=V.shift();if(U===void 0){X();return}W++,this.send(U.message).then((J)=>{K[U.index]={status:"sent",result:J},G?.onSuccess?.(U.message,U.index,J)}).catch((J)=>{if(K[U.index]={status:"failed",error:J},G?.onError?.(U.message,U.index,J),Y)Z=!0}).finally(()=>{W--,w(),X()})};for(let U=0;U<Q;U++)w()})}}else{let _=G?.concurrency??1,$=[...B.entries()],Q=0;await new Promise((V)=>{let W=()=>{if($.length===0&&Q===0||Z)V()},A=()=>{if($.length===0||Z){W();return}let X=$.shift();if(X===void 0){W();return}let[w,U]=X;Q++,this.send(U).then((J)=>{K[w]={status:"sent",result:J},G?.onSuccess?.(U,w,J)}).catch((J)=>{if(K[w]={status:"failed",error:J},G?.onError?.(U,w,J),Y)Z=!0}).finally(()=>{Q--,A(),W()})};for(let X=0;X<_;X++)A()})}let N=0,O=0;for(let _ of K){if(_===void 0)continue;if(_.status==="sent")N++;else O++}return{total:B.length,sent:N,failed:O,results:K}}verify(){if(this.transport.verify)return this.transport.verify();return Promise.resolve({ok:!0,provider:"mailer"})}close(){if(this.transport.close)return this.transport.close();return Promise.resolve()}}
2
- export{k as t,q as u};
3
-
4
- //# debugId=3F1ECBDC030264A764756E2164756E21
@@ -1,11 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/core/plugin.ts", "../src/mailer.ts"],
4
- "sourcesContent": [
5
- "/**\n * @module\n * Plugin pipeline for sently.\n * Plugins transform MailOptions before message construction.\n * They run sequentially — each receives the previous plugin's output.\n *\n * @example\n * ```ts\n * import { runPlugins } from \"sently/core/plugin\";\n * const result = await runPlugins(options, [pluginA, pluginB]);\n * ```\n */\nimport type { MailOptions, MailPlugin } from \"./types.js\";\n\n/**\n * Run a list of plugins sequentially over MailOptions.\n * If plugins is empty or undefined, returns options unchanged.\n * Each plugin may be sync or async.\n *\n * @param options - the original mail options\n * @param plugins - ordered list of plugins to apply\n * @returns transformed mail options after all plugins have run\n */\nexport async function runPlugins(\n options: MailOptions,\n plugins: MailPlugin[] | undefined,\n): Promise<MailOptions> {\n if (!plugins || plugins.length === 0) {\n return options;\n }\n\n let current = options;\n for (const plugin of plugins) {\n current = await plugin(current);\n }\n return current;\n}\n",
6
- "/**\n * @module\n * Lightweight mailer factory for custom transports — no SMTP code in the bundle.\n *\n * Use this entry instead of `sently` when you pass a transport explicitly\n * (Resend, SendGrid, etc.) and want the smallest bundle size.\n *\n * @example\n * ```ts\n * import { createMailer } from \"sently/mailer\";\n * import { ResendTransport } from \"sently/transports/resend\";\n *\n * const mailer = await createMailer({\n * transport: new ResendTransport({ apiKey: process.env.RESEND_API_KEY! }),\n * });\n *\n * await mailer.send({\n * from: \"onboarding@yourdomain.com\",\n * to: \"recipient@example.com\",\n * subject: \"Hello\",\n * html: \"<p>Sent via Resend</p>\",\n * });\n * ```\n */\nimport { extractEmails } from \"./core/address.js\";\nimport { runPlugins } from \"./core/plugin.js\";\nimport { RateLimiter } from \"./core/rate-limiter.js\";\nimport type {\n BulkSendOptions,\n BulkSendResult,\n Mailer,\n MailerHookContext,\n MailerHooks,\n MailOptions,\n MailPlugin,\n SendResult,\n Transport,\n TransportMailerOptions,\n VerifyResult,\n} from \"./core/types.js\";\nimport { RetryTransport } from \"./transports/retry.js\";\n\nexport type { MailerHookContext, MailerHooks, TransportMailerOptions };\n\n/**\n * Create a mailer that wraps a custom {@link Transport} (HTTP API, preview, retry, etc.).\n */\nexport async function createMailer(options: TransportMailerOptions): Promise<Mailer> {\n return new MailerImpl(options.transport, options.plugins ?? [], options.hooks);\n}\n\nfunction hasAttachments(message: MailOptions): boolean {\n return message.attachments !== undefined && message.attachments.length > 0;\n}\n\n/** Infer a provider label from a transport instance for hook context. */\nfunction inferProvider(transport: Transport): string {\n const name = transport.constructor.name;\n if (name === \"Object\") {\n return \"custom\";\n }\n if (name.endsWith(\"Transport\")) {\n return name.slice(0, -\"Transport\".length).toLowerCase();\n }\n return name.toLowerCase() || \"unknown\";\n}\n\n/** Build hook context from mail options (no body fields). */\nfunction buildHookContext(options: MailOptions, transport: Transport): MailerHookContext {\n return {\n ...(options.messageId !== undefined ? { messageId: options.messageId } : {}),\n to: extractEmails(options.to),\n subject: options.subject,\n provider: inferProvider(transport),\n };\n}\n\n/**\n * Invoke a mailer hook without letting hook failures break the send.\n * In non-production environments, hook errors are logged with `console.warn`.\n */\nasync function invokeHook<T extends unknown[]>(\n hook: ((...args: T) => void | Promise<void>) | undefined,\n ...args: T\n): Promise<void> {\n if (hook === undefined) {\n return;\n }\n try {\n await hook(...args);\n } catch (hookError) {\n const isProduction = typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\";\n if (!isProduction) {\n console.warn(\"[sently] Mailer hook threw; send continues:\", hookError);\n }\n }\n}\n\n/** Internal mailer implementation shared with the full `sently` entry. */\nexport class MailerImpl implements Mailer {\n constructor(\n private readonly transport: Transport,\n private readonly plugins: MailPlugin[] = [],\n private readonly hooks?: MailerHooks,\n ) {}\n\n async send(options: MailOptions): Promise<SendResult> {\n const processed = await runPlugins(options, this.plugins);\n const ctx = buildHookContext(processed, this.transport);\n\n await invokeHook(this.hooks?.onSend, ctx);\n\n if (this.hooks?.onRetry !== undefined && this.transport instanceof RetryTransport) {\n this.transport.setMailerOnRetry((attempt, error) => {\n void invokeHook(this.hooks?.onRetry, ctx, attempt, error);\n });\n }\n\n try {\n const result = await this.transport.send(processed);\n const successCtx: MailerHookContext = {\n ...ctx,\n messageId: result.messageId,\n };\n await invokeHook(this.hooks?.onSuccess, successCtx, result);\n return result;\n } catch (error) {\n await invokeHook(this.hooks?.onError, ctx, error);\n throw error;\n } finally {\n if (this.transport instanceof RetryTransport) {\n this.transport.setMailerOnRetry(undefined);\n }\n }\n }\n\n private async processMessage(message: MailOptions): Promise<MailOptions> {\n return runPlugins(message, this.plugins);\n }\n\n async sendBulk(messages: MailOptions[], options?: BulkSendOptions): Promise<BulkSendResult> {\n if (messages.length === 0) {\n return { total: 0, sent: 0, failed: 0, results: [] };\n }\n\n const results: BulkSendResult[\"results\"] = new Array(messages.length);\n const stopOnError = options?.stopOnError ?? false;\n let halted = false;\n\n const recordSuccess = async (\n message: MailOptions,\n index: number,\n result: SendResult,\n processed?: MailOptions,\n ): Promise<void> => {\n results[index] = { status: \"sent\", result };\n if (processed !== undefined && this.hooks !== undefined) {\n const ctx = buildHookContext(processed, this.transport);\n await invokeHook(this.hooks.onSend, ctx);\n await invokeHook(this.hooks.onSuccess, { ...ctx, messageId: result.messageId }, result);\n }\n options?.onSuccess?.(message, index, result);\n };\n\n const recordFailure = async (\n message: MailOptions,\n index: number,\n error: unknown,\n processed?: MailOptions,\n ): Promise<void> => {\n results[index] = { status: \"failed\", error };\n if (processed !== undefined && this.hooks !== undefined) {\n const ctx = buildHookContext(processed, this.transport);\n await invokeHook(this.hooks.onSend, ctx);\n await invokeHook(this.hooks.onError, ctx, error);\n }\n options?.onError?.(message, index, error);\n if (stopOnError) {\n halted = true;\n }\n };\n\n if (this.transport.sendBatch) {\n const batchEntries: Array<{ index: number; message: MailOptions }> = [];\n const singleEntries: Array<{ index: number; message: MailOptions }> = [];\n\n for (const [index, message] of messages.entries()) {\n if (hasAttachments(message)) {\n singleEntries.push({ index, message });\n } else {\n batchEntries.push({ index, message });\n }\n }\n\n if (batchEntries.length > 0 && !halted) {\n const chunkSize = this.transport.batchMax ?? batchEntries.length;\n const rateDelta = options?.rateDelta ?? 2;\n const rateLimiter =\n rateDelta > 0\n ? new RateLimiter(rateDelta, options?.rateLimit ?? 1000, options?.now)\n : null;\n\n for (\n let chunkStart = 0;\n chunkStart < batchEntries.length && !halted;\n chunkStart += chunkSize\n ) {\n const chunk = batchEntries.slice(chunkStart, chunkStart + chunkSize);\n\n if (rateLimiter) {\n await rateLimiter.acquire();\n }\n\n try {\n const processed = await Promise.all(\n chunk.map(({ message }) => this.processMessage(message)),\n );\n const batchResults = await this.transport.sendBatch(processed);\n\n for (let i = 0; i < chunk.length; i++) {\n const entry = chunk[i] as { index: number; message: MailOptions };\n const processedMessage = processed[i] as MailOptions;\n const result = batchResults[i];\n if (result === undefined) {\n await recordFailure(\n entry.message,\n entry.index,\n new Error(\"Batch response missing result for message\"),\n processedMessage,\n );\n } else if (result.batchError !== undefined) {\n await recordFailure(\n entry.message,\n entry.index,\n result.batchError,\n processedMessage,\n );\n } else {\n await recordSuccess(entry.message, entry.index, result, processedMessage);\n }\n }\n } catch (error) {\n const processed = await Promise.all(\n chunk.map(({ message }) => this.processMessage(message)),\n );\n for (let i = 0; i < chunk.length; i++) {\n if (halted) {\n break;\n }\n const entry = chunk[i] as { index: number; message: MailOptions };\n await recordFailure(entry.message, entry.index, error, processed[i]);\n }\n }\n }\n }\n\n if (singleEntries.length > 0 && !halted) {\n const concurrency = options?.concurrency ?? 1;\n const queue = [...singleEntries];\n let active = 0;\n\n await new Promise<void>((resolve) => {\n const maybeDone = (): void => {\n if ((queue.length === 0 && active === 0) || halted) {\n resolve();\n }\n };\n\n const processNext = (): void => {\n if (queue.length === 0 || halted) {\n maybeDone();\n return;\n }\n\n const entry = queue.shift();\n if (entry === undefined) {\n maybeDone();\n return;\n }\n\n active++;\n void this.send(entry.message)\n .then((result) => {\n results[entry.index] = { status: \"sent\", result };\n options?.onSuccess?.(entry.message, entry.index, result);\n })\n .catch((error: unknown) => {\n results[entry.index] = { status: \"failed\", error };\n options?.onError?.(entry.message, entry.index, error);\n if (stopOnError) {\n halted = true;\n }\n })\n .finally(() => {\n active--;\n processNext();\n maybeDone();\n });\n };\n\n for (let i = 0; i < concurrency; i++) {\n processNext();\n }\n });\n }\n } else {\n const concurrency = options?.concurrency ?? 1;\n const queue = [...messages.entries()];\n let active = 0;\n\n await new Promise<void>((resolve) => {\n const maybeDone = (): void => {\n if ((queue.length === 0 && active === 0) || halted) {\n resolve();\n }\n };\n\n const processNext = (): void => {\n if (queue.length === 0 || halted) {\n maybeDone();\n return;\n }\n\n const entry = queue.shift();\n if (entry === undefined) {\n maybeDone();\n return;\n }\n\n const [index, message] = entry;\n active++;\n\n void this.send(message)\n .then((result) => {\n results[index] = { status: \"sent\", result };\n options?.onSuccess?.(message, index, result);\n })\n .catch((error: unknown) => {\n results[index] = { status: \"failed\", error };\n options?.onError?.(message, index, error);\n if (stopOnError) {\n halted = true;\n }\n })\n .finally(() => {\n active--;\n processNext();\n maybeDone();\n });\n };\n\n for (let i = 0; i < concurrency; i++) {\n processNext();\n }\n });\n }\n\n let sent = 0;\n let failed = 0;\n for (const result of results) {\n if (result === undefined) {\n continue;\n }\n if (result.status === \"sent\") {\n sent++;\n } else {\n failed++;\n }\n }\n\n return {\n total: messages.length,\n sent,\n failed,\n results,\n };\n }\n\n verify(): Promise<VerifyResult> {\n if (this.transport.verify) {\n return this.transport.verify();\n }\n return Promise.resolve({ ok: true, provider: \"mailer\" });\n }\n\n close(): Promise<void> {\n if (this.transport.close) {\n return this.transport.close();\n }\n return Promise.resolve();\n }\n}\n"
7
- ],
8
- "mappings": "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",
9
- "debugId": "3F1ECBDC030264A764756E2164756E21",
10
- "names": []
11
- }
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/core/errors.ts"],
4
- "sourcesContent": [
5
- "/**\n * @module\n * Unified error hierarchy for sently transports and SMTP.\n */\n\n/** Stable machine-readable error codes shared across providers. */\nexport type SentlyErrorCode =\n | \"SMTP_AUTH_FAILED\"\n | \"RATE_LIMITED\"\n | \"TIMEOUT\"\n | \"CONNECTION_FAILED\"\n | \"PROVIDER_ERROR\"\n | \"BAD_REQUEST\";\n\n/** Options for constructing a {@link SentlyError}. */\nexport interface SentlyErrorOptions {\n /** HTTP status code when the failure originated from an HTTP transport. */\n statusCode?: number;\n /** Original error or response payload. */\n cause?: unknown;\n /** Provider identifier (e.g. `\"smtp\"`, `\"resend\"`). */\n provider?: string;\n}\n\n/**\n * Base error class for all sently transport and protocol failures.\n *\n * Subclasses may shadow {@link code} with provider-specific or numeric values\n * (e.g. SMTP response codes). Use {@link sentlyCode} for the stable machine-readable\n * code in those cases.\n */\nexport class SentlyError extends Error {\n /**\n * Stable machine-readable error code.\n * Preserved even when a subclass shadows {@link code}.\n */\n readonly sentlyCode: SentlyErrorCode;\n\n /** HTTP status code when applicable. */\n readonly statusCode?: number;\n\n /** Provider identifier when applicable. */\n readonly provider?: string;\n\n /**\n * Error code — machine-readable string on {@link SentlyError}, or a legacy\n * provider/SMTP-specific value on subclasses (numeric SMTP codes, Brevo/SES API codes).\n */\n code: string | number;\n\n /** Creates a sently error with a machine-readable code and optional metadata. */\n constructor(message: string, sentlyCode: SentlyErrorCode, options?: SentlyErrorOptions) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"SentlyError\";\n this.sentlyCode = sentlyCode;\n this.code = sentlyCode;\n if (options?.statusCode !== undefined) {\n this.statusCode = options.statusCode;\n }\n if (options?.provider !== undefined) {\n this.provider = options.provider;\n }\n }\n}\n\n/**\n * Map an HTTP status code to a stable sently error code.\n *\n * @param status - HTTP response status code\n * @returns Machine-readable error code\n */\nexport function httpStatusToSentlyCode(status: number): SentlyErrorCode {\n if (status === 429) {\n return \"RATE_LIMITED\";\n }\n if (status >= 500) {\n return \"PROVIDER_ERROR\";\n }\n if (status >= 400) {\n return \"BAD_REQUEST\";\n }\n return \"PROVIDER_ERROR\";\n}\n\n/**\n * Map an SMTP response code and command to a stable sently error code.\n *\n * @param smtpCode - Three-digit SMTP response code (0 for local/parse errors)\n * @param command - SMTP command that failed\n * @returns Machine-readable error code\n */\nexport function smtpCodeToSentlyCode(smtpCode: number, command: string): SentlyErrorCode {\n if (smtpCode === 535 || smtpCode === 534) {\n return \"SMTP_AUTH_FAILED\";\n }\n if (smtpCode === 421 || smtpCode === 450 || smtpCode === 451) {\n return \"TIMEOUT\";\n }\n if (smtpCode === 0) {\n if (command === \"CONNECT\" || command === \"READ\" || command === \"MX\") {\n return \"CONNECTION_FAILED\";\n }\n return \"PROVIDER_ERROR\";\n }\n if (smtpCode >= 500) {\n return \"PROVIDER_ERROR\";\n }\n if (smtpCode >= 400) {\n return \"BAD_REQUEST\";\n }\n return \"PROVIDER_ERROR\";\n}\n"
6
- ],
7
- "mappings": "AA+BO,MAAM,UAAoB,KAAM,CAK5B,WAGA,WAGA,SAMT,KAGA,WAAW,CAAC,EAAiB,EAA6B,EAA8B,CACtF,MAAM,EAAS,GAAS,QAAU,OAAY,CAAE,MAAO,EAAQ,KAAM,EAAI,MAAS,EAIlF,GAHA,KAAK,KAAO,cACZ,KAAK,WAAa,EAClB,KAAK,KAAO,EACR,GAAS,aAAe,OAC1B,KAAK,WAAa,EAAQ,WAE5B,GAAI,GAAS,WAAa,OACxB,KAAK,SAAW,EAAQ,SAG9B,CAQO,SAAS,CAAsB,CAAC,EAAiC,CACtE,GAAI,IAAW,IACb,MAAO,eAET,GAAI,GAAU,IACZ,MAAO,iBAET,GAAI,GAAU,IACZ,MAAO,cAET,MAAO,iBAUF,SAAS,CAAoB,CAAC,EAAkB,EAAkC,CACvF,GAAI,IAAa,KAAO,IAAa,IACnC,MAAO,mBAET,GAAI,IAAa,KAAO,IAAa,KAAO,IAAa,IACvD,MAAO,UAET,GAAI,IAAa,EAAG,CAClB,GAAI,IAAY,WAAa,IAAY,QAAU,IAAY,KAC7D,MAAO,oBAET,MAAO,iBAET,GAAI,GAAY,IACd,MAAO,iBAET,GAAI,GAAY,IACd,MAAO,cAET,MAAO",
8
- "debugId": "2A4786BCA338BD1D64756E2164756E21",
9
- "names": []
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/transports/smtp.ts"],
4
- "sourcesContent": [
5
- "/**\n * @module\n * SMTP transport — orchestrates socket adapter, MIME builder, and protocol logic.\n *\n * @example\n * ```ts\n * import { SMTPTransport } from \"sently/transports/smtp\";\n * import { NodeAdapter } from \"sently/adapters/node\";\n * import { createMailer } from \"sently\";\n *\n * const mailer = await createMailer({\n * transport: new SMTPTransport({\n * host: \"smtp.example.com\",\n * auth: { user: \"you@example.com\", pass: \"secret\" },\n * adapter: new NodeAdapter(),\n * }),\n * });\n * ```\n */\nimport { OAuth2Client } from \"../auth/oauth2.js\";\nimport { buildMIME, type MIMEBuildResult } from \"../core/mime.js\";\nimport type { SMTPResponse } from \"../core/smtp.js\";\nimport {\n accumulateResponse,\n assertResponse,\n computeCRAMMD5,\n encodeAuthLoginPass,\n encodeAuthLoginUser,\n encodeCommand,\n encodeLine,\n parseEHLO,\n parseResponse,\n SMTPError,\n selectAuthMethod,\n} from \"../core/smtp.js\";\nimport type {\n MailOptions,\n SendResult,\n SMTPConfig,\n SocketAdapter,\n Transport,\n VerifyResult,\n} from \"../core/types.js\";\nimport { resolveAttachments } from \"./resolve-attachments.js\";\n\n/**\n * SMTP transport orchestrating adapter, MIME builder, and protocol logic.\n */\nexport class SMTPTransport implements Transport {\n /** Resolved SMTP configuration with defaults applied. */\n private readonly config: ResolvedSMTPConfig;\n /** Active socket adapter for the current session, if any. */\n private adapter: SocketAdapter | null = null;\n\n /** Creates an SMTP transport with the given configuration. */\n constructor(config: SMTPConfig) {\n this.config = resolveSMTPConfig(config);\n }\n\n /** Sends an email via SMTP using the configured adapter. */\n async send(options: MailOptions): Promise<SendResult> {\n const resolvedOptions = {\n ...options,\n attachments: await resolveAttachments(options.attachments),\n };\n const mime = await buildMIME(resolvedOptions, this.config.dkim);\n const adapter = await this.getAdapter();\n\n const host = this.config.direct\n ? await resolveMX(mime.envelope.from.split(\"@\")[1] ?? this.config.host)\n : this.config.host;\n\n await adapter.connect(host, this.config.port);\n this.adapter = adapter;\n\n try {\n await openSMTPSession(adapter, this.config);\n return await deliverSMTPMessage(adapter, mime);\n } finally {\n await closeSMTPSession(adapter);\n this.adapter = null;\n }\n }\n\n /** Verifies SMTP connectivity and authentication without sending mail. */\n async verify(): Promise<VerifyResult> {\n try {\n const adapter = await this.getAdapter();\n await adapter.connect(this.config.host, this.config.port);\n\n try {\n await openSMTPSession(adapter, this.config);\n return { ok: true, provider: \"smtp\" };\n } finally {\n await closeSMTPSession(adapter);\n }\n } catch (err) {\n return {\n ok: false,\n provider: \"smtp\",\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n /** Closes the underlying socket adapter if connected. */\n async close(): Promise<void> {\n if (this.adapter) {\n await this.adapter.close();\n this.adapter = null;\n }\n }\n\n /** Returns the configured socket adapter or throws if none is set. */\n private async getAdapter(): Promise<SocketAdapter> {\n if (!this.config.adapter) {\n throw new SMTPError(\"No socket adapter configured\", 0, \"CONNECT\", \"\");\n }\n return this.config.adapter;\n }\n}\n\n/** Resolved SMTP transport configuration with defaults applied. */\nexport interface ResolvedSMTPConfig {\n /** SMTP server hostname. */\n host: string;\n /** SMTP port with secure/default applied. */\n port: number;\n /** Whether implicit TLS is used. */\n secure: boolean;\n /** Resolved authentication credentials, if any. */\n auth?: SMTPConfig[\"auth\"];\n /** Whether AUTH requires an encrypted connection. */\n requireTLS?: boolean;\n /** TLS options for STARTTLS and direct TLS. */\n tls?: SMTPConfig[\"tls\"];\n /** DKIM signing configuration. */\n dkim?: SMTPConfig[\"dkim\"];\n /** Socket connect timeout in milliseconds. */\n connectionTimeout?: number;\n /** Timeout waiting for the SMTP greeting in milliseconds. */\n greetingTimeout?: number;\n /** Idle socket timeout in milliseconds. */\n socketTimeout?: number;\n /** Direct-to-MX delivery mode. */\n direct?: boolean;\n /** Runtime socket adapter. */\n adapter?: SocketAdapter;\n}\n\n/** Apply defaults to SMTP configuration. */\nexport function resolveSMTPConfig(config: SMTPConfig): ResolvedSMTPConfig {\n const secure = config.secure ?? false;\n return {\n host: config.host,\n port: config.port ?? (secure ? 465 : 587),\n secure,\n ...(config.auth !== undefined ? { auth: config.auth } : {}),\n ...(config.requireTLS !== undefined ? { requireTLS: config.requireTLS } : {}),\n ...(config.dkim !== undefined ? { dkim: config.dkim } : {}),\n ...(config.tls !== undefined ? { tls: config.tls } : {}),\n ...(config.connectionTimeout !== undefined\n ? { connectionTimeout: config.connectionTimeout }\n : {}),\n ...(config.greetingTimeout !== undefined ? { greetingTimeout: config.greetingTimeout } : {}),\n ...(config.socketTimeout !== undefined ? { socketTimeout: config.socketTimeout } : {}),\n ...(config.direct !== undefined ? { direct: config.direct } : {}),\n ...(config.adapter !== undefined ? { adapter: config.adapter } : {}),\n };\n}\n\n/**\n * Connect greeting, EHLO, optional STARTTLS, and AUTH on an open adapter.\n */\nexport async function openSMTPSession(\n adapter: SocketAdapter,\n config: ResolvedSMTPConfig,\n): Promise<void> {\n const greeting = await readSMTPResponse(adapter);\n assertResponse(greeting, [220], \"greeting\");\n\n let capabilities = await ehlo(adapter, config.host);\n const supportsStartTls = capabilities.some((cap) => cap.toUpperCase() === \"STARTTLS\");\n if (!config.secure && !adapter.secure && supportsStartTls) {\n await sendRaw(adapter, encodeCommand({ type: \"STARTTLS\" }));\n const starttlsResp = await readSMTPResponse(adapter);\n assertResponse(starttlsResp, [220], \"STARTTLS\");\n await adapter.startTLS(config.tls);\n capabilities = await ehlo(adapter, config.host);\n }\n\n if (config.auth) {\n const tlsRequired = config.requireTLS ?? true;\n const encrypted = adapter.secure || config.secure;\n if (tlsRequired && !encrypted) {\n throw new SMTPError(\n \"Refusing to authenticate over unencrypted connection. \" +\n \"Set requireTLS: false to disable this check (not recommended).\",\n 0,\n \"AUTH\",\n \"\",\n );\n }\n await authenticate(adapter, config.auth, capabilities);\n }\n}\n\n/**\n * MAIL FROM, RCPT TO, and DATA for a built MIME message on an authenticated session.\n */\nexport async function deliverSMTPMessage(\n adapter: SocketAdapter,\n mime: MIMEBuildResult,\n): Promise<SendResult> {\n await sendCommand(adapter, { type: \"MAIL_FROM\", address: mime.envelope.from });\n const mailResp = await readSMTPResponse(adapter);\n assertResponse(mailResp, [250], \"MAIL FROM\");\n\n const accepted: string[] = [];\n const rejected: string[] = [];\n\n for (const recipient of mime.envelope.to) {\n await sendRaw(adapter, encodeCommand({ type: \"RCPT_TO\", address: recipient }));\n const rcptResp = await readSMTPResponse(adapter);\n if (rcptResp.isSuccess) {\n accepted.push(recipient);\n } else {\n rejected.push(recipient);\n }\n }\n\n await sendCommand(adapter, { type: \"DATA\" });\n const dataResp = await readSMTPResponse(adapter);\n assertResponse(dataResp, [354], \"DATA\");\n\n let finalResp: SMTPResponse;\n try {\n await sendRaw(adapter, encodeCommand({ type: \"DATA_BODY\", content: mime.raw }));\n finalResp = await readSMTPResponse(adapter);\n } catch (err) {\n await sendRaw(adapter, encodeCommand({ type: \"DATA_BODY\", content: mime.raw }));\n finalResp = await readSMTPResponse(adapter);\n if (finalResp.isError) {\n throw err;\n }\n }\n assertResponse(finalResp, [250], \"DATA end\");\n\n return {\n messageId: mime.messageId,\n accepted,\n rejected,\n response: finalResp.message,\n envelope: mime.envelope,\n };\n}\n\n/**\n * QUIT and close an SMTP session adapter.\n */\nexport async function closeSMTPSession(adapter: SocketAdapter): Promise<void> {\n try {\n await sendCommand(adapter, { type: \"QUIT\" });\n await readSMTPResponse(adapter);\n } catch {\n // ignore errors during shutdown\n } finally {\n await adapter.close();\n }\n}\n\nasync function ehlo(adapter: SocketAdapter, host: string): Promise<string[]> {\n await sendCommand(adapter, { type: \"EHLO\", domain: host });\n const response = await readSMTPResponse(adapter);\n assertResponse(response, [250], \"EHLO\");\n return parseEHLO(response);\n}\n\nasync function authenticate(\n adapter: SocketAdapter,\n auth: NonNullable<SMTPConfig[\"auth\"]>,\n capabilities: string[],\n): Promise<void> {\n if (auth.type === \"OAUTH2\" && auth.oauth2) {\n const client = new OAuth2Client(auth.oauth2);\n const xoauth2 = await client.buildXOAUTH2();\n await sendCommand(adapter, { type: \"AUTH_XOAUTH2\", xoauth2String: xoauth2 });\n let resp = await readSMTPResponse(adapter);\n if (resp.code === 334) {\n await sendRaw(adapter, encodeLine(\"\"));\n resp = await readSMTPResponse(adapter);\n }\n assertResponse(resp, [235], \"AUTH XOAUTH2\");\n return;\n }\n\n const method = auth.type ?? selectAuthMethod(capabilities);\n\n if (method === \"CRAM-MD5\") {\n const pass = requirePassword(auth, \"CRAM-MD5\");\n await sendCommand(adapter, { type: \"AUTH_CRAM_MD5_INIT\" });\n let resp = await readSMTPResponse(adapter);\n assertResponse(resp, [334], \"AUTH CRAM-MD5\");\n const challenge = resp.message.trim();\n const response = await computeCRAMMD5(challenge, auth.user, pass);\n await sendCommand(adapter, { type: \"AUTH_CRAM_MD5_RESPONSE\", response });\n resp = await readSMTPResponse(adapter);\n assertResponse(resp, [235], \"AUTH CRAM-MD5 response\");\n return;\n }\n\n if (method === \"PLAIN\") {\n const pass = requirePassword(auth, \"PLAIN\");\n await sendRaw(adapter, encodeCommand({ type: \"AUTH_PLAIN\", user: auth.user, pass }));\n const resp = await readSMTPResponse(adapter);\n assertResponse(resp, [235], \"AUTH PLAIN\");\n return;\n }\n\n const pass = requirePassword(auth, \"LOGIN\");\n await sendRaw(adapter, encodeCommand({ type: \"AUTH_LOGIN\", user: auth.user, pass }));\n let resp = await readSMTPResponse(adapter);\n assertResponse(resp, [334], \"AUTH LOGIN\");\n\n await sendRaw(adapter, encodeAuthLoginUser(auth.user));\n resp = await readSMTPResponse(adapter);\n assertResponse(resp, [334], \"AUTH LOGIN user\");\n\n await sendRaw(adapter, encodeAuthLoginPass(pass));\n resp = await readSMTPResponse(adapter);\n assertResponse(resp, [235], \"AUTH LOGIN pass\");\n}\n\nfunction requirePassword(auth: NonNullable<SMTPConfig[\"auth\"]>, method: string): string {\n if (!auth.pass) {\n throw new SMTPError(`Password required for ${method} authentication`, 0, `AUTH ${method}`, \"\");\n }\n return auth.pass;\n}\n\nasync function sendCommand(\n adapter: SocketAdapter,\n command: Parameters<typeof encodeCommand>[0],\n): Promise<void> {\n await sendRaw(adapter, encodeCommand(command));\n}\n\nasync function sendRaw(adapter: SocketAdapter, data: Uint8Array): Promise<void> {\n await adapter.write(data);\n}\n\n/** Reads and parses a complete SMTP response from the adapter. */\nasync function readSMTPResponse(adapter: SocketAdapter): Promise<SMTPResponse> {\n const chunks: Uint8Array[] = [];\n for await (const chunk of adapter.read()) {\n chunks.push(chunk);\n const complete = accumulateResponse(chunks);\n if (complete) {\n return parseResponse(complete);\n }\n }\n throw new SMTPError(\"Connection closed while reading SMTP response\", 0, \"READ\", \"\");\n}\n\nasync function resolveMX(domain: string): Promise<string> {\n const dns = await import(\"node:dns/promises\");\n const records = await dns.resolveMx(domain);\n if (records.length === 0) {\n throw new SMTPError(`No MX records for ${domain}`, 0, \"MX\", \"\");\n }\n records.sort((a: { priority: number }, b: { priority: number }) => a.priority - b.priority);\n return records[0]?.exchange ?? domain;\n}\n\n/** @internal Test helper for raw line writes. */\nexport { encodeLine, readSMTPResponse };\n"
6
- ],
7
- "mappings": "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",
8
- "debugId": "DFA0A23A4210988264756E2164756E21",
9
- "names": []
10
- }
@@ -1,4 +0,0 @@
1
- import{D as G}from"./chunk-w3fnjh04.js";var H=[429,500,502,503,504];function I(q,x,z){if(x==="exponential")return z*2**(q-1);if(x==="linear")return z*q;return z}function J(q,x){if(q instanceof G&&q.code===535)return!1;if(typeof q==="object"&&q!==null&&"statusCode"in q&&typeof q.statusCode==="number")return x.includes(q.statusCode);return!0}class K{inner;_sleep;maxAttempts;backoff;baseDelay;retryOn;onRetry;mailerOnRetry;constructor(q,x,z=(B)=>new Promise((C)=>setTimeout(C,B))){this.inner=q;this._sleep=z;this.maxAttempts=x?.maxAttempts??3,this.backoff=x?.backoff??"exponential",this.baseDelay=x?.baseDelay??1000,this.retryOn=x?.retryOn??H,this.onRetry=x?.onRetry,this.mailerOnRetry=void 0}setMailerOnRetry(q){if(q!==void 0&&this.mailerOnRetry!==void 0&&this.mailerOnRetry!==q){if(!(typeof process<"u"&&process.env?.NODE_ENV==="production"))console.warn("[sently] RetryTransport.setMailerOnRetry: overwriting an active mailer onRetry callback. Do not share one RetryTransport instance across multiple mailers.")}this.mailerOnRetry=q}async send(q){let x;for(let z=1;z<=this.maxAttempts;z++)try{return await this.inner.send(q)}catch(B){if(x=B,z===this.maxAttempts)throw B;if(!J(B,this.retryOn))throw B;let C=I(z,this.backoff,this.baseDelay);this.onRetry?.(z,B),this.mailerOnRetry?.(z,B),await this._sleep(C)}throw x}async verify(){if(this.inner.verify)return this.inner.verify();return{ok:!0,provider:"retry"}}async close(){await this.inner.close?.()}async sendBatch(q){if(this.inner.sendBatch)return this.inner.sendBatch(q);return Promise.all(q.map((x)=>this.send(x)))}}
2
- export{K as v};
3
-
4
- //# debugId=BFA284A1AC0693B364756E2164756E21
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/transports/retry.ts"],
4
- "sourcesContent": [
5
- "/**\n * @module\n * RetryTransport — decorator that wraps any sently transport\n * and retries failed sends with configurable backoff.\n * Works with SMTP, Resend, SendGrid, SES, and any custom transport.\n *\n * @example\n * ```ts\n * import { RetryTransport } from 'sently/transports/retry'\n * import { ResendTransport } from 'sently/transports/resend'\n *\n * const transport = new RetryTransport(\n * new ResendTransport({ apiKey }),\n * { maxAttempts: 3, backoff: 'exponential', retryOn: [429, 503] }\n * )\n * ```\n */\nimport { SMTPError } from \"../core/smtp.js\";\nimport type {\n MailOptions,\n RetryConfig,\n SendResult,\n Transport,\n VerifyResult,\n} from \"../core/types.js\";\n\nconst DEFAULT_RETRY_ON = [429, 500, 502, 503, 504];\n\nfunction computeDelay(attempt: number, backoff: string, base: number): number {\n if (backoff === \"exponential\") {\n return base * 2 ** (attempt - 1);\n }\n if (backoff === \"linear\") {\n return base * attempt;\n }\n return base;\n}\n\nfunction shouldRetry(err: unknown, retryOn: number[]): boolean {\n if (err instanceof SMTPError && err.code === 535) {\n return false;\n }\n\n if (\n typeof err === \"object\" &&\n err !== null &&\n \"statusCode\" in err &&\n typeof (err as { statusCode: unknown }).statusCode === \"number\"\n ) {\n return retryOn.includes((err as { statusCode: number }).statusCode);\n }\n\n return true;\n}\n\n/**\n * Decorator transport that retries failed sends with configurable backoff.\n */\nexport class RetryTransport implements Transport {\n /** Maximum send attempts including the initial try. */\n private readonly maxAttempts: number;\n /** Backoff strategy between retries. */\n private readonly backoff: \"exponential\" | \"linear\" | \"fixed\";\n /** Base delay in milliseconds before the first retry. */\n private readonly baseDelay: number;\n /** HTTP status codes that trigger a retry. */\n private readonly retryOn: number[];\n /** Optional callback invoked before each retry attempt. */\n private readonly onRetry: RetryConfig[\"onRetry\"];\n /** Additional onRetry callback wired by {@link MailerImpl} hooks per send. */\n private mailerOnRetry: RetryConfig[\"onRetry\"];\n\n /** Wraps an inner transport with retry logic and optional backoff configuration. */\n constructor(\n /** Transport that performs the actual send on each attempt. */\n private readonly inner: Transport,\n config?: RetryConfig,\n /** Injectable sleep function for testing backoff timing. */\n private readonly _sleep: (ms: number) => Promise<void> = (ms) =>\n new Promise((resolve) => setTimeout(resolve, ms)),\n ) {\n this.maxAttempts = config?.maxAttempts ?? 3;\n this.backoff = config?.backoff ?? \"exponential\";\n this.baseDelay = config?.baseDelay ?? 1000;\n this.retryOn = config?.retryOn ?? DEFAULT_RETRY_ON;\n this.onRetry = config?.onRetry;\n this.mailerOnRetry = undefined;\n }\n\n /**\n * Register a per-send onRetry callback from mailer lifecycle hooks.\n * Do not share one {@link RetryTransport} across multiple mailers — the last\n * `setMailerOnRetry` wins; overwriting an active callback logs a dev warning.\n * @internal Used by {@link MailerImpl}; cleared after each send.\n */\n setMailerOnRetry(callback: RetryConfig[\"onRetry\"] | undefined): void {\n if (\n callback !== undefined &&\n this.mailerOnRetry !== undefined &&\n this.mailerOnRetry !== callback\n ) {\n const isProduction = typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\";\n if (!isProduction) {\n console.warn(\n \"[sently] RetryTransport.setMailerOnRetry: overwriting an active mailer onRetry callback. Do not share one RetryTransport instance across multiple mailers.\",\n );\n }\n }\n this.mailerOnRetry = callback;\n }\n\n /** Sends with retries according to configured backoff and retry rules. */\n async send(options: MailOptions): Promise<SendResult> {\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= this.maxAttempts; attempt++) {\n try {\n return await this.inner.send(options);\n } catch (err) {\n lastError = err;\n if (attempt === this.maxAttempts) {\n throw err;\n }\n if (!shouldRetry(err, this.retryOn)) {\n throw err;\n }\n const delay = computeDelay(attempt, this.backoff, this.baseDelay);\n this.onRetry?.(attempt, err);\n this.mailerOnRetry?.(attempt, err);\n await this._sleep(delay);\n }\n }\n\n throw lastError;\n }\n\n /** Delegates to the inner transport verify or returns a default success result. */\n async verify(): Promise<VerifyResult> {\n if (this.inner.verify) {\n return this.inner.verify();\n }\n return { ok: true, provider: \"retry\" };\n }\n\n /** Delegates close to the inner transport if available. */\n async close(): Promise<void> {\n await this.inner.close?.();\n }\n\n /** Delegates batch sends to the inner transport when available. */\n async sendBatch(messages: MailOptions[]): Promise<SendResult[]> {\n if (this.inner.sendBatch) {\n return this.inner.sendBatch(messages);\n }\n return Promise.all(messages.map((message) => this.send(message)));\n }\n}\n"
6
- ],
7
- "mappings": "wCA0BA,IAAM,EAAmB,CAAC,IAAK,IAAK,IAAK,IAAK,GAAG,EAEjD,SAAS,CAAY,CAAC,EAAiB,EAAiB,EAAsB,CAC5E,GAAI,IAAY,cACd,OAAO,EAAO,IAAM,EAAU,GAEhC,GAAI,IAAY,SACd,OAAO,EAAO,EAEhB,OAAO,EAGT,SAAS,CAAW,CAAC,EAAc,EAA4B,CAC7D,GAAI,aAAe,GAAa,EAAI,OAAS,IAC3C,MAAO,GAGT,GACE,OAAO,IAAQ,UACf,IAAQ,MACR,eAAgB,GAChB,OAAQ,EAAgC,aAAe,SAEvD,OAAO,EAAQ,SAAU,EAA+B,UAAU,EAGpE,MAAO,GAMF,MAAM,CAAoC,CAiB5B,MAGA,OAlBF,YAEA,QAEA,UAEA,QAEA,QAET,cAGR,WAAW,CAEQ,EACjB,EAEiB,EAAwC,CAAC,IACxD,IAAI,QAAQ,CAAC,IAAY,WAAW,EAAS,CAAE,CAAC,EAClD,CALiB,aAGA,cAGjB,KAAK,YAAc,GAAQ,aAAe,EAC1C,KAAK,QAAU,GAAQ,SAAW,cAClC,KAAK,UAAY,GAAQ,WAAa,KACtC,KAAK,QAAU,GAAQ,SAAW,EAClC,KAAK,QAAU,GAAQ,QACvB,KAAK,cAAgB,OASvB,gBAAgB,CAAC,EAAoD,CACnE,GACE,IAAa,QACb,KAAK,gBAAkB,QACvB,KAAK,gBAAkB,GAGvB,GAAI,EADiB,OAAO,QAAY,KAAe,QAAQ,KAAK,WAAa,cAE/E,QAAQ,KACN,4JACF,EAGJ,KAAK,cAAgB,OAIjB,KAAI,CAAC,EAA2C,CACpD,IAAI,EAEJ,QAAS,EAAU,EAAG,GAAW,KAAK,YAAa,IACjD,GAAI,CACF,OAAO,MAAM,KAAK,MAAM,KAAK,CAAO,EACpC,MAAO,EAAK,CAEZ,GADA,EAAY,EACR,IAAY,KAAK,YACnB,MAAM,EAER,GAAI,CAAC,EAAY,EAAK,KAAK,OAAO,EAChC,MAAM,EAER,IAAM,EAAQ,EAAa,EAAS,KAAK,QAAS,KAAK,SAAS,EAChE,KAAK,UAAU,EAAS,CAAG,EAC3B,KAAK,gBAAgB,EAAS,CAAG,EACjC,MAAM,KAAK,OAAO,CAAK,EAI3B,MAAM,OAIF,OAAM,EAA0B,CACpC,GAAI,KAAK,MAAM,OACb,OAAO,KAAK,MAAM,OAAO,EAE3B,MAAO,CAAE,GAAI,GAAM,SAAU,OAAQ,OAIjC,MAAK,EAAkB,CAC3B,MAAM,KAAK,MAAM,QAAQ,OAIrB,UAAS,CAAC,EAAgD,CAC9D,GAAI,KAAK,MAAM,UACb,OAAO,KAAK,MAAM,UAAU,CAAQ,EAEtC,OAAO,QAAQ,IAAI,EAAS,IAAI,CAAC,IAAY,KAAK,KAAK,CAAO,CAAC,CAAC,EAEpE",
8
- "debugId": "BFA284A1AC0693B364756E2164756E21",
9
- "names": []
10
- }
@@ -1,13 +0,0 @@
1
- import{O,P as K,R as H}from"./chunk-wzdcz88x.js";import{S as v,U as B}from"./chunk-n601jhpd.js";var j=64;function X(q){return q>>>0}function U(q){let z=g(q),G=1732584193,Q=4023233417,N=2562383102,J=271733878;for(let F=0;F<z.length;F+=64){let $=z.subarray(F,F+64),w=new Uint32Array(16);for(let W=0;W<16;W++){let A=W*4;w[W]=X(($[A]??0)|($[A+1]??0)<<8|($[A+2]??0)<<16|($[A+3]??0)<<24)}let x=G,D=Q,I=N,R=J;for(let W=0;W<64;W++){let A,_;if(W<16)A=X(D&I|~D&R),_=W;else if(W<32)A=X(D&R|I&~R),_=X((5*W+1)%16);else if(W<48)A=X(D^I^R),_=X((3*W+5)%16);else A=X(I^(D|~R)),_=X(7*W%16);let y=R;R=I,I=D,D=X(D+T(X(x+A+X((P[W]??0)+(w[_]??0))),L[W]??0)),x=y}G=X(G+x),Q=X(Q+D),N=X(N+I),J=X(J+R)}let Y=new Uint8Array(16),V=new DataView(Y.buffer);return V.setUint32(0,G,!0),V.setUint32(4,Q,!0),V.setUint32(8,N,!0),V.setUint32(12,J,!0),Y}var L=[7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21],P=new Uint32Array([3614090360,3905402710,606105819,3250441966,4118548399,1200080426,2821735955,4249261313,1770035416,2336552879,4294925233,2304563134,1804603682,4254626195,2792965006,1236535329,4129170786,3225465664,643717713,3921069994,3593408605,38016083,3634488961,3889429448,568446438,3275163606,4107603335,1163531501,2850285829,4243563512,1735328473,2368359562,4294588738,2272392833,1839030562,4259657740,2763975236,1272893353,4139469664,3200236656,681279174,3936430074,3572445317,76029189,3654602809,3873151461,530742520,3299628645,4096336452,1126891415,2878612391,4237533241,1700485571,2399980690,4293915773,2240044497,1873313359,4264355552,2734768916,1309151649,4149444226,3174756917,718787259,3951481745]);function T(q,z){return X(q<<z|q>>>32-z)}function g(q){let z=q.length*8,G=(56-(q.length+1)%64+64)%64,Q=q.length+1+G+8,N=new Uint8Array(Q);N.set(q),N[q.length]=128;let J=new DataView(N.buffer);return J.setUint32(Q-8,z>>>0,!0),J.setUint32(Q-4,Math.floor(z/4294967296),!0),N}function C(q,z){let G=q;if(G.length>j)G=U(G);let Q=new Uint8Array(j);Q.set(G);let N=new Uint8Array(j),J=new Uint8Array(j);for(let $=0;$<j;$++)N[$]=(Q[$]??0)^54,J[$]=(Q[$]??0)^92;let Y=new Uint8Array(N.length+z.length);Y.set(N),Y.set(z,N.length);let V=U(Y),F=new Uint8Array(J.length+V.length);return F.set(J),F.set(V,J.length),U(F)}function E(q){return Array.from(q,(z)=>z.toString(16).padStart(2,"0")).join("")}async function M(q,z,G){let Q=K(q.trim()),N=H(G),J=C(N,Q),Y=E(J);return O(`${z} ${Y}`).replace(/\r\n/g,"")}class Z extends v{command;response;constructor(q,z,G,Q){super(q,B(z,G),{provider:"smtp"});this.command=G;this.response=Q;this.name="SMTPError",this.code=z}}function u(q){let z;switch(q.type){case"EHLO":{z=`EHLO ${q.domain.replace(/[\r\n]/g,"")}`;break}case"STARTTLS":z="STARTTLS";break;case"AUTH_LOGIN":z="AUTH LOGIN";break;case"AUTH_PLAIN":z=`AUTH PLAIN ${O(`\x00${q.user}\x00${q.pass}`).replace(/\r\n/g,"")}`;break;case"AUTH_CRAM_MD5_INIT":z="AUTH CRAM-MD5";break;case"AUTH_CRAM_MD5_RESPONSE":return H(`${q.response}\r
2
- `);case"AUTH_XOAUTH2":z=`AUTH XOAUTH2 ${q.xoauth2String}`;break;case"MAIL_FROM":if(/[\r\n]/.test(q.address))throw new Z("Invalid address: contains CRLF",0,"MAIL FROM",q.address);z=`MAIL FROM:<${q.address}>`;break;case"RCPT_TO":if(/[\r\n]/.test(q.address))throw new Z("Invalid address: contains CRLF",0,"RCPT TO",q.address);z=`RCPT TO:<${q.address}>`;break;case"DATA":z="DATA";break;case"DATA_BODY":return H(S(q.content));case"QUIT":z="QUIT";break;case"RSET":z="RSET";break;case"NOOP":z="NOOP";break}return H(`${z}\r
3
- `)}function l(q){let z=new TextDecoder().decode(q).trim(),G=z.split(/\r?\n/),N=(G[G.length-1]??"").match(/^(\d{3})([\s-])(.*)$/);if(!N)throw new Z("Invalid SMTP response",0,"PARSE",z);let J=Number.parseInt(N[1]??"0",10),Y=G.map((V)=>V.replace(/^\d{3}[\s-]/,"")).join(" ");return{code:J,message:Y,isSuccess:J>=200&&J<300,isReady:J>=300&&J<400,isError:J>=400}}function p(q){if(q.length===0)return null;let z=q.reduce((V,F)=>V+F.length,0),G=new Uint8Array(z),Q=0;for(let V of q)G.set(V,Q),Q+=V.length;let J=new TextDecoder().decode(G).split(/\r?\n/).filter((V)=>V.length>0);if(J.length===0)return null;let Y=J[J.length-1]??"";if(/^\d{3} /.test(Y))return G;return null}function m(q){let z=q.map((G)=>G.toUpperCase());if(z.some((G)=>G.includes("AUTH")&&G.includes("XOAUTH2")))return"OAUTH2";if(z.some((G)=>G.includes("AUTH")&&G.includes("CRAM-MD5")))return"CRAM-MD5";if(z.some((G)=>G.includes("AUTH")&&G.includes("LOGIN")))return"LOGIN";if(z.some((G)=>G.includes("AUTH")&&G.includes("PLAIN")))return"PLAIN";throw new Z("No supported AUTH method",0,"EHLO",q.join(" "))}function i(q){return q.message.split(/\s+/).flatMap((z)=>z.split(/\r?\n/)).filter(Boolean)}function r(q,z,G){if(!z.includes(q.code))throw new Z(`Unexpected SMTP response for ${G}`,q.code,G,q.message)}function S(q){return`${new TextDecoder().decode(q).split(/\r?\n/).map((N)=>N.startsWith(".")?`.${N}`:N).join(`\r
4
- `)}\r
5
- .\r
6
- `}function t(q){return H(`${O(q).replace(/\r\n/g,"")}\r
7
- `)}function o(q){return H(`${O(q).replace(/\r\n/g,"")}\r
8
- `)}function n(q){return H(`${q}\r
9
- `)}function s(q){return H(`${q}\r
10
- `)}
11
- export{M as C,Z as D,u as E,l as F,p as G,m as H,i as I,r as J,t as K,o as L,n as M,s as N};
12
-
13
- //# debugId=387F8E628B7D3D7064756E2164756E21