@visulima/notification 1.0.9 → 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 (125) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/channels/email/index.d.ts +23 -23
  3. package/dist/channels/email/index.js +1 -1
  4. package/dist/channels/inapp/index.d.ts +31 -31
  5. package/dist/digest/index.d.ts +55 -55
  6. package/dist/digest/index.js +1 -1
  7. package/dist/events/index.d.ts +16 -16
  8. package/dist/i18n/index.d.ts +21 -21
  9. package/dist/i18n/index.js +1 -1
  10. package/dist/index.d.ts +97 -108
  11. package/dist/index.js +1 -1
  12. package/dist/layouts/index.d.ts +28 -28
  13. package/dist/middleware/index.d.ts +49 -49
  14. package/dist/middleware/index.js +1 -1
  15. package/dist/packem_shared/Notification-BuS_QjJv.js +1 -0
  16. package/dist/packem_shared/NotificationError-B1ZZqWxL.js +1 -0
  17. package/dist/packem_shared/{RequiredOptionError-CuL42XRq.js → RequiredOptionError-CH4g-BZM.js} +1 -1
  18. package/dist/packem_shared/apnsProvider-BV5-wOvD.js +1 -0
  19. package/dist/packem_shared/{circuitBreakerMiddleware-BlZN7SVT.js → circuitBreakerMiddleware-o3G_6N3s.js} +1 -1
  20. package/dist/packem_shared/{createDigester-vMNPejGF.js → createDigester-DCwWhmpi.js} +1 -1
  21. package/dist/packem_shared/{createNotificationWorkflow-B70OgeED.js → createNotificationWorkflow-lseG_9fC.js} +1 -1
  22. package/dist/packem_shared/createQueueWorker-BIXWHJLY.js +1 -0
  23. package/dist/packem_shared/{createTranslator-CY91C2eS.js → createTranslator-BL2M8eeD.js} +1 -1
  24. package/dist/packem_shared/{discordProvider-BhfXcCcI.js → discordProvider-D4LpBljj.js} +1 -1
  25. package/dist/packem_shared/{emailChannel-CNDlX96Q.js → emailChannel-BoLLbyrn.js} +1 -1
  26. package/dist/packem_shared/{expoProvider-DsZR4sUk.js → expoProvider-BPJr9c0e.js} +1 -1
  27. package/dist/packem_shared/{failoverProvider-D1dAmW8U.js → failoverProvider-CJsDGjzf.js} +1 -1
  28. package/dist/packem_shared/fcmProvider-qIR12R9m.js +1 -0
  29. package/dist/packem_shared/hmacBase64-CNksyDoB.js +1 -0
  30. package/dist/packem_shared/{messageBirdProvider-BfiTaNLn.js → messageBirdProvider-FK9_UONf.js} +1 -1
  31. package/dist/packem_shared/{mockProvider-BLwTZlkw.js → mockProvider-C2hHPSVa.js} +1 -1
  32. package/dist/packem_shared/{msTeamsProvider-DrmL3RYX.js → msTeamsProvider-DeGPjmCt.js} +1 -1
  33. package/dist/packem_shared/notification.d-D0ado_cy.d.ts +104 -0
  34. package/dist/packem_shared/{plivoProvider-Dr8d5yD3.js → plivoProvider-DaCu7J3X.js} +1 -1
  35. package/dist/packem_shared/{provider.d-BQAGriz6.d.ts → provider.d-Dh32nRm9.d.ts} +10 -10
  36. package/dist/packem_shared/{roundRobinProvider-BetXJUUm.js → roundRobinProvider-HowYifRe.js} +1 -1
  37. package/dist/packem_shared/{slackProvider-DPG1IlA0.js → slackProvider-Caxbs4Pa.js} +1 -1
  38. package/dist/packem_shared/{slackWebhook-Cpmm_0El.js → slackWebhook-IB4mVnBk.js} +1 -1
  39. package/dist/packem_shared/{sms-CU-OZvNU.js → sms-BbxkOLQm.js} +1 -1
  40. package/dist/packem_shared/{snsProvider-C2T2UxDK.js → snsProvider-BS4D6w-i.js} +3 -3
  41. package/dist/packem_shared/{standardWebhook-Bk0UUeDW.js → standardWebhook-C_AQWUi5.js} +1 -1
  42. package/dist/packem_shared/{telegramProvider-wyx3ksVm.js → telegramProvider-BIc_GgpY.js} +1 -1
  43. package/dist/packem_shared/{telnyxProvider-jgpEwgPh.js → telnyxProvider-wjmTXBwh.js} +1 -1
  44. package/dist/packem_shared/{tracer.d-Co1s_NwG.d.ts → tracer.d-BPznIQx9.d.ts} +2 -2
  45. package/dist/packem_shared/{twilioProvider-DMYWqvgZ.js → twilioProvider-Bf_zsF9z.js} +1 -1
  46. package/dist/packem_shared/twilioWebhook-Hhf9aWV1.js +1 -0
  47. package/dist/packem_shared/types.d-BU-37j3S.d.ts +10 -0
  48. package/dist/packem_shared/{types.d-GUzX1jTk.d.ts → types.d-C7l7qdMG.d.ts} +52 -52
  49. package/dist/packem_shared/{types.d-CximoA8M.d.ts → types.d-CRs03TYV.d.ts} +13 -13
  50. package/dist/packem_shared/{types.d-C1GoEAlI.d-Bv3grfyD.d.ts → types.d-CcjfiGpo.d-DuZME7ry.d.ts} +27 -34
  51. package/dist/packem_shared/{types.d-67TogK4k.d.ts → types.d-r8K0ICyx.d.ts} +7 -7
  52. package/dist/packem_shared/{vonageProvider-CT4KoWXu.js → vonageProvider-oRg9dpS1.js} +1 -1
  53. package/dist/packem_shared/{webPushProvider-DwjmWASr.js → webPushProvider-BtZHb_X_.js} +1 -1
  54. package/dist/packem_shared/{webcrypto-bY7wJCB5.js → webcrypto-CFuQmh5-.js} +1 -1
  55. package/dist/packem_shared/webhookProvider-CwkDb1cZ.js +1 -0
  56. package/dist/preferences/index.d.ts +19 -19
  57. package/dist/providers/chat/discord/index.d.ts +5 -5
  58. package/dist/providers/chat/discord/index.js +1 -1
  59. package/dist/providers/chat/msteams/index.d.ts +7 -7
  60. package/dist/providers/chat/msteams/index.js +1 -1
  61. package/dist/providers/chat/slack/index.d.ts +6 -6
  62. package/dist/providers/chat/slack/index.js +1 -1
  63. package/dist/providers/chat/telegram/index.d.ts +5 -5
  64. package/dist/providers/chat/telegram/index.js +1 -1
  65. package/dist/providers/failover/index.d.ts +7 -7
  66. package/dist/providers/failover/index.js +1 -1
  67. package/dist/providers/mock/index.d.ts +5 -5
  68. package/dist/providers/mock/index.js +1 -1
  69. package/dist/providers/opentelemetry/index.d.ts +14 -14
  70. package/dist/providers/push/apns/index.d.ts +9 -9
  71. package/dist/providers/push/apns/index.js +1 -1
  72. package/dist/providers/push/expo/index.d.ts +5 -5
  73. package/dist/providers/push/expo/index.js +1 -1
  74. package/dist/providers/push/fcm/index.d.ts +13 -13
  75. package/dist/providers/push/fcm/index.js +1 -1
  76. package/dist/providers/push/web-push/index.d.ts +11 -11
  77. package/dist/providers/push/web-push/index.js +1 -1
  78. package/dist/providers/roundrobin/index.d.ts +8 -8
  79. package/dist/providers/roundrobin/index.js +1 -1
  80. package/dist/providers/sms/messagebird/index.d.ts +5 -5
  81. package/dist/providers/sms/messagebird/index.js +1 -1
  82. package/dist/providers/sms/plivo/index.d.ts +5 -5
  83. package/dist/providers/sms/plivo/index.js +1 -1
  84. package/dist/providers/sms/sns/index.d.ts +6 -6
  85. package/dist/providers/sms/sns/index.js +1 -1
  86. package/dist/providers/sms/telnyx/index.d.ts +5 -5
  87. package/dist/providers/sms/telnyx/index.js +1 -1
  88. package/dist/providers/sms/twilio/index.d.ts +5 -5
  89. package/dist/providers/sms/twilio/index.js +1 -1
  90. package/dist/providers/sms/vonage/index.d.ts +5 -5
  91. package/dist/providers/sms/vonage/index.js +1 -1
  92. package/dist/providers/webhook/index.d.ts +7 -7
  93. package/dist/providers/webhook/index.js +1 -1
  94. package/dist/queue/bullmq-queue.d.ts +24 -24
  95. package/dist/queue/index.d.ts +17 -15
  96. package/dist/queue/index.js +1 -1
  97. package/dist/queue/pg-boss-queue.d.ts +27 -26
  98. package/dist/queue/pg-boss-queue.js +1 -1
  99. package/dist/queue/sqs-queue.d.ts +27 -27
  100. package/dist/queue/sqs-queue.js +1 -1
  101. package/dist/queue/unstorage-queue.d.ts +21 -14
  102. package/dist/queue/unstorage-queue.js +1 -1
  103. package/dist/routing/index.d.ts +22 -22
  104. package/dist/template-engines/handlebars.d.ts +13 -13
  105. package/dist/template-engines/handlebars.js +1 -1
  106. package/dist/template-engines/liquid.d.ts +13 -13
  107. package/dist/template-engines/liquid.js +1 -1
  108. package/dist/template-engines/string.d.ts +17 -17
  109. package/dist/utils/result.d.ts +32 -32
  110. package/dist/utils/result.js +1 -1
  111. package/dist/webhooks/index.d.ts +84 -84
  112. package/dist/webhooks/index.js +1 -1
  113. package/dist/workflow/index.d.ts +42 -42
  114. package/dist/workflow/index.js +1 -1
  115. package/package.json +3 -3
  116. package/dist/packem_shared/Notification-B22tuJPy.js +0 -1
  117. package/dist/packem_shared/NotificationError-DVfMJQ1u.js +0 -1
  118. package/dist/packem_shared/apnsProvider-C9WSv5sc.js +0 -1
  119. package/dist/packem_shared/createQueueWorker-DjQBxjXc.js +0 -1
  120. package/dist/packem_shared/fcmProvider-DWRx8XBv.js +0 -1
  121. package/dist/packem_shared/hmacBase64-BhhoX0uo.js +0 -1
  122. package/dist/packem_shared/notification.d-DFCVTods.d.ts +0 -104
  123. package/dist/packem_shared/twilioWebhook-C-Iwuv7y.js +0 -1
  124. package/dist/packem_shared/types.d-td-F2Oh0.d.ts +0 -10
  125. package/dist/packem_shared/webhookProvider-CPA1nKXJ.js +0 -1
@@ -1,16 +1,16 @@
1
- import { T as TemplateRenderer } from "../packem_shared/types.d-td-F2Oh0.js";
1
+ import { T as TemplateRenderer } from "../packem_shared/types.d-BU-37j3S.js";
2
2
  /**
3
- * Renders a [Handlebars](https://handlebarsjs.com/) template to a string.
4
- *
5
- * `handlebars` is an optional peer, loaded lazily so a missing install surfaces here
6
- * as a {@link NotificationError} rather than at import time. Pure JS — edge-safe and
7
- * runnable on Cloudflare Workers.
8
- * @param template The Handlebars template string.
9
- * @param data The data/variables exposed to the template.
10
- * @param options Handlebars compile options.
11
- * @returns The rendered string.
12
- * @throws {TypeError} When the template is not a string.
13
- * @throws {NotificationError} When `handlebars` is not installed or rendering fails.
14
- */
3
+ * Renders a [Handlebars](https://handlebarsjs.com/) template to a string.
4
+ *
5
+ * `handlebars` is an optional peer, loaded lazily so a missing install surfaces here
6
+ * as a {@link NotificationError} rather than at import time. Pure JS — edge-safe and
7
+ * runnable on Cloudflare Workers.
8
+ * @param template The Handlebars template string.
9
+ * @param data The data/variables exposed to the template.
10
+ * @param options Handlebars compile options.
11
+ * @returns The rendered string.
12
+ * @throws {TypeError} When the template is not a string.
13
+ * @throws {NotificationError} When `handlebars` is not installed or rendering fails.
14
+ */
15
15
  declare const renderHandlebars: TemplateRenderer;
16
16
  export { renderHandlebars as default, renderHandlebars };
@@ -1 +1 @@
1
- import r from"../packem_shared/NotificationError-DVfMJQ1u.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,16 +1,16 @@
1
- import { T as TemplateRenderer } from "../packem_shared/types.d-td-F2Oh0.js";
1
+ import { T as TemplateRenderer } from "../packem_shared/types.d-BU-37j3S.js";
2
2
  /**
3
- * Renders a [LiquidJS](https://liquidjs.com/) template to a string.
4
- *
5
- * `liquidjs` is an optional peer, loaded lazily so a missing install surfaces here as
6
- * a {@link NotificationError} rather than at import time. Pure JS — edge-safe and
7
- * runnable on Cloudflare Workers.
8
- * @param template The Liquid template string.
9
- * @param data The data/variables exposed to the template.
10
- * @param options LiquidJS engine options (passed to the `Liquid` constructor).
11
- * @returns The rendered output.
12
- * @throws {TypeError} When the template is not a string.
13
- * @throws {NotificationError} When `liquidjs` is not installed or rendering fails.
14
- */
3
+ * Renders a [LiquidJS](https://liquidjs.com/) template to a string.
4
+ *
5
+ * `liquidjs` is an optional peer, loaded lazily so a missing install surfaces here as
6
+ * a {@link NotificationError} rather than at import time. Pure JS — edge-safe and
7
+ * runnable on Cloudflare Workers.
8
+ * @param template The Liquid template string.
9
+ * @param data The data/variables exposed to the template.
10
+ * @param options LiquidJS engine options (passed to the `Liquid` constructor).
11
+ * @returns The rendered output.
12
+ * @throws {TypeError} When the template is not a string.
13
+ * @throws {NotificationError} When `liquidjs` is not installed or rendering fails.
14
+ */
15
15
  declare const renderLiquid: TemplateRenderer;
16
16
  export { renderLiquid as default, renderLiquid };
@@ -1 +1 @@
1
- import r from"../packem_shared/NotificationError-DVfMJQ1u.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,20 +1,20 @@
1
- import { T as TemplateRenderer } from "../packem_shared/types.d-td-F2Oh0.js";
1
+ import { T as TemplateRenderer } from "../packem_shared/types.d-BU-37j3S.js";
2
2
  /**
3
- * Zero-dependency `{{var}}` interpolation renderer. Edge-safe and peer-free.
4
- *
5
- * Replaces `{{ key }}` / `{{ a.b.c }}` placeholders with the matching value from
6
- * `data`. Unmatched placeholders render as an empty string. Whitespace inside the
7
- * braces is ignored. This is intentionally minimal — for conditionals/loops use the
8
- * Handlebars or Liquid renderers.
9
- * @param template The template string containing `{{var}}` placeholders.
10
- * @param data The data/variables to interpolate.
11
- * @returns The rendered string.
12
- * @throws {TypeError} When the template is not a string.
13
- * @example
14
- * ```ts
15
- * renderString("Hi {{ user.name }}, code {{code}}", { code: "123", user: { name: "Ada" } });
16
- * // => "Hi Ada, code 123"
17
- * ```
18
- */
3
+ * Zero-dependency `{{var}}` interpolation renderer. Edge-safe and peer-free.
4
+ *
5
+ * Replaces `{{ key }}` / `{{ a.b.c }}` placeholders with the matching value from
6
+ * `data`. Unmatched placeholders render as an empty string. Whitespace inside the
7
+ * braces is ignored. This is intentionally minimal — for conditionals/loops use the
8
+ * Handlebars or Liquid renderers.
9
+ * @param template The template string containing `{{var}}` placeholders.
10
+ * @param data The data/variables to interpolate.
11
+ * @returns The rendered string.
12
+ * @throws {TypeError} When the template is not a string.
13
+ * @example
14
+ * ```ts
15
+ * renderString("Hi {{ user.name }}, code {{code}}", { code: "123", user: { name: "Ada" } });
16
+ * // => "Hi Ada, code 123"
17
+ * ```
18
+ */
19
19
  declare const renderString: TemplateRenderer;
20
20
  export { renderString as default, renderString };
@@ -1,54 +1,54 @@
1
- import { R as Result } from "../packem_shared/types.d-GUzX1jTk.js";
1
+ import { R as Result } from "../packem_shared/types.d-C7l7qdMG.js";
2
2
  /**
3
- * A successful {@link Result} with its data narrowed to be present.
4
- */
3
+ * A successful {@link Result} with its data narrowed to be present.
4
+ */
5
5
  type OkResult<T> = Result<T> & {
6
6
  data: T;
7
7
  success: true;
8
8
  };
9
9
  /**
10
- * A failed {@link Result}, narrowed to the failure case.
11
- */
10
+ * A failed {@link Result}, narrowed to the failure case.
11
+ */
12
12
  type FailResult<T> = Result<T> & {
13
13
  success: false;
14
14
  };
15
15
  /**
16
- * Returns whether a {@link Result} succeeded, narrowing `data` to be present.
17
- * @param result The result to test.
18
- * @returns `true` when the result is successful.
19
- */
16
+ * Returns whether a {@link Result} succeeded, narrowing `data` to be present.
17
+ * @param result The result to test.
18
+ * @returns `true` when the result is successful.
19
+ */
20
20
  declare const isOk: <T>(result: Result<T>) => result is OkResult<T>;
21
21
  /**
22
- * Returns whether a {@link Result} failed.
23
- * @param result The result to test.
24
- * @returns `true` when the result is a failure.
25
- */
22
+ * Returns whether a {@link Result} failed.
23
+ * @param result The result to test.
24
+ * @returns `true` when the result is a failure.
25
+ */
26
26
  declare const isErr: <T>(result: Result<T>) => result is FailResult<T>;
27
27
  /**
28
- * Returns the data of a successful {@link Result}, or throws its error.
29
- * @param result The result to unwrap.
30
- * @returns The contained data.
31
- * @throws {NotificationError} The result's error (wrapped when it is not already an `Error`).
32
- */
28
+ * Returns the data of a successful {@link Result}, or throws its error.
29
+ * @param result The result to unwrap.
30
+ * @returns The contained data.
31
+ * @throws {NotificationError} The result's error (wrapped when it is not already an `Error`).
32
+ */
33
33
  declare const unwrap: <T>(result: Result<T>) => T;
34
34
  /**
35
- * Returns the data of a successful {@link Result}, or a fallback when it failed.
36
- * @param result The result to unwrap.
37
- * @param fallback The value to return on failure.
38
- * @returns The data, or the fallback.
39
- */
35
+ * Returns the data of a successful {@link Result}, or a fallback when it failed.
36
+ * @param result The result to unwrap.
37
+ * @param fallback The value to return on failure.
38
+ * @returns The data, or the fallback.
39
+ */
40
40
  declare const unwrapOr: <T>(result: Result<T>, fallback: T) => T;
41
41
  /**
42
- * Maps the data of a successful {@link Result}, passing failures through unchanged.
43
- * @param result The result to map.
44
- * @param function_ The mapper applied to the data on success.
45
- * @returns A new result with the mapped data, or the original failure.
46
- */
42
+ * Maps the data of a successful {@link Result}, passing failures through unchanged.
43
+ * @param result The result to map.
44
+ * @param function_ The mapper applied to the data on success.
45
+ * @returns A new result with the mapped data, or the original failure.
46
+ */
47
47
  declare const mapOk: <T, U>(result: Result<T>, function_: (data: T) => U) => Result<U>;
48
48
  /**
49
- * Runs an async function and captures its outcome as a {@link Result}, never throwing.
50
- * @param function_ The async function to run.
51
- * @returns A successful result with the value, or a failed result with the thrown error.
52
- */
49
+ * Runs an async function and captures its outcome as a {@link Result}, never throwing.
50
+ * @param function_ The async function to run.
51
+ * @returns A successful result with the value, or a failed result with the thrown error.
52
+ */
53
53
  declare const tryAsync: <T>(function_: () => Promise<T>) => Promise<Result<T>>;
54
54
  export { FailResult, OkResult, isErr, isOk, mapOk, tryAsync, unwrap, unwrapOr };
@@ -1 +1 @@
1
- import e from"../packem_shared/NotificationError-DVfMJQ1u.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,110 +1,110 @@
1
- import { N as NotificationEvent } from "../packem_shared/types.d-GUzX1jTk.js";
1
+ import { N as NotificationEvent } from "../packem_shared/types.d-C7l7qdMG.js";
2
2
  /**
3
- * Computes an HMAC over `message` and returns the lowercase hex digest.
4
- * @param key The shared secret (UTF-8 string) or raw key bytes.
5
- * @param message The message to sign.
6
- * @param hash The hash algorithm (`"SHA-1"` or `"SHA-256"`).
7
- * @returns The hex-encoded HMAC.
8
- */
3
+ * Computes an HMAC over `message` and returns the lowercase hex digest.
4
+ * @param key The shared secret (UTF-8 string) or raw key bytes.
5
+ * @param message The message to sign.
6
+ * @param hash The hash algorithm (`"SHA-1"` or `"SHA-256"`).
7
+ * @returns The hex-encoded HMAC.
8
+ */
9
9
  declare const hmacHex: (key: string | Uint8Array, message: string, hash: "SHA-1" | "SHA-256") => Promise<string>;
10
10
  /**
11
- * Computes an HMAC over `message` and returns the base64 digest.
12
- * @param key The shared secret (UTF-8 string) or raw key bytes.
13
- * @param message The message to sign.
14
- * @param hash The hash algorithm (`"SHA-1"` or `"SHA-256"`).
15
- * @returns The base64-encoded HMAC.
16
- */
11
+ * Computes an HMAC over `message` and returns the base64 digest.
12
+ * @param key The shared secret (UTF-8 string) or raw key bytes.
13
+ * @param message The message to sign.
14
+ * @param hash The hash algorithm (`"SHA-1"` or `"SHA-256"`).
15
+ * @returns The base64-encoded HMAC.
16
+ */
17
17
  declare const hmacBase64: (key: string | Uint8Array, message: string, hash: "SHA-1" | "SHA-256") => Promise<string>;
18
18
  /**
19
- * Constant-time string comparison to avoid leaking match position via timing.
20
- *
21
- * Both inputs are compared in full; the function returns early only on length
22
- * mismatch (which is not secret).
23
- * @param a The first string.
24
- * @param b The second string.
25
- * @returns `true` when the strings are equal.
26
- */
19
+ * Constant-time string comparison to avoid leaking match position via timing.
20
+ *
21
+ * Both inputs are compared in full; the function returns early only on length
22
+ * mismatch (which is not secret).
23
+ * @param a The first string.
24
+ * @param b The second string.
25
+ * @returns `true` when the strings are equal.
26
+ */
27
27
  declare const timingSafeEqual: (a: string, b: string) => boolean;
28
28
  /**
29
- * Case-insensitive map of inbound request headers. Values may be a single string or
30
- * an array (mirroring `node:http` and `Headers`); verifiers normalise both forms.
31
- */
29
+ * Case-insensitive map of inbound request headers. Values may be a single string or
30
+ * an array (mirroring `node:http` and `Headers`); verifiers normalise both forms.
31
+ */
32
32
  type WebhookHeaders = Record<string, string | string[] | undefined>;
33
33
  /**
34
- * A provider inbound-webhook verifier: validates the request signature and normalises
35
- * the body into a {@link NotificationEvent}.
36
- */
34
+ * A provider inbound-webhook verifier: validates the request signature and normalises
35
+ * the body into a {@link NotificationEvent}.
36
+ */
37
37
  interface WebhookVerifier {
38
38
  /**
39
- * Normalises a verified webhook body into a {@link NotificationEvent}.
40
- * @param body The raw request body (string).
41
- * @returns The normalised event, or `undefined` when the body is not a delivery event.
42
- */
39
+ * Normalises a verified webhook body into a {@link NotificationEvent}.
40
+ * @param body The raw request body (string).
41
+ * @returns The normalised event, or `undefined` when the body is not a delivery event.
42
+ */
43
43
  parse: (body: string) => NotificationEvent | undefined;
44
44
  /**
45
- * Verifies the request signature against the shared secret.
46
- * @param payload The raw request body (string).
47
- * @param headers The inbound request headers.
48
- * @param secret The provider signing secret / auth token.
49
- * @returns `true` when the signature is valid.
50
- */
45
+ * Verifies the request signature against the shared secret.
46
+ * @param payload The raw request body (string).
47
+ * @param headers The inbound request headers.
48
+ * @param secret The provider signing secret / auth token.
49
+ * @returns `true` when the signature is valid.
50
+ */
51
51
  verify: (payload: string, headers: WebhookHeaders, secret: string) => Promise<boolean>;
52
52
  }
53
53
  /**
54
- * Reads a header value case-insensitively, coercing array values to their first entry.
55
- * @param headers The inbound headers.
56
- * @param name The header name to read.
57
- * @returns The header value, or `undefined` when absent.
58
- */
54
+ * Reads a header value case-insensitively, coercing array values to their first entry.
55
+ * @param headers The inbound headers.
56
+ * @param name The header name to read.
57
+ * @returns The header value, or `undefined` when absent.
58
+ */
59
59
  declare const getHeader: (headers: WebhookHeaders, name: string) => string | undefined;
60
60
  /**
61
- * Verifier + parser for Slack event/interaction webhooks.
62
- *
63
- * Verification follows Slack's v0 signing scheme: the signature is
64
- * `v0=` + hex HMAC-SHA256 (keyed by the signing secret) of `v0:{timestamp}:{body}`.
65
- * The request timestamp is checked against a 5-minute replay window. Edge-safe — uses
66
- * Web Crypto only.
67
- */
61
+ * Verifier + parser for Slack event/interaction webhooks.
62
+ *
63
+ * Verification follows Slack's v0 signing scheme: the signature is
64
+ * `v0=` + hex HMAC-SHA256 (keyed by the signing secret) of `v0:{timestamp}:{body}`.
65
+ * The request timestamp is checked against a 5-minute replay window. Edge-safe — uses
66
+ * Web Crypto only.
67
+ */
68
68
  declare const slackWebhook: WebhookVerifier;
69
69
  /**
70
- * Verifier + parser for AWS SNS HTTP/S subscription deliveries.
71
- *
72
- * NOTE: signature verification is NOT yet implemented. Real verification requires
73
- * fetching the X.509 certificate at `SigningCertURL`, validating its cert chain back to
74
- * an Amazon root, and checking the RSA-SHA1/RSA-SHA256 signature over the canonical
75
- * string-to-sign (SignatureVersion 1 and 2). Until that lands, {@link snsWebhook.verify}
76
- * fails closed and always returns `false` — accepting a payload purely on its structure
77
- * (a `Signature` field plus an `sns.*.amazonaws.com` `SigningCertURL`) is an auth bypass,
78
- * since both are attacker-controllable. `parse` remains available for callers that have
79
- * verified the message out-of-band. Callers handling `SubscriptionConfirmation` should
80
- * confirm the subscription by requesting the `SubscribeURL` from the parsed metadata.
81
- * Edge-safe — performs no `node:*` work.
82
- *
83
- * TODO: implement RSA-SHA1/RSA-SHA256 verification of the canonical string-to-sign
84
- * against the fetched signing certificate (SignatureVersion 1 and 2).
85
- */
70
+ * Verifier + parser for AWS SNS HTTP/S subscription deliveries.
71
+ *
72
+ * NOTE: signature verification is NOT yet implemented. Real verification requires
73
+ * fetching the X.509 certificate at `SigningCertURL`, validating its cert chain back to
74
+ * an Amazon root, and checking the RSA-SHA1/RSA-SHA256 signature over the canonical
75
+ * string-to-sign (SignatureVersion 1 and 2). Until that lands, {@link snsWebhook.verify}
76
+ * fails closed and always returns `false` — accepting a payload purely on its structure
77
+ * (a `Signature` field plus an `sns.*.amazonaws.com` `SigningCertURL`) is an auth bypass,
78
+ * since both are attacker-controllable. `parse` remains available for callers that have
79
+ * verified the message out-of-band. Callers handling `SubscriptionConfirmation` should
80
+ * confirm the subscription by requesting the `SubscribeURL` from the parsed metadata.
81
+ * Edge-safe — performs no `node:*` work.
82
+ *
83
+ * TODO: implement RSA-SHA1/RSA-SHA256 verification of the canonical string-to-sign
84
+ * against the fetched signing certificate (SignatureVersion 1 and 2).
85
+ */
86
86
  declare const snsWebhook: WebhookVerifier;
87
87
  /**
88
- * Verifier + parser implementing the generic
89
- * [Standard Webhooks](https://www.standardwebhooks.com/) HMAC scheme.
90
- *
91
- * The signed content is `{id}.{timestamp}.{body}`; the signature is the base64
92
- * HMAC-SHA256 prefixed with `v1,`. The `webhook-signature` header may carry several
93
- * space-separated signatures (key rotation) — verification passes when any matches.
94
- * If the secret begins with `whsec_`, the base64 remainder is decoded to raw key bytes
95
- * and the HMAC is keyed with those bytes (per the spec); otherwise the raw secret string
96
- * is used directly. A hex digest is also accepted as a fallback for non-conformant
97
- * senders. Edge-safe — uses Web Crypto only.
98
- */
88
+ * Verifier + parser implementing the generic
89
+ * [Standard Webhooks](https://www.standardwebhooks.com/) HMAC scheme.
90
+ *
91
+ * The signed content is `{id}.{timestamp}.{body}`; the signature is the base64
92
+ * HMAC-SHA256 prefixed with `v1,`. The `webhook-signature` header may carry several
93
+ * space-separated signatures (key rotation) — verification passes when any matches.
94
+ * If the secret begins with `whsec_`, the base64 remainder is decoded to raw key bytes
95
+ * and the HMAC is keyed with those bytes (per the spec); otherwise the raw secret string
96
+ * is used directly. A hex digest is also accepted as a fallback for non-conformant
97
+ * senders. Edge-safe — uses Web Crypto only.
98
+ */
99
99
  declare const standardWebhook: WebhookVerifier;
100
100
  /**
101
- * Verifier + parser for Twilio status-callback webhooks.
102
- *
103
- * Verification follows Twilio's scheme: `X-Twilio-Signature` is the base64 HMAC-SHA1
104
- * (keyed by the auth token) of the request URL concatenated with the form parameters
105
- * sorted by key. The full request URL must be provided via the
106
- * `x-twilio-signature-url` header (the verifier cannot reconstruct it from the body).
107
- * Edge-safe — uses Web Crypto only.
108
- */
101
+ * Verifier + parser for Twilio status-callback webhooks.
102
+ *
103
+ * Verification follows Twilio's scheme: `X-Twilio-Signature` is the base64 HMAC-SHA1
104
+ * (keyed by the auth token) of the request URL concatenated with the form parameters
105
+ * sorted by key. The full request URL must be provided via the
106
+ * `x-twilio-signature-url` header (the verifier cannot reconstruct it from the body).
107
+ * Edge-safe — uses Web Crypto only.
108
+ */
109
109
  declare const twilioWebhook: WebhookVerifier;
110
110
  export { type WebhookHeaders, type WebhookVerifier, getHeader, hmacBase64, hmacHex, slackWebhook, snsWebhook, standardWebhook, timingSafeEqual, twilioWebhook };
@@ -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,9 +1,9 @@
1
- import { M as MaybePromise, D as Duration, W as WorkflowConfig, a as WorkflowDefinition } from "../packem_shared/types.d-C1GoEAlI.d-Bv3grfyD.js";
1
+ import { M as MaybePromise, D as Duration, W as WorkflowConfig, a as WorkflowDefinition } from "../packem_shared/types.d-CcjfiGpo.d-DuZME7ry.js";
2
2
  import '@standard-schema/spec';
3
- import { C as ChannelPayloadMap, N as Notification } from "../packem_shared/notification.d-DFCVTods.js";
4
- import { C as ChannelType, c as Receipt } from "../packem_shared/types.d-GUzX1jTk.js";
5
- import "../packem_shared/types.d-CximoA8M.js";
6
- import "../packem_shared/provider.d-BQAGriz6.js";
3
+ import { C as ChannelPayloadMap, N as Notification } from "../packem_shared/notification.d-D0ado_cy.js";
4
+ import { C as ChannelType, c as Receipt } from "../packem_shared/types.d-C7l7qdMG.js";
5
+ import "../packem_shared/types.d-CRs03TYV.js";
6
+ import "../packem_shared/provider.d-Dh32nRm9.js";
7
7
  /** The context handed to a step resolver / skip predicate. */
8
8
  interface StepResolverContext<PayloadT> {
9
9
  /** The validated trigger payload of the run. */
@@ -16,27 +16,27 @@ interface ChannelStepOptions<PayloadT> {
16
16
  /** Skip the send when this returns `true`; the step records `undefined`. */
17
17
  skip?: (context: StepResolverContext<PayloadT>) => MaybePromise<boolean>;
18
18
  /**
19
- * Treat a `FailureReceipt` as a thrown error so the run fails and the step
20
- * re-runs on the next resume/sweep. Defaults to `false`.
21
- */
19
+ * Treat a `FailureReceipt` as a thrown error so the run fails and the step
20
+ * re-runs on the next resume/sweep. Defaults to `false`.
21
+ */
22
22
  throwOnFailure?: boolean;
23
23
  }
24
24
  /**
25
- * A durable channel step. Resolves a channel payload and delivers it through the
26
- * bound {@link Notification} facade exactly once; the receipt is recorded and
27
- * returned on replay without re-sending. Returns `undefined` when `skip` matches.
28
- *
29
- * IMPORTANT: a delivery failure surfaces as a `FailureReceipt` (the facade does not
30
- * throw), so by default a failed send is **recorded as a completed step and not
31
- * retried** — inspect `receipt.successful`, or pass `throwOnFailure: true` to turn
32
- * a failure into a thrown error that re-runs the step on the next activation.
33
- */
25
+ * A durable channel step. Resolves a channel payload and delivers it through the
26
+ * bound {@link Notification} facade exactly once; the receipt is recorded and
27
+ * returned on replay without re-sending. Returns `undefined` when `skip` matches.
28
+ *
29
+ * IMPORTANT: a delivery failure surfaces as a `FailureReceipt` (the facade does not
30
+ * throw), so by default a failed send is **recorded as a completed step and not
31
+ * retried** — inspect `receipt.successful`, or pass `throwOnFailure: true` to turn
32
+ * a failure into a thrown error that re-runs the step on the next activation.
33
+ */
34
34
  type ChannelStep<ChannelT extends ChannelType, PayloadT> = (id: string, resolve: StepResolver<PayloadT, ChannelPayloadMap[ChannelT]>, options?: ChannelStepOptions<PayloadT>) => Promise<Receipt | undefined>;
35
35
  /**
36
- * The `step` object handed to a notification workflow body. Channel steps deliver
37
- * exactly once; `delay` pauses durably; `custom` is an escape hatch to the raw
38
- * engine step.
39
- */
36
+ * The `step` object handed to a notification workflow body. Channel steps deliver
37
+ * exactly once; `delay` pauses durably; `custom` is an escape hatch to the raw
38
+ * engine step.
39
+ */
40
40
  interface NotificationStep<PayloadT> {
41
41
  chat: ChannelStep<"chat", PayloadT>;
42
42
  custom: <T>(id: string, function_: () => MaybePromise<T>) => Promise<T>;
@@ -58,26 +58,26 @@ interface NotificationWorkflowConfig<PayloadT, OutputT> extends Omit<WorkflowCon
58
58
  run: NotificationWorkflowRun<PayloadT, OutputT>;
59
59
  }
60
60
  /**
61
- * Define a durable notification workflow on top of [`@visulima/workflow`](https://visulima.com/packages/workflow).
62
- *
63
- * The returned value is a plain `WorkflowDefinition`, so it plugs straight into a
64
- * workflow runtime (`createRuntime({ workflows: [wf] })` → `runtime.trigger(wf, payload)`).
65
- * Channel steps deliver through the bound `notification` facade exactly once.
66
- * @param notification The multi-channel facade messages are delivered through.
67
- * @param config The workflow id, optional payload schema, and notification-flavoured `run`.
68
- * @returns A {@link WorkflowDefinition} ready to register/trigger on a runtime.
69
- * @example
70
- * ```ts
71
- * const onComment = createNotificationWorkflow(notify, {
72
- * id: "comment-posted",
73
- * payload: z.object({ subscriberId: z.string(), author: z.string() }),
74
- * run: async ({ step, payload }) => {
75
- * await step.inApp("inbox", () => ({ to: payload.subscriberId, body: `${payload.author} commented` }));
76
- * await step.delay("cooldown", { amount: 1, unit: "hours" });
77
- * await step.email("nudge", () => ({ from: "x@y.com", to: payload.subscriberId, subject: "New comment", html: "<p>…</p>" }));
78
- * },
79
- * });
80
- * ```
81
- */
61
+ * Define a durable notification workflow on top of [`@visulima/workflow`](https://visulima.com/packages/workflow).
62
+ *
63
+ * The returned value is a plain `WorkflowDefinition`, so it plugs straight into a
64
+ * workflow runtime (`createRuntime({ workflows: [wf] })` → `runtime.trigger(wf, payload)`).
65
+ * Channel steps deliver through the bound `notification` facade exactly once.
66
+ * @param notification The multi-channel facade messages are delivered through.
67
+ * @param config The workflow id, optional payload schema, and notification-flavoured `run`.
68
+ * @returns A {@link WorkflowDefinition} ready to register/trigger on a runtime.
69
+ * @example
70
+ * ```ts
71
+ * const onComment = createNotificationWorkflow(notify, {
72
+ * id: "comment-posted",
73
+ * payload: z.object({ subscriberId: z.string(), author: z.string() }),
74
+ * run: async ({ step, payload }) => {
75
+ * await step.inApp("inbox", () => ({ to: payload.subscriberId, body: `${payload.author} commented` }));
76
+ * await step.delay("cooldown", { amount: 1, unit: "hours" });
77
+ * await step.email("nudge", () => ({ from: "x@y.com", to: payload.subscriberId, subject: "New comment", html: "<p>…</p>" }));
78
+ * },
79
+ * });
80
+ * ```
81
+ */
82
82
  declare const createNotificationWorkflow: <PayloadT = unknown, OutputT = unknown>(notification: Notification, config: NotificationWorkflowConfig<PayloadT, OutputT>) => WorkflowDefinition<PayloadT, OutputT>;
83
83
  export { type ChannelStep, type ChannelStepOptions, type NotificationStep, type NotificationWorkflowConfig, type NotificationWorkflowRun, type StepResolver, type StepResolverContext, createNotificationWorkflow };
@@ -1 +1 @@
1
- import{default as a}from"../packem_shared/createNotificationWorkflow-B70OgeED.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.9",
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.6",
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-DVfMJQ1u.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 h}from"node:module";const d=h(import.meta.url),t=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,m=o=>{if(typeof t<"u"&&t.versions&&t.versions.node){const[e,r]=t.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return t.getBuiltinModule(o)}return d(o)},{createRequire:c}=m("node:module"),f=new Map([["Error",Error],["EvalError",EvalError],["RangeError",RangeError],["ReferenceError",ReferenceError],["SyntaxError",SyntaxError],["TypeError",TypeError],["URIError",URIError]]);typeof AggregateError<"u"&&f.set("AggregateError",AggregateError);const E=c(import.meta.url),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,y=o=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[e,r]=i.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return i.getBuiltinModule(o)}return E(o)};y("node:util");class b extends Error{loc;title;hint;type="VisulimaError";constructor({cause:e,hint:r,location:s,message:l,name:u,stack:p,title:g}){super(l,{cause:e}),this.title=g,this.name=u,this.stack=p??this.stack,this.loc=s,this.hint=r}setLocation(e){this.loc=e}setName(e){this.name=e}setMessage(e){this.message=e}setHint(e){this.hint=e}}const v=c(import.meta.url),n=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,a=o=>{if(typeof n<"u"&&n.versions&&n.versions.node){const[e,r]=n.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return n.getBuiltinModule(o)}return v(o)};a("node:fs");a("node:path");a("node:url");class T extends b{component;code;constructor(e,r,s){super({cause:s?.cause,hint:s?.hint,message:`[@visulima/notification] [${e}] ${r}`,name:"NotificationError",title:`Notification ${e} Error`}),this.component=e,this.code=s?.code}}export{T as default};
@@ -1 +0,0 @@
1
- import{createRequire as I}from"node:module";import g from"./RequiredOptionError-CuL42XRq.js";import{defineProvider as j}from"./defineProvider-C9q-7iwt.js";import{t as k}from"./credentials-CG0zkn-W.js";import{a as N}from"./sms-CU-OZvNU.js";const S=I(import.meta.url),f=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,y=o=>{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(o)}return S(o)},{sign:T,createPrivateKey:$}=y("node:crypto"),{connect:P}=y("node:http2"),J="https://api.push.apple.com",K="https://api.sandbox.push.apple.com",O=3e3*1e3,R=200,h=o=>Buffer.from(o,"utf8").toString("base64url"),q=(o,t,r)=>{const l=h(JSON.stringify({alg:"ES256",kid:o.keyId,typ:"JWT"})),c=h(JSON.stringify({iat:r,iss:o.teamId})),u=`${l}.${c}`,n=T("sha256",Buffer.from(u,"utf8"),{dsaEncoding:"ieee-p1363",key:t}).toString("base64url");return`${u}.${n}`},z=j(o=>{const t=o??{};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?J:K;let l,c,u=0,n;const b=()=>(l??=$({format:"pem",key:t.signingKey}),l),w=()=>{const e=Date.now();return(!c||e-u>O)&&(c=q(t,b(),Math.floor(e/1e3)),u=e),c},_=()=>((!n||n.closed||n.destroyed)&&(n=P(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=_().request({":method":"POST",":path":`/3/device/${e}`,"apns-topic":t.bundleId,authorization:`bearer ${w()}`,"content-type":"application/json"});let d=0,p="";i.setEncoding("utf8"),i.on("response",s=>{d=s[":status"]??0}),i.on("data",s=>{p+=s}),i.on("error",s=>{a({error:s.message,id:e,status:"failed"})}),i.on("end",()=>{if(d===R){a({id:e,messageId:e,status:"sent"});return}let s=`HTTP ${String(d)}`;if(p)try{s=JSON.parse(p).reason??s}catch{s=p}a({error:s,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=k(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 p of m)d.push(await v(p,i));return N("push","apns",d)},shutdown:()=>{n&&!n.closed&&n.close(),n=void 0}}});export{z 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-DVfMJQ1u.js";import d from"./RequiredOptionError-CuL42XRq.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};