hazo_notify 5.0.1 → 5.2.1

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 (112) hide show
  1. package/README.md +5 -5
  2. package/dist/components/notification_bell/index.d.ts +11 -1
  3. package/dist/components/notification_bell/index.d.ts.map +1 -1
  4. package/dist/components/notification_bell/index.js +33 -1
  5. package/dist/components/notification_bell/index.js.map +1 -1
  6. package/dist/lib/adapters/email/adapter.d.ts +2 -0
  7. package/dist/lib/adapters/email/adapter.d.ts.map +1 -1
  8. package/dist/lib/adapters/email/adapter.js +53 -22
  9. package/dist/lib/adapters/email/adapter.js.map +1 -1
  10. package/dist/lib/adapters/webhook/adapter.d.ts +10 -0
  11. package/dist/lib/adapters/webhook/adapter.d.ts.map +1 -0
  12. package/dist/lib/adapters/webhook/adapter.js +90 -0
  13. package/dist/lib/adapters/webhook/adapter.js.map +1 -0
  14. package/dist/lib/adapters/webhook/index.d.ts +8 -0
  15. package/dist/lib/adapters/webhook/index.d.ts.map +1 -0
  16. package/dist/lib/adapters/webhook/index.js +3 -0
  17. package/dist/lib/adapters/webhook/index.js.map +1 -0
  18. package/dist/lib/adapters/webhook/types.d.ts +45 -0
  19. package/dist/lib/adapters/webhook/types.d.ts.map +1 -0
  20. package/dist/lib/adapters/webhook/types.js +12 -0
  21. package/dist/lib/adapters/webhook/types.js.map +1 -0
  22. package/dist/lib/api/inbox.d.ts +32 -0
  23. package/dist/lib/api/inbox.d.ts.map +1 -1
  24. package/dist/lib/api/inbox.js +68 -0
  25. package/dist/lib/api/inbox.js.map +1 -1
  26. package/dist/lib/dispatcher/index.d.ts +2 -2
  27. package/dist/lib/dispatcher/index.d.ts.map +1 -1
  28. package/dist/lib/dispatcher/index.js +28 -8
  29. package/dist/lib/dispatcher/index.js.map +1 -1
  30. package/dist/lib/inbox/broadcaster.d.ts +44 -0
  31. package/dist/lib/inbox/broadcaster.d.ts.map +1 -0
  32. package/dist/lib/inbox/broadcaster.js +62 -0
  33. package/dist/lib/inbox/broadcaster.js.map +1 -0
  34. package/dist/lib/inbox/index.d.ts +2 -0
  35. package/dist/lib/inbox/index.d.ts.map +1 -1
  36. package/dist/lib/inbox/index.js +1 -0
  37. package/dist/lib/inbox/index.js.map +1 -1
  38. package/dist/lib/inbox/storage.d.ts.map +1 -1
  39. package/dist/lib/inbox/storage.js +7 -2
  40. package/dist/lib/inbox/storage.js.map +1 -1
  41. package/dist/lib/inbox/types.d.ts +7 -0
  42. package/dist/lib/inbox/types.d.ts.map +1 -1
  43. package/dist/lib/jobs/submit.d.ts.map +1 -1
  44. package/dist/lib/jobs/submit.js +1 -0
  45. package/dist/lib/jobs/submit.js.map +1 -1
  46. package/dist/lib/jobs/types.d.ts +1 -0
  47. package/dist/lib/jobs/types.d.ts.map +1 -1
  48. package/dist/lib/lifecycle/default_templates.d.ts +9 -0
  49. package/dist/lib/lifecycle/default_templates.d.ts.map +1 -0
  50. package/dist/lib/lifecycle/default_templates.js +160 -0
  51. package/dist/lib/lifecycle/default_templates.js.map +1 -0
  52. package/dist/lib/lifecycle/dispatch.d.ts +37 -0
  53. package/dist/lib/lifecycle/dispatch.d.ts.map +1 -0
  54. package/dist/lib/lifecycle/dispatch.js +32 -0
  55. package/dist/lib/lifecycle/dispatch.js.map +1 -0
  56. package/dist/lib/lifecycle/events.d.ts +34 -0
  57. package/dist/lib/lifecycle/events.d.ts.map +1 -0
  58. package/dist/lib/lifecycle/events.js +118 -0
  59. package/dist/lib/lifecycle/events.js.map +1 -0
  60. package/dist/lib/lifecycle/handler.d.ts +29 -0
  61. package/dist/lib/lifecycle/handler.d.ts.map +1 -0
  62. package/dist/lib/lifecycle/handler.js +145 -0
  63. package/dist/lib/lifecycle/handler.js.map +1 -0
  64. package/dist/lib/lifecycle/index.d.ts +23 -0
  65. package/dist/lib/lifecycle/index.d.ts.map +1 -0
  66. package/dist/lib/lifecycle/index.js +21 -0
  67. package/dist/lib/lifecycle/index.js.map +1 -0
  68. package/dist/lib/lifecycle/register.d.ts +29 -0
  69. package/dist/lib/lifecycle/register.d.ts.map +1 -0
  70. package/dist/lib/lifecycle/register.js +29 -0
  71. package/dist/lib/lifecycle/register.js.map +1 -0
  72. package/dist/lib/lifecycle/resolver.d.ts +22 -0
  73. package/dist/lib/lifecycle/resolver.d.ts.map +1 -0
  74. package/dist/lib/lifecycle/resolver.js +105 -0
  75. package/dist/lib/lifecycle/resolver.js.map +1 -0
  76. package/dist/lib/lifecycle/scheduler.d.ts +27 -0
  77. package/dist/lib/lifecycle/scheduler.d.ts.map +1 -0
  78. package/dist/lib/lifecycle/scheduler.js +108 -0
  79. package/dist/lib/lifecycle/scheduler.js.map +1 -0
  80. package/dist/lib/lifecycle/status.d.ts +39 -0
  81. package/dist/lib/lifecycle/status.d.ts.map +1 -0
  82. package/dist/lib/lifecycle/status.js +67 -0
  83. package/dist/lib/lifecycle/status.js.map +1 -0
  84. package/dist/lib/lifecycle/types.d.ts +165 -0
  85. package/dist/lib/lifecycle/types.d.ts.map +1 -0
  86. package/dist/lib/lifecycle/types.js +11 -0
  87. package/dist/lib/lifecycle/types.js.map +1 -0
  88. package/dist/lib/preferences/index.d.ts +3 -0
  89. package/dist/lib/preferences/index.d.ts.map +1 -0
  90. package/dist/lib/preferences/index.js +3 -0
  91. package/dist/lib/preferences/index.js.map +1 -0
  92. package/dist/lib/preferences/storage.d.ts +33 -0
  93. package/dist/lib/preferences/storage.d.ts.map +1 -0
  94. package/dist/lib/preferences/storage.js +125 -0
  95. package/dist/lib/preferences/storage.js.map +1 -0
  96. package/dist/lib/preferences/types.d.ts +59 -0
  97. package/dist/lib/preferences/types.d.ts.map +1 -0
  98. package/dist/lib/preferences/types.js +20 -0
  99. package/dist/lib/preferences/types.js.map +1 -0
  100. package/dist/lib/template_manager/db/template_repository.d.ts +4 -1
  101. package/dist/lib/template_manager/db/template_repository.d.ts.map +1 -1
  102. package/dist/lib/template_manager/db/template_repository.js +17 -1
  103. package/dist/lib/template_manager/db/template_repository.js.map +1 -1
  104. package/dist/lib/template_manager/types.d.ts +1 -0
  105. package/dist/lib/template_manager/types.d.ts.map +1 -1
  106. package/migrations/008_lifecycle_status.pg.sql +27 -0
  107. package/migrations/008_lifecycle_status.sqlite.sql +24 -0
  108. package/migrations/009_templates_locale.pg.sql +6 -0
  109. package/migrations/009_templates_locale.sqlite.sql +4 -0
  110. package/migrations/010_preferences.pg.sql +26 -0
  111. package/migrations/010_preferences.sqlite.sql +32 -0
  112. package/package.json +15 -3
package/README.md CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  A reusable component library for sending email notifications with scope-aware template management. Implements Zeptomail API integration with support for text and HTML emails, Handlebars-based email templates with multi-tenant resolution, multiple attachments, and comprehensive security features.
4
4
 
5
- **Version**: 4.0.2
5
+ **Version**: 5.2.1
6
6
 
7
- > **⚠ Readers on v4:** Many examples below still show the v3.x API surface (`send_email`, `hazo_notify/emailer`, `channels: { in_app, email, banner }`, direct `template_html` / `template_text` access). **v4.0.0 introduced a channel-pluggable architecture** — outbound sends go through `dispatch()` → inbox row + per-channel delivery row → `EmailChannel`/`TelegramChannel` adapter, with a multi-channel worker fleet. For the current v4 API see:
7
+ > **⚠ Readers on older versions:** Many examples below still show the v3.x API surface (`send_email`, `hazo_notify/emailer`, `channels: { in_app, email, banner }`, direct `template_html` / `template_text` access). **v4.0.0 introduced a channel-pluggable architecture** — outbound sends go through `dispatch()` → inbox row + per-channel delivery row → `EmailChannel`/`TelegramChannel` adapter, with a multi-channel worker fleet. For the current API see:
8
8
  >
9
- > - [`TECHDOC.md`](./TECHDOC.md) — v4 architecture and API reference (channel registry, dispatch flow, worker fleet, adapters, schema)
9
+ > - [`TECHDOC.md`](./TECHDOC.md) — v4+ architecture and API reference (channel registry, dispatch flow, worker fleet, adapters, schema)
10
10
  > - [`SETUP_CHECKLIST.md`](./SETUP_CHECKLIST.md) §"v4.0.0 Migration" — migrations 005/006/007, dispatch rewrite, boot changes
11
- > - [`CHANGE_LOG.md`](./CHANGE_LOG.md) — full breaking-change manifest for v4.0.0
11
+ > - [`CHANGE_LOG.md`](./CHANGE_LOG.md) — full breaking-change manifest and release history
12
12
  >
13
- > A full v4-aware rewrite of this README is tracked for v4.0.2. The examples that follow remain accurate for v3.x consumers; v4 consumers should read the docs above.
13
+ > A full v5-aware rewrite of this README is planned. The examples that follow remain accurate for v3.x consumers; v5 consumers should read the docs above.
14
14
 
15
15
  ## Features
16
16
 
@@ -51,6 +51,16 @@ export interface NotificationBellProps {
51
51
  components: NotificationBellComponents;
52
52
  onItemClick?: (item: InboxItem) => void;
53
53
  bellIcon?: ReactNode;
54
+ /**
55
+ * Enable real-time push via SSE. When enabled the bell opens an EventSource
56
+ * to `eventSourceUrl` and refreshes the unread count on `notification.created`
57
+ * events. Falls back to polling if the connection drops.
58
+ */
59
+ realtime?: {
60
+ enabled: boolean;
61
+ /** URL of the SSE stream endpoint. Default: `${apiBasePath}/stream` */
62
+ eventSourceUrl?: string;
63
+ };
54
64
  }
55
- export declare function NotificationBell({ apiBasePath, pollIntervalMs, components: C, onItemClick, bellIcon, }: NotificationBellProps): import("react/jsx-runtime").JSX.Element;
65
+ export declare function NotificationBell({ apiBasePath, pollIntervalMs, components: C, onItemClick, bellIcon, realtime, }: NotificationBellProps): import("react/jsx-runtime").JSX.Element;
56
66
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/notification_bell/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAoC,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI7F,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;IAC5F,YAAY,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAC,CAAC;IAC3G,mBAAmB,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChF,mBAAmB,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjG,gBAAgB,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;IAChF,KAAK,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,0BAA0B,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,WAAkC,EAClC,cAAgC,EAChC,UAAU,EAAE,CAAC,EACb,WAAW,EACX,QAAQ,GACT,EAAE,qBAAqB,2CAiFvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/notification_bell/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAoC,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI7F,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;IAC5F,YAAY,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAC,CAAC;IAC3G,mBAAmB,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChF,mBAAmB,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjG,gBAAgB,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;IAChF,KAAK,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,0BAA0B,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,uEAAuE;QACvE,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,WAAkC,EAClC,cAAgC,EAChC,UAAU,EAAE,CAAC,EACb,WAAW,EACX,QAAQ,EACR,QAAQ,GACT,EAAE,qBAAqB,2CAoHvB"}
@@ -9,7 +9,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  */
10
10
  import { useEffect, useState, useCallback } from "react";
11
11
  const DEFAULT_POLL_MS = 30000;
12
- export function NotificationBell({ apiBasePath = "/api/notifications", pollIntervalMs = DEFAULT_POLL_MS, components: C, onItemClick, bellIcon, }) {
12
+ export function NotificationBell({ apiBasePath = "/api/notifications", pollIntervalMs = DEFAULT_POLL_MS, components: C, onItemClick, bellIcon, realtime, }) {
13
13
  const [unread, setUnread] = useState(0);
14
14
  const [open, setOpen] = useState(false);
15
15
  const [items, setItems] = useState([]);
@@ -56,6 +56,38 @@ export function NotificationBell({ apiBasePath = "/api/notifications", pollInter
56
56
  }, [fetchCount, pollIntervalMs]);
57
57
  useEffect(() => { if (open)
58
58
  fetchList(); }, [open, fetchList]);
59
+ // Real-time SSE subscription
60
+ useEffect(() => {
61
+ if (!realtime?.enabled)
62
+ return;
63
+ if (typeof EventSource === "undefined")
64
+ return;
65
+ const url = realtime.eventSourceUrl ?? `${apiBasePath}/stream`;
66
+ let es = null;
67
+ let reconnect_timer = null;
68
+ function connect() {
69
+ es = new EventSource(url, { withCredentials: true });
70
+ es.addEventListener('notification.created', () => {
71
+ // Refresh unread count immediately on new notification
72
+ fetchCount();
73
+ // If dropdown is open, refresh the list too
74
+ if (open)
75
+ fetchList();
76
+ });
77
+ es.onerror = () => {
78
+ es?.close();
79
+ es = null;
80
+ // Back-off reconnect: try again in 5 s
81
+ reconnect_timer = setTimeout(connect, 5000);
82
+ };
83
+ }
84
+ connect();
85
+ return () => {
86
+ es?.close();
87
+ if (reconnect_timer)
88
+ clearTimeout(reconnect_timer);
89
+ };
90
+ }, [realtime?.enabled, realtime?.eventSourceUrl, apiBasePath, open, fetchCount, fetchList]);
59
91
  const handleItem = async (item) => {
60
92
  await fetch(`${apiBasePath}/${item.id}/read`, { method: "POST", credentials: "include" });
61
93
  setUnread((n) => Math.max(0, n - 1));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/notification_bell/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/notification_bell/index.tsx"],"names":[],"mappings":"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"}
@@ -11,6 +11,8 @@ import type { ChannelAdapter, ChannelCapabilities, ChannelSendContext, ChannelSe
11
11
  import type { EmailerConfig, EmailSendResponse, EmailAttachment } from "./types.js";
12
12
  /** Payload shape for the email channel. */
13
13
  export interface EmailPayload {
14
+ /** Explicit recipient email. When provided, validated on dispatch. At send time, recipient is resolved via resolveRecipient. */
15
+ to?: string;
14
16
  subject: string;
15
17
  body_text?: string;
16
18
  body_html?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/email/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMpF,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAOhE;AAED,4DAA4D;AAC5D,qBAAa,YAAa,YAAW,cAAc,CAAC,YAAY,CAAC;IAgBnD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAfjC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAaxC;gBAE2B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,aAAa,CAAA;KAAO;IAElE,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,uBAAuB;IAW5C,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAgCjF;AAID,OAAO,QAAQ,yBAAyB,CAAC;IACvC,UAAU,iBAAiB;QACzB,KAAK,EAAE,YAAY,CAAC;KACrB;CACF"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/email/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOpF,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,gIAAgI;IAChI,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAOhE;AAED,4DAA4D;AAC5D,qBAAa,YAAa,YAAW,cAAc,CAAC,YAAY,CAAC;IAgBnD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAfjC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAaxC;gBAE2B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,aAAa,CAAA;KAAO;IAElE,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,uBAAuB;IAc5C,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAyDjF;AAID,OAAO,QAAQ,yBAAyB,CAAC;IACvC,UAAU,iBAAiB;QACzB,KAAK,EAAE,YAAY,CAAC;KACrB;CACF"}
@@ -10,6 +10,7 @@
10
10
  import { load_emailer_config } from "./config.js";
11
11
  import { get_email_provider } from "./providers/index.js";
12
12
  import { wrapEnvelope } from "./envelope.js";
13
+ import { validate_email_address } from "./utils/validation.js";
13
14
  /**
14
15
  * Returns true if the send failure is retryable (transient), false if permanent.
15
16
  *
@@ -51,6 +52,9 @@ export class EmailChannel {
51
52
  }
52
53
  validate(p) {
53
54
  const errors = [];
55
+ if (p.to !== undefined && !validate_email_address(p.to)) {
56
+ errors.push("to: invalid email address");
57
+ }
54
58
  if (!p.subject || p.subject.length === 0) {
55
59
  errors.push("subject required");
56
60
  }
@@ -60,28 +64,55 @@ export class EmailChannel {
60
64
  return errors.length > 0 ? { ok: false, errors } : { ok: true };
61
65
  }
62
66
  async send(p, ctx) {
63
- const config = this.opts.config ?? load_emailer_config();
64
- const provider = get_email_provider(config);
65
- const body_text = ctx.rendered_bodies.text ?? p.body_text ?? "";
66
- const body_html = ctx.rendered_bodies.html ?? p.body_html;
67
- // ScopeBranding and OrgBranding are structurally identical cast is safe.
68
- const { text, html } = wrapEnvelope({
69
- body_text,
70
- body_html,
71
- branding: ctx.branding,
72
- });
73
- const r = await provider.send_email({
74
- to: ctx.recipient,
75
- subject: p.subject,
76
- content: { text, html },
77
- attachments: p.attachments,
78
- reply_to: p.reply_to,
79
- cc: p.cc,
80
- bcc: p.bcc,
81
- }, config, ctx.logger);
82
- return r.success
83
- ? { ok: true, message_id: r.message_id }
84
- : { ok: false, error: r.error ?? "send_failed", retryable: classifyEmailError(r) };
67
+ try {
68
+ // Wrap config loading so that missing config / missing API key → permanent failure
69
+ // (retryable: false) rather than an unhandled exception that the flush worker
70
+ // conservatively treats as retryable. An infinite retry loop on a bad config
71
+ // is far more harmful than an immediate permanent failure.
72
+ let config;
73
+ try {
74
+ config = this.opts.config ?? load_emailer_config();
75
+ }
76
+ catch (e) {
77
+ return {
78
+ ok: false,
79
+ error: `email_config_error: ${e instanceof Error ? e.message : String(e)}`,
80
+ retryable: false,
81
+ };
82
+ }
83
+ const provider = get_email_provider(config);
84
+ const body_text = ctx.rendered_bodies.text ?? p.body_text ?? "";
85
+ const body_html = ctx.rendered_bodies.html ?? p.body_html;
86
+ // ScopeBranding and OrgBranding are structurally identical — cast is safe.
87
+ const { text, html } = wrapEnvelope({
88
+ body_text,
89
+ body_html,
90
+ branding: ctx.branding,
91
+ });
92
+ const r = await provider.send_email({
93
+ to: ctx.recipient,
94
+ subject: p.subject,
95
+ content: { text, html },
96
+ attachments: p.attachments,
97
+ reply_to: p.reply_to,
98
+ cc: p.cc,
99
+ bcc: p.bcc,
100
+ }, config, ctx.logger);
101
+ return r.success
102
+ ? { ok: true, message_id: r.message_id }
103
+ : { ok: false, error: r.error ?? "send_failed", retryable: classifyEmailError(r) };
104
+ }
105
+ catch (e) {
106
+ // Any unhandled exception (network error thrown from provider, provider bug,
107
+ // etc.) must be a permanent failure — never retryable. Without this outer
108
+ // catch the flush worker conservatively marks the delivery as retryable,
109
+ // causing infinite retry loops that never reach a final state.
110
+ return {
111
+ ok: false,
112
+ error: `send_error: ${e instanceof Error ? e.message : String(e)}`,
113
+ retryable: false,
114
+ };
115
+ }
85
116
  }
86
117
  }
87
118
  //# sourceMappingURL=adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../../src/lib/adapters/email/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAgB7C;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAoB;IACrD,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvE,MAAM,MAAM,GAAI,CAAC,CAAC,YAAoC,CAAC,MAAM,CAAC;IAC9D,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,KAAK,CAAC,CAAC,kCAAkC;AAClD,CAAC;AAED,4DAA4D;AAC5D,MAAM,OAAO,YAAY;IAgBvB,YAA6B,OAAmC,EAAE;QAArC,SAAI,GAAJ,IAAI,CAAiC;QAfzD,iBAAY,GAAwB;YAC3C,UAAU,EAAE,OAAO;YACnB,YAAY,EAAE,OAAO;YACrB,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;YACpC,eAAe,EAAE,IAAI;YACrB,oBAAoB,EAAE,KAAK;YAC3B,2BAA2B,EAAE,IAAI;YACjC,KAAK,EAAE;gBACL,YAAY,EAAE,CAAC;gBACf,+DAA+D;gBAC/D,UAAU,EAAE,CAAC,CAAS,EAAE,IAAa,EAAU,EAAE,CAC/C,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAM,EAAE,KAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aAC1E;SACF,CAAC;IAEmE,CAAC;IAEtE,QAAQ,CAAC,CAAe;QACtB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAe,EAAE,GAAuB;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,mBAAmB,EAAE,CAAC;QACzD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,SAAS,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;QAChE,MAAM,SAAS,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC;QAE1D,2EAA2E;QAC3E,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC;YAClC,SAAS;YACT,SAAS;YACT,QAAQ,EAAE,GAAG,CAAC,QAA8B;SAC7C,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,UAAU,CACjC;YACE,EAAE,EAAE,GAAG,CAAC,SAAS;YACjB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;YACvB,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,GAAG,EAAE,CAAC,CAAC,GAAG;SACF,EACV,MAAM,EACN,GAAG,CAAC,MAAe,CACpB,CAAC;QAEF,OAAO,CAAC,CAAC,OAAO;YACd,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE;YACxC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,aAAa,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,CAAC;CACF"}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../../src/lib/adapters/email/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ChannelAdapter, ChannelCapabilities, ChannelSendContext, ChannelSendResult, ChannelValidationResult } from '../../channels/types.js';
2
+ import type { WebhookPayload, WebhookChannelOptions } from './types.js';
3
+ export declare class WebhookChannel implements ChannelAdapter<WebhookPayload> {
4
+ private readonly opts;
5
+ readonly capabilities: ChannelCapabilities;
6
+ constructor(opts: WebhookChannelOptions);
7
+ validate(_payload: WebhookPayload): ChannelValidationResult;
8
+ send(payload: WebhookPayload, ctx: ChannelSendContext): Promise<ChannelSendResult>;
9
+ }
10
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/webhook/adapter.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAmB,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEzF,qBAAa,cAAe,YAAW,cAAc,CAAC,cAAc,CAAC;IAGvD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;gBAEd,IAAI,EAAE,qBAAqB;IAgBxD,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,uBAAuB;IAIrD,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAoEzF"}
@@ -0,0 +1,90 @@
1
+ // src/lib/adapters/webhook/adapter.ts
2
+ /**
3
+ * Webhook channel adapter.
4
+ *
5
+ * POSTs a signed JSON envelope to a consumer-supplied URL per scope_id.
6
+ * Retries on 5xx and 429 (Retry-After header honoured).
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ import { createHmac } from 'node:crypto';
11
+ export class WebhookChannel {
12
+ constructor(opts) {
13
+ this.opts = opts;
14
+ this.capabilities = {
15
+ channel_id: opts.channel_id ?? 'webhook',
16
+ display_name: 'Webhook',
17
+ template_body_keys: [],
18
+ max_text_length: null,
19
+ splits_long_messages: false,
20
+ supports_explicit_recipient: false,
21
+ retry: {
22
+ max_attempts: 3,
23
+ backoff_ms: (n, hint) => hint ?? Math.min(60000, 2000 * Math.pow(2, Math.max(0, n - 1))),
24
+ },
25
+ };
26
+ }
27
+ validate(_payload) {
28
+ return { ok: true };
29
+ }
30
+ async send(payload, ctx) {
31
+ const url = await this.opts.resolveUrl(ctx.scope_id);
32
+ if (!url) {
33
+ return {
34
+ ok: false,
35
+ error: `no_url: no webhook URL configured for scope '${ctx.scope_id}'`,
36
+ retryable: false,
37
+ };
38
+ }
39
+ const envelope = {
40
+ inbox_id: ctx.inbox_id,
41
+ user_id: ctx.user_id,
42
+ scope_id: ctx.scope_id,
43
+ rendered_bodies: ctx.rendered_bodies,
44
+ metadata: payload.metadata ?? {},
45
+ timestamp: new Date().toISOString(),
46
+ };
47
+ const body = JSON.stringify(envelope);
48
+ const headers = {
49
+ 'Content-Type': 'application/json',
50
+ };
51
+ if (this.opts.secret) {
52
+ const sig = createHmac('sha256', this.opts.secret).update(body).digest('hex');
53
+ headers['X-Hazo-Signature'] = `sha256=${sig}`;
54
+ }
55
+ const controller = new AbortController();
56
+ const timeout = setTimeout(() => controller.abort(), this.opts.timeout_ms ?? 30000);
57
+ try {
58
+ const res = await fetch(url, {
59
+ method: 'POST',
60
+ headers,
61
+ body,
62
+ signal: controller.signal,
63
+ });
64
+ if (res.ok) {
65
+ return { ok: true };
66
+ }
67
+ const retry_after_raw = res.headers.get('Retry-After');
68
+ const retry_after_ms = retry_after_raw
69
+ ? Number(retry_after_raw) * 1000
70
+ : undefined;
71
+ return {
72
+ ok: false,
73
+ error: `HTTP ${res.status}`,
74
+ retryable: res.status === 429 || res.status >= 500,
75
+ retry_after_ms,
76
+ };
77
+ }
78
+ catch (err) {
79
+ return {
80
+ ok: false,
81
+ error: err instanceof Error ? err.message : String(err),
82
+ retryable: true,
83
+ };
84
+ }
85
+ finally {
86
+ clearTimeout(timeout);
87
+ }
88
+ }
89
+ }
90
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../../src/lib/adapters/webhook/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { WebhookChannel } from './adapter.js';
2
+ export type { WebhookPayload, WebhookEnvelope, WebhookChannelOptions, } from './types.js';
3
+ declare module 'hazo_notify/channels' {
4
+ interface ChannelPayloadMap {
5
+ webhook: import('./types.js').WebhookPayload;
6
+ }
7
+ }
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/webhook/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EACV,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAU,iBAAiB;QACzB,OAAO,EAAE,OAAO,YAAY,EAAE,cAAc,CAAC;KAC9C;CACF"}
@@ -0,0 +1,3 @@
1
+ // src/lib/adapters/webhook/index.ts
2
+ export { WebhookChannel } from './adapter.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/adapters/webhook/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Types for the webhook channel adapter.
3
+ *
4
+ * The webhook adapter POSTs a signed JSON envelope to a per-scope URL.
5
+ * URL management is the consumer's responsibility — the adapter calls
6
+ * `resolveUrl(scope_id)` at send time.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ /** channel_payloads entry for the webhook channel. */
11
+ export interface WebhookPayload {
12
+ /** Extra metadata merged into the envelope `metadata` field. */
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+ /** Shape of the JSON body POSTed to the webhook endpoint. */
16
+ export interface WebhookEnvelope {
17
+ inbox_id: string;
18
+ user_id: string;
19
+ scope_id: string;
20
+ rendered_bodies: Record<string, string>;
21
+ metadata: Record<string, unknown>;
22
+ timestamp: string;
23
+ }
24
+ /** Constructor options for WebhookChannel. */
25
+ export interface WebhookChannelOptions {
26
+ /**
27
+ * Stable channel ID (default: 'webhook'). Override to register multiple
28
+ * webhook channels with different IDs (e.g. 'webhook_slack', 'webhook_crm').
29
+ */
30
+ channel_id?: string;
31
+ /**
32
+ * Resolves the destination URL for a given scope_id. Return null to skip
33
+ * the send (delivery will be marked failed with reason "no_url").
34
+ */
35
+ resolveUrl: (scope_id: string) => Promise<string | null>;
36
+ /**
37
+ * HMAC-SHA256 signing secret. When provided, adds header:
38
+ * X-Hazo-Signature: sha256=<hex>
39
+ * The signature covers the raw JSON body bytes.
40
+ */
41
+ secret?: string;
42
+ /** Request timeout in ms (default: 30_000). */
43
+ timeout_ms?: number;
44
+ }
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/webhook/types.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAEH,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8CAA8C;AAC9C,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,12 @@
1
+ // src/lib/adapters/webhook/types.ts
2
+ /**
3
+ * Types for the webhook channel adapter.
4
+ *
5
+ * The webhook adapter POSTs a signed JSON envelope to a per-scope URL.
6
+ * URL management is the consumer's responsibility — the adapter calls
7
+ * `resolveUrl(scope_id)` at send time.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/adapters/webhook/types.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC;;;;;;;;GAQG"}
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @packageDocumentation
8
8
  */
9
+ import type { InboxBroadcastEvent } from "../inbox/broadcaster.js";
9
10
  interface SimpleRequest {
10
11
  url: string;
11
12
  }
@@ -29,5 +30,36 @@ export declare function createInboxRoutes(opts: CreateInboxRoutesOptions): {
29
30
  }): Promise<SimpleResponse>;
30
31
  markAllReadHandler(req: SimpleRequest): Promise<SimpleResponse>;
31
32
  };
33
+ export interface CreateInboxStreamRouteOptions {
34
+ /** Extract authenticated user_id from the request. Return null to reject. */
35
+ getAuth: (req: Request) => Promise<{
36
+ user_id: string;
37
+ } | null>;
38
+ /**
39
+ * Subscribe a listener for a user_id. Returns an unsubscribe function.
40
+ * Wire this to the subscribe returned by createInboxBroadcaster().
41
+ */
42
+ subscribe: (user_id: string, fn: (event: InboxBroadcastEvent) => void) => () => void;
43
+ /** Heartbeat interval in ms (default 20 000). Keeps proxies alive. */
44
+ heartbeat_ms?: number;
45
+ }
46
+ /**
47
+ * Returns a Next.js-compatible GET handler for `text/event-stream`.
48
+ *
49
+ * Consumer mounting:
50
+ * ```ts
51
+ * // app/api/notifications/stream/route.ts
52
+ * import { createInboxStreamRoute } from 'hazo_notify/api/inbox';
53
+ * import { subscribe } from '@/lib/notify-init';
54
+ * export const GET = createInboxStreamRoute({ getAuth, subscribe });
55
+ * ```
56
+ *
57
+ * Events pushed to clients:
58
+ * event: notification.created\ndata: {"user_id":"…","inbox_id":"…"}\n\n
59
+ *
60
+ * The client (NotificationBell with realtime enabled) listens for
61
+ * `notification.created` and refreshes its unread count on receipt.
62
+ */
63
+ export declare function createInboxStreamRoute(opts: CreateInboxStreamRouteOptions): (req: Request) => Promise<Response>;
32
64
  export {};
33
65
  //# sourceMappingURL=inbox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../../src/lib/api/inbox.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,UAAU,aAAa;IAAG,GAAG,EAAE,MAAM,CAAA;CAAE;AACvC,UAAU,cAAc;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE;AAMrE,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACxF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB;qBAErC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;4BAiBhC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;yBAQ9D,aAAa,OACb;QAAE,MAAM,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAC9B,OAAO,CAAC,cAAc,CAAC;4BAOI,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;EAOxE"}
1
+ {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../../src/lib/api/inbox.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,UAAU,aAAa;IAAG,GAAG,EAAE,MAAM,CAAA;CAAE;AACvC,UAAU,cAAc;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE;AAMrE,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACxF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB;qBAErC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;4BAiBhC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;yBAQ9D,aAAa,OACb;QAAE,MAAM,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAC9B,OAAO,CAAC,cAAc,CAAC;4BAOI,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;EAOxE;AAID,MAAM,WAAW,6BAA6B;IAC5C,6EAA6E;IAC7E,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC/D;;;OAGG;IACH,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACrF,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,6BAA6B,IAG9C,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAwD3D"}
@@ -49,4 +49,72 @@ export function createInboxRoutes(opts) {
49
49
  },
50
50
  };
51
51
  }
52
+ /**
53
+ * Returns a Next.js-compatible GET handler for `text/event-stream`.
54
+ *
55
+ * Consumer mounting:
56
+ * ```ts
57
+ * // app/api/notifications/stream/route.ts
58
+ * import { createInboxStreamRoute } from 'hazo_notify/api/inbox';
59
+ * import { subscribe } from '@/lib/notify-init';
60
+ * export const GET = createInboxStreamRoute({ getAuth, subscribe });
61
+ * ```
62
+ *
63
+ * Events pushed to clients:
64
+ * event: notification.created\ndata: {"user_id":"…","inbox_id":"…"}\n\n
65
+ *
66
+ * The client (NotificationBell with realtime enabled) listens for
67
+ * `notification.created` and refreshes its unread count on receipt.
68
+ */
69
+ export function createInboxStreamRoute(opts) {
70
+ const heartbeat_ms = opts.heartbeat_ms ?? 20000;
71
+ return async function GET(req) {
72
+ const auth = await opts.getAuth(req);
73
+ if (!auth) {
74
+ return new Response('Unauthorized', { status: 401 });
75
+ }
76
+ const { user_id } = auth;
77
+ const encoder = new TextEncoder();
78
+ let unsub = null;
79
+ let heartbeat = null;
80
+ const stream = new ReadableStream({
81
+ start(controller) {
82
+ // Send an initial connection confirmation event
83
+ controller.enqueue(encoder.encode(`event: connected\ndata: {"user_id":"${user_id}"}\n\n`));
84
+ // Subscribe to broadcaster events for this user
85
+ unsub = opts.subscribe(user_id, (event) => {
86
+ try {
87
+ controller.enqueue(encoder.encode(`event: notification.created\ndata: ${JSON.stringify(event)}\n\n`));
88
+ }
89
+ catch {
90
+ // Stream closed — subscriber will be cleaned up in cancel()
91
+ }
92
+ });
93
+ // Heartbeat to keep proxy connections alive
94
+ heartbeat = setInterval(() => {
95
+ try {
96
+ controller.enqueue(encoder.encode(`: ping\n\n`));
97
+ }
98
+ catch {
99
+ if (heartbeat)
100
+ clearInterval(heartbeat);
101
+ }
102
+ }, heartbeat_ms);
103
+ },
104
+ cancel() {
105
+ if (heartbeat)
106
+ clearInterval(heartbeat);
107
+ unsub?.();
108
+ },
109
+ });
110
+ return new Response(stream, {
111
+ headers: {
112
+ 'Content-Type': 'text/event-stream',
113
+ 'Cache-Control': 'no-cache, no-transform',
114
+ Connection: 'keep-alive',
115
+ 'X-Accel-Buffering': 'no', // Disable nginx buffering
116
+ },
117
+ });
118
+ };
119
+ }
52
120
  //# sourceMappingURL=inbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../../src/lib/api/inbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../../src/lib/api/inbox.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { DispatchInput, DispatchResult } from "../inbox/types.js";
2
- export type { DispatchInput, DispatchResult } from "../inbox/types.js";
1
+ import type { DispatchInput, DispatchResult } from '../inbox/types.js';
2
+ export type { DispatchInput, DispatchResult } from '../inbox/types.js';
3
3
  export declare function dispatch(input: DispatchInput): Promise<DispatchResult>;
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/dispatcher/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEvE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAIvE,wBAAsB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAkE5E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/dispatcher/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEvE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAIvE,wBAAsB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CA0F5E"}