sently 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +24 -88
- package/dist/adapters/bun.js +1 -1
- package/dist/adapters/cf.js +2 -2
- package/dist/adapters/cf.js.map +1 -1
- package/dist/adapters/deno.js +1 -1
- package/dist/adapters/node.js +1 -1
- package/dist/auth/oauth2.js +1 -1
- package/dist/chunk-74rha3ac.js +4 -0
- package/dist/chunk-74rha3ac.js.map +10 -0
- package/dist/{chunk-9ckbc9mk.js → chunk-a1c87hn1.js} +2 -2
- package/dist/{chunk-9ckbc9mk.js.map → chunk-a1c87hn1.js.map} +1 -1
- package/dist/{chunk-gkec86xg.js → chunk-cvrbfke9.js} +3 -3
- package/dist/{chunk-gkec86xg.js.map → chunk-cvrbfke9.js.map} +1 -1
- package/dist/{chunk-50ycrgx6.js → chunk-d5rwm3br.js} +2 -2
- package/dist/{chunk-50ycrgx6.js.map → chunk-d5rwm3br.js.map} +1 -1
- package/dist/{chunk-bzw0fdmy.js → chunk-fjq6b8gj.js} +2 -2
- package/dist/{chunk-bzw0fdmy.js.map → chunk-fjq6b8gj.js.map} +1 -1
- package/dist/{chunk-xdx6ypr5.js → chunk-gh5n759p.js} +3 -3
- package/dist/{chunk-xdx6ypr5.js.map → chunk-gh5n759p.js.map} +1 -1
- package/dist/{chunk-v8eh0n8d.js → chunk-gkkv7yqm.js} +2 -2
- package/dist/{chunk-v8eh0n8d.js.map → chunk-gkkv7yqm.js.map} +1 -1
- package/dist/{chunk-tfxje74k.js → chunk-kebhy657.js} +2 -2
- package/dist/{chunk-tfxje74k.js.map → chunk-kebhy657.js.map} +1 -1
- package/dist/{chunk-rszb1n1d.js → chunk-keksa6fx.js} +2 -2
- package/dist/{chunk-rszb1n1d.js.map → chunk-keksa6fx.js.map} +1 -1
- package/dist/{chunk-z7j2n9k8.js → chunk-r7ee9tk7.js} +2 -2
- package/dist/{chunk-z7j2n9k8.js.map → chunk-r7ee9tk7.js.map} +1 -1
- package/dist/{chunk-zm7fe0wb.js → chunk-rm78s1ek.js} +2 -2
- package/dist/{chunk-zm7fe0wb.js.map → chunk-rm78s1ek.js.map} +1 -1
- package/dist/chunk-vae5rfb1.js +4 -0
- package/dist/chunk-vae5rfb1.js.map +11 -0
- package/dist/core/errors.js +3 -0
- package/dist/core/errors.js.map +9 -0
- package/dist/core/smtp.js +2 -2
- package/dist/core/smtp.js.map +1 -1
- package/dist/core/types.d.ts +5 -6
- package/dist/detect.d.ts +1 -7
- package/dist/detect.js +2 -2
- package/dist/detect.js.map +3 -4
- package/dist/dkim.js +2 -2
- package/dist/dkim.js.map +1 -1
- package/dist/idempotency.js +2 -2
- package/dist/idempotency.js.map +2 -2
- package/dist/index.d.ts +7 -3
- package/dist/index.js +8 -2
- package/dist/mailer.js +2 -2
- package/dist/mailer.js.map +1 -1
- package/dist/plugins/react.js +2 -2
- package/dist/plugins/react.js.map +1 -1
- package/dist/plugins/template.js +1 -1
- package/dist/pool/pool.js +2 -2
- package/dist/pool/pool.js.map +1 -1
- package/dist/smtp-mailer.d.ts +27 -0
- package/dist/smtp-mailer.js +3 -0
- package/dist/smtp-mailer.js.map +10 -0
- package/dist/transports/brevo.js +2 -2
- package/dist/transports/brevo.js.map +1 -1
- package/dist/transports/mailgun.js +2 -2
- package/dist/transports/mailgun.js.map +2 -2
- package/dist/transports/postmark.js +2 -2
- package/dist/transports/postmark.js.map +1 -1
- package/dist/transports/preview.js +2 -2
- package/dist/transports/preview.js.map +1 -1
- package/dist/transports/resend.js +2 -2
- package/dist/transports/resend.js.map +1 -1
- package/dist/transports/retry.js +2 -2
- package/dist/transports/retry.js.map +4 -3
- package/dist/transports/sendgrid.js +2 -2
- package/dist/transports/sendgrid.js.map +2 -2
- package/dist/transports/ses.js +3 -3
- package/dist/transports/ses.js.map +1 -1
- package/dist/transports/smtp.js +2 -2
- package/dist/transports/smtp.js.map +1 -1
- package/dist/webhooks/brevo.js +1 -1
- package/dist/webhooks/mailgun.js +1 -1
- package/dist/webhooks/postmark.js +1 -1
- package/dist/webhooks/resend.js +1 -1
- package/dist/webhooks/sendgrid.js +1 -1
- package/dist/webhooks/ses.js +1 -1
- package/dist/webhooks/timing-safe-equal.js +1 -1
- package/package.json +5 -1
- package/dist/chunk-1cmggzw0.js +0 -4
- package/dist/chunk-1cmggzw0.js.map +0 -10
- package/dist/chunk-wp4qxk1j.js +0 -4
- package/dist/chunk-wp4qxk1j.js.map +0 -11
package/dist/webhooks/ses.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{d as Q,e as U,g as X}from"../chunk-q8k3m6qe.js";import"../chunk-
|
|
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-
|
|
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.
|
|
3
|
+
"version": "0.6.2",
|
|
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"
|
package/dist/chunk-1cmggzw0.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{D as G}from"./chunk-gkec86xg.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
|
-
}
|
package/dist/chunk-wp4qxk1j.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{v as I}from"./chunk-1cmggzw0.js";import{w as M}from"./chunk-tfxje74k.js";import{A as R}from"./chunk-xdx6ypr5.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
|
-
}
|