@visulima/notification 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +14 -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-B22tuJPy.js → Notification-DH2mcFWI.js} +1 -1
  16. package/dist/packem_shared/NotificationError-B8CyoEaX.js +1 -0
  17. package/dist/packem_shared/{RequiredOptionError-CuL42XRq.js → RequiredOptionError-Bs282gKK.js} +1 -1
  18. package/dist/packem_shared/apnsProvider-BPH0pHvd.js +1 -0
  19. package/dist/packem_shared/{circuitBreakerMiddleware-BlZN7SVT.js → circuitBreakerMiddleware-CRBi0H7e.js} +1 -1
  20. package/dist/packem_shared/{createDigester-vMNPejGF.js → createDigester-DenmT8_X.js} +1 -1
  21. package/dist/packem_shared/{createNotificationWorkflow-B70OgeED.js → createNotificationWorkflow-5AY-ays0.js} +1 -1
  22. package/dist/packem_shared/{createTranslator-CY91C2eS.js → createTranslator-ByyvYNfG.js} +1 -1
  23. package/dist/packem_shared/{discordProvider-BhfXcCcI.js → discordProvider-BvKwrC8K.js} +1 -1
  24. package/dist/packem_shared/{emailChannel-CNDlX96Q.js → emailChannel-Cf8wZPZL.js} +1 -1
  25. package/dist/packem_shared/{expoProvider-DsZR4sUk.js → expoProvider-13gY7Ne8.js} +1 -1
  26. package/dist/packem_shared/{failoverProvider-D1dAmW8U.js → failoverProvider-DXcwmYev.js} +1 -1
  27. package/dist/packem_shared/{fcmProvider-DWRx8XBv.js → fcmProvider-DsGjzBzz.js} +1 -1
  28. package/dist/packem_shared/{messageBirdProvider-BfiTaNLn.js → messageBirdProvider-D1c3jUqj.js} +1 -1
  29. package/dist/packem_shared/{mockProvider-BLwTZlkw.js → mockProvider-DZ3immtm.js} +1 -1
  30. package/dist/packem_shared/{msTeamsProvider-DrmL3RYX.js → msTeamsProvider-Cd-BUhH1.js} +1 -1
  31. package/dist/packem_shared/notification.d-D0ado_cy.d.ts +104 -0
  32. package/dist/packem_shared/{plivoProvider-Dr8d5yD3.js → plivoProvider-C_koQ8X-.js} +1 -1
  33. package/dist/packem_shared/{provider.d-BQAGriz6.d.ts → provider.d-Dh32nRm9.d.ts} +10 -10
  34. package/dist/packem_shared/{roundRobinProvider-BetXJUUm.js → roundRobinProvider-CK3Vyc_u.js} +1 -1
  35. package/dist/packem_shared/{slackProvider-DPG1IlA0.js → slackProvider-B92QDf3e.js} +1 -1
  36. package/dist/packem_shared/{sms-CU-OZvNU.js → sms-64HGUCLu.js} +1 -1
  37. package/dist/packem_shared/{snsProvider-C2T2UxDK.js → snsProvider-CPGjOUP_.js} +1 -1
  38. package/dist/packem_shared/{telegramProvider-wyx3ksVm.js → telegramProvider-BmmroM5A.js} +1 -1
  39. package/dist/packem_shared/{telnyxProvider-jgpEwgPh.js → telnyxProvider-C41tE4VF.js} +1 -1
  40. package/dist/packem_shared/{tracer.d-Co1s_NwG.d.ts → tracer.d-BPznIQx9.d.ts} +2 -2
  41. package/dist/packem_shared/{twilioProvider-DMYWqvgZ.js → twilioProvider-DanDTzi3.js} +1 -1
  42. package/dist/packem_shared/{types.d-67TogK4k.d.ts → types.d--kw9ifOI.d.ts} +6 -6
  43. package/dist/packem_shared/types.d-BU-37j3S.d.ts +10 -0
  44. package/dist/packem_shared/{types.d-GUzX1jTk.d.ts → types.d-C7l7qdMG.d.ts} +52 -52
  45. package/dist/packem_shared/{types.d-CximoA8M.d.ts → types.d-CRs03TYV.d.ts} +13 -13
  46. package/dist/packem_shared/{types.d-C1GoEAlI.d-Bv3grfyD.d.ts → types.d-CcjfiGpo.d-DuZME7ry.d.ts} +27 -34
  47. package/dist/packem_shared/{vonageProvider-CT4KoWXu.js → vonageProvider-epeGBWW8.js} +1 -1
  48. package/dist/packem_shared/{webPushProvider-DwjmWASr.js → webPushProvider-K6-Drhaf.js} +1 -1
  49. package/dist/packem_shared/{webhookProvider-CPA1nKXJ.js → webhookProvider-DlwFyaGc.js} +1 -1
  50. package/dist/preferences/index.d.ts +19 -19
  51. package/dist/providers/chat/discord/index.d.ts +5 -5
  52. package/dist/providers/chat/discord/index.js +1 -1
  53. package/dist/providers/chat/msteams/index.d.ts +7 -7
  54. package/dist/providers/chat/msteams/index.js +1 -1
  55. package/dist/providers/chat/slack/index.d.ts +6 -6
  56. package/dist/providers/chat/slack/index.js +1 -1
  57. package/dist/providers/chat/telegram/index.d.ts +5 -5
  58. package/dist/providers/chat/telegram/index.js +1 -1
  59. package/dist/providers/failover/index.d.ts +7 -7
  60. package/dist/providers/failover/index.js +1 -1
  61. package/dist/providers/mock/index.d.ts +5 -5
  62. package/dist/providers/mock/index.js +1 -1
  63. package/dist/providers/opentelemetry/index.d.ts +14 -14
  64. package/dist/providers/push/apns/index.d.ts +9 -9
  65. package/dist/providers/push/apns/index.js +1 -1
  66. package/dist/providers/push/expo/index.d.ts +5 -5
  67. package/dist/providers/push/expo/index.js +1 -1
  68. package/dist/providers/push/fcm/index.d.ts +13 -13
  69. package/dist/providers/push/fcm/index.js +1 -1
  70. package/dist/providers/push/web-push/index.d.ts +11 -11
  71. package/dist/providers/push/web-push/index.js +1 -1
  72. package/dist/providers/roundrobin/index.d.ts +8 -8
  73. package/dist/providers/roundrobin/index.js +1 -1
  74. package/dist/providers/sms/messagebird/index.d.ts +5 -5
  75. package/dist/providers/sms/messagebird/index.js +1 -1
  76. package/dist/providers/sms/plivo/index.d.ts +5 -5
  77. package/dist/providers/sms/plivo/index.js +1 -1
  78. package/dist/providers/sms/sns/index.d.ts +6 -6
  79. package/dist/providers/sms/sns/index.js +1 -1
  80. package/dist/providers/sms/telnyx/index.d.ts +5 -5
  81. package/dist/providers/sms/telnyx/index.js +1 -1
  82. package/dist/providers/sms/twilio/index.d.ts +5 -5
  83. package/dist/providers/sms/twilio/index.js +1 -1
  84. package/dist/providers/sms/vonage/index.d.ts +5 -5
  85. package/dist/providers/sms/vonage/index.js +1 -1
  86. package/dist/providers/webhook/index.d.ts +7 -7
  87. package/dist/providers/webhook/index.js +1 -1
  88. package/dist/queue/bullmq-queue.d.ts +24 -24
  89. package/dist/queue/index.d.ts +15 -15
  90. package/dist/queue/pg-boss-queue.d.ts +26 -26
  91. package/dist/queue/sqs-queue.d.ts +27 -27
  92. package/dist/queue/unstorage-queue.d.ts +14 -14
  93. package/dist/routing/index.d.ts +22 -22
  94. package/dist/template-engines/handlebars.d.ts +13 -13
  95. package/dist/template-engines/handlebars.js +1 -1
  96. package/dist/template-engines/liquid.d.ts +13 -13
  97. package/dist/template-engines/liquid.js +1 -1
  98. package/dist/template-engines/string.d.ts +17 -17
  99. package/dist/utils/result.d.ts +32 -32
  100. package/dist/utils/result.js +1 -1
  101. package/dist/webhooks/index.d.ts +84 -84
  102. package/dist/workflow/index.d.ts +42 -42
  103. package/dist/workflow/index.js +1 -1
  104. package/package.json +2 -2
  105. package/dist/packem_shared/NotificationError-DVfMJQ1u.js +0 -1
  106. package/dist/packem_shared/apnsProvider-C9WSv5sc.js +0 -1
  107. package/dist/packem_shared/notification.d-DFCVTods.d.ts +0 -104
  108. package/dist/packem_shared/types.d-td-F2Oh0.d.ts +0 -10
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { type M as Middleware, type S as SendContext, type a as SendFunction, c as composeMiddleware } from "./packem_shared/types.d-CximoA8M.js";
2
- import { C as ChannelPayloadMap, a as NotificationMessage } from "./packem_shared/notification.d-DFCVTods.js";
3
- export { N as Notification, type b as NotificationProviders, type S as SendManyOptions, c as createNotification, s as send } from "./packem_shared/notification.d-DFCVTods.js";
4
- export { type P as Provider, type a as ProviderFactory, d as defineProvider } from "./packem_shared/provider.d-BQAGriz6.js";
5
- export type { d as BaseConfig, B as BaseNotificationPayload, C as ChannelType, b as ChatPayload, f as EmailAddressLike, E as EmailChannelPayload, g as FailureReceipt, F as FeatureFlags, I as InAppPayload, M as MaybePromise, N as NotificationEvent, e as NotificationEventType, h as NotificationPayload, a as NotificationResult, P as PushPayload, c as Receipt, i as RecipientResult, R as Result, S as SmsPayload, j as SuccessReceipt, W as WebhookPayload } from "./packem_shared/types.d-GUzX1jTk.js";
1
+ export { type M as Middleware, type S as SendContext, type a as SendFunction, c as composeMiddleware } from "./packem_shared/types.d-CRs03TYV.js";
2
+ import { C as ChannelPayloadMap, a as NotificationMessage } from "./packem_shared/notification.d-D0ado_cy.js";
3
+ export { N as Notification, type b as NotificationProviders, type S as SendManyOptions, c as createNotification, s as send } from "./packem_shared/notification.d-D0ado_cy.js";
4
+ export { type P as Provider, type a as ProviderFactory, d as defineProvider } from "./packem_shared/provider.d-Dh32nRm9.js";
5
+ export type { d as BaseConfig, B as BaseNotificationPayload, C as ChannelType, b as ChatPayload, f as EmailAddressLike, E as EmailChannelPayload, g as FailureReceipt, F as FeatureFlags, I as InAppPayload, M as MaybePromise, N as NotificationEvent, e as NotificationEventType, h as NotificationPayload, a as NotificationResult, P as PushPayload, c as Receipt, i as RecipientResult, R as Result, S as SmsPayload, j as SuccessReceipt, W as WebhookPayload } from "./packem_shared/types.d-C7l7qdMG.js";
6
6
  interface ErrorProperties {
7
7
  cause?: unknown;
8
8
  hint?: ErrorHint;
@@ -18,55 +18,44 @@ interface ErrorLocation {
18
18
  line?: number;
19
19
  }
20
20
  /**
21
- * A message that explains to the user how they can fix the error.
22
- * @example
23
- * ```ts
24
- * const error = new VisulimaError({
25
- * hint: "Try running `npm install` to install missing dependencies.",
26
- * location: {
27
- * file: "src/index.ts",
28
- * line: 1,
29
- * column: 1,
30
- * },
31
- * message: "Cannot find module 'react'",
32
- * name: "ModuleNotFoundError",
33
- * });
34
- * ```
35
- *
36
- * For more complex hints, you can pass an array of strings or a single string in markdown format.
37
- */
21
+ * A message that explains to the user how they can fix the error.
22
+ * @example
23
+ * ```ts
24
+ * const error = new VisulimaError({
25
+ * hint: "Try running `npm install` to install missing dependencies.",
26
+ * location: {
27
+ * file: "src/index.ts",
28
+ * line: 1,
29
+ * column: 1,
30
+ * },
31
+ * message: "Cannot find module 'react'",
32
+ * name: "ModuleNotFoundError",
33
+ * });
34
+ * ```
35
+ *
36
+ * For more complex hints, you can pass an array of strings or a single string in markdown format.
37
+ */
38
38
  type ErrorHint = string[] | string;
39
39
  declare class VisulimaError extends Error {
40
40
  loc: ErrorLocation | undefined;
41
41
  title: string | undefined;
42
42
  /**
43
- * A message that explains to the user how they can fix the error.
44
- */
43
+ * A message that explains to the user how they can fix the error.
44
+ */
45
45
  hint: ErrorHint | undefined;
46
46
  type: string;
47
- constructor({
48
- cause,
49
- hint,
50
- location,
51
- message,
52
- name,
53
- stack,
54
- title
55
- }: ErrorProperties);
47
+ constructor({ cause, hint, location, message, name, stack, title }: ErrorProperties);
56
48
  setLocation(location: ErrorLocation): void;
57
49
  setName(name: string): void;
58
50
  setMessage(message: string): void;
59
51
  setHint(hint: ErrorHint): void;
60
52
  }
61
53
  /**
62
- * Will return an array of all causes in the error in the order they occurred.
63
- */
64
- /**
65
- * Base error class for notification package operations.
66
- * @param component The component name where the error occurred.
67
- * @param message The error message describing what went wrong.
68
- * @param options Optional error options including cause, code, and hint.
69
- */
54
+ * Base error class for notification package operations.
55
+ * @param component The component name where the error occurred.
56
+ * @param message The error message describing what went wrong.
57
+ * @param options Optional error options including cause, code, and hint.
58
+ */
70
59
  declare class NotificationError extends VisulimaError {
71
60
  readonly component: string;
72
61
  readonly code?: string;
@@ -77,98 +66,98 @@ declare class NotificationError extends VisulimaError {
77
66
  });
78
67
  }
79
68
  /**
80
- * Error for missing required options.
81
- * @param component The component name where the error occurred.
82
- * @param name The name(s) of the missing required option(s).
83
- */
69
+ * Error for missing required options.
70
+ * @param component The component name where the error occurred.
71
+ * @param name The name(s) of the missing required option(s).
72
+ */
84
73
  declare class RequiredOptionError extends NotificationError {
85
74
  constructor(component: string, name: string | string[]);
86
75
  }
87
76
  /**
88
- * Fluent builder for assembling a multi-channel {@link NotificationMessage}.
89
- *
90
- * Mirrors the ergonomics of `@visulima/email`'s `MailMessage`: chainable, per-channel
91
- * setters that accumulate a plain message object. It is a thin convenience over the
92
- * existing `NotificationMessage` shape and does not change the facade — `build()`
93
- * returns the exact object `Notification.send()` already accepts.
94
- * @example
95
- * ```ts
96
- * const message = createNotificationMessage()
97
- * .sms({ text: "your code is 123", to: "+15555550100" })
98
- * .push({ body: "deploy finished", title: "CI", to: "device-token" })
99
- * .idempotencyKey("deploy-42")
100
- * .build();
101
- *
102
- * await createNotification({ sms, push }).send(message);
103
- * ```
104
- */
77
+ * Fluent builder for assembling a multi-channel {@link NotificationMessage}.
78
+ *
79
+ * Mirrors the ergonomics of `@visulima/email`'s `MailMessage`: chainable, per-channel
80
+ * setters that accumulate a plain message object. It is a thin convenience over the
81
+ * existing `NotificationMessage` shape and does not change the facade — `build()`
82
+ * returns the exact object `Notification.send()` already accepts.
83
+ * @example
84
+ * ```ts
85
+ * const message = createNotificationMessage()
86
+ * .sms({ text: "your code is 123", to: "+15555550100" })
87
+ * .push({ body: "deploy finished", title: "CI", to: "device-token" })
88
+ * .idempotencyKey("deploy-42")
89
+ * .build();
90
+ *
91
+ * await createNotification({ sms, push }).send(message);
92
+ * ```
93
+ */
105
94
  declare class NotificationMessageBuilder {
106
95
  #private;
107
96
  /**
108
- * Sets the SMS payload for the message.
109
- * @param payload The SMS channel payload.
110
- * @returns This instance for method chaining.
111
- */
97
+ * Sets the SMS payload for the message.
98
+ * @param payload The SMS channel payload.
99
+ * @returns This instance for method chaining.
100
+ */
112
101
  sms(payload: ChannelPayloadMap["sms"]): this;
113
102
  /**
114
- * Sets the push payload for the message.
115
- * @param payload The push channel payload.
116
- * @returns This instance for method chaining.
117
- */
103
+ * Sets the push payload for the message.
104
+ * @param payload The push channel payload.
105
+ * @returns This instance for method chaining.
106
+ */
118
107
  push(payload: ChannelPayloadMap["push"]): this;
119
108
  /**
120
- * Sets the chat payload for the message.
121
- * @param payload The chat channel payload.
122
- * @returns This instance for method chaining.
123
- */
109
+ * Sets the chat payload for the message.
110
+ * @param payload The chat channel payload.
111
+ * @returns This instance for method chaining.
112
+ */
124
113
  chat(payload: ChannelPayloadMap["chat"]): this;
125
114
  /**
126
- * Sets the in-app inbox payload for the message.
127
- * @param payload The in-app channel payload.
128
- * @returns This instance for method chaining.
129
- */
115
+ * Sets the in-app inbox payload for the message.
116
+ * @param payload The in-app channel payload.
117
+ * @returns This instance for method chaining.
118
+ */
130
119
  inApp(payload: ChannelPayloadMap["inapp"]): this;
131
120
  /**
132
- * Sets the outbound webhook payload for the message.
133
- * @param payload The webhook channel payload.
134
- * @returns This instance for method chaining.
135
- */
121
+ * Sets the outbound webhook payload for the message.
122
+ * @param payload The webhook channel payload.
123
+ * @returns This instance for method chaining.
124
+ */
136
125
  webhook(payload: ChannelPayloadMap["webhook"]): this;
137
126
  /**
138
- * Sets the email payload for the message.
139
- * @param payload The email channel payload.
140
- * @returns This instance for method chaining.
141
- */
127
+ * Sets the email payload for the message.
128
+ * @param payload The email channel payload.
129
+ * @returns This instance for method chaining.
130
+ */
142
131
  email(payload: ChannelPayloadMap["email"]): this;
143
132
  /**
144
- * Sets metadata applied to every present channel payload at build time.
145
- *
146
- * Per-channel `metadata` already set on a payload takes precedence over these
147
- * builder-level values (the builder values are spread first).
148
- * @param metadata Arbitrary metadata to attach.
149
- * @returns This instance for method chaining.
150
- */
133
+ * Sets metadata applied to every present channel payload at build time.
134
+ *
135
+ * Per-channel `metadata` already set on a payload takes precedence over these
136
+ * builder-level values (the builder values are spread first).
137
+ * @param metadata Arbitrary metadata to attach.
138
+ * @returns This instance for method chaining.
139
+ */
151
140
  metadata(metadata: Record<string, unknown>): this;
152
141
  /**
153
- * Sets an idempotency key applied to every present channel payload at build time.
154
- *
155
- * A per-channel `idempotencyKey` already set on a payload takes precedence.
156
- * @param key The idempotency key used to dedupe retried sends.
157
- * @returns This instance for method chaining.
158
- */
142
+ * Sets an idempotency key applied to every present channel payload at build time.
143
+ *
144
+ * A per-channel `idempotencyKey` already set on a payload takes precedence.
145
+ * @param key The idempotency key used to dedupe retried sends.
146
+ * @returns This instance for method chaining.
147
+ */
159
148
  idempotencyKey(key: string): this;
160
149
  /**
161
- * Builds the plain {@link NotificationMessage}.
162
- *
163
- * Applies builder-level `metadata` / `idempotencyKey` to each present channel
164
- * payload without overriding values already set on the individual payloads.
165
- * @returns The assembled multi-channel message.
166
- */
150
+ * Builds the plain {@link NotificationMessage}.
151
+ *
152
+ * Applies builder-level `metadata` / `idempotencyKey` to each present channel
153
+ * payload without overriding values already set on the individual payloads.
154
+ * @returns The assembled multi-channel message.
155
+ */
167
156
  build(): NotificationMessage;
168
157
  }
169
158
  /**
170
- * Creates a new {@link NotificationMessageBuilder}.
171
- * @returns A fresh fluent message builder.
172
- */
159
+ * Creates a new {@link NotificationMessageBuilder}.
160
+ * @returns A fresh fluent message builder.
161
+ */
173
162
  declare const createNotificationMessage: () => NotificationMessageBuilder;
174
163
  export { type ChannelPayloadMap, NotificationError, type NotificationMessage, NotificationMessageBuilder, RequiredOptionError, createNotificationMessage };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{default as r}from"./packem_shared/NotificationError-DVfMJQ1u.js";import{default as t}from"./packem_shared/RequiredOptionError-CuL42XRq.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-B22tuJPy.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-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,45 +1,45 @@
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
  /** Options for {@link defineLayout}. */
3
3
  interface LayoutOptions {
4
4
  /**
5
- * The renderer used for the layout template. Defaults to the zero-dependency
6
- * `renderString` (`{{var}}`); pass the Handlebars/Liquid renderer for logic.
7
- */
5
+ * The renderer used for the layout template. Defaults to the zero-dependency
6
+ * `renderString` (`{{var}}`); pass the Handlebars/Liquid renderer for logic.
7
+ */
8
8
  render?: TemplateRenderer;
9
9
  /** Name of the slot variable the content is injected as. Defaults to `"content"`. */
10
10
  slot?: string;
11
11
  /**
12
- * The layout template. Must contain the slot placeholder (default `{{content}}`).
13
- * With the Handlebars renderer use the unescaped `{{{content}}}` so the already-
14
- * rendered HTML body is not double-escaped.
15
- */
12
+ * The layout template. Must contain the slot placeholder (default `{{content}}`).
13
+ * With the Handlebars renderer use the unescaped `{{{content}}}` so the already-
14
+ * rendered HTML body is not double-escaped.
15
+ */
16
16
  template: string;
17
17
  }
18
18
  /** A reusable layout: renders a content string into its slot, then renders the wrapper. */
19
19
  interface Layout {
20
20
  /**
21
- * Wrap `content` in the layout.
22
- * @param content The already-rendered body to inject into the slot.
23
- * @param variables Extra variables available to the layout template (e.g. `unsubscribeUrl`).
24
- */
21
+ * Wrap `content` in the layout.
22
+ * @param content The already-rendered body to inject into the slot.
23
+ * @param variables Extra variables available to the layout template (e.g. `unsubscribeUrl`).
24
+ */
25
25
  render: (content: string, variables?: Record<string, unknown>) => Promise<string>;
26
26
  }
27
27
  /**
28
- * Define a reusable content layout — shared chrome (header/footer/brand) with a
29
- * `{{content}}` slot the per-notification body drops into. Code-first and engine-
30
- * agnostic: it reuses the package's template renderers, so it stays edge-safe with
31
- * the default `renderString`.
32
- * @param options The layout template, optional renderer and slot name.
33
- * @returns A {@link Layout} whose `render(content, vars)` returns the wrapped string.
34
- * @example
35
- * ```ts
36
- * const branded = defineLayout({
37
- * template: `<table><tr><td>{{content}}</td></tr><tr><td><a href="{{unsubscribeUrl}}">unsubscribe</a></td></tr></table>`,
38
- * });
39
- *
40
- * const html = await branded.render("<p>Welcome!</p>", { unsubscribeUrl: "https://app/u/123" });
41
- * await notify.sendToChannel("email", { from, to, subject: "Hi", html });
42
- * ```
43
- */
28
+ * Define a reusable content layout — shared chrome (header/footer/brand) with a
29
+ * `{{content}}` slot the per-notification body drops into. Code-first and engine-
30
+ * agnostic: it reuses the package's template renderers, so it stays edge-safe with
31
+ * the default `renderString`.
32
+ * @param options The layout template, optional renderer and slot name.
33
+ * @returns A {@link Layout} whose `render(content, vars)` returns the wrapped string.
34
+ * @example
35
+ * ```ts
36
+ * const branded = defineLayout({
37
+ * template: `<table><tr><td>{{content}}</td></tr><tr><td><a href="{{unsubscribeUrl}}">unsubscribe</a></td></tr></table>`,
38
+ * });
39
+ *
40
+ * const html = await branded.render("<p>Welcome!</p>", { unsubscribeUrl: "https://app/u/123" });
41
+ * await notify.sendToChannel("email", { from, to, subject: "Hi", html });
42
+ * ```
43
+ */
44
44
  declare const defineLayout: (options: LayoutOptions) => Layout;
45
45
  export { type Layout, type LayoutOptions, defineLayout };
@@ -1,7 +1,7 @@
1
- import { M as Middleware, S as SendContext } from "../packem_shared/types.d-CximoA8M.js";
2
- export { type a as SendFunction, c as composeMiddleware } from "../packem_shared/types.d-CximoA8M.js";
3
- import { C as ChannelType, B as BaseNotificationPayload } from "../packem_shared/types.d-GUzX1jTk.js";
4
- import { A as Attributes, C as Context, T as Tracer } from "../packem_shared/tracer.d-Co1s_NwG.js";
1
+ import { M as Middleware, S as SendContext } from "../packem_shared/types.d-CRs03TYV.js";
2
+ export { type a as SendFunction, c as composeMiddleware } from "../packem_shared/types.d-CRs03TYV.js";
3
+ import { C as ChannelType, B as BaseNotificationPayload } from "../packem_shared/types.d-C7l7qdMG.js";
4
+ import { A as Attributes, C as Context, T as Tracer } from "../packem_shared/tracer.d-BPznIQx9.js";
5
5
  interface CircuitBreakerMiddlewareOptions {
6
6
  /** Time in ms the circuit stays open before a trial request (default 30000). */
7
7
  resetTimeout?: number;
@@ -9,11 +9,11 @@ interface CircuitBreakerMiddlewareOptions {
9
9
  threshold?: number;
10
10
  }
11
11
  /**
12
- * Trips a circuit after consecutive failures, short-circuiting further sends until a
13
- * cool-off elapses (then allows a single trial request).
14
- * @param options Failure `threshold` and open-circuit `resetTimeout` (ms).
15
- * @returns A middleware.
16
- */
12
+ * Trips a circuit after consecutive failures, short-circuiting further sends until a
13
+ * cool-off elapses (then allows a single trial request).
14
+ * @param options Failure `threshold` and open-circuit `resetTimeout` (ms).
15
+ * @returns A middleware.
16
+ */
17
17
  declare const circuitBreakerMiddleware: (options?: CircuitBreakerMiddlewareOptions) => Middleware;
18
18
  interface DedupeMiddlewareOptions {
19
19
  /** Derive the dedupe key (default: `payload.idempotencyKey`). */
@@ -22,21 +22,21 @@ interface DedupeMiddlewareOptions {
22
22
  ttl?: number;
23
23
  }
24
24
  /**
25
- * Suppresses duplicate sends within a TTL window, keyed by idempotency key. A suppressed
26
- * send resolves successfully with `sent: false` and a `deduped:` message id.
27
- * @param options Custom `keyFn` and `ttl` (ms) controlling how keys are derived and expire.
28
- * @returns A middleware.
29
- */
25
+ * Suppresses duplicate sends within a TTL window, keyed by idempotency key. A suppressed
26
+ * send resolves successfully with `sent: false` and a `deduped:` message id.
27
+ * @param options Custom `keyFn` and `ttl` (ms) controlling how keys are derived and expire.
28
+ * @returns A middleware.
29
+ */
30
30
  declare const dedupeMiddleware: (options?: DedupeMiddlewareOptions) => Middleware;
31
31
  interface LoggingMiddlewareOptions {
32
32
  /** Console-like logger (default `console`). */
33
33
  logger?: Console;
34
34
  }
35
35
  /**
36
- * Logs each send attempt and its outcome.
37
- * @param options Provide a custom console-like `logger` (defaults to the global console).
38
- * @returns A middleware.
39
- */
36
+ * Logs each send attempt and its outcome.
37
+ * @param options Provide a custom console-like `logger` (defaults to the global console).
38
+ * @returns A middleware.
39
+ */
40
40
  declare const loggingMiddleware: (options?: LoggingMiddlewareOptions) => Middleware;
41
41
  interface RateLimitMiddlewareOptions {
42
42
  /** Time window in ms over which `rate` tokens are available (default 1000). */
@@ -45,10 +45,10 @@ interface RateLimitMiddlewareOptions {
45
45
  rate: number;
46
46
  }
47
47
  /**
48
- * Throttles sends with a token-bucket rate limiter.
49
- * @param options Bucket `rate` (capacity) and refill `interval` (ms).
50
- * @returns A middleware.
51
- */
48
+ * Throttles sends with a token-bucket rate limiter.
49
+ * @param options Bucket `rate` (capacity) and refill `interval` (ms).
50
+ * @returns A middleware.
51
+ */
52
52
  declare const rateLimitMiddleware: (options: RateLimitMiddlewareOptions) => Middleware;
53
53
  interface RetryMiddlewareOptions {
54
54
  /** Base backoff delay in ms (default 250). */
@@ -59,14 +59,14 @@ interface RetryMiddlewareOptions {
59
59
  shouldRetry?: (error: unknown) => boolean;
60
60
  }
61
61
  /**
62
- * Retries failed sends with exponential backoff + jitter.
63
- * @param options Attempt count (`retries`), `baseDelay` (ms) and a `shouldRetry` predicate.
64
- * @returns A middleware.
65
- */
62
+ * Retries failed sends with exponential backoff + jitter.
63
+ * @param options Attempt count (`retries`), `baseDelay` (ms) and a `shouldRetry` predicate.
64
+ * @returns A middleware.
65
+ */
66
66
  declare const retryMiddleware: (options?: RetryMiddlewareOptions) => Middleware;
67
67
  /**
68
- * Options for {@link suppressionMiddleware}.
69
- */
68
+ * Options for {@link suppressionMiddleware}.
69
+ */
70
70
  interface SuppressionMiddlewareOptions {
71
71
  /** Returns whether a recipient is suppressed on a channel (unsubscribed, hard-bounced); may be async. */
72
72
  isSuppressed: (recipient: string, channel: ChannelType) => boolean | Promise<boolean>;
@@ -74,14 +74,14 @@ interface SuppressionMiddlewareOptions {
74
74
  resolveRecipient?: (payload: BaseNotificationPayload) => string | undefined;
75
75
  }
76
76
  /**
77
- * Short-circuits sends to suppressed recipients (unsubscribed, hard-bounced, ...). When the resolved
78
- * recipient is suppressed the send resolves successfully with `sent: false` and a `suppressed:` message
79
- * id, mirroring how {@link import("./dedupe").dedupeMiddleware} returns a synthetic success.
80
- *
81
- * Edge-safe: pure logic with no Node built-ins, so it runs on Cloudflare Workers and other edge runtimes.
82
- * @param options Suppression check and optional recipient resolver. See {@link SuppressionMiddlewareOptions}.
83
- * @returns A middleware.
84
- */
77
+ * Short-circuits sends to suppressed recipients (unsubscribed, hard-bounced, ...). When the resolved
78
+ * recipient is suppressed the send resolves successfully with `sent: false` and a `suppressed:` message
79
+ * id, mirroring how {@link import("./dedupe").dedupeMiddleware} returns a synthetic success.
80
+ *
81
+ * Edge-safe: pure logic with no Node built-ins, so it runs on Cloudflare Workers and other edge runtimes.
82
+ * @param options Suppression check and optional recipient resolver. See {@link SuppressionMiddlewareOptions}.
83
+ * @returns A middleware.
84
+ */
85
85
  declare const suppressionMiddleware: (options: SuppressionMiddlewareOptions) => Middleware;
86
86
  /**
87
87
  * Advisory options influencing aggregation configuration parameters.
@@ -131,7 +131,7 @@ interface MetricOptions {
131
131
  */
132
132
  declare enum ValueType {
133
133
  INT = 0,
134
- DOUBLE = 1,
134
+ DOUBLE = 1
135
135
  }
136
136
  /**
137
137
  * Counter is the most common synchronous instrument. This instrument supports
@@ -361,22 +361,22 @@ interface Meter {
361
361
  }
362
362
  interface TelemetryMiddlewareOptions {
363
363
  /**
364
- * The OpenTelemetry {@link Meter} used to record a send counter and duration histogram.
365
- * When omitted, no metrics are recorded.
366
- */
364
+ * The OpenTelemetry {@link Meter} used to record a send counter and duration histogram.
365
+ * When omitted, no metrics are recorded.
366
+ */
367
367
  meter?: Meter;
368
368
  /**
369
- * The OpenTelemetry {@link Tracer} used to create a span per send. When omitted, no span
370
- * is recorded (keeping `@opentelemetry/api` an optional peer dependency).
371
- */
369
+ * The OpenTelemetry {@link Tracer} used to create a span per send. When omitted, no span
370
+ * is recorded (keeping `@opentelemetry/api` an optional peer dependency).
371
+ */
372
372
  tracer?: Tracer;
373
373
  }
374
374
  /**
375
- * Records an OpenTelemetry span plus a send counter and duration histogram for each send.
376
- * Edge-safe: `@opentelemetry/api` is runtime-agnostic and both the tracer and meter are
377
- * injected, so nothing is emitted until the host application supplies them.
378
- * @param options Provide a `tracer` and/or `meter` to enable tracing and metrics.
379
- * @returns A middleware.
380
- */
375
+ * Records an OpenTelemetry span plus a send counter and duration histogram for each send.
376
+ * Edge-safe: `@opentelemetry/api` is runtime-agnostic and both the tracer and meter are
377
+ * injected, so nothing is emitted until the host application supplies them.
378
+ * @param options Provide a `tracer` and/or `meter` to enable tracing and metrics.
379
+ * @returns A middleware.
380
+ */
381
381
  declare const telemetryMiddleware: (options?: TelemetryMiddlewareOptions) => Middleware;
382
382
  export { type CircuitBreakerMiddlewareOptions, type DedupeMiddlewareOptions, type LoggingMiddlewareOptions, type Middleware, type RateLimitMiddlewareOptions, type RetryMiddlewareOptions, type SendContext, type SuppressionMiddlewareOptions, type TelemetryMiddlewareOptions, circuitBreakerMiddleware, dedupeMiddleware, loggingMiddleware, rateLimitMiddleware, retryMiddleware, suppressionMiddleware, telemetryMiddleware };
@@ -1 +1 @@
1
- import{circuitBreakerMiddleware as o}from"../packem_shared/circuitBreakerMiddleware-BlZN7SVT.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-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 +1 @@
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
+ 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};
@@ -0,0 +1 @@
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 +1 @@
1
- import s from"./NotificationError-DVfMJQ1u.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-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};
@@ -0,0 +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 +1 @@
1
- import u from"./NotificationError-DVfMJQ1u.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-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 +1 @@
1
- import r from"./NotificationError-DVfMJQ1u.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-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 +1 @@
1
- import{defineWorkflow as y}from"@visulima/workflow";import c from"./NotificationError-DVfMJQ1u.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-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 +1 @@
1
- import{IntlMessageFormat as f}from"intl-messageformat";import g from"./NotificationError-DVfMJQ1u.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-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 +1 @@
1
- import s from"./NotificationError-DVfMJQ1u.js";import c from"./RequiredOptionError-CuL42XRq.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-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 +1 @@
1
- import n from"./NotificationError-DVfMJQ1u.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-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 +1 @@
1
- import d from"./NotificationError-DVfMJQ1u.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-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 +1 @@
1
- import l from"./NotificationError-DVfMJQ1u.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-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};