@visulima/notification 1.0.10 → 1.0.11

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 (80) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/channels/email/index.js +1 -1
  3. package/dist/digest/index.js +1 -1
  4. package/dist/i18n/index.js +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/middleware/index.js +1 -1
  7. package/dist/packem_shared/Notification-BuS_QjJv.js +1 -0
  8. package/dist/packem_shared/NotificationError-B1ZZqWxL.js +1 -0
  9. package/dist/packem_shared/{RequiredOptionError-Bs282gKK.js → RequiredOptionError-CH4g-BZM.js} +1 -1
  10. package/dist/packem_shared/{apnsProvider-BPH0pHvd.js → apnsProvider-BV5-wOvD.js} +1 -1
  11. package/dist/packem_shared/{circuitBreakerMiddleware-CRBi0H7e.js → circuitBreakerMiddleware-o3G_6N3s.js} +1 -1
  12. package/dist/packem_shared/{createDigester-DenmT8_X.js → createDigester-DCwWhmpi.js} +1 -1
  13. package/dist/packem_shared/{createNotificationWorkflow-5AY-ays0.js → createNotificationWorkflow-lseG_9fC.js} +1 -1
  14. package/dist/packem_shared/createQueueWorker-BIXWHJLY.js +1 -0
  15. package/dist/packem_shared/{createTranslator-ByyvYNfG.js → createTranslator-BL2M8eeD.js} +1 -1
  16. package/dist/packem_shared/{discordProvider-BvKwrC8K.js → discordProvider-D4LpBljj.js} +1 -1
  17. package/dist/packem_shared/{emailChannel-Cf8wZPZL.js → emailChannel-BoLLbyrn.js} +1 -1
  18. package/dist/packem_shared/{expoProvider-13gY7Ne8.js → expoProvider-BPJr9c0e.js} +1 -1
  19. package/dist/packem_shared/{failoverProvider-DXcwmYev.js → failoverProvider-CJsDGjzf.js} +1 -1
  20. package/dist/packem_shared/fcmProvider-qIR12R9m.js +1 -0
  21. package/dist/packem_shared/hmacBase64-CNksyDoB.js +1 -0
  22. package/dist/packem_shared/{messageBirdProvider-D1c3jUqj.js → messageBirdProvider-FK9_UONf.js} +1 -1
  23. package/dist/packem_shared/{mockProvider-DZ3immtm.js → mockProvider-C2hHPSVa.js} +1 -1
  24. package/dist/packem_shared/{msTeamsProvider-Cd-BUhH1.js → msTeamsProvider-DeGPjmCt.js} +1 -1
  25. package/dist/packem_shared/{plivoProvider-C_koQ8X-.js → plivoProvider-DaCu7J3X.js} +1 -1
  26. package/dist/packem_shared/{roundRobinProvider-CK3Vyc_u.js → roundRobinProvider-HowYifRe.js} +1 -1
  27. package/dist/packem_shared/{slackProvider-B92QDf3e.js → slackProvider-Caxbs4Pa.js} +1 -1
  28. package/dist/packem_shared/{slackWebhook-Cpmm_0El.js → slackWebhook-IB4mVnBk.js} +1 -1
  29. package/dist/packem_shared/{sms-64HGUCLu.js → sms-BbxkOLQm.js} +1 -1
  30. package/dist/packem_shared/{snsProvider-CPGjOUP_.js → snsProvider-BS4D6w-i.js} +3 -3
  31. package/dist/packem_shared/{standardWebhook-Bk0UUeDW.js → standardWebhook-C_AQWUi5.js} +1 -1
  32. package/dist/packem_shared/{telegramProvider-BmmroM5A.js → telegramProvider-BIc_GgpY.js} +1 -1
  33. package/dist/packem_shared/{telnyxProvider-C41tE4VF.js → telnyxProvider-wjmTXBwh.js} +1 -1
  34. package/dist/packem_shared/{twilioProvider-DanDTzi3.js → twilioProvider-Bf_zsF9z.js} +1 -1
  35. package/dist/packem_shared/twilioWebhook-Hhf9aWV1.js +1 -0
  36. package/dist/packem_shared/{types.d--kw9ifOI.d.ts → types.d-r8K0ICyx.d.ts} +1 -1
  37. package/dist/packem_shared/{vonageProvider-epeGBWW8.js → vonageProvider-oRg9dpS1.js} +1 -1
  38. package/dist/packem_shared/{webPushProvider-K6-Drhaf.js → webPushProvider-BtZHb_X_.js} +1 -1
  39. package/dist/packem_shared/{webcrypto-bY7wJCB5.js → webcrypto-CFuQmh5-.js} +1 -1
  40. package/dist/packem_shared/webhookProvider-CwkDb1cZ.js +1 -0
  41. package/dist/providers/chat/discord/index.js +1 -1
  42. package/dist/providers/chat/msteams/index.js +1 -1
  43. package/dist/providers/chat/slack/index.js +1 -1
  44. package/dist/providers/chat/telegram/index.js +1 -1
  45. package/dist/providers/failover/index.js +1 -1
  46. package/dist/providers/mock/index.js +1 -1
  47. package/dist/providers/push/apns/index.js +1 -1
  48. package/dist/providers/push/expo/index.js +1 -1
  49. package/dist/providers/push/fcm/index.js +1 -1
  50. package/dist/providers/push/web-push/index.js +1 -1
  51. package/dist/providers/roundrobin/index.js +1 -1
  52. package/dist/providers/sms/messagebird/index.js +1 -1
  53. package/dist/providers/sms/plivo/index.js +1 -1
  54. package/dist/providers/sms/sns/index.js +1 -1
  55. package/dist/providers/sms/telnyx/index.js +1 -1
  56. package/dist/providers/sms/twilio/index.js +1 -1
  57. package/dist/providers/sms/vonage/index.js +1 -1
  58. package/dist/providers/webhook/index.js +1 -1
  59. package/dist/queue/bullmq-queue.d.ts +1 -1
  60. package/dist/queue/index.d.ts +3 -1
  61. package/dist/queue/index.js +1 -1
  62. package/dist/queue/pg-boss-queue.d.ts +4 -3
  63. package/dist/queue/pg-boss-queue.js +1 -1
  64. package/dist/queue/sqs-queue.d.ts +1 -1
  65. package/dist/queue/sqs-queue.js +1 -1
  66. package/dist/queue/unstorage-queue.d.ts +8 -1
  67. package/dist/queue/unstorage-queue.js +1 -1
  68. package/dist/template-engines/handlebars.js +1 -1
  69. package/dist/template-engines/liquid.js +1 -1
  70. package/dist/utils/result.js +1 -1
  71. package/dist/webhooks/index.js +1 -1
  72. package/dist/workflow/index.js +1 -1
  73. package/package.json +3 -3
  74. package/dist/packem_shared/Notification-DH2mcFWI.js +0 -1
  75. package/dist/packem_shared/NotificationError-B8CyoEaX.js +0 -1
  76. package/dist/packem_shared/createQueueWorker-DjQBxjXc.js +0 -1
  77. package/dist/packem_shared/fcmProvider-DsGjzBzz.js +0 -1
  78. package/dist/packem_shared/hmacBase64-BhhoX0uo.js +0 -1
  79. package/dist/packem_shared/twilioWebhook-C-Iwuv7y.js +0 -1
  80. package/dist/packem_shared/webhookProvider-DlwFyaGc.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## @visulima/notification [1.0.11](https://github.com/visulima/visulima/compare/%40visulima%2Fnotification%401.0.10...%40visulima%2Fnotification%401.0.11) (2026-08-02)
2
+
3
+
4
+ ### Dependencies
5
+
6
+ * **@visulima/email:** upgraded to 2.1.8
7
+ * **@visulima/error:** upgraded to 6.1.0
8
+ * **@visulima/workflow:** upgraded to 2.0.0
9
+
1
10
  ## @visulima/notification [1.0.10](https://github.com/visulima/visulima/compare/%40visulima%2Fnotification%401.0.9...%40visulima%2Fnotification%401.0.10) (2026-07-27)
2
11
 
3
12
 
@@ -1 +1 @@
1
- import{emailChannel as l}from"../../packem_shared/emailChannel-Cf8wZPZL.js";export{l as emailChannel};
1
+ import{emailChannel as l}from"../../packem_shared/emailChannel-BoLLbyrn.js";export{l as emailChannel};
@@ -1 +1 @@
1
- import{default as r}from"../packem_shared/createDigester-DenmT8_X.js";import{default as a}from"../packem_shared/MemoryDigestStore-Bw-sE5MI.js";import{default as f}from"../packem_shared/UnstorageDigestStore-QAcO3Vb_.js";export{a as MemoryDigestStore,f as UnstorageDigestStore,r as createDigester};
1
+ import{default as r}from"../packem_shared/createDigester-DCwWhmpi.js";import{default as a}from"../packem_shared/MemoryDigestStore-Bw-sE5MI.js";import{default as f}from"../packem_shared/UnstorageDigestStore-QAcO3Vb_.js";export{a as MemoryDigestStore,f as UnstorageDigestStore,r as createDigester};
@@ -1 +1 @@
1
- import{default as e}from"../packem_shared/createTranslator-ByyvYNfG.js";export{e as createTranslator};
1
+ import{default as e}from"../packem_shared/createTranslator-BL2M8eeD.js";export{e as createTranslator};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{default as r}from"./packem_shared/NotificationError-B8CyoEaX.js";import{default as t}from"./packem_shared/RequiredOptionError-Bs282gKK.js";import{composeMiddleware as f}from"./packem_shared/composeMiddleware-D6dR8DUS.js";import{Notification as c,createNotification as n,send as p}from"./packem_shared/Notification-DH2mcFWI.js";import{NotificationMessageBuilder as m,createNotificationMessage as x}from"./packem_shared/NotificationMessageBuilder-Br_aZusY.js";import{defineProvider as l}from"./packem_shared/defineProvider-C9q-7iwt.js";export{c as Notification,r as NotificationError,m as NotificationMessageBuilder,t as RequiredOptionError,f as composeMiddleware,n as createNotification,x as createNotificationMessage,l as defineProvider,p as send};
1
+ import{default as r}from"./packem_shared/NotificationError-B1ZZqWxL.js";import{default as t}from"./packem_shared/RequiredOptionError-CH4g-BZM.js";import{composeMiddleware as f}from"./packem_shared/composeMiddleware-D6dR8DUS.js";import{Notification as c,createNotification as n,send as p}from"./packem_shared/Notification-BuS_QjJv.js";import{NotificationMessageBuilder as m,createNotificationMessage as x}from"./packem_shared/NotificationMessageBuilder-Br_aZusY.js";import{defineProvider as l}from"./packem_shared/defineProvider-C9q-7iwt.js";export{c as Notification,r as NotificationError,m as NotificationMessageBuilder,t as RequiredOptionError,f as composeMiddleware,n as createNotification,x as createNotificationMessage,l as defineProvider,p as send};
@@ -1 +1 @@
1
- import{circuitBreakerMiddleware as o}from"../packem_shared/circuitBreakerMiddleware-CRBi0H7e.js";import{dedupeMiddleware as i}from"../packem_shared/dedupeMiddleware-CQmPJd_h.js";import{loggingMiddleware as p}from"../packem_shared/loggingMiddleware-Cs6EDLcL.js";import{rateLimitMiddleware as a}from"../packem_shared/rateLimitMiddleware-DWmEYq-m.js";import{retryMiddleware as f}from"../packem_shared/retryMiddleware-uUJDcUoP.js";import{suppressionMiddleware as x}from"../packem_shared/suppressionMiddleware-CY-Qo1A_.js";import{telemetryMiddleware as s}from"../packem_shared/telemetryMiddleware-B1N4k171.js";import{composeMiddleware as g}from"../packem_shared/composeMiddleware-D6dR8DUS.js";export{o as circuitBreakerMiddleware,g as composeMiddleware,i as dedupeMiddleware,p as loggingMiddleware,a as rateLimitMiddleware,f as retryMiddleware,x as suppressionMiddleware,s as telemetryMiddleware};
1
+ import{circuitBreakerMiddleware as o}from"../packem_shared/circuitBreakerMiddleware-o3G_6N3s.js";import{dedupeMiddleware as i}from"../packem_shared/dedupeMiddleware-CQmPJd_h.js";import{loggingMiddleware as p}from"../packem_shared/loggingMiddleware-Cs6EDLcL.js";import{rateLimitMiddleware as a}from"../packem_shared/rateLimitMiddleware-DWmEYq-m.js";import{retryMiddleware as f}from"../packem_shared/retryMiddleware-uUJDcUoP.js";import{suppressionMiddleware as x}from"../packem_shared/suppressionMiddleware-CY-Qo1A_.js";import{telemetryMiddleware as s}from"../packem_shared/telemetryMiddleware-B1N4k171.js";import{composeMiddleware as g}from"../packem_shared/composeMiddleware-D6dR8DUS.js";export{o as circuitBreakerMiddleware,g as composeMiddleware,i as dedupeMiddleware,p as loggingMiddleware,a as rateLimitMiddleware,f as retryMiddleware,x as suppressionMiddleware,s as telemetryMiddleware};
@@ -0,0 +1 @@
1
+ import h from"./NotificationError-B1ZZqWxL.js";import{composeMiddleware as u}from"./composeMiddleware-D6dR8DUS.js";const c=(a,s,e)=>{if(a.success&&a.data)return{channel:s,messageId:a.data.messageId,provider:a.data.provider??e,response:a.data.response,successful:!0,timestamp:a.data.timestamp};const{error:t}=a;let i;return t instanceof Error?i=t.message:t==null?i="Unknown error":typeof t=="string"?i=t:i=JSON.stringify(t),{channel:s,errorMessages:[i],provider:e,successful:!1}};class l{#s;#e=[];#t=new Map;#a;constructor(s){this.#s=s}use(s){return this.#e.push(s),this}setLogger(s){return this.#a=s,this}getProvider(s){return this.#s[s]}async sendToChannel(s,e){const t=this.#s[s];if(!t)return{channel:s,errorMessages:[`No provider registered for channel "${s}"`],successful:!1};try{await this.#i(t)}catch(n){return c({error:n,success:!1},s,t.id)}const i=async n=>t.send(n.payload),r=u(this.#e,i);try{const n=await r({channel:s,payload:e,provider:t.id});return c(n,s,t.id)}catch(n){return c({error:n,success:!1},s,t.id)}}async send(s){const e=Object.keys(s);if(e.length===0)throw new h("notification","send() called with an empty message");return Promise.all(e.map(async t=>this.sendToChannel(t,s[t])))}async*sendMany(s,e={}){const t=Math.max(1,e.concurrency??10),i=[...s];let r=0;for(;r<i.length;){const n=i.slice(r,r+t);r+=t;const d=await Promise.all(n.map(async o=>this.send(o)));for(const o of d)yield o}}async initialize(){await Promise.all(Object.values(this.#s).map(async s=>this.#i(s)))}async shutdown(){await Promise.all(Object.values(this.#s).map(async s=>{const{shutdown:e}=s;e&&await e()}))}async#i(s){const e=this.#t.get(s.id);if(e){await e;return}const t=(async()=>{await s.initialize(),this.#a?.debug(`[@visulima/notification] initialized provider "${s.id}"`)})();this.#t.set(s.id,t);try{await t}catch(i){throw this.#t.delete(s.id),i}}}const m=a=>new l(a),p=async(a,s,e)=>new l({[a]:s}).sendToChannel(a,e);export{l as Notification,m as createNotification,p as send};
@@ -0,0 +1 @@
1
+ class h extends Error{loc;title;hint;type="VisulimaError";constructor({cause:t,hint:e,location:s,message:o,name:a,stack:c,title:n}){super(o,{cause:t}),this.title=n,this.name=a,this.stack=c??this.stack,this.loc=s,this.hint=e}setLocation(t){this.loc=t}setName(t){this.name=t}setMessage(t){this.message=t}setHint(t){this.hint=t}}class r extends h{component;code;constructor(t,e,s){super({cause:s?.cause,hint:s?.hint,message:`[@visulima/notification] [${t}] ${e}`,name:"NotificationError",title:`Notification ${t} Error`}),this.component=t,this.code=s?.code}}export{r as default};
@@ -1 +1 @@
1
- import s from"./NotificationError-B8CyoEaX.js";class a extends s{constructor(o,e){const r=Array.isArray(e)?`Missing required options: ${e.map(i=>`'${i}'`).join(", ")}`:`Missing required option: '${e}'`;super(o,r,{hint:Array.isArray(e)?`Please provide the following required options: ${e.map(i=>`'${i}'`).join(", ")}`:`Please provide the required option: '${e}'`}),this.name="RequiredOptionError"}}export{a as default};
1
+ import s from"./NotificationError-B1ZZqWxL.js";class a extends s{constructor(o,e){const r=Array.isArray(e)?`Missing required options: ${e.map(i=>`'${i}'`).join(", ")}`:`Missing required option: '${e}'`;super(o,r,{hint:Array.isArray(e)?`Please provide the following required options: ${e.map(i=>`'${i}'`).join(", ")}`:`Please provide the required option: '${e}'`}),this.name="RequiredOptionError"}}export{a as default};
@@ -1 +1 @@
1
- import{createRequire as I}from"node:module";import g from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as k}from"./defineProvider-C9q-7iwt.js";import{t as N}from"./credentials-CG0zkn-W.js";import{a as R}from"./sms-64HGUCLu.js";let S;const T=s=>(S??=I(import.meta.url))(s),f=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,y=s=>{if(typeof f<"u"&&f.versions&&f.versions.node){const[t,r]=f.versions.node.split(".").map(Number);if(t>22||t===22&&r>=3||t===20&&r>=16)return f.getBuiltinModule(s)}return T(s)},{sign:$,createPrivateKey:P}=y("node:crypto"),{connect:j}=y("node:http2"),q="https://api.push.apple.com",J="https://api.sandbox.push.apple.com",K=3e3*1e3,O=200,h=s=>Buffer.from(s,"utf8").toString("base64url"),B=(s,t,r)=>{const l=h(JSON.stringify({alg:"ES256",kid:s.keyId,typ:"JWT"})),p=h(JSON.stringify({iat:r,iss:s.teamId})),u=`${l}.${p}`,n=$("sha256",Buffer.from(u,"utf8"),{dsaEncoding:"ieee-p1363",key:t}).toString("base64url");return`${u}.${n}`},A=k(s=>{const t=s??{};if(!t.teamId)throw new g("apns","teamId");if(!t.keyId)throw new g("apns","keyId");if(!t.signingKey)throw new g("apns","signingKey");if(!t.bundleId)throw new g("apns","bundleId");const r=t.production?q:J;let l,p,u=0,n;const b=()=>(l??=P({format:"pem",key:t.signingKey}),l),_=()=>{const e=Date.now();return(!p||e-u>K)&&(p=B(t,b(),Math.floor(e/1e3)),u=e),p},w=()=>((!n||n.closed||n.destroyed)&&(n=j(r),n.on("error",e=>{t.logger?.warn(`[@visulima/notification] [apns] HTTP/2 session error: ${e.message}`)})),n),v=async(e,m)=>new Promise(a=>{const i=w().request({":method":"POST",":path":`/3/device/${e}`,"apns-topic":t.bundleId,authorization:`bearer ${_()}`,"content-type":"application/json"});let d=0,c="";i.setEncoding("utf8"),i.on("response",o=>{d=o[":status"]??0}),i.on("data",o=>{c+=o}),i.on("error",o=>{a({error:o.message,id:e,status:"failed"})}),i.on("end",()=>{if(d===O){a({id:e,messageId:e,status:"sent"});return}let o=`HTTP ${String(d)}`;if(c)try{o=JSON.parse(c).reason??o}catch{o=c}a({error:o,id:e,status:"failed"})}),i.end(m)});return{channel:"push",endpoint:r,features:{batchSending:!1,media:!0,richContent:!0},id:"apns",initialize:()=>{},isAvailable:()=>!0,options:t,send:async e=>{const m=N(e.to),a={alert:{body:e.body,title:e.title}};e.sound!==void 0&&(a.sound=e.sound),e.badge!==void 0&&(a.badge=e.badge);const i=JSON.stringify({...e.data,aps:a}),d=[];for(const c of m)d.push(await v(c,i));return R("push","apns",d)},shutdown:()=>{n&&!n.closed&&n.close(),n=void 0}}});export{A as default};
1
+ import{createRequire as I}from"node:module";import g from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as k}from"./defineProvider-C9q-7iwt.js";import{t as N}from"./credentials-CG0zkn-W.js";import{a as R}from"./sms-BbxkOLQm.js";let S;const T=s=>(S??=I(import.meta.url))(s),f=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,y=s=>{if(typeof f<"u"&&f.versions&&f.versions.node){const[t,r]=f.versions.node.split(".").map(Number);if(t>22||t===22&&r>=3||t===20&&r>=16)return f.getBuiltinModule(s)}return T(s)},{sign:$,createPrivateKey:P}=y("node:crypto"),{connect:j}=y("node:http2"),q="https://api.push.apple.com",J="https://api.sandbox.push.apple.com",K=3e3*1e3,O=200,h=s=>Buffer.from(s,"utf8").toString("base64url"),B=(s,t,r)=>{const l=h(JSON.stringify({alg:"ES256",kid:s.keyId,typ:"JWT"})),p=h(JSON.stringify({iat:r,iss:s.teamId})),u=`${l}.${p}`,n=$("sha256",Buffer.from(u,"utf8"),{dsaEncoding:"ieee-p1363",key:t}).toString("base64url");return`${u}.${n}`},A=k(s=>{const t=s??{};if(!t.teamId)throw new g("apns","teamId");if(!t.keyId)throw new g("apns","keyId");if(!t.signingKey)throw new g("apns","signingKey");if(!t.bundleId)throw new g("apns","bundleId");const r=t.production?q:J;let l,p,u=0,n;const b=()=>(l??=P({format:"pem",key:t.signingKey}),l),_=()=>{const e=Date.now();return(!p||e-u>K)&&(p=B(t,b(),Math.floor(e/1e3)),u=e),p},w=()=>((!n||n.closed||n.destroyed)&&(n=j(r),n.on("error",e=>{t.logger?.warn(`[@visulima/notification] [apns] HTTP/2 session error: ${e.message}`)})),n),v=async(e,m)=>new Promise(a=>{const i=w().request({":method":"POST",":path":`/3/device/${e}`,"apns-topic":t.bundleId,authorization:`bearer ${_()}`,"content-type":"application/json"});let d=0,c="";i.setEncoding("utf8"),i.on("response",o=>{d=o[":status"]??0}),i.on("data",o=>{c+=o}),i.on("error",o=>{a({error:o.message,id:e,status:"failed"})}),i.on("end",()=>{if(d===O){a({id:e,messageId:e,status:"sent"});return}let o=`HTTP ${String(d)}`;if(c)try{o=JSON.parse(c).reason??o}catch{o=c}a({error:o,id:e,status:"failed"})}),i.end(m)});return{channel:"push",endpoint:r,features:{batchSending:!1,media:!0,richContent:!0},id:"apns",initialize:()=>{},isAvailable:()=>!0,options:t,send:async e=>{const m=N(e.to),a={alert:{body:e.body,title:e.title}};e.sound!==void 0&&(a.sound=e.sound),e.badge!==void 0&&(a.badge=e.badge);const i=JSON.stringify({...e.data,aps:a}),d=[];for(const c of m)d.push(await v(c,i));return R("push","apns",d)},shutdown:()=>{n&&!n.closed&&n.close(),n=void 0}}});export{A as default};
@@ -1 +1 @@
1
- import u from"./NotificationError-B8CyoEaX.js";const p=(o={})=>{const i=o.threshold??5,n=o.resetTimeout??3e4;let r=0,s=0,e="closed";return async(t,a)=>{if(e==="open")if(Date.now()-s>=n)e="half-open";else return{error:new u("circuit-breaker",`Circuit open for "${t.provider}"`),success:!1};const c=await a(t);return c.success?(r=0,e="closed"):(r+=1,r>=i&&(e="open",s=Date.now())),c}};export{p as circuitBreakerMiddleware};
1
+ import u from"./NotificationError-B1ZZqWxL.js";const p=(o={})=>{const i=o.threshold??5,n=o.resetTimeout??3e4;let r=0,s=0,e="closed";return async(t,a)=>{if(e==="open")if(Date.now()-s>=n)e="half-open";else return{error:new u("circuit-breaker",`Circuit open for "${t.provider}"`),success:!1};const c=await a(t);return c.success?(r=0,e="closed"):(r+=1,r>=i&&(e="open",s=Date.now())),c}};export{p as circuitBreakerMiddleware};
@@ -1 +1 @@
1
- import r from"./NotificationError-B8CyoEaX.js";import u from"./MemoryDigestStore-Bw-sE5MI.js";const d={days:864e5,hours:36e5,milliseconds:1,minutes:6e4,ms:1,seconds:1e3,weeks:6048e5},c=async(e,t)=>{if(typeof e=="number"){if(!Number.isFinite(e))throw new r("digest",`Window must be a finite number of milliseconds. Received: ${String(e)}.`);return t+Math.max(0,e)}if("cron"in e){let i;try{i=await import("croner")}catch(o){throw new r("digest","croner is not installed (required for cron windows). Please install it: pnpm add croner",{cause:o})}const n=new i.Cron(e.cron,e.tz?{timezone:e.tz}:{}).nextRun(new Date(t));if(n===null)throw new r("digest",`Cron expression "${e.cron}" has no future occurrence.`);return n.getTime()}if(!Number.isFinite(e.amount))throw new r("digest",`Window amount must be a finite number. Received: ${String(e.amount)}.`);return t+Math.max(0,e.amount)*d[e.unit]},m=()=>globalThis.crypto.randomUUID(),p=e=>{const t=e.store??new u;return{add:async i=>{const n=e.key(i),o=typeof e.window=="function"?e.window(i):e.window,s={id:m(),payload:i,time:Date.now()};return t.append(n,s,await c(o,Date.now()))},sweep:async(i=Date.now(),n=100)=>{if(!Number.isInteger(n)||n<=0)throw new r("digest",`sweep limit must be a positive integer. Received: ${String(n)}.`);const o=await t.due(i,n);let s=0;for(const w of o){const a=await t.read(w);a!==void 0&&a.events.length>0&&(await e.onFlush(a.events,w),s+=1),a!==void 0&&await t.remove(w)}return s}}};export{p as default};
1
+ import r from"./NotificationError-B1ZZqWxL.js";import u from"./MemoryDigestStore-Bw-sE5MI.js";const d={days:864e5,hours:36e5,milliseconds:1,minutes:6e4,ms:1,seconds:1e3,weeks:6048e5},c=async(e,t)=>{if(typeof e=="number"){if(!Number.isFinite(e))throw new r("digest",`Window must be a finite number of milliseconds. Received: ${String(e)}.`);return t+Math.max(0,e)}if("cron"in e){let i;try{i=await import("croner")}catch(o){throw new r("digest","croner is not installed (required for cron windows). Please install it: pnpm add croner",{cause:o})}const n=new i.Cron(e.cron,e.tz?{timezone:e.tz}:{}).nextRun(new Date(t));if(n===null)throw new r("digest",`Cron expression "${e.cron}" has no future occurrence.`);return n.getTime()}if(!Number.isFinite(e.amount))throw new r("digest",`Window amount must be a finite number. Received: ${String(e.amount)}.`);return t+Math.max(0,e.amount)*d[e.unit]},m=()=>globalThis.crypto.randomUUID(),p=e=>{const t=e.store??new u;return{add:async i=>{const n=e.key(i),o=typeof e.window=="function"?e.window(i):e.window,s={id:m(),payload:i,time:Date.now()};return t.append(n,s,await c(o,Date.now()))},sweep:async(i=Date.now(),n=100)=>{if(!Number.isInteger(n)||n<=0)throw new r("digest",`sweep limit must be a positive integer. Received: ${String(n)}.`);const o=await t.due(i,n);let s=0;for(const w of o){const a=await t.read(w);a!==void 0&&a.events.length>0&&(await e.onFlush(a.events,w),s+=1),a!==void 0&&await t.remove(w)}return s}}};export{p as default};
@@ -1 +1 @@
1
- import{defineWorkflow as y}from"@visulima/workflow";import c from"./NotificationError-B8CyoEaX.js";const m=(d,p)=>{const l=e=>{const n=async(a,s,o,r)=>e.step(s,async()=>{if(r?.skip&&await r.skip({payload:e.payload}))return;const u=await o({payload:e.payload}),t=await d.sendToChannel(a,u);if(r?.throwOnFailure&&!t.successful)throw new c(a,t.errorMessages.join("; "));return t}),i={chat:(a,s,o)=>n("chat",a,s,o),custom:(a,s)=>e.step(a,s),delay:(a,s)=>e.sleep(a,s),email:(a,s,o)=>n("email",a,s,o),inApp:(a,s,o)=>n("inapp",a,s,o),push:(a,s,o)=>n("push",a,s,o),sms:(a,s,o)=>n("sms",a,s,o),webhook:(a,s,o)=>n("webhook",a,s,o)};return p.run({payload:e.payload,runId:e.runId,step:i})};return y({id:p.id,payload:p.payload,run:l,tags:p.tags})};export{m as default};
1
+ import{defineWorkflow as y}from"@visulima/workflow";import c from"./NotificationError-B1ZZqWxL.js";const m=(d,p)=>{const l=e=>{const n=async(a,s,o,r)=>e.step(s,async()=>{if(r?.skip&&await r.skip({payload:e.payload}))return;const u=await o({payload:e.payload}),t=await d.sendToChannel(a,u);if(r?.throwOnFailure&&!t.successful)throw new c(a,t.errorMessages.join("; "));return t}),i={chat:(a,s,o)=>n("chat",a,s,o),custom:(a,s)=>e.step(a,s),delay:(a,s)=>e.sleep(a,s),email:(a,s,o)=>n("email",a,s,o),inApp:(a,s,o)=>n("inapp",a,s,o),push:(a,s,o)=>n("push",a,s,o),sms:(a,s,o)=>n("sms",a,s,o),webhook:(a,s,o)=>n("webhook",a,s,o)};return p.run({payload:e.payload,runId:e.runId,step:i})};return y({id:p.id,payload:p.payload,run:l,tags:p.tags})};export{m as default};
@@ -0,0 +1 @@
1
+ const u=async a=>new Promise(o=>{setTimeout(o,a)}),w=(a,o,e={})=>{const f=e.maxAttempts??5,l=e.pollInterval??1e3,n=e.backoff??(t=>Math.min(3e4,1e3*2**(t-1)));let r=!1;const i=async()=>{const t=await a.reserve();if(!t)return!1;try{const s=await o.send(t.message);s.some(c=>!c.successful)?t.attempts>=f?(await a.ack(t.id),e.onDrop?.(t,s)):await a.retry(t.id,n(t.attempts)):await a.ack(t.id)}catch(s){e.onError?.(s,t);try{await a.retry(t.id,n(t.attempts))}catch(c){e.onError?.(c,t)}}return!0},m=async()=>{for(;r;){let t=!1;try{t=await i()}catch(s){e.onError?.(s)}t||await u(l)}};return{drain:async()=>{for(;await i(););},start:()=>{r||(r=!0,m().catch(()=>{r=!1}))},stop:()=>{r=!1}}};export{w as createQueueWorker};
@@ -1 +1 @@
1
- import{IntlMessageFormat as f}from"intl-messageformat";import g from"./NotificationError-B8CyoEaX.js";const u=/[-_]/u,m=e=>e.split(u)[0]??e,$=e=>{const n=new Map,c=(t,o)=>{for(const s of[t,m(t),e.fallbackLocale,m(e.fallbackLocale)]){const a=e.messages[s]?.[o];if(a!==void 0)return{locale:s,message:a}}};return{has:(t,o)=>c(t,o)!==void 0,translate:(t,o,s)=>{const a=c(t,o);if(a===void 0)return e.onMissing?e.onMissing(t,o):o;const r=`${a.locale}\0${o}`;let l=n.get(r);l===void 0&&(l=new f(a.message,a.locale.replaceAll("_","-")),n.set(r,l));try{return String(l.format(s))}catch(i){throw new g("i18n",`Failed to format message "${o}" for locale "${a.locale}": ${i.message}`,{cause:i})}}}};export{$ as default};
1
+ import{IntlMessageFormat as f}from"intl-messageformat";import g from"./NotificationError-B1ZZqWxL.js";const u=/[-_]/u,m=e=>e.split(u)[0]??e,$=e=>{const n=new Map,c=(t,o)=>{for(const s of[t,m(t),e.fallbackLocale,m(e.fallbackLocale)]){const a=e.messages[s]?.[o];if(a!==void 0)return{locale:s,message:a}}};return{has:(t,o)=>c(t,o)!==void 0,translate:(t,o,s)=>{const a=c(t,o);if(a===void 0)return e.onMissing?e.onMissing(t,o):o;const r=`${a.locale}\0${o}`;let l=n.get(r);l===void 0&&(l=new f(a.message,a.locale.replaceAll("_","-")),n.set(r,l));try{return String(l.format(s))}catch(i){throw new g("i18n",`Failed to format message "${o}" for locale "${a.locale}": ${i.message}`,{cause:i})}}}};export{$ as default};
@@ -1 +1 @@
1
- import s from"./NotificationError-B8CyoEaX.js";import c from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as l}from"./defineProvider-C9q-7iwt.js";import{r as m}from"./http-DT3tyixg.js";import{n as u}from"./id-C_FRCsUM.js";const k=l(a=>{const e=a??{};if(!e.webhookUrl)throw new c("discord","webhookUrl");const i=e.retries??3,d=e.timeout??3e4,n=e.webhookUrl.includes("?")?`${e.webhookUrl}&wait=true`:`${e.webhookUrl}?wait=true`;return{channel:"chat",endpoint:e.webhookUrl,features:{batchSending:!1,richContent:!0},id:"discord",initialize:()=>{},isAvailable:()=>!!e.webhookUrl,options:e,send:async r=>{const o={content:r.text,embeds:r.blocks,username:e.username};r.threadId&&(o.thread_id=r.threadId);const t=await m(n,{body:JSON.stringify(o),headers:{"Content-Type":"application/json"},method:"POST",timeout:d},i);return!t.success||!t.data?{error:new s("discord",t.error instanceof Error?t.error.message:"Request failed"),success:!1}:t.data.status>=400?{error:new s("discord",t.data.body.message??`HTTP ${String(t.data.status)}`),success:!1}:{data:{channel:"chat",messageId:t.data.body.id??u("discord"),provider:"discord",sent:!0,timestamp:new Date},success:!0}},validateCredentials:()=>!!e.webhookUrl}});export{k as default};
1
+ import s from"./NotificationError-B1ZZqWxL.js";import c from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as l}from"./defineProvider-C9q-7iwt.js";import{r as m}from"./http-DT3tyixg.js";import{n as u}from"./id-C_FRCsUM.js";const k=l(a=>{const e=a??{};if(!e.webhookUrl)throw new c("discord","webhookUrl");const i=e.retries??3,d=e.timeout??3e4,n=e.webhookUrl.includes("?")?`${e.webhookUrl}&wait=true`:`${e.webhookUrl}?wait=true`;return{channel:"chat",endpoint:e.webhookUrl,features:{batchSending:!1,richContent:!0},id:"discord",initialize:()=>{},isAvailable:()=>!!e.webhookUrl,options:e,send:async r=>{const o={content:r.text,embeds:r.blocks,username:e.username};r.threadId&&(o.thread_id=r.threadId);const t=await m(n,{body:JSON.stringify(o),headers:{"Content-Type":"application/json"},method:"POST",timeout:d},i);return!t.success||!t.data?{error:new s("discord",t.error instanceof Error?t.error.message:"Request failed"),success:!1}:t.data.status>=400?{error:new s("discord",t.data.body.message??`HTTP ${String(t.data.status)}`),success:!1}:{data:{channel:"chat",messageId:t.data.body.id??u("discord"),provider:"discord",sent:!0,timestamp:new Date},success:!0}},validateCredentials:()=>!!e.webhookUrl}});export{k as default};
@@ -1 +1 @@
1
- import n from"./NotificationError-B8CyoEaX.js";const c=(t,r={})=>{const a=r.id??"email";return{channel:"email",features:{attachments:!0,batchSending:!0,richContent:!0,templates:!0,tracking:!0},id:a,initialize:()=>{},isAvailable:()=>!0,send:async s=>{const e=await t.send(s);return!e.success||!e.data?{error:new n(a,e.error instanceof Error?e.error.message:"Email send failed",{cause:e.error}),success:!1}:{data:{channel:"email",messageId:e.data.messageId,provider:e.data.provider??a,response:e.data.response,sent:e.data.sent??!0,timestamp:e.data.timestamp??new Date},success:!0}}}};export{c as emailChannel};
1
+ import n from"./NotificationError-B1ZZqWxL.js";const c=(t,r={})=>{const a=r.id??"email";return{channel:"email",features:{attachments:!0,batchSending:!0,richContent:!0,templates:!0,tracking:!0},id:a,initialize:()=>{},isAvailable:()=>!0,send:async s=>{const e=await t.send(s);return!e.success||!e.data?{error:new n(a,e.error instanceof Error?e.error.message:"Email send failed",{cause:e.error}),success:!1}:{data:{channel:"email",messageId:e.data.messageId,provider:e.data.provider??a,response:e.data.response,sent:e.data.sent??!0,timestamp:e.data.timestamp??new Date},success:!0}}}};export{c as emailChannel};
@@ -1 +1 @@
1
- import d from"./NotificationError-B8CyoEaX.js";import{defineProvider as x}from"./defineProvider-C9q-7iwt.js";import{t as T}from"./credentials-CG0zkn-W.js";import{r as w}from"./http-DT3tyixg.js";import{n as A}from"./id-C_FRCsUM.js";const $="https://exp.host",R=x(l=>{const t=l??{},u=t.endpoint??$,f=t.retries??3,h=t.timeout??3e4,g=`${u}/--/api/v2/push/send`;return{channel:"push",endpoint:u,features:{batchSending:!0,media:!0,richContent:!0},id:"expo",initialize:()=>{},isAvailable:()=>!0,options:t,send:async s=>{const p=T(s.to),y=p.map(r=>({badge:s.badge,body:s.body,data:s.data,sound:s.sound??"default",title:s.title,to:r})),c={"Content-Type":"application/json"};t.accessToken&&(c.Authorization=`Bearer ${t.accessToken}`);const e=await w(g,{body:JSON.stringify(y),headers:c,method:"POST",timeout:h},f);if(!e.success||!e.data)return{error:new d("expo",e.error instanceof Error?e.error.message:"Request failed"),success:!1};if(e.data.status>=400)return{error:new d("expo",`HTTP ${String(e.data.status)}`),success:!1};const a=e.data.body.data;let n;Array.isArray(a)?n=a:n=a?[a]:[];const i=p.map((r,b)=>{const o=n[b];return o?.status==="error"?{error:o.details?.error??o.message??"error",id:r,status:"failed"}:{id:r,messageId:o?.id,status:"sent"}}),m=i.filter(r=>r.status==="sent");return m.length===0?{error:new d("expo",i[0]?.error??"All tokens failed"),success:!1}:{data:{channel:"push",messageId:m[0]?.messageId??A("expo"),provider:"expo",recipients:i,sent:!0,timestamp:new Date},success:!0}}}});export{R as default};
1
+ import d from"./NotificationError-B1ZZqWxL.js";import{defineProvider as x}from"./defineProvider-C9q-7iwt.js";import{t as T}from"./credentials-CG0zkn-W.js";import{r as w}from"./http-DT3tyixg.js";import{n as A}from"./id-C_FRCsUM.js";const $="https://exp.host",R=x(l=>{const t=l??{},u=t.endpoint??$,f=t.retries??3,h=t.timeout??3e4,g=`${u}/--/api/v2/push/send`;return{channel:"push",endpoint:u,features:{batchSending:!0,media:!0,richContent:!0},id:"expo",initialize:()=>{},isAvailable:()=>!0,options:t,send:async s=>{const p=T(s.to),y=p.map(r=>({badge:s.badge,body:s.body,data:s.data,sound:s.sound??"default",title:s.title,to:r})),c={"Content-Type":"application/json"};t.accessToken&&(c.Authorization=`Bearer ${t.accessToken}`);const e=await w(g,{body:JSON.stringify(y),headers:c,method:"POST",timeout:h},f);if(!e.success||!e.data)return{error:new d("expo",e.error instanceof Error?e.error.message:"Request failed"),success:!1};if(e.data.status>=400)return{error:new d("expo",`HTTP ${String(e.data.status)}`),success:!1};const a=e.data.body.data;let n;Array.isArray(a)?n=a:n=a?[a]:[];const i=p.map((r,b)=>{const o=n[b];return o?.status==="error"?{error:o.details?.error??o.message??"error",id:r,status:"failed"}:{id:r,messageId:o?.id,status:"sent"}}),m=i.filter(r=>r.status==="sent");return m.length===0?{error:new d("expo",i[0]?.error??"All tokens failed"),success:!1}:{data:{channel:"push",messageId:m[0]?.messageId??A("expo"),provider:"expo",recipients:i,sent:!0,timestamp:new Date},success:!0}}}});export{R as default};
@@ -1 +1 @@
1
- import l from"./NotificationError-B8CyoEaX.js";const d=(r,o={})=>{if(r.length===0)throw new l("failover","At least one provider is required");const n=o.id??"failover";return{channel:r[0].channel,id:n,initialize:async()=>{await Promise.all(r.map(async e=>e.initialize()))},isAvailable:async()=>(await Promise.all(r.map(async e=>e.isAvailable()))).some(Boolean),send:async e=>{const s=[];for(const a of r){const i=await a.send(e);if(i.success)return i;const t=i.error instanceof Error?i.error.message:String(i.error);s.push(`${a.id}: ${t}`),o.logger?.warn(`[@visulima/notification] [${n}] provider "${a.id}" failed, trying next`)}return{error:new l(n,`All ${String(r.length)} providers failed: ${s.join("; ")}`),success:!1}}}};export{d as failoverProvider};
1
+ import l from"./NotificationError-B1ZZqWxL.js";const d=(r,o={})=>{if(r.length===0)throw new l("failover","At least one provider is required");const n=o.id??"failover";return{channel:r[0].channel,id:n,initialize:async()=>{await Promise.all(r.map(async e=>e.initialize()))},isAvailable:async()=>(await Promise.all(r.map(async e=>e.isAvailable()))).some(Boolean),send:async e=>{const s=[];for(const a of r){const i=await a.send(e);if(i.success)return i;const t=i.error instanceof Error?i.error.message:String(i.error);s.push(`${a.id}: ${t}`),o.logger?.warn(`[@visulima/notification] [${n}] provider "${a.id}" failed, trying next`)}return{error:new l(n,`All ${String(r.length)} providers failed: ${s.join("; ")}`),success:!1}}}};export{d as failoverProvider};
@@ -0,0 +1 @@
1
+ import g from"./NotificationError-B1ZZqWxL.js";import n from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as l}from"./defineProvider-C9q-7iwt.js";import{t as h}from"./credentials-CG0zkn-W.js";import{r as y}from"./http-DT3tyixg.js";import{a as T}from"./sms-BbxkOLQm.js";const O=l(c=>{const e=c??{};if(!e.projectId)throw new n("fcm","projectId");if(!e.accessToken&&!e.getAccessToken)throw new n("fcm",["accessToken","getAccessToken"]);const i=e.endpoint??"https://fcm.googleapis.com",d=e.retries??3,m=e.timeout??3e4,f=`${i}/v1/projects/${e.projectId}/messages:send`,p=s=>{if(s)return Object.fromEntries(Object.entries(s).map(([o,r])=>[o,typeof r=="string"?r:JSON.stringify(r)]))},u=async(s,o,r)=>{const a={data:p(o.data),notification:{body:o.body,image:o.imageUrl,title:o.title},token:s},t=await y(f,{body:JSON.stringify({message:a}),headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},method:"POST",timeout:m},d);return!t.success||!t.data?{error:t.error instanceof Error?t.error.message:"Request failed",id:s,status:"failed"}:t.data.status>=400?{error:t.data.body.error?.message??`HTTP ${String(t.data.status)}`,id:s,status:"failed"}:{id:s,messageId:t.data.body.name,status:"sent"}};return{channel:"push",endpoint:i,features:{batchSending:!1,media:!0,richContent:!0},id:"fcm",initialize:()=>{},isAvailable:()=>!!(e.projectId&&(e.accessToken??e.getAccessToken)),options:e,send:async s=>{let o;try{o=e.getAccessToken?await e.getAccessToken():e.accessToken}catch(t){return{error:new g("fcm","Failed to obtain access token",{cause:t}),success:!1}}const r=h(s.to),a=[];for(const t of r)a.push(await u(t,s,o));return T("push","fcm",a)}}});export{O as default};
@@ -0,0 +1 @@
1
+ import{t as o,h as r,a as s}from"./webcrypto-CFuQmh5-.js";const l=300,c=async(a,e,t)=>s(await r(a,e,t)),f=async(a,e,t)=>o(await r(a,e,t)),h=(a,e)=>{if(a.length!==e.length)return!1;let t=0;for(let n=0;n<a.length;n+=1)t|=(a.codePointAt(n)??0)^(e.codePointAt(n)??0);return t===0},m=(a,e)=>{if(a===void 0)return!1;const t=Number.parseInt(a,10);if(Number.isNaN(t))return!1;const n=Math.floor(Date.now()/1e3);return Math.abs(n-t)<=e};export{l as REPLAY_WINDOW_SECONDS,f as hmacBase64,c as hmacHex,m as isWithinReplayWindow,h as timingSafeEqual};
@@ -1 +1 @@
1
- import t from"./NotificationError-B8CyoEaX.js";import g from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as l}from"./defineProvider-C9q-7iwt.js";import{t as y}from"./credentials-CG0zkn-W.js";import{r as b}from"./http-DT3tyixg.js";import{b as h}from"./sms-64HGUCLu.js";const v="https://rest.messagebird.com",$=l(n=>{const e=n??{};if(!e.accessKey)throw new g("messagebird","accessKey");const i=e.endpoint??v,d=e.retries??3,c=e.timeout??3e4,m=`${i}/messages`;return{channel:"sms",endpoint:i,features:{batchSending:!0,deliveryReceipts:!0,media:!1},id:"messagebird",initialize:()=>{},isAvailable:()=>!!e.accessKey,options:e,send:async r=>{const a=y(r.to),o=r.from??e.from;if(!o)return{error:new t("messagebird","Missing originator: provide `from` on the payload or provider config"),success:!1};const s=await b(m,{body:JSON.stringify({body:r.text,originator:o,recipients:a}),headers:{Authorization:`AccessKey ${e.accessKey}`,"Content-Type":"application/json"},method:"POST",timeout:c},d);if(!s.success||!s.data)return{error:new t("messagebird",s.error instanceof Error?s.error.message:"Request failed"),success:!1};if(s.data.status>=400)return{error:new t("messagebird",s.data.body.errors?.[0]?.description??`HTTP ${String(s.data.status)}`),success:!1};const f=s.data.body.id??"",p=a.map(u=>({id:u,messageId:f,status:"sent"}));return h("messagebird",p)},validateCredentials:()=>!!e.accessKey}});export{$ as default};
1
+ import t from"./NotificationError-B1ZZqWxL.js";import g from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as l}from"./defineProvider-C9q-7iwt.js";import{t as y}from"./credentials-CG0zkn-W.js";import{r as b}from"./http-DT3tyixg.js";import{b as h}from"./sms-BbxkOLQm.js";const v="https://rest.messagebird.com",$=l(n=>{const e=n??{};if(!e.accessKey)throw new g("messagebird","accessKey");const i=e.endpoint??v,d=e.retries??3,c=e.timeout??3e4,m=`${i}/messages`;return{channel:"sms",endpoint:i,features:{batchSending:!0,deliveryReceipts:!0,media:!1},id:"messagebird",initialize:()=>{},isAvailable:()=>!!e.accessKey,options:e,send:async r=>{const a=y(r.to),o=r.from??e.from;if(!o)return{error:new t("messagebird","Missing originator: provide `from` on the payload or provider config"),success:!1};const s=await b(m,{body:JSON.stringify({body:r.text,originator:o,recipients:a}),headers:{Authorization:`AccessKey ${e.accessKey}`,"Content-Type":"application/json"},method:"POST",timeout:c},d);if(!s.success||!s.data)return{error:new t("messagebird",s.error instanceof Error?s.error.message:"Request failed"),success:!1};if(s.data.status>=400)return{error:new t("messagebird",s.data.body.errors?.[0]?.description??`HTTP ${String(s.data.status)}`),success:!1};const f=s.data.body.id??"",p=a.map(u=>({id:u,messageId:f,status:"sent"}));return h("messagebird",p)},validateCredentials:()=>!!e.accessKey}});export{$ as default};
@@ -1 +1 @@
1
- import c from"./NotificationError-B8CyoEaX.js";import{defineProvider as d}from"./defineProvider-C9q-7iwt.js";let n=0;const p=d((e={})=>{const t=[],s=e.channel??"sms",r=e.id??"mock",o={clear:()=>{t.length=0},last:()=>t.at(-1),sent:t};return{channel:s,getInstance:()=>o,id:r,initialize:()=>{},isAvailable:()=>!0,send:l=>{if(e.failWith!==void 0)return{error:new c(r,e.failWith),success:!1};n+=1;const a=new Date,i=`mock-${String(n)}`;return t.push({messageId:i,payload:l,timestamp:a}),{data:{channel:s,messageId:i,provider:r,sent:!0,timestamp:a},success:!0}},validateCredentials:()=>!0}});export{p as mockProvider};
1
+ import c from"./NotificationError-B1ZZqWxL.js";import{defineProvider as d}from"./defineProvider-C9q-7iwt.js";let n=0;const p=d((e={})=>{const t=[],s=e.channel??"sms",r=e.id??"mock",o={clear:()=>{t.length=0},last:()=>t.at(-1),sent:t};return{channel:s,getInstance:()=>o,id:r,initialize:()=>{},isAvailable:()=>!0,send:l=>{if(e.failWith!==void 0)return{error:new c(r,e.failWith),success:!1};n+=1;const a=new Date,i=`mock-${String(n)}`;return t.push({messageId:i,payload:l,timestamp:a}),{data:{channel:s,messageId:i,provider:r,sent:!0,timestamp:a},success:!0}},validateCredentials:()=>!0}});export{p as mockProvider};
@@ -1 +1 @@
1
- import r from"./NotificationError-B8CyoEaX.js";import m from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as c}from"./defineProvider-C9q-7iwt.js";import{r as d}from"./http-DT3tyixg.js";import{n as l}from"./id-C_FRCsUM.js";const b=c(a=>{const e=a??{};if(!e.webhookUrl)throw new m("msteams","webhookUrl");const o=e.retries??3,n=e.timeout??3e4;return{channel:"chat",endpoint:e.webhookUrl,features:{batchSending:!1,richContent:!0},id:"msteams",initialize:()=>{},isAvailable:()=>!!e.webhookUrl,options:e,send:async s=>{const i=s.blocks??{"@context":"https://schema.org/extensions","@type":"MessageCard",text:s.text},t=await d(e.webhookUrl,{body:JSON.stringify(i),headers:{"Content-Type":"application/json"},method:"POST",timeout:n},o);return!t.success||!t.data?{error:new r("msteams",t.error instanceof Error?t.error.message:"Request failed"),success:!1}:t.data.status>=400?{error:new r("msteams",`HTTP ${String(t.data.status)}: ${t.data.body}`),success:!1}:{data:{channel:"chat",messageId:l("msteams"),provider:"msteams",sent:!0,timestamp:new Date},success:!0}},validateCredentials:()=>!!e.webhookUrl}});export{b as default};
1
+ import r from"./NotificationError-B1ZZqWxL.js";import m from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as c}from"./defineProvider-C9q-7iwt.js";import{r as d}from"./http-DT3tyixg.js";import{n as l}from"./id-C_FRCsUM.js";const b=c(a=>{const e=a??{};if(!e.webhookUrl)throw new m("msteams","webhookUrl");const o=e.retries??3,n=e.timeout??3e4;return{channel:"chat",endpoint:e.webhookUrl,features:{batchSending:!1,richContent:!0},id:"msteams",initialize:()=>{},isAvailable:()=>!!e.webhookUrl,options:e,send:async s=>{const i=s.blocks??{"@context":"https://schema.org/extensions","@type":"MessageCard",text:s.text},t=await d(e.webhookUrl,{body:JSON.stringify(i),headers:{"Content-Type":"application/json"},method:"POST",timeout:n},o);return!t.success||!t.data?{error:new r("msteams",t.error instanceof Error?t.error.message:"Request failed"),success:!1}:t.data.status>=400?{error:new r("msteams",`HTTP ${String(t.data.status)}: ${t.data.body}`),success:!1}:{data:{channel:"chat",messageId:l("msteams"),provider:"msteams",sent:!0,timestamp:new Date},success:!0}},validateCredentials:()=>!!e.webhookUrl}});export{b as default};
@@ -1 +1 @@
1
- import o from"./NotificationError-B8CyoEaX.js";import d from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as w}from"./defineProvider-C9q-7iwt.js";import{b as y,t as T}from"./credentials-CG0zkn-W.js";import{r as b}from"./http-DT3tyixg.js";import{b as I}from"./sms-64HGUCLu.js";const S="https://api.plivo.com",q=w(p=>{const e=p??{};if(!e.authId)throw new d("plivo","authId");if(!e.authToken)throw new d("plivo","authToken");const a=e.endpoint??S,m=e.retries??3,c=e.timeout??3e4,f=`${a}/v1/Account/${e.authId}/Message/`,l=y(e.authId,e.authToken);return{channel:"sms",endpoint:a,features:{batchSending:!0,deliveryReceipts:!0,media:!0},id:"plivo",initialize:()=>{},isAvailable:()=>!!(e.authId&&e.authToken),options:e,send:async s=>{const r=T(s.to),i=s.from??e.from;if(!i)return{error:new o("plivo","Missing sender: provide `from` on the payload or provider config"),success:!1};const t=await b(f,{body:JSON.stringify({dst:r.join("<"),src:i,text:s.text}),headers:{Authorization:l,"Content-Type":"application/json"},method:"POST",timeout:c},m);if(!t.success||!t.data)return{error:new o("plivo",t.error instanceof Error?t.error.message:"Request failed"),success:!1};if(t.data.status>=400)return{error:new o("plivo",t.data.body.error??`HTTP ${String(t.data.status)}`),success:!1};const{body:n}=t.data,h=n.message_uuid?.[0]??"",u=r.map((v,g)=>({id:v,messageId:n.message_uuid?.[g],status:"sent"}));return I("plivo",u.length>0?u:[{id:r[0]??"",messageId:h,status:"sent"}])},validateCredentials:()=>!!(e.authId&&e.authToken)}});export{q as default};
1
+ import o from"./NotificationError-B1ZZqWxL.js";import d from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as w}from"./defineProvider-C9q-7iwt.js";import{b as y,t as T}from"./credentials-CG0zkn-W.js";import{r as b}from"./http-DT3tyixg.js";import{b as I}from"./sms-BbxkOLQm.js";const S="https://api.plivo.com",q=w(p=>{const e=p??{};if(!e.authId)throw new d("plivo","authId");if(!e.authToken)throw new d("plivo","authToken");const a=e.endpoint??S,m=e.retries??3,c=e.timeout??3e4,f=`${a}/v1/Account/${e.authId}/Message/`,l=y(e.authId,e.authToken);return{channel:"sms",endpoint:a,features:{batchSending:!0,deliveryReceipts:!0,media:!0},id:"plivo",initialize:()=>{},isAvailable:()=>!!(e.authId&&e.authToken),options:e,send:async s=>{const r=T(s.to),i=s.from??e.from;if(!i)return{error:new o("plivo","Missing sender: provide `from` on the payload or provider config"),success:!1};const t=await b(f,{body:JSON.stringify({dst:r.join("<"),src:i,text:s.text}),headers:{Authorization:l,"Content-Type":"application/json"},method:"POST",timeout:c},m);if(!t.success||!t.data)return{error:new o("plivo",t.error instanceof Error?t.error.message:"Request failed"),success:!1};if(t.data.status>=400)return{error:new o("plivo",t.data.body.error??`HTTP ${String(t.data.status)}`),success:!1};const{body:n}=t.data,h=n.message_uuid?.[0]??"",u=r.map((v,g)=>({id:v,messageId:n.message_uuid?.[g],status:"sent"}));return I("plivo",u.length>0?u:[{id:r[0]??"",messageId:h,status:"sent"}])},validateCredentials:()=>!!(e.authId&&e.authToken)}});export{q as default};
@@ -1 +1 @@
1
- import c from"./NotificationError-B8CyoEaX.js";const g=(e,a={})=>{if(e.length===0)throw new c("roundrobin","At least one provider is required");const t=a.id??"roundrobin",d=a.failover??!0,u=e[0];let i=0;return{channel:u.channel,id:t,initialize:async()=>{await Promise.all(e.map(async r=>r.initialize()))},isAvailable:async()=>(await Promise.all(e.map(async r=>r.isAvailable()))).some(Boolean),send:async r=>{const f=i;i=(i+1)%e.length;const o=[],h=d?e.length:1;for(let s=0;s<h;s+=1){const l=e[(f+s)%e.length],n=await l.send(r);if(n.success)return n;o.push(`${l.id}: ${n.error instanceof Error?n.error.message:String(n.error)}`)}return{error:new c(t,`Send failed: ${o.join("; ")}`),success:!1}}}};export{g as roundRobinProvider};
1
+ import c from"./NotificationError-B1ZZqWxL.js";const g=(e,a={})=>{if(e.length===0)throw new c("roundrobin","At least one provider is required");const t=a.id??"roundrobin",d=a.failover??!0,u=e[0];let i=0;return{channel:u.channel,id:t,initialize:async()=>{await Promise.all(e.map(async r=>r.initialize()))},isAvailable:async()=>(await Promise.all(e.map(async r=>r.isAvailable()))).some(Boolean),send:async r=>{const f=i;i=(i+1)%e.length;const o=[],h=d?e.length:1;for(let s=0;s<h;s+=1){const l=e[(f+s)%e.length],n=await l.send(r);if(n.success)return n;o.push(`${l.id}: ${n.error instanceof Error?n.error.message:String(n.error)}`)}return{error:new c(t,`Send failed: ${o.join("; ")}`),success:!1}}}};export{g as roundRobinProvider};
@@ -1 +1 @@
1
- import r from"./NotificationError-B8CyoEaX.js";import{defineProvider as b}from"./defineProvider-C9q-7iwt.js";import{r as m}from"./http-DT3tyixg.js";import{n as d}from"./id-C_FRCsUM.js";const w="https://slack.com/api",S=b(h=>{const e=h??{};if(!e.token&&!e.webhookUrl)throw new r("slack","Provide either `token` (Web API) or `webhookUrl`",{hint:"Set one of token/webhookUrl in the provider config"});const n=e.endpoint??w,k=e.retries??3,u=e.timeout??3e4;return{channel:"chat",endpoint:n,features:{batchSending:!1,richContent:!0},id:"slack",initialize:()=>{},isAvailable:()=>!!(e.token??e.webhookUrl),options:e,send:async s=>{const o=!!e.webhookUrl,f=o?e.webhookUrl:`${n}/chat.postMessage`,i=s.to??e.defaultChannel;if(!o&&!i)return{error:new r("slack","Missing channel: provide `to` or `defaultChannel`"),success:!1};const c={blocks:s.blocks,text:s.text,thread_ts:s.threadId};o||(c.channel=i);const l={"Content-Type":"application/json"};o||(l.Authorization=`Bearer ${e.token??""}`);const t=await m(f,{body:JSON.stringify(c),headers:l,method:"POST",timeout:u},k);if(!t.success||!t.data)return{error:new r("slack",t.error instanceof Error?t.error.message:"Request failed"),success:!1};if(o){if(t.data.status>=400||t.data.body!=="ok"){const p=typeof t.data.body=="string"?t.data.body:JSON.stringify(t.data.body);return{error:new r("slack",`Webhook failed: ${p}`),success:!1}}return{data:{channel:"chat",messageId:d("slack"),provider:"slack",sent:!0,timestamp:new Date},success:!0}}const a=t.data.body;return a.ok?{data:{channel:"chat",messageId:a.ts??d("slack"),provider:"slack",response:a,sent:!0,timestamp:new Date},success:!0}:{error:new r("slack",a.error??"Slack API error"),success:!1}},validateCredentials:()=>!!(e.token??e.webhookUrl)}});export{S as default};
1
+ import r from"./NotificationError-B1ZZqWxL.js";import{defineProvider as b}from"./defineProvider-C9q-7iwt.js";import{r as m}from"./http-DT3tyixg.js";import{n as d}from"./id-C_FRCsUM.js";const w="https://slack.com/api",S=b(h=>{const e=h??{};if(!e.token&&!e.webhookUrl)throw new r("slack","Provide either `token` (Web API) or `webhookUrl`",{hint:"Set one of token/webhookUrl in the provider config"});const n=e.endpoint??w,k=e.retries??3,u=e.timeout??3e4;return{channel:"chat",endpoint:n,features:{batchSending:!1,richContent:!0},id:"slack",initialize:()=>{},isAvailable:()=>!!(e.token??e.webhookUrl),options:e,send:async s=>{const o=!!e.webhookUrl,f=o?e.webhookUrl:`${n}/chat.postMessage`,i=s.to??e.defaultChannel;if(!o&&!i)return{error:new r("slack","Missing channel: provide `to` or `defaultChannel`"),success:!1};const c={blocks:s.blocks,text:s.text,thread_ts:s.threadId};o||(c.channel=i);const l={"Content-Type":"application/json"};o||(l.Authorization=`Bearer ${e.token??""}`);const t=await m(f,{body:JSON.stringify(c),headers:l,method:"POST",timeout:u},k);if(!t.success||!t.data)return{error:new r("slack",t.error instanceof Error?t.error.message:"Request failed"),success:!1};if(o){if(t.data.status>=400||t.data.body!=="ok"){const p=typeof t.data.body=="string"?t.data.body:JSON.stringify(t.data.body);return{error:new r("slack",`Webhook failed: ${p}`),success:!1}}return{data:{channel:"chat",messageId:d("slack"),provider:"slack",sent:!0,timestamp:new Date},success:!0}}const a=t.data.body;return a.ok?{data:{channel:"chat",messageId:a.ts??d("slack"),provider:"slack",response:a,sent:!0,timestamp:new Date},success:!0}:{error:new r("slack",a.error??"Slack API error"),success:!1}},validateCredentials:()=>!!(e.token??e.webhookUrl)}});export{S as default};
@@ -1 +1 @@
1
- import{isWithinReplayWindow as o,REPLAY_WINDOW_SECONDS as c,hmacHex as l,timingSafeEqual as m}from"./hmacBase64-BhhoX0uo.js";import{getHeader as a,tryParseObject as p}from"./getHeader-C_gkdnMQ.js";const d="X-Slack-Signature",f="X-Slack-Request-Timestamp",y={parse:r=>{const e=p(r);if(e===void 0)return;const t=e.event??e,n=typeof t.channel=="string"?t.channel:void 0,i=typeof t.ts=="string"?t.ts:"";return{channel:"chat",messageId:typeof e.event_id=="string"?e.event_id:i,provider:"slack",recipient:n,timestamp:new Date,type:"delivered"}},verify:async(r,e,t)=>{if(t.trim()==="")return!1;const n=a(e,d),i=a(e,f);if(n===void 0||i===void 0||!o(i,c))return!1;const s=await l(t,`v0:${i}:${r}`,"SHA-256");return m(`v0=${s}`,n)}};export{y as slackWebhook};
1
+ import{isWithinReplayWindow as o,REPLAY_WINDOW_SECONDS as c,hmacHex as l,timingSafeEqual as m}from"./hmacBase64-CNksyDoB.js";import{getHeader as a,tryParseObject as p}from"./getHeader-C_gkdnMQ.js";const d="X-Slack-Signature",f="X-Slack-Request-Timestamp",y={parse:r=>{const e=p(r);if(e===void 0)return;const t=e.event??e,n=typeof t.channel=="string"?t.channel:void 0,i=typeof t.ts=="string"?t.ts:"";return{channel:"chat",messageId:typeof e.event_id=="string"?e.event_id:i,provider:"slack",recipient:n,timestamp:new Date,type:"delivered"}},verify:async(r,e,t)=>{if(t.trim()==="")return!1;const n=a(e,d),i=a(e,f);if(n===void 0||i===void 0||!o(i,c))return!1;const s=await l(t,`v0:${i}:${r}`,"SHA-256");return m(`v0=${s}`,n)}};export{y as slackWebhook};
@@ -1 +1 @@
1
- import n from"./NotificationError-B8CyoEaX.js";const i=(t,e,s)=>{const r=s.filter(a=>a.status==="sent");return r.length===0?{error:new n(e,s[0]?.error??"All recipients failed"),success:!1}:{data:{channel:t,messageId:r[0]?.messageId??"",provider:e,recipients:s,sent:!0,timestamp:new Date},success:!0}},o=(t,e)=>i("sms",t,e),u=async(t,e)=>{const s=[];for(const r of t)s.push(await e(r));return s};export{i as a,o as b,u as s};
1
+ import n from"./NotificationError-B1ZZqWxL.js";const i=(t,e,s)=>{const r=s.filter(a=>a.status==="sent");return r.length===0?{error:new n(e,s[0]?.error??"All recipients failed"),success:!1}:{data:{channel:t,messageId:r[0]?.messageId??"",provider:e,recipients:s,sent:!0,timestamp:new Date},success:!0}},o=(t,e)=>i("sms",t,e),u=async(t,e)=>{const s=[];for(const r of t)s.push(await e(r));return s};export{i as a,o as b,u as s};
@@ -1,4 +1,4 @@
1
- import x from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as K}from"./defineProvider-C9q-7iwt.js";import{t as z}from"./credentials-CG0zkn-W.js";import{r as C}from"./http-DT3tyixg.js";import{n as R}from"./id-C_FRCsUM.js";import{s as j,b as P}from"./sms-64HGUCLu.js";import{b as w,d as h,u as c,e as p}from"./webcrypto-bY7wJCB5.js";const b="sns",T="us-east-1",H=/<Message>([\s\S]*?)<\/Message>/,q=/<MessageId>([\s\S]*?)<\/MessageId>/,D=t=>{const e=t.toISOString().replaceAll(/[:-]|\.\d{3}/g,"");return{amzDate:e,dateStamp:e.slice(0,8)}},O=async(t,e,o)=>{const i=await p(c(`AWS4${t}`),c(e)),m=await p(i,c(o)),d=await p(m,c(b));return p(d,c("aws4_request"))},k=t=>{const{pathname:e}=new URL(t);return e===""||e==="/"?"/":e.split("/").map(o=>encodeURIComponent(o).replaceAll("*","%2A").replaceAll("'","%27").replaceAll("(","%28").replaceAll(")","%29").replaceAll("!","%21")).join("/")},L=async(t,e,o,i,m)=>{const{amzDate:d,dateStamp:S}=D(new Date),f=w(await h(c(m))),a={"Content-Type":"application/x-www-form-urlencoded",host:o,"x-amz-content-sha256":f,"x-amz-date":d};t.sessionToken&&(a["x-amz-security-token"]=t.sessionToken);const n={};for(const[l,g]of Object.entries(a))n[l.toLowerCase()]=g.trim();const s=Object.keys(n).toSorted((l,g)=>l.localeCompare(g)),u=s.join(";"),y=s.map(l=>`${l}:${n[l]??""}
1
+ import x from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as K}from"./defineProvider-C9q-7iwt.js";import{t as z}from"./credentials-CG0zkn-W.js";import{r as C}from"./http-DT3tyixg.js";import{n as R}from"./id-C_FRCsUM.js";import{s as j,b as P}from"./sms-BbxkOLQm.js";import{a as w,g as h,u as c,i as p}from"./webcrypto-CFuQmh5-.js";const b="sns",T="us-east-1",H=/<Message>([\s\S]*?)<\/Message>/,q=/<MessageId>([\s\S]*?)<\/MessageId>/,D=t=>{const e=t.toISOString().replaceAll(/[:-]|\.\d{3}/g,"");return{amzDate:e,dateStamp:e.slice(0,8)}},O=async(t,e,o)=>{const i=await p(c(`AWS4${t}`),c(e)),m=await p(i,c(o)),d=await p(m,c(b));return p(d,c("aws4_request"))},k=t=>{const{pathname:e}=new URL(t);return e===""||e==="/"?"/":e.split("/").map(o=>encodeURIComponent(o).replaceAll("*","%2A").replaceAll("'","%27").replaceAll("(","%28").replaceAll(")","%29").replaceAll("!","%21")).join("/")},L=async(t,e,o,i,m)=>{const{amzDate:d,dateStamp:S}=D(new Date),f=w(await h(c(m))),a={"Content-Type":"application/x-www-form-urlencoded",host:o,"x-amz-content-sha256":f,"x-amz-date":d};t.sessionToken&&(a["x-amz-security-token"]=t.sessionToken);const n={};for(const[l,A]of Object.entries(a))n[l.toLowerCase()]=A.trim();const s=Object.keys(n).toSorted((l,A)=>l.localeCompare(A)),u=s.join(";"),y=s.map(l=>`${l}:${n[l]??""}
2
2
  `).join(""),r=["POST",k(i),"",y,u,f].join(`
3
- `),A=`${S}/${e}/${b}/aws4_request`,$=["AWS4-HMAC-SHA256",d,A,w(await h(c(r)))].join(`
4
- `),I=await O(t.secretAccessKey,S,e),M=w(await p(I,c($)));return a.Authorization=`AWS4-HMAC-SHA256 Credential=${t.accessKeyId}/${A}, SignedHeaders=${u}, Signature=${M}`,{headers:a,url:i}},B=K(t=>{const e=t??{};if(!e.accessKeyId||!e.secretAccessKey)throw new x("sns",["accessKeyId","secretAccessKey"]);const o=e.region??T,i=e.endpoint??`https://sns.${o}.amazonaws.com/`,{host:m}=new URL(i),d=e.retries??3,S=e.timeout??3e4,f=async(a,n)=>{const s=new URLSearchParams;s.set("Action","Publish"),s.set("Version","2010-03-31"),s.set("PhoneNumber",a),s.set("Message",n.text),n.from&&(s.set("MessageAttributes.entry.1.Name","AWS.SNS.SMS.SenderID"),s.set("MessageAttributes.entry.1.Value.DataType","String"),s.set("MessageAttributes.entry.1.Value.StringValue",n.from));const u=s.toString(),y=await L(e,o,m,i,u),r=await C(y.url,{body:u,headers:y.headers,method:"POST",timeout:S},d);if(!r.success||!r.data)return{error:r.error instanceof Error?r.error.message:"Request failed",id:a,status:"failed"};if(r.data.status>=400)return{error:H.exec(r.data.body)?.[1]??`HTTP ${String(r.data.status)}`,id:a,status:"failed"};const A=q.exec(r.data.body)?.[1];return{id:a,messageId:A??R("sns"),status:"sent"}};return{channel:"sms",endpoint:i,features:{batchSending:!1,deliveryReceipts:!1,media:!1,scheduling:!1},id:"sns",initialize:()=>{},isAvailable:()=>!!(e.accessKeyId&&e.secretAccessKey),options:e,send:async a=>{const n=await j(z(a.to),async s=>f(s,a));return P("sns",n)},validateCredentials:()=>!!(e.accessKeyId&&e.secretAccessKey)}});export{B as default};
3
+ `),g=`${S}/${e}/${b}/aws4_request`,$=["AWS4-HMAC-SHA256",d,g,w(await h(c(r)))].join(`
4
+ `),I=await O(t.secretAccessKey,S,e),M=w(await p(I,c($)));return a.Authorization=`AWS4-HMAC-SHA256 Credential=${t.accessKeyId}/${g}, SignedHeaders=${u}, Signature=${M}`,{headers:a,url:i}},B=K(t=>{const e=t??{};if(!e.accessKeyId||!e.secretAccessKey)throw new x("sns",["accessKeyId","secretAccessKey"]);const o=e.region??T,i=e.endpoint??`https://sns.${o}.amazonaws.com/`,{host:m}=new URL(i),d=e.retries??3,S=e.timeout??3e4,f=async(a,n)=>{const s=new URLSearchParams;s.set("Action","Publish"),s.set("Version","2010-03-31"),s.set("PhoneNumber",a),s.set("Message",n.text),n.from&&(s.set("MessageAttributes.entry.1.Name","AWS.SNS.SMS.SenderID"),s.set("MessageAttributes.entry.1.Value.DataType","String"),s.set("MessageAttributes.entry.1.Value.StringValue",n.from));const u=s.toString(),y=await L(e,o,m,i,u),r=await C(y.url,{body:u,headers:y.headers,method:"POST",timeout:S},d);if(!r.success||!r.data)return{error:r.error instanceof Error?r.error.message:"Request failed",id:a,status:"failed"};if(r.data.status>=400)return{error:H.exec(r.data.body)?.[1]??`HTTP ${String(r.data.status)}`,id:a,status:"failed"};const g=q.exec(r.data.body)?.[1];return{id:a,messageId:g??R("sns"),status:"sent"}};return{channel:"sms",endpoint:i,features:{batchSending:!1,deliveryReceipts:!1,media:!1,scheduling:!1},id:"sns",initialize:()=>{},isAvailable:()=>!!(e.accessKeyId&&e.secretAccessKey),options:e,send:async a=>{const n=await j(z(a.to),async s=>f(s,a));return P("sns",n)},validateCredentials:()=>!!(e.accessKeyId&&e.secretAccessKey)}});export{B as default};
@@ -1 +1 @@
1
- import{isWithinReplayWindow as m,REPLAY_WINDOW_SECONDS as v,hmacBase64 as w,hmacHex as y,timingSafeEqual as p}from"./hmacBase64-BhhoX0uo.js";import{getHeader as s,tryParseObject as g}from"./getHeader-C_gkdnMQ.js";const b="webhook-id",k="webhook-timestamp",A="webhook-signature",S=new Set(["bounced","clicked","delivered","failed","interacted","queued","read","sent"]),W=r=>{const e=atob(r),t=new Uint8Array(e.length);for(let i=0;i<e.length;i+=1)t[i]=e.codePointAt(i)??0;return t},D={parse:r=>{const e=g(r);if(e===void 0)return;const t=typeof e.type=="string"?e.type:void 0,i=t!==void 0&&S.has(t)?t:"delivered";return{messageId:typeof e.id=="string"?e.id:"",provider:"standard-webhooks",recipient:typeof e.recipient=="string"?e.recipient:void 0,timestamp:new Date,type:i}},verify:async(r,e,t)=>{if(t.trim()==="")return!1;const i=s(e,b),o=s(e,k),a=s(e,A);if(i===void 0||o===void 0||a===void 0||!m(o,v))return!1;const d=t.startsWith("whsec_")?W(t.slice(6)):t,c=`${i}.${o}.${r}`,l=await w(d,c,"SHA-256"),u=await y(d,c,"SHA-256"),h=a.split(" ");for(const n of h){const f=n.includes(",")?n.split(",")[1]??"":n;if(p(l,f)||p(u,f))return!0}return!1}};export{D as standardWebhook};
1
+ import{isWithinReplayWindow as m,REPLAY_WINDOW_SECONDS as v,hmacBase64 as w,hmacHex as y,timingSafeEqual as p}from"./hmacBase64-CNksyDoB.js";import{getHeader as s,tryParseObject as g}from"./getHeader-C_gkdnMQ.js";const b="webhook-id",k="webhook-timestamp",A="webhook-signature",S=new Set(["bounced","clicked","delivered","failed","interacted","queued","read","sent"]),W=r=>{const e=atob(r),t=new Uint8Array(e.length);for(let i=0;i<e.length;i+=1)t[i]=e.codePointAt(i)??0;return t},D={parse:r=>{const e=g(r);if(e===void 0)return;const t=typeof e.type=="string"?e.type:void 0,i=t!==void 0&&S.has(t)?t:"delivered";return{messageId:typeof e.id=="string"?e.id:"",provider:"standard-webhooks",recipient:typeof e.recipient=="string"?e.recipient:void 0,timestamp:new Date,type:i}},verify:async(r,e,t)=>{if(t.trim()==="")return!1;const i=s(e,b),o=s(e,k),a=s(e,A);if(i===void 0||o===void 0||a===void 0||!m(o,v))return!1;const d=t.startsWith("whsec_")?W(t.slice(6)):t,c=`${i}.${o}.${r}`,l=await w(d,c,"SHA-256"),u=await y(d,c,"SHA-256"),h=a.split(" ");for(const n of h){const f=n.includes(",")?n.split(",")[1]??"":n;if(p(l,f)||p(u,f))return!0}return!1}};export{D as standardWebhook};
@@ -1 +1 @@
1
- import r from"./NotificationError-B8CyoEaX.js";import m from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as p}from"./defineProvider-C9q-7iwt.js";import{r as u}from"./http-DT3tyixg.js";const f="https://api.telegram.org",T=p(i=>{const e=i??{};if(!e.botToken)throw new m("telegram","botToken");const o=e.endpoint??f,d=e.retries??3,c=e.timeout??3e4,l=`${o}/bot${e.botToken}/sendMessage`;return{channel:"chat",endpoint:o,features:{batchSending:!1,richContent:!0},id:"telegram",initialize:()=>{},isAvailable:()=>!!e.botToken,options:e,send:async a=>{const s=a.to??e.defaultChatId;if(s===void 0)return{error:new r("telegram","Missing chat id: provide `to` or `defaultChatId`"),success:!1};const n={chat_id:s,text:a.text};e.parseMode&&(n.parse_mode=e.parseMode);const t=await u(l,{body:JSON.stringify(n),headers:{"Content-Type":"application/json"},method:"POST",timeout:c},d);return!t.success||!t.data?{error:new r("telegram",t.error instanceof Error?t.error.message:"Request failed"),success:!1}:t.data.body.ok?{data:{channel:"chat",messageId:String(t.data.body.result?.message_id??""),provider:"telegram",response:t.data.body,sent:!0,timestamp:new Date},success:!0}:{error:new r("telegram",t.data.body.description??`HTTP ${String(t.data.status)}`),success:!1}},validateCredentials:()=>!!e.botToken}});export{T as default};
1
+ import r from"./NotificationError-B1ZZqWxL.js";import m from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as p}from"./defineProvider-C9q-7iwt.js";import{r as u}from"./http-DT3tyixg.js";const f="https://api.telegram.org",T=p(i=>{const e=i??{};if(!e.botToken)throw new m("telegram","botToken");const o=e.endpoint??f,d=e.retries??3,c=e.timeout??3e4,l=`${o}/bot${e.botToken}/sendMessage`;return{channel:"chat",endpoint:o,features:{batchSending:!1,richContent:!0},id:"telegram",initialize:()=>{},isAvailable:()=>!!e.botToken,options:e,send:async a=>{const s=a.to??e.defaultChatId;if(s===void 0)return{error:new r("telegram","Missing chat id: provide `to` or `defaultChatId`"),success:!1};const n={chat_id:s,text:a.text};e.parseMode&&(n.parse_mode=e.parseMode);const t=await u(l,{body:JSON.stringify(n),headers:{"Content-Type":"application/json"},method:"POST",timeout:c},d);return!t.success||!t.data?{error:new r("telegram",t.error instanceof Error?t.error.message:"Request failed"),success:!1}:t.data.body.ok?{data:{channel:"chat",messageId:String(t.data.body.result?.message_id??""),provider:"telegram",response:t.data.body,sent:!0,timestamp:new Date},success:!0}:{error:new r("telegram",t.data.body.description??`HTTP ${String(t.data.status)}`),success:!1}},validateCredentials:()=>!!e.botToken}});export{T as default};
@@ -1 +1 @@
1
- import u from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as p}from"./defineProvider-C9q-7iwt.js";import{t as g}from"./credentials-CG0zkn-W.js";import{r as c}from"./http-DT3tyixg.js";import{s as y,b as h}from"./sms-64HGUCLu.js";const x="https://api.telnyx.com",I=p(n=>{const e=n??{};if(!e.apiKey)throw new u("telnyx","apiKey");const o=e.endpoint??x,d=e.retries??3,m=e.timeout??3e4,l=`${o}/v2/messages`,f=async(t,s)=>{const i=s.from??e.from;if(!i&&!e.messagingProfileId)return{error:"Missing sender: provide `from`, provider `from`, or `messagingProfileId`",id:t,status:"failed"};const a={text:s.text,to:t};i&&(a.from=i),e.messagingProfileId&&(a.messaging_profile_id=e.messagingProfileId),s.mediaUrls&&s.mediaUrls.length>0&&(a.media_urls=s.mediaUrls);const r=await c(l,{body:JSON.stringify(a),headers:{Authorization:`Bearer ${e.apiKey}`,"Content-Type":"application/json"},method:"POST",timeout:m},d);return!r.success||!r.data?{error:r.error instanceof Error?r.error.message:"Request failed",id:t,status:"failed"}:r.data.status>=400?{error:r.data.body.errors?.[0]?.detail??`HTTP ${String(r.data.status)}`,id:t,status:"failed"}:{id:t,messageId:r.data.body.data?.id,status:"sent"}};return{channel:"sms",endpoint:o,features:{batchSending:!1,deliveryReceipts:!0,media:!0,scheduling:!0},id:"telnyx",initialize:()=>{},isAvailable:()=>!!e.apiKey,options:e,send:async t=>{const s=await y(g(t.to),async i=>f(i,t));return h("telnyx",s)},validateCredentials:()=>!!e.apiKey}});export{I as default};
1
+ import u from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as p}from"./defineProvider-C9q-7iwt.js";import{t as g}from"./credentials-CG0zkn-W.js";import{r as c}from"./http-DT3tyixg.js";import{s as y,b as h}from"./sms-BbxkOLQm.js";const x="https://api.telnyx.com",I=p(n=>{const e=n??{};if(!e.apiKey)throw new u("telnyx","apiKey");const o=e.endpoint??x,d=e.retries??3,m=e.timeout??3e4,l=`${o}/v2/messages`,f=async(t,s)=>{const i=s.from??e.from;if(!i&&!e.messagingProfileId)return{error:"Missing sender: provide `from`, provider `from`, or `messagingProfileId`",id:t,status:"failed"};const a={text:s.text,to:t};i&&(a.from=i),e.messagingProfileId&&(a.messaging_profile_id=e.messagingProfileId),s.mediaUrls&&s.mediaUrls.length>0&&(a.media_urls=s.mediaUrls);const r=await c(l,{body:JSON.stringify(a),headers:{Authorization:`Bearer ${e.apiKey}`,"Content-Type":"application/json"},method:"POST",timeout:m},d);return!r.success||!r.data?{error:r.error instanceof Error?r.error.message:"Request failed",id:t,status:"failed"}:r.data.status>=400?{error:r.data.body.errors?.[0]?.detail??`HTTP ${String(r.data.status)}`,id:t,status:"failed"}:{id:t,messageId:r.data.body.data?.id,status:"sent"}};return{channel:"sms",endpoint:o,features:{batchSending:!1,deliveryReceipts:!0,media:!0,scheduling:!0},id:"telnyx",initialize:()=>{},isAvailable:()=>!!e.apiKey,options:e,send:async t=>{const s=await y(g(t.to),async i=>f(i,t));return h("telnyx",s)},validateCredentials:()=>!!e.apiKey}});export{I as default};
@@ -1 +1 @@
1
- import n from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as g}from"./defineProvider-C9q-7iwt.js";import{b as S,t as h}from"./credentials-CG0zkn-W.js";import{r as w}from"./http-DT3tyixg.js";import{s as y,b as T}from"./sms-64HGUCLu.js";const v="https://api.twilio.com",M=g(d=>{const e=d??{};if(!e.accountSid)throw new n("twilio","accountSid");if(!e.authToken)throw new n("twilio","authToken");const a=e.endpoint??v,c=e.retries??3,u=e.timeout??3e4,m=`${a}/2010-04-01/Accounts/${e.accountSid}/Messages.json`,l=S(e.accountSid,e.authToken),f=async(t,o)=>{const i=new URLSearchParams;i.set("To",t),i.set("Body",o.text);const r=o.from??e.from;if(e.messagingServiceSid)i.set("MessagingServiceSid",e.messagingServiceSid);else if(r)i.set("From",r);else return{error:"Missing sender: provide `from` on the payload or provider config",id:t,status:"failed"};for(const p of o.mediaUrls??[])i.append("MediaUrl",p);const s=await w(m,{body:i.toString(),headers:{Authorization:l,"Content-Type":"application/x-www-form-urlencoded"},method:"POST",timeout:u},c);return!s.success||!s.data?{error:s.error instanceof Error?s.error.message:"Request failed",id:t,status:"failed"}:s.data.status>=400?{error:s.data.body.error_message??`HTTP ${String(s.data.status)}`,id:t,status:"failed"}:{id:t,messageId:s.data.body.sid,status:"sent"}};return{channel:"sms",endpoint:a,features:{batchSending:!1,deliveryReceipts:!0,media:!0,scheduling:!0},id:"twilio",initialize:()=>{},isAvailable:()=>!!(e.accountSid&&e.authToken),options:e,send:async t=>{const o=await y(h(t.to),async i=>f(i,t));return T("twilio",o)},validateCredentials:()=>!!(e.accountSid&&e.authToken)}});export{M as default};
1
+ import n from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as g}from"./defineProvider-C9q-7iwt.js";import{b as S,t as h}from"./credentials-CG0zkn-W.js";import{r as w}from"./http-DT3tyixg.js";import{s as y,b as T}from"./sms-BbxkOLQm.js";const v="https://api.twilio.com",M=g(d=>{const e=d??{};if(!e.accountSid)throw new n("twilio","accountSid");if(!e.authToken)throw new n("twilio","authToken");const a=e.endpoint??v,c=e.retries??3,u=e.timeout??3e4,m=`${a}/2010-04-01/Accounts/${e.accountSid}/Messages.json`,l=S(e.accountSid,e.authToken),f=async(t,o)=>{const i=new URLSearchParams;i.set("To",t),i.set("Body",o.text);const r=o.from??e.from;if(e.messagingServiceSid)i.set("MessagingServiceSid",e.messagingServiceSid);else if(r)i.set("From",r);else return{error:"Missing sender: provide `from` on the payload or provider config",id:t,status:"failed"};for(const p of o.mediaUrls??[])i.append("MediaUrl",p);const s=await w(m,{body:i.toString(),headers:{Authorization:l,"Content-Type":"application/x-www-form-urlencoded"},method:"POST",timeout:u},c);return!s.success||!s.data?{error:s.error instanceof Error?s.error.message:"Request failed",id:t,status:"failed"}:s.data.status>=400?{error:s.data.body.error_message??`HTTP ${String(s.data.status)}`,id:t,status:"failed"}:{id:t,messageId:s.data.body.sid,status:"sent"}};return{channel:"sms",endpoint:a,features:{batchSending:!1,deliveryReceipts:!0,media:!0,scheduling:!0},id:"twilio",initialize:()=>{},isAvailable:()=>!!(e.accountSid&&e.authToken),options:e,send:async t=>{const o=await y(h(t.to),async i=>f(i,t));return T("twilio",o)},validateCredentials:()=>!!(e.accountSid&&e.authToken)}});export{M as default};
@@ -0,0 +1 @@
1
+ import{hmacBase64 as u,timingSafeEqual as c}from"./hmacBase64-CNksyDoB.js";import{getHeader as s}from"./getHeader-C_gkdnMQ.js";const f="X-Twilio-Signature",m={delivered:"delivered",failed:"failed",queued:"queued",sending:"queued",sent:"sent",undelivered:"failed"},S=(r,e)=>{const i=Object.keys(e).toSorted();let t=r;for(const o of i)t+=`${o}${e[o]??""}`;return t},a=r=>{const e={};return new URLSearchParams(r).forEach((i,t)=>{e[t]=i}),e},p={parse:r=>{const e=a(r),i=e.MessageStatus??e.SmsStatus??e.CallStatus;if(i===void 0)return;const t=m[i.toLowerCase()];return t===void 0?void 0:{channel:"sms",messageId:e.MessageSid??e.SmsSid??e.CallSid??"",provider:"twilio",recipient:e.To,timestamp:new Date,type:t}},verify:async(r,e,i)=>{if(i.trim()==="")return!1;const t=s(e,f),o=s(e,"x-twilio-signature-url");if(t===void 0||o===void 0)return!1;const n=a(r),d=S(o,n),l=await u(i,d,"SHA-1");return c(l,t)}};export{p as twilioWebhook};
@@ -3,7 +3,7 @@ import { a as NotificationMessage } from "./notification.d-D0ado_cy.js";
3
3
  * A queued notification job.
4
4
  */
5
5
  interface QueueJob {
6
- /** Number of delivery attempts so far. */
6
+ /** Number of delivery attempts including the current one (1 on first reserve). */
7
7
  attempts: number;
8
8
  /** Unique job id. */
9
9
  id: string;
@@ -1 +1 @@
1
- import n from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as l}from"./defineProvider-C9q-7iwt.js";import{t as g}from"./credentials-CG0zkn-W.js";import{r as y}from"./http-DT3tyixg.js";import{s as v,b as w}from"./sms-64HGUCLu.js";const S="https://rest.nexmo.com",P=l(d=>{const e=d??{};if(!e.apiKey)throw new n("vonage","apiKey");if(!e.apiSecret)throw new n("vonage","apiSecret");const o=e.endpoint??S,p=e.retries??3,c=e.timeout??3e4,m=`${o}/sms/json`,f=async(t,a)=>{const s=a.from??e.from;if(!s)return{error:"Missing sender: provide `from` on the payload or provider config",id:t,status:"failed"};const u=new URLSearchParams({api_key:e.apiKey,api_secret:e.apiSecret,from:s,text:a.text,to:t}),r=await y(m,{body:u.toString(),headers:{"Content-Type":"application/x-www-form-urlencoded"},method:"POST",timeout:c},p);if(!r.success||!r.data)return{error:r.error instanceof Error?r.error.message:"Request failed",id:t,status:"failed"};const i=r.data.body.messages?.[0];return i?.status!=="0"?{error:i?.["error-text"]??`Vonage status ${i?.status??"unknown"}`,id:t,status:"failed"}:{id:t,messageId:i["message-id"],status:"sent"}};return{channel:"sms",endpoint:o,features:{batchSending:!1,deliveryReceipts:!0,media:!1},id:"vonage",initialize:()=>{},isAvailable:()=>!!(e.apiKey&&e.apiSecret),options:e,send:async t=>{const a=await v(g(t.to),async s=>f(s,t));return w("vonage",a)},validateCredentials:()=>!!(e.apiKey&&e.apiSecret)}});export{P as default};
1
+ import n from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as l}from"./defineProvider-C9q-7iwt.js";import{t as g}from"./credentials-CG0zkn-W.js";import{r as y}from"./http-DT3tyixg.js";import{s as v,b as w}from"./sms-BbxkOLQm.js";const S="https://rest.nexmo.com",P=l(d=>{const e=d??{};if(!e.apiKey)throw new n("vonage","apiKey");if(!e.apiSecret)throw new n("vonage","apiSecret");const o=e.endpoint??S,p=e.retries??3,c=e.timeout??3e4,m=`${o}/sms/json`,f=async(t,a)=>{const s=a.from??e.from;if(!s)return{error:"Missing sender: provide `from` on the payload or provider config",id:t,status:"failed"};const u=new URLSearchParams({api_key:e.apiKey,api_secret:e.apiSecret,from:s,text:a.text,to:t}),r=await y(m,{body:u.toString(),headers:{"Content-Type":"application/x-www-form-urlencoded"},method:"POST",timeout:c},p);if(!r.success||!r.data)return{error:r.error instanceof Error?r.error.message:"Request failed",id:t,status:"failed"};const i=r.data.body.messages?.[0];return i?.status!=="0"?{error:i?.["error-text"]??`Vonage status ${i?.status??"unknown"}`,id:t,status:"failed"}:{id:t,messageId:i["message-id"],status:"sent"}};return{channel:"sms",endpoint:o,features:{batchSending:!1,deliveryReceipts:!0,media:!1},id:"vonage",initialize:()=>{},isAvailable:()=>!!(e.apiKey&&e.apiSecret),options:e,send:async t=>{const a=await v(g(t.to),async s=>f(s,t));return w("vonage",a)},validateCredentials:()=>!!(e.apiKey&&e.apiSecret)}});export{P as default};
@@ -1 +1 @@
1
- import K from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as C}from"./defineProvider-C9q-7iwt.js";import{t as A}from"./credentials-CG0zkn-W.js";import{m as E}from"./http-DT3tyixg.js";import{n as U}from"./id-C_FRCsUM.js";import{a as $}from"./sms-64HGUCLu.js";import{u as y,f as S,t as f,s as d,r as k,c as g,h as P,a as T}from"./webcrypto-bY7wJCB5.js";const j=2419200,x=i=>{let e=i;if(typeof i=="string")try{e=JSON.parse(i)}catch{return}const t=e;if(!(!t||typeof t.endpoint!="string"||typeof t.keys?.p256dh!="string"||typeof t.keys.auth!="string"))return t},B=async(i,e)=>{const t=S(e),p=f(t.slice(1,33)),r=f(t.slice(33,65));return d().importKey("jwk",{crv:"P-256",d:i,ext:!0,key_ops:["sign"],kty:"EC",x:p,y:r},{name:"ECDSA",namedCurve:"P-256"},!1,["sign"])},D=async(i,e,t)=>{const p=f(y(JSON.stringify({alg:"ES256",typ:"JWT"}))),r=f(y(JSON.stringify({aud:i,exp:Math.floor(Date.now()/1e3)+720*60,sub:e}))),u=`${p}.${r}`,a=await d().sign({hash:"SHA-256",name:"ECDSA"},t,y(u));return`${u}.${f(new Uint8Array(a))}`},H=async(i,e)=>{const t=S(i.keys.p256dh),p=S(i.keys.auth),r=k(16),u=await d().generateKey({name:"ECDH",namedCurve:"P-256"},!0,["deriveBits"]),a=new Uint8Array(await d().exportKey("raw",u.publicKey)),n=await d().importKey("raw",t,{name:"ECDH",namedCurve:"P-256"},!1,[]),m=new Uint8Array(await d().deriveBits({name:"ECDH",public:n},u.privateKey,256)),s=g(y("WebPush: info\0"),t,a),l=await P(p,m,s,32),v=await P(r,l,y("Content-Encoding: aes128gcm\0"),16),w=await P(r,l,y("Content-Encoding: nonce\0"),12),b=await d().importKey("raw",v,{name:"AES-GCM"},!1,["encrypt"]),h=g(e,new Uint8Array([2])),o=new Uint8Array(await d().encrypt({iv:w,name:"AES-GCM"},b,h)),c=g(r,T(4096,4),new Uint8Array([a.length]),a);return g(c,o)},z=C(i=>{const e=i??{};if(!e.vapidPublicKey||!e.vapidPrivateKey||!e.vapidSubject)throw new K("web-push",["vapidPublicKey","vapidPrivateKey","vapidSubject"]);const t=e.ttl??j,p=e.urgency??"normal",r=e.timeout??3e4,u=async(a,n,m)=>{const s=x(a);if(!s)return{error:"Invalid push subscription (expected { endpoint, keys: { p256dh, auth } })",id:a,status:"failed"};const{origin:l}=new URL(s.endpoint),v=await D(l,e.vapidSubject,m),w=JSON.stringify({badge:n.badge,body:n.body,data:n.data,image:n.imageUrl,title:n.title}),b=await H(s,y(w)),h={Authorization:`vapid t=${v},k=${e.vapidPublicKey}`,"Content-Encoding":"aes128gcm","Content-Type":"application/octet-stream",TTL:String(t),Urgency:p},o=await E(s.endpoint,{body:b,headers:h,method:"POST",timeout:r});if(!o.success||!o.data)return{error:o.error instanceof Error?o.error.message:"Request failed",id:a,status:"failed"};const{status:c}=o.data;return c===404||c===410?{error:`Subscription gone (HTTP ${String(c)}) — remove this subscription`,id:a,status:"failed"}:c>=400?{error:`HTTP ${String(c)}: ${typeof o.data.body=="string"?o.data.body:""}`.trim(),id:a,status:"failed"}:{id:a,messageId:U("web-push"),status:"sent"}};return{channel:"push",features:{batchSending:!1,media:!1,richContent:!0},id:"web-push",initialize:()=>{},isAvailable:()=>!!(e.vapidPublicKey&&e.vapidPrivateKey&&e.vapidSubject),options:e,send:async a=>{const n=A(a.to),m=await B(e.vapidPrivateKey,e.vapidPublicKey),s=[];for(const l of n)s.push(await u(l,a,m));return $("push","web-push",s)},validateCredentials:()=>!!(e.vapidPublicKey&&e.vapidPrivateKey&&e.vapidSubject)}});export{z as default};
1
+ import K from"./RequiredOptionError-CH4g-BZM.js";import{defineProvider as C}from"./defineProvider-C9q-7iwt.js";import{t as A}from"./credentials-CG0zkn-W.js";import{m as E}from"./http-DT3tyixg.js";import{n as U}from"./id-C_FRCsUM.js";import{a as $}from"./sms-BbxkOLQm.js";import{u as y,f as S,b as f,s as d,r as k,c as g,d as P,e as T}from"./webcrypto-CFuQmh5-.js";const j=2419200,x=i=>{let e=i;if(typeof i=="string")try{e=JSON.parse(i)}catch{return}const t=e;if(!(!t||typeof t.endpoint!="string"||typeof t.keys?.p256dh!="string"||typeof t.keys.auth!="string"))return t},B=async(i,e)=>{const t=S(e),p=f(t.slice(1,33)),r=f(t.slice(33,65));return d().importKey("jwk",{crv:"P-256",d:i,ext:!0,key_ops:["sign"],kty:"EC",x:p,y:r},{name:"ECDSA",namedCurve:"P-256"},!1,["sign"])},D=async(i,e,t)=>{const p=f(y(JSON.stringify({alg:"ES256",typ:"JWT"}))),r=f(y(JSON.stringify({aud:i,exp:Math.floor(Date.now()/1e3)+720*60,sub:e}))),u=`${p}.${r}`,a=await d().sign({hash:"SHA-256",name:"ECDSA"},t,y(u));return`${u}.${f(new Uint8Array(a))}`},H=async(i,e)=>{const t=S(i.keys.p256dh),p=S(i.keys.auth),r=k(16),u=await d().generateKey({name:"ECDH",namedCurve:"P-256"},!0,["deriveBits"]),a=new Uint8Array(await d().exportKey("raw",u.publicKey)),n=await d().importKey("raw",t,{name:"ECDH",namedCurve:"P-256"},!1,[]),m=new Uint8Array(await d().deriveBits({name:"ECDH",public:n},u.privateKey,256)),s=g(y("WebPush: info\0"),t,a),l=await P(p,m,s,32),b=await P(r,l,y("Content-Encoding: aes128gcm\0"),16),v=await P(r,l,y("Content-Encoding: nonce\0"),12),w=await d().importKey("raw",b,{name:"AES-GCM"},!1,["encrypt"]),h=g(e,new Uint8Array([2])),o=new Uint8Array(await d().encrypt({iv:v,name:"AES-GCM"},w,h)),c=g(r,T(4096,4),new Uint8Array([a.length]),a);return g(c,o)},z=C(i=>{const e=i??{};if(!e.vapidPublicKey||!e.vapidPrivateKey||!e.vapidSubject)throw new K("web-push",["vapidPublicKey","vapidPrivateKey","vapidSubject"]);const t=e.ttl??j,p=e.urgency??"normal",r=e.timeout??3e4,u=async(a,n,m)=>{const s=x(a);if(!s)return{error:"Invalid push subscription (expected { endpoint, keys: { p256dh, auth } })",id:a,status:"failed"};const{origin:l}=new URL(s.endpoint),b=await D(l,e.vapidSubject,m),v=JSON.stringify({badge:n.badge,body:n.body,data:n.data,image:n.imageUrl,title:n.title}),w=await H(s,y(v)),h={Authorization:`vapid t=${b},k=${e.vapidPublicKey}`,"Content-Encoding":"aes128gcm","Content-Type":"application/octet-stream",TTL:String(t),Urgency:p},o=await E(s.endpoint,{body:w,headers:h,method:"POST",timeout:r});if(!o.success||!o.data)return{error:o.error instanceof Error?o.error.message:"Request failed",id:a,status:"failed"};const{status:c}=o.data;return c===404||c===410?{error:`Subscription gone (HTTP ${String(c)}) — remove this subscription`,id:a,status:"failed"}:c>=400?{error:`HTTP ${String(c)}: ${typeof o.data.body=="string"?o.data.body:""}`.trim(),id:a,status:"failed"}:{id:a,messageId:U("web-push"),status:"sent"}};return{channel:"push",features:{batchSending:!1,media:!1,richContent:!0},id:"web-push",initialize:()=>{},isAvailable:()=>!!(e.vapidPublicKey&&e.vapidPrivateKey&&e.vapidSubject),options:e,send:async a=>{const n=A(a.to),m=await B(e.vapidPrivateKey,e.vapidPublicKey),s=[];for(const l of n)s.push(await u(l,a,m));return $("push","web-push",s)},validateCredentials:()=>!!(e.vapidPublicKey&&e.vapidPrivateKey&&e.vapidSubject)}});export{z as default};
@@ -1 +1 @@
1
- const l=r=>new Uint8Array(new ArrayBuffer(r)),i=r=>{if(r.buffer instanceof ArrayBuffer)return r;const t=l(r.length);return t.set(r),t},o=()=>globalThis.crypto.subtle,u=r=>{const t=l(r);return globalThis.crypto.getRandomValues(t),t},c=r=>{const t=new TextEncoder().encode(r),e=l(t.length);return e.set(t),e},y=(...r)=>{let t=0;for(const a of r)t+=a.length;const e=l(t);let n=0;for(const a of r)e.set(a,n),n+=a.length;return e},g=r=>{let t="";for(const e of r)t+=e.toString(16).padStart(2,"0");return t},h=r=>{let t="";for(const e of r)t+=String.fromCodePoint(e);return btoa(t)},A=r=>{let t=h(r).replaceAll("+","-").replaceAll("/","_");for(;t.endsWith("=");)t=t.slice(0,-1);return t},w=r=>{const t=r.replaceAll("-","+").replaceAll("_","/"),e=t.padEnd(t.length+(4-t.length%4)%4,"="),n=atob(e),a=l(n.length);for(let s=0;s<n.length;s+=1)a[s]=n.codePointAt(s)??0;return a},d=(r,t)=>{const e=l(t);let n=r;for(let a=t-1;a>=0;a-=1)e[a]=n%256,n=Math.floor(n/256);return e},p=async r=>{const t=await o().digest("SHA-256",r);return new Uint8Array(t)},m=async(r,t)=>{const e=await o().importKey("raw",r,{hash:"SHA-256",name:"HMAC"},!1,["sign"]),n=await o().sign("HMAC",e,t);return new Uint8Array(n)},B=async(r,t,e)=>{const n=typeof r=="string"?c(r):i(r),a=typeof t=="string"?c(t):i(t),s=await o().importKey("raw",n,{hash:e,name:"HMAC"},!1,["sign"]),f=await o().sign("HMAC",s,a);return new Uint8Array(f)},H=async(r,t,e,n)=>{const a=await o().importKey("raw",t,"HKDF",!1,["deriveBits"]),s=await o().deriveBits({hash:"SHA-256",info:e,name:"HKDF",salt:r},a,n*8);return new Uint8Array(s)};export{d as a,g as b,y as c,p as d,m as e,w as f,h as g,H as h,B as i,u as r,o as s,A as t,c as u};
1
+ const l=r=>new Uint8Array(new ArrayBuffer(r)),i=r=>{if(r.buffer instanceof ArrayBuffer)return r;const t=l(r.length);return t.set(r),t},o=()=>globalThis.crypto.subtle,u=r=>{const t=l(r);return globalThis.crypto.getRandomValues(t),t},c=r=>{const t=new TextEncoder().encode(r),e=l(t.length);return e.set(t),e},y=(...r)=>{let t=0;for(const a of r)t+=a.length;const e=l(t);let n=0;for(const a of r)e.set(a,n),n+=a.length;return e},g=r=>{let t="";for(const e of r)t+=e.toString(16).padStart(2,"0");return t},h=r=>{let t="";for(const e of r)t+=String.fromCodePoint(e);return btoa(t)},A=r=>{let t=h(r).replaceAll("+","-").replaceAll("/","_");for(;t.endsWith("=");)t=t.slice(0,-1);return t},w=r=>{const t=r.replaceAll("-","+").replaceAll("_","/"),e=t.padEnd(t.length+(4-t.length%4)%4,"="),n=atob(e),a=l(n.length);for(let s=0;s<n.length;s+=1)a[s]=n.codePointAt(s)??0;return a},d=(r,t)=>{const e=l(t);let n=r;for(let a=t-1;a>=0;a-=1)e[a]=n%256,n=Math.floor(n/256);return e},p=async r=>{const t=await o().digest("SHA-256",r);return new Uint8Array(t)},m=async(r,t)=>{const e=await o().importKey("raw",r,{hash:"SHA-256",name:"HMAC"},!1,["sign"]),n=await o().sign("HMAC",e,t);return new Uint8Array(n)},B=async(r,t,e)=>{const n=typeof r=="string"?c(r):i(r),a=typeof t=="string"?c(t):i(t),s=await o().importKey("raw",n,{hash:e,name:"HMAC"},!1,["sign"]),f=await o().sign("HMAC",s,a);return new Uint8Array(f)},H=async(r,t,e,n)=>{const a=await o().importKey("raw",t,"HKDF",!1,["deriveBits"]),s=await o().deriveBits({hash:"SHA-256",info:e,name:"HKDF",salt:r},a,n*8);return new Uint8Array(s)};export{g as a,A as b,y as c,H as d,d as e,w as f,p as g,B as h,m as i,u as r,o as s,h as t,c as u};
@@ -0,0 +1 @@
1
+ import s from"./NotificationError-B1ZZqWxL.js";import i from"./RequiredOptionError-CH4g-BZM.js";import{r as d}from"./http-DT3tyixg.js";import{n as u}from"./id-C_FRCsUM.js";const l=(t={})=>{const a=t.retries??3,n=t.timeout??3e4;return{channel:"webhook",endpoint:t.url,features:{},id:"webhook",initialize:()=>{},isAvailable:()=>!0,send:async o=>{const r=o.url??t.url;if(!r)return{error:new i("webhook","url"),success:!1};const e=await d(r,{body:typeof o.body=="string"?o.body:JSON.stringify(o.body),headers:{"Content-Type":"application/json",...t.headers,...o.headers},method:o.method??t.method??"POST",timeout:n},a);return!e.success||!e.data?{error:new s("webhook",e.error instanceof Error?e.error.message:"Request failed"),success:!1}:e.data.status>=400?{error:new s("webhook",`HTTP ${String(e.data.status)}`),success:!1}:{data:{channel:"webhook",messageId:u("webhook"),provider:"webhook",response:e.data.body,sent:!0,timestamp:new Date},success:!0}}}};export{l as webhookProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../../packem_shared/discordProvider-BvKwrC8K.js";export{o as discordProvider};
1
+ import{default as o}from"../../../packem_shared/discordProvider-D4LpBljj.js";export{o as discordProvider};
@@ -1 +1 @@
1
- import{default as a}from"../../../packem_shared/msTeamsProvider-Cd-BUhH1.js";export{a as msTeamsProvider};
1
+ import{default as a}from"../../../packem_shared/msTeamsProvider-DeGPjmCt.js";export{a as msTeamsProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../../packem_shared/slackProvider-B92QDf3e.js";export{e as slackProvider};
1
+ import{default as e}from"../../../packem_shared/slackProvider-Caxbs4Pa.js";export{e as slackProvider};
@@ -1 +1 @@
1
- import{default as a}from"../../../packem_shared/telegramProvider-BmmroM5A.js";export{a as telegramProvider};
1
+ import{default as a}from"../../../packem_shared/telegramProvider-BIc_GgpY.js";export{a as telegramProvider};
@@ -1 +1 @@
1
- import{failoverProvider as e}from"../../packem_shared/failoverProvider-DXcwmYev.js";export{e as failoverProvider};
1
+ import{failoverProvider as e}from"../../packem_shared/failoverProvider-CJsDGjzf.js";export{e as failoverProvider};
@@ -1 +1 @@
1
- import{mockProvider as e}from"../../packem_shared/mockProvider-DZ3immtm.js";export{e as mockProvider};
1
+ import{mockProvider as e}from"../../packem_shared/mockProvider-C2hHPSVa.js";export{e as mockProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../../packem_shared/apnsProvider-BPH0pHvd.js";export{e as apnsProvider};
1
+ import{default as e}from"../../../packem_shared/apnsProvider-BV5-wOvD.js";export{e as apnsProvider};
@@ -1 +1 @@
1
- import{default as r}from"../../../packem_shared/expoProvider-13gY7Ne8.js";export{r as expoProvider};
1
+ import{default as r}from"../../../packem_shared/expoProvider-BPJr9c0e.js";export{r as expoProvider};
@@ -1 +1 @@
1
- import{default as f}from"../../../packem_shared/fcmProvider-DsGjzBzz.js";export{f as fcmProvider};
1
+ import{default as f}from"../../../packem_shared/fcmProvider-qIR12R9m.js";export{f as fcmProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../../packem_shared/webPushProvider-K6-Drhaf.js";export{o as webPushProvider};
1
+ import{default as o}from"../../../packem_shared/webPushProvider-BtZHb_X_.js";export{o as webPushProvider};
@@ -1 +1 @@
1
- import{roundRobinProvider as d}from"../../packem_shared/roundRobinProvider-CK3Vyc_u.js";export{d as roundRobinProvider};
1
+ import{roundRobinProvider as d}from"../../packem_shared/roundRobinProvider-HowYifRe.js";export{d as roundRobinProvider};
@@ -1 +1 @@
1
- import{default as a}from"../../../packem_shared/messageBirdProvider-D1c3jUqj.js";export{a as messageBirdProvider};
1
+ import{default as a}from"../../../packem_shared/messageBirdProvider-FK9_UONf.js";export{a as messageBirdProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../../packem_shared/plivoProvider-C_koQ8X-.js";export{e as plivoProvider};
1
+ import{default as e}from"../../../packem_shared/plivoProvider-DaCu7J3X.js";export{e as plivoProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../../packem_shared/snsProvider-CPGjOUP_.js";export{o as snsProvider};
1
+ import{default as o}from"../../../packem_shared/snsProvider-BS4D6w-i.js";export{o as snsProvider};
@@ -1 +1 @@
1
- import{default as o}from"../../../packem_shared/telnyxProvider-C41tE4VF.js";export{o as telnyxProvider};
1
+ import{default as o}from"../../../packem_shared/telnyxProvider-wjmTXBwh.js";export{o as telnyxProvider};
@@ -1 +1 @@
1
- import{default as e}from"../../../packem_shared/twilioProvider-DanDTzi3.js";export{e as twilioProvider};
1
+ import{default as e}from"../../../packem_shared/twilioProvider-Bf_zsF9z.js";export{e as twilioProvider};
@@ -1 +1 @@
1
- import{default as r}from"../../../packem_shared/vonageProvider-epeGBWW8.js";export{r as vonageProvider};
1
+ import{default as r}from"../../../packem_shared/vonageProvider-oRg9dpS1.js";export{r as vonageProvider};
@@ -1 +1 @@
1
- import{webhookProvider as e}from"../../packem_shared/webhookProvider-DlwFyaGc.js";export{e as webhookProvider};
1
+ import{webhookProvider as e}from"../../packem_shared/webhookProvider-CwkDb1cZ.js";export{e as webhookProvider};
@@ -1,5 +1,5 @@
1
1
  import { a as NotificationMessage } from "../packem_shared/notification.d-D0ado_cy.js";
2
- import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d--kw9ifOI.js";
2
+ import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d-r8K0ICyx.js";
3
3
  import "../packem_shared/types.d-CRs03TYV.js";
4
4
  import "../packem_shared/types.d-C7l7qdMG.js";
5
5
  import "../packem_shared/provider.d-Dh32nRm9.js";
@@ -1,6 +1,6 @@
1
1
  export { BullMqQueue, createBullMqQueue } from "./bullmq-queue.js";
2
2
  import { a as NotificationMessage, N as Notification } from "../packem_shared/notification.d-D0ado_cy.js";
3
- import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d--kw9ifOI.js";
3
+ import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d-r8K0ICyx.js";
4
4
  export { PgBossQueue, type PgBossQueueOptions, createPgBossQueue } from "./pg-boss-queue.js";
5
5
  export { SqsQueue, type SqsQueueOptions, createSqsQueue } from "./sqs-queue.js";
6
6
  import { c as Receipt } from "../packem_shared/types.d-C7l7qdMG.js";
@@ -27,6 +27,8 @@ interface QueueWorkerOptions {
27
27
  maxAttempts?: number;
28
28
  /** Called when a job is dropped after exhausting attempts. */
29
29
  onDrop?: (job: QueueJob, receipts: Receipt[]) => void;
30
+ /** Called when the queue or a delivery throws; the loop keeps polling. */
31
+ onError?: (error: unknown, job?: QueueJob) => void;
30
32
  /** Poll interval in ms when the queue is empty (default 1000). */
31
33
  pollInterval?: number;
32
34
  }
@@ -1 +1 @@
1
- import{BullMqQueue as r,createBullMqQueue as o}from"./bullmq-queue.js";import{default as Q}from"../packem_shared/MemoryQueue-CXgWoZoY.js";import{PgBossQueue as a,createPgBossQueue as f}from"./pg-boss-queue.js";import{SqsQueue as l,createSqsQueue as p}from"./sqs-queue.js";import{createQueueWorker as c}from"../packem_shared/createQueueWorker-DjQBxjXc.js";export{r as BullMqQueue,Q as MemoryQueue,a as PgBossQueue,l as SqsQueue,o as createBullMqQueue,f as createPgBossQueue,c as createQueueWorker,p as createSqsQueue};
1
+ import{BullMqQueue as r,createBullMqQueue as o}from"./bullmq-queue.js";import{default as Q}from"../packem_shared/MemoryQueue-CXgWoZoY.js";import{PgBossQueue as a,createPgBossQueue as f}from"./pg-boss-queue.js";import{SqsQueue as l,createSqsQueue as p}from"./sqs-queue.js";import{createQueueWorker as c}from"../packem_shared/createQueueWorker-BIXWHJLY.js";export{r as BullMqQueue,Q as MemoryQueue,a as PgBossQueue,l as SqsQueue,o as createBullMqQueue,f as createPgBossQueue,c as createQueueWorker,p as createSqsQueue};
@@ -1,5 +1,5 @@
1
1
  import { a as NotificationMessage } from "../packem_shared/notification.d-D0ado_cy.js";
2
- import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d--kw9ifOI.js";
2
+ import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d-r8K0ICyx.js";
3
3
  import "../packem_shared/types.d-CRs03TYV.js";
4
4
  import "../packem_shared/types.d-C7l7qdMG.js";
5
5
  import "../packem_shared/provider.d-Dh32nRm9.js";
@@ -39,8 +39,9 @@ interface PgBossQueueOptions {
39
39
  * A {@link NotificationQueue} backed by [pg-boss](https://github.com/timgit/pg-boss) (Postgres, v10 API).
40
40
  *
41
41
  * Pass a started pg-boss instance — `pg-boss` is an optional peer dependency and is never started here.
42
- * `reserve` uses `fetch` with `includeMetadata`, so the job's `attempts` reflects pg-boss's own
43
- * `retryCount`. `retry` calls `fail`, so the retry delay is governed by the queue's pg-boss retry policy
42
+ * `reserve` uses `fetch` with `includeMetadata`, so the job's `attempts` is pg-boss's own
43
+ * `retryCount` plus the current delivery (1 on first reserve, matching the other adapters).
44
+ * `retry` calls `fail`, so the retry delay is governed by the queue's pg-boss retry policy
44
45
  * rather than the `delayMs` argument.
45
46
  *
46
47
  * Runtime: NODE ONLY (requires a Postgres connection). Not Cloudflare Workers compatible.
@@ -1 +1 @@
1
- class i{#e;#t;constructor(e,t){this.#e=e,this.#t=t.queueName}async enqueue(e,t){const a=t?.scheduledAt===void 0?void 0:new Date(t.scheduledAt);return await this.#e.send(this.#t,e,a===void 0?{}:{startAfter:a})??""}async reserve(){const e=await this.#e.fetch(this.#t,{batchSize:1,includeMetadata:!0}),t=Array.isArray(e)?e[0]:e;if(t)return{attempts:t.retryCount??0,id:t.id,message:t.data,scheduledAt:0}}async ack(e){await this.#e.complete(this.#t,e)}async retry(e){await this.#e.fail(this.#t,e)}async size(){return await this.#e.getQueueSize(this.#t)}}const r=(s,e)=>new i(s,e);export{i as PgBossQueue,r as createPgBossQueue};
1
+ class i{#e;#t;constructor(e,t){this.#e=e,this.#t=t.queueName}async enqueue(e,t){const a=t?.scheduledAt===void 0?void 0:new Date(t.scheduledAt);return await this.#e.send(this.#t,e,a===void 0?{}:{startAfter:a})??""}async reserve(){const e=await this.#e.fetch(this.#t,{batchSize:1,includeMetadata:!0}),t=Array.isArray(e)?e[0]:e;if(t)return{attempts:(t.retryCount??0)+1,id:t.id,message:t.data,scheduledAt:0}}async ack(e){await this.#e.complete(this.#t,e)}async retry(e){await this.#e.fail(this.#t,e)}async size(){return await this.#e.getQueueSize(this.#t)}}const r=(s,e)=>new i(s,e);export{i as PgBossQueue,r as createPgBossQueue};
@@ -1,5 +1,5 @@
1
1
  import { a as NotificationMessage } from "../packem_shared/notification.d-D0ado_cy.js";
2
- import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d--kw9ifOI.js";
2
+ import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d-r8K0ICyx.js";
3
3
  import "../packem_shared/types.d-CRs03TYV.js";
4
4
  import "../packem_shared/types.d-C7l7qdMG.js";
5
5
  import "../packem_shared/provider.d-Dh32nRm9.js";
@@ -1 +1 @@
1
- const a="ApproximateNumberOfMessages",r="ApproximateNumberOfMessagesNotVisible",u=(s,e)=>{if(s===void 0)return 0;const t=Math.ceil((s-e)/1e3);return Math.max(0,t)};class n{#e;#t;#s;#i;constructor(e,t){this.#e=e,this.#t=t.queueUrl,this.#s=t.visibilityTimeout??30,this.#i=t.waitTimeSeconds??0}async enqueue(e,t){const i=u(t?.scheduledAt,Date.now());if(i>900)throw new RangeError(`SQS supports a maximum scheduling delay of ${String(900)}s (15 minutes); use a scheduler for longer delays`);return(await this.#e.sendMessage({DelaySeconds:i,MessageBody:JSON.stringify(e),QueueUrl:this.#t})).MessageId??""}async reserve(){const e=(await this.#e.receiveMessage({AttributeNames:["ApproximateReceiveCount"],MaxNumberOfMessages:1,QueueUrl:this.#t,VisibilityTimeout:this.#s,WaitTimeSeconds:this.#i})).Messages?.[0];if(!e?.ReceiptHandle)return;const t=Number(e.Attributes?.ApproximateReceiveCount??"1");let i;try{i=JSON.parse(e.Body??"{}")}catch{await this.#e.deleteMessage({QueueUrl:this.#t,ReceiptHandle:e.ReceiptHandle});return}return{attempts:Math.max(0,t-1),id:e.ReceiptHandle,message:i,scheduledAt:0}}async ack(e){await this.#e.deleteMessage({QueueUrl:this.#t,ReceiptHandle:e})}async retry(e,t=0){await this.#e.changeMessageVisibility({QueueUrl:this.#t,ReceiptHandle:e,VisibilityTimeout:Math.min(900,Math.max(0,Math.ceil(t/1e3)))})}async size(){const e=await this.#e.getQueueAttributes({AttributeNames:[a,r],QueueUrl:this.#t});return Number(e.Attributes?.[a]??0)+Number(e.Attributes?.[r]??0)}}const c=(s,e)=>new n(s,e);export{n as SqsQueue,c as createSqsQueue};
1
+ const a="ApproximateNumberOfMessages",r="ApproximateNumberOfMessagesNotVisible",u=(s,e)=>{if(s===void 0)return 0;const t=Math.ceil((s-e)/1e3);return Math.max(0,t)};class n{#e;#t;#s;#i;constructor(e,t){this.#e=e,this.#t=t.queueUrl,this.#s=t.visibilityTimeout??30,this.#i=t.waitTimeSeconds??0}async enqueue(e,t){const i=u(t?.scheduledAt,Date.now());if(i>900)throw new RangeError(`SQS supports a maximum scheduling delay of ${String(900)}s (15 minutes); use a scheduler for longer delays`);return(await this.#e.sendMessage({DelaySeconds:i,MessageBody:JSON.stringify(e),QueueUrl:this.#t})).MessageId??""}async reserve(){const e=(await this.#e.receiveMessage({AttributeNames:["ApproximateReceiveCount"],MaxNumberOfMessages:1,QueueUrl:this.#t,VisibilityTimeout:this.#s,WaitTimeSeconds:this.#i})).Messages?.[0];if(!e?.ReceiptHandle)return;const t=Number(e.Attributes?.ApproximateReceiveCount??"1");let i;try{i=JSON.parse(e.Body??"{}")}catch{await this.#e.deleteMessage({QueueUrl:this.#t,ReceiptHandle:e.ReceiptHandle});return}return{attempts:Math.max(1,t),id:e.ReceiptHandle,message:i,scheduledAt:0}}async ack(e){await this.#e.deleteMessage({QueueUrl:this.#t,ReceiptHandle:e})}async retry(e,t=0){await this.#e.changeMessageVisibility({QueueUrl:this.#t,ReceiptHandle:e,VisibilityTimeout:Math.min(900,Math.max(0,Math.ceil(t/1e3)))})}async size(){const e=await this.#e.getQueueAttributes({AttributeNames:[a,r],QueueUrl:this.#t});return Number(e.Attributes?.[a]??0)+Number(e.Attributes?.[r]??0)}}const c=(s,e)=>new n(s,e);export{n as SqsQueue,c as createSqsQueue};
@@ -1,6 +1,6 @@
1
1
  import { S as Storage } from "../packem_shared/unstorage.DqlWKU2I.d-CogP3Etw.js";
2
2
  import { a as NotificationMessage } from "../packem_shared/notification.d-D0ado_cy.js";
3
- import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d--kw9ifOI.js";
3
+ import { Q as QueueJob, N as NotificationQueue } from "../packem_shared/types.d-r8K0ICyx.js";
4
4
  import "../packem_shared/types.d-CRs03TYV.js";
5
5
  import "../packem_shared/types.d-C7l7qdMG.js";
6
6
  import "../packem_shared/provider.d-Dh32nRm9.js";
@@ -8,6 +8,13 @@ import "../packem_shared/provider.d-Dh32nRm9.js";
8
8
  * A {@link NotificationQueue} backed by an [unstorage](https://unstorage.unjs.io) driver,
9
9
  * giving durable, multi-backend persistence (Redis, filesystem, KV, ...). `unstorage` is
10
10
  * an optional peer dependency — pass a configured `Storage` instance.
11
+ *
12
+ * Each job is a single self-contained document keyed by the configured prefix followed by `:job:` and the job id;
13
+ * there is no shared pending index, so concurrent `enqueue`s cannot lose-update each other.
14
+ * `reserve` scans the job documents under the prefix for the next due, unreserved job and
15
+ * marks it reserved. Individual reads/writes are still not transactional, so two workers
16
+ * racing `reserve` on the *same* job can both take it (double delivery); for that level of
17
+ * contention prefer a store with atomic guarantees, or reserve from one instance.
11
18
  */
12
19
  declare class UnstorageQueue implements NotificationQueue {
13
20
  #private;
@@ -1 +1 @@
1
- import{n as h}from"../packem_shared/id-C_FRCsUM.js";class c{#t;#e;constructor(t,s="notification:queue"){this.#t=t,this.#e=s}async enqueue(t,s){const e={attempts:0,id:h("job"),message:t,scheduledAt:s?.scheduledAt};return await this.#t.setItem(this.#s(e.id),e),await this.#n(e.id),e.id}async reserve(){const t=Date.now(),s=await this.#i();for(const e of s){const i=await this.#t.getItem(this.#s(e));if(i&&(i.scheduledAt??0)<=t)return i.attempts+=1,await this.#t.setItem(this.#s(e),i),await this.#a(s.filter(n=>n!==e)),i}}async ack(t){await this.#t.removeItem(this.#s(t))}async retry(t,s=0){const e=await this.#t.getItem(this.#s(t));e&&(e.scheduledAt=Date.now()+s,await this.#t.setItem(this.#s(t),e),await this.#n(t))}async size(){return(await this.#i()).length}#s(t){return`${this.#e}:job:${t}`}async#i(){return await this.#t.getItem(`${this.#e}:pending`)??[]}async#a(t){await this.#t.setItem(`${this.#e}:pending`,t)}async#n(t){const s=await this.#i();s.includes(t)||(s.push(t),await this.#a(s))}}const o=(a,t)=>new c(a,t);export{c as UnstorageQueue,o as createUnstorageQueue};
1
+ import{n as r}from"../packem_shared/id-C_FRCsUM.js";class n{#t;#a;constructor(t,e="notification:queue"){this.#t=t,this.#a=e}async enqueue(t,e){const s={attempts:0,id:r("job"),message:t,scheduledAt:e?.scheduledAt};return await this.#t.setItem(this.#e(s.id),s),s.id}async reserve(){const t=Date.now(),e=await this.#t.getKeys(this.#s());for(const s of e){const a=await this.#t.getItem(s);if(a&&!a.reserved&&(a.scheduledAt??0)<=t)return a.attempts+=1,a.reserved=!0,await this.#t.setItem(s,a),{attempts:a.attempts,id:a.id,message:a.message,scheduledAt:a.scheduledAt}}}async ack(t){await this.#t.removeItem(this.#e(t))}async retry(t,e=0){const s=await this.#t.getItem(this.#e(t));s&&(s.scheduledAt=Date.now()+e,s.reserved=!1,await this.#t.setItem(this.#e(t),s))}async size(){const t=await this.#t.getKeys(this.#s());return(await Promise.all(t.map(async e=>this.#t.getItem(e)))).filter(e=>e!==null&&!e.reserved).length}#s(){return`${this.#a}:job:`}#e(t){return`${this.#s()}${t}`}}const c=(i,t)=>new n(i,t);export{n as UnstorageQueue,c as createUnstorageQueue};
@@ -1 +1 @@
1
- import r from"../packem_shared/NotificationError-B8CyoEaX.js";const d=async(a,n,s)=>{if(typeof a!="string")throw new TypeError("Handlebars template must be a string");let t;try{const e=await import("handlebars");t=e.default??e}catch(e){throw new r("handlebars","handlebars is not installed. Please install it: pnpm add handlebars",{cause:e})}try{return t.compile(a,s)(n??{})}catch(e){throw new r("handlebars",`Failed to render Handlebars template: ${e.message}`,{cause:e})}};export{d as default,d as renderHandlebars};
1
+ import r from"../packem_shared/NotificationError-B1ZZqWxL.js";const d=async(a,n,s)=>{if(typeof a!="string")throw new TypeError("Handlebars template must be a string");let t;try{const e=await import("handlebars");t=e.default??e}catch(e){throw new r("handlebars","handlebars is not installed. Please install it: pnpm add handlebars",{cause:e})}try{return t.compile(a,s)(n??{})}catch(e){throw new r("handlebars",`Failed to render Handlebars template: ${e.message}`,{cause:e})}};export{d as default,d as renderHandlebars};
@@ -1 +1 @@
1
- import r from"../packem_shared/NotificationError-B8CyoEaX.js";const s=async(t,a,d)=>{if(typeof t!="string")throw new TypeError("Liquid template must be a string");let i;try{i=await import("liquidjs")}catch(e){throw new r("liquid","liquidjs is not installed. Please install it: pnpm add liquidjs",{cause:e})}try{return await new i.Liquid(d??{}).parseAndRender(t,a??{})}catch(e){throw new r("liquid",`Failed to render Liquid template: ${e.message}`,{cause:e})}};export{s as default,s as renderLiquid};
1
+ import r from"../packem_shared/NotificationError-B1ZZqWxL.js";const s=async(t,a,d)=>{if(typeof t!="string")throw new TypeError("Liquid template must be a string");let i;try{i=await import("liquidjs")}catch(e){throw new r("liquid","liquidjs is not installed. Please install it: pnpm add liquidjs",{cause:e})}try{return await new i.Liquid(d??{}).parseAndRender(t,a??{})}catch(e){throw new r("liquid",`Failed to render Liquid template: ${e.message}`,{cause:e})}};export{s as default,s as renderLiquid};
@@ -1 +1 @@
1
- import e from"../packem_shared/NotificationError-B8CyoEaX.js";const c=r=>r.success,t=r=>!r.success,u=r=>{if(r.success)return r.data;throw r.error instanceof Error?r.error:new e("result","Called unwrap() on a failed result",{cause:r.error})},o=(r,s)=>r.success?r.data:s,n=(r,s)=>r.success?{data:s(r.data),success:!0}:{error:r.error,success:!1},d=async r=>{try{return{data:await r(),success:!0}}catch(s){return{error:s,success:!1}}};export{t as isErr,c as isOk,n as mapOk,d as tryAsync,u as unwrap,o as unwrapOr};
1
+ import e from"../packem_shared/NotificationError-B1ZZqWxL.js";const c=r=>r.success,t=r=>!r.success,u=r=>{if(r.success)return r.data;throw r.error instanceof Error?r.error:new e("result","Called unwrap() on a failed result",{cause:r.error})},o=(r,s)=>r.success?r.data:s,n=(r,s)=>r.success?{data:s(r.data),success:!0}:{error:r.error,success:!1},d=async r=>{try{return{data:await r(),success:!0}}catch(s){return{error:s,success:!1}}};export{t as isErr,c as isOk,n as mapOk,d as tryAsync,u as unwrap,o as unwrapOr};
@@ -1 +1 @@
1
- import{hmacBase64 as r,hmacHex as t,timingSafeEqual as a}from"../packem_shared/hmacBase64-BhhoX0uo.js";import{slackWebhook as f}from"../packem_shared/slackWebhook-Cpmm_0El.js";import{snsWebhook as h}from"../packem_shared/snsWebhook-BKBTQyEW.js";import{standardWebhook as k}from"../packem_shared/standardWebhook-Bk0UUeDW.js";import{twilioWebhook as b}from"../packem_shared/twilioWebhook-C-Iwuv7y.js";import{getHeader as W}from"../packem_shared/getHeader-C_gkdnMQ.js";export{W as getHeader,r as hmacBase64,t as hmacHex,f as slackWebhook,h as snsWebhook,k as standardWebhook,a as timingSafeEqual,b as twilioWebhook};
1
+ import{hmacBase64 as r,hmacHex as t,timingSafeEqual as a}from"../packem_shared/hmacBase64-CNksyDoB.js";import{slackWebhook as f}from"../packem_shared/slackWebhook-IB4mVnBk.js";import{snsWebhook as h}from"../packem_shared/snsWebhook-BKBTQyEW.js";import{standardWebhook as k}from"../packem_shared/standardWebhook-C_AQWUi5.js";import{twilioWebhook as b}from"../packem_shared/twilioWebhook-Hhf9aWV1.js";import{getHeader as W}from"../packem_shared/getHeader-C_gkdnMQ.js";export{W as getHeader,r as hmacBase64,t as hmacHex,f as slackWebhook,h as snsWebhook,k as standardWebhook,a as timingSafeEqual,b as twilioWebhook};
@@ -1 +1 @@
1
- import{default as a}from"../packem_shared/createNotificationWorkflow-5AY-ays0.js";export{a as createNotificationWorkflow};
1
+ import{default as a}from"../packem_shared/createNotificationWorkflow-lseG_9fC.js";export{a as createNotificationWorkflow};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/notification",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "A reusable, ESM-only, edge-ready multi-channel notification library with SMS, push, chat, in-app and webhook providers",
5
5
  "keywords": [
6
6
  "apns",
@@ -234,8 +234,8 @@
234
234
  "peerDependencies": {
235
235
  "@aws-sdk/client-sqs": "^3.0.0",
236
236
  "@opentelemetry/api": "^1.0.0 || ^2.0.0",
237
- "@visulima/email": "2.1.7",
238
- "@visulima/workflow": "1.0.0",
237
+ "@visulima/email": "2.1.8",
238
+ "@visulima/workflow": "2.0.0",
239
239
  "bullmq": "^5.0.0",
240
240
  "croner": "^10.0.1",
241
241
  "handlebars": ">=4.7.9",
@@ -1 +0,0 @@
1
- import h from"./NotificationError-B8CyoEaX.js";import{composeMiddleware as u}from"./composeMiddleware-D6dR8DUS.js";const c=(n,s,t)=>{if(n.success&&n.data)return{channel:s,messageId:n.data.messageId,provider:n.data.provider??t,response:n.data.response,successful:!0,timestamp:n.data.timestamp};const{error:e}=n;let i;return e instanceof Error?i=e.message:e==null?i="Unknown error":typeof e=="string"?i=e:i=JSON.stringify(e),{channel:s,errorMessages:[i],provider:t,successful:!1}};class d{#s;#e=[];#t=new Set;#n;constructor(s){this.#s=s}use(s){return this.#e.push(s),this}setLogger(s){return this.#n=s,this}getProvider(s){return this.#s[s]}async sendToChannel(s,t){const e=this.#s[s];if(!e)return{channel:s,errorMessages:[`No provider registered for channel "${s}"`],successful:!1};try{await this.#i(e)}catch(r){return c({error:r,success:!1},s,e.id)}const i=async r=>e.send(r.payload),a=await u(this.#e,i)({channel:s,payload:t,provider:e.id});return c(a,s,e.id)}async send(s){const t=Object.keys(s);if(t.length===0)throw new h("notification","send() called with an empty message");return Promise.all(t.map(async e=>this.sendToChannel(e,s[e])))}async*sendMany(s,t={}){const e=Math.max(1,t.concurrency??10),i=[...s];let a=0;for(;a<i.length;){const r=i.slice(a,a+e);a+=e;const l=await Promise.all(r.map(async o=>this.send(o)));for(const o of l)yield o}}async initialize(){await Promise.all(Object.values(this.#s).map(async s=>this.#i(s)))}async shutdown(){await Promise.all(Object.values(this.#s).map(async s=>{const{shutdown:t}=s;t&&await t()}))}async#i(s){this.#t.has(s.id)||(await s.initialize(),this.#n?.debug(`[@visulima/notification] initialized provider "${s.id}"`),this.#t.add(s.id))}}const p=n=>new d(n),y=async(n,s,t)=>new d({[n]:s}).sendToChannel(n,t);export{d as Notification,p as createNotification,y as send};
@@ -1 +0,0 @@
1
- import{createRequire as d}from"node:module";let g;const m=r=>(g??=d(import.meta.url))(r),s=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,f=r=>{if(typeof s<"u"&&s.versions&&s.versions.node){const[e,o]=s.versions.node.split(".").map(Number);if(e>22||e===22&&o>=3||e===20&&o>=16)return s.getBuiltinModule(r)}return m(r)},{createRequire:c}=f("node:module"),E=new Map([["Error",Error],["EvalError",EvalError],["RangeError",RangeError],["ReferenceError",ReferenceError],["SyntaxError",SyntaxError],["TypeError",TypeError],["URIError",URIError]]);typeof AggregateError<"u"&&E.set("AggregateError",AggregateError);let y;const _=r=>(y??=c(import.meta.url))(r),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,b=r=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[e,o]=i.versions.node.split(".").map(Number);if(e>22||e===22&&o>=3||e===20&&o>=16)return i.getBuiltinModule(r)}return _(r)};b("node:util");class v extends Error{loc;title;hint;type="VisulimaError";constructor({cause:e,hint:o,location:t,message:l,name:u,stack:p,title:h}){super(l,{cause:e}),this.title=h,this.name=u,this.stack=p??this.stack,this.loc=t,this.hint=o}setLocation(e){this.loc=e}setName(e){this.name=e}setMessage(e){this.message=e}setHint(e){this.hint=e}}let T;const R=r=>(T??=c(import.meta.url))(r),n=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,a=r=>{if(typeof n<"u"&&n.versions&&n.versions.node){const[e,o]=n.versions.node.split(".").map(Number);if(e>22||e===22&&o>=3||e===20&&o>=16)return n.getBuiltinModule(r)}return R(r)};a("node:fs");a("node:path");a("node:url");class M extends v{component;code;constructor(e,o,t){super({cause:t?.cause,hint:t?.hint,message:`[@visulima/notification] [${e}] ${o}`,name:"NotificationError",title:`Notification ${e} Error`}),this.component=e,this.code=t?.code}}export{M as default};
@@ -1 +0,0 @@
1
- const l=async e=>new Promise(n=>{setTimeout(n,e)}),w=(e,n,s={})=>{const o=s.maxAttempts??5,i=s.pollInterval??1e3,u=s.backoff??(a=>Math.min(3e4,1e3*2**(a-1)));let t=!1;const r=async()=>{const a=await e.reserve();if(!a)return!1;const c=await n.send(a.message);return c.some(m=>!m.successful)?a.attempts>=o?(await e.ack(a.id),s.onDrop?.(a,c)):await e.retry(a.id,u(a.attempts)):await e.ack(a.id),!0},f=async()=>{for(;t;)await r()||await l(i)};return{drain:async()=>{for(;await r(););},start:()=>{t||(t=!0,f().catch(()=>{t=!1}))},stop:()=>{t=!1}}};export{w as createQueueWorker};
@@ -1 +0,0 @@
1
- import c from"./NotificationError-B8CyoEaX.js";import d from"./RequiredOptionError-Bs282gKK.js";import{defineProvider as h}from"./defineProvider-C9q-7iwt.js";import{t as y}from"./credentials-CG0zkn-W.js";import{r as T}from"./http-DT3tyixg.js";const I=h(m=>{const e=m??{};if(!e.projectId)throw new d("fcm","projectId");if(!e.accessToken&&!e.getAccessToken)throw new d("fcm",["accessToken","getAccessToken"]);const i=e.endpoint??"https://fcm.googleapis.com",f=e.retries??3,u=e.timeout??3e4,p=`${i}/v1/projects/${e.projectId}/messages:send`,l=s=>{if(s)return Object.fromEntries(Object.entries(s).map(([r,o])=>[r,typeof o=="string"?o:JSON.stringify(o)]))},g=async(s,r,o)=>{const a={data:l(r.data),notification:{body:r.body,image:r.imageUrl,title:r.title},token:s},t=await T(p,{body:JSON.stringify({message:a}),headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},method:"POST",timeout:u},f);return!t.success||!t.data?{error:t.error instanceof Error?t.error.message:"Request failed",id:s,status:"failed"}:t.data.status>=400?{error:t.data.body.error?.message??`HTTP ${String(t.data.status)}`,id:s,status:"failed"}:{id:s,messageId:t.data.body.name,status:"sent"}};return{channel:"push",endpoint:i,features:{batchSending:!1,media:!0,richContent:!0},id:"fcm",initialize:()=>{},isAvailable:()=>!!(e.projectId&&(e.accessToken??e.getAccessToken)),options:e,send:async s=>{let r;try{r=e.getAccessToken?await e.getAccessToken():e.accessToken}catch(n){return{error:new c("fcm","Failed to obtain access token",{cause:n}),success:!1}}const o=y(s.to),a=[];for(const n of o)a.push(await g(n,s,r));const t=a.filter(n=>n.status==="sent");return t.length===0?{error:new c("fcm",a[0]?.error??"All tokens failed"),success:!1}:{data:{channel:"push",messageId:t[0]?.messageId??"",provider:"fcm",recipients:a,sent:!0,timestamp:new Date},success:!0}}}});export{I as default};
@@ -1 +0,0 @@
1
- import{g as o,i as r,b as i}from"./webcrypto-bY7wJCB5.js";const l=300,c=async(a,t,e)=>i(await r(a,t,e)),f=async(a,t,e)=>o(await r(a,t,e)),h=(a,t)=>{if(a.length!==t.length)return!1;let e=0;for(let n=0;n<a.length;n+=1)e|=(a.codePointAt(n)??0)^(t.codePointAt(n)??0);return e===0},m=(a,t)=>{if(a===void 0)return!1;const e=Number.parseInt(a,10);if(Number.isNaN(e))return!1;const n=Math.floor(Date.now()/1e3);return Math.abs(n-e)<=t};export{l as REPLAY_WINDOW_SECONDS,f as hmacBase64,c as hmacHex,m as isWithinReplayWindow,h as timingSafeEqual};
@@ -1 +0,0 @@
1
- import{hmacBase64 as u,timingSafeEqual as c}from"./hmacBase64-BhhoX0uo.js";import{getHeader as a}from"./getHeader-C_gkdnMQ.js";const m="X-Twilio-Signature",f={delivered:"delivered",failed:"failed",queued:"queued",sending:"queued",sent:"sent",undelivered:"failed"},S=(i,e)=>{const r=Object.keys(e).toSorted((o,s)=>o.localeCompare(s));let t=i;for(const o of r)t+=`${o}${e[o]??""}`;return t},n=i=>{const e={};return new URLSearchParams(i).forEach((r,t)=>{e[t]=r}),e},g={parse:i=>{const e=n(i),r=e.MessageStatus??e.SmsStatus??e.CallStatus;if(r===void 0)return;const t=f[r.toLowerCase()];return t===void 0?void 0:{channel:"sms",messageId:e.MessageSid??e.SmsSid??e.CallSid??"",provider:"twilio",recipient:e.To,timestamp:new Date,type:t}},verify:async(i,e,r)=>{if(r.trim()==="")return!1;const t=a(e,m),o=a(e,"x-twilio-signature-url");if(t===void 0||o===void 0)return!1;const s=n(i),d=S(o,s),l=await u(r,d,"SHA-1");return c(l,t)}};export{g as twilioWebhook};
@@ -1 +0,0 @@
1
- import s from"./NotificationError-B8CyoEaX.js";import i from"./RequiredOptionError-Bs282gKK.js";import{r as d}from"./http-DT3tyixg.js";import{n as u}from"./id-C_FRCsUM.js";const w=(t={})=>{const a=t.retries??3,n=t.timeout??3e4;return{channel:"webhook",endpoint:t.url,features:{},id:"webhook",initialize:()=>{},isAvailable:()=>!0,send:async o=>{const r=o.url??t.url;if(!r)throw new i("webhook","url");const e=await d(r,{body:typeof o.body=="string"?o.body:JSON.stringify(o.body),headers:{"Content-Type":"application/json",...t.headers,...o.headers},method:o.method??t.method??"POST",timeout:n},a);return!e.success||!e.data?{error:new s("webhook",e.error instanceof Error?e.error.message:"Request failed"),success:!1}:e.data.status>=400?{error:new s("webhook",`HTTP ${String(e.data.status)}`),success:!1}:{data:{channel:"webhook",messageId:u("webhook"),provider:"webhook",response:e.data.body,sent:!0,timestamp:new Date},success:!0}}}};export{w as webhookProvider};