@zerotal/notifications 1.4.0 → 1.5.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.
package/CHANGELOG.md CHANGED
@@ -4,10 +4,44 @@ All notable changes to this package are documented here. The format is
4
4
  based on [Keep a Changelog](https://keepachangelog.com/); this package
5
5
  follows the Zerotal monorepo's unified versioning.
6
6
 
7
- **Maturity: `beta`**
7
+ **Maturity: `stable`**
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [1.5.0] — 2026-08-15
12
+
13
+ ### Added
14
+
15
+ - **Tests for `ResendDriver`.** Unlike SMTP, this driver's correctness is entirely
16
+ the shape of one JSON request, and every way of getting it wrong is quiet in
17
+ development — a stub answers 200 either way. Pinned: the bearer token and
18
+ endpoint, `Name <addr>` formatting, optional keys omitted rather than sent empty
19
+ (Resend rejects `cc: []`), `replyTo` mapped to the API's `reply_to` (sending the
20
+ camelCase key is accepted and silently ignored, so replies would go to the
21
+ sender), base64 encoding for both string and binary attachments, and
22
+ `content_type` / `content_id` key names. Plus the half that matters most: a
23
+ non-2xx raises, because a mail driver that swallows a 401 reports every send as
24
+ delivered while nothing arrives. 173 tests → 185.
25
+
26
+ - **27 exports gained documentation** — the channel classes behind each channel
27
+ name, the three mail drivers, the delivery events (`NotificationSent`,
28
+ `MessageSent`, `MessageFailed`, `MessageQueued`), the full error table,
29
+ `OnDemandNotifiable`, `RichLine`, and the `recentDeliveries()` / `channelStats()`
30
+ counters the admin console renders. The broadcast wire event is now named as
31
+ `BROADCAST_NOTIFICATION_EVENT` where its value was already documented.
32
+
33
+ ### Changed
34
+
35
+ - **Five exports are marked `@internal`** — `SendNotificationJob`,
36
+ `BroadcastNotificationJob`, `validateNotificationConfig` and the two command
37
+ classes. Queue-serialisation plumbing and CLI wiring, none of it API: you queue
38
+ through `notifyLater()` and run the commands through `bun zt`. The promise is 38
39
+ exports, not 43.
40
+
41
+ - **Maturity is now `stable`** — the public API follows SemVer strictly for the rest
42
+ of the 1.x line. Every promised export is documented and the transports are
43
+ covered, including the HTTP driver whose failures are otherwise invisible.
44
+
11
45
  ## [1.0.3] — 2026-08-07
12
46
 
13
47
  ### Changed
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@zerotal/notifications",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "license": "MIT",
5
- "maturity": "beta",
5
+ "maturity": "stable",
6
6
  "private": false,
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
@@ -29,12 +29,12 @@
29
29
  "typecheck": "tsc --noEmit"
30
30
  },
31
31
  "dependencies": {
32
- "@zerotal/core": "1.4.0",
33
- "@zerotal/orm": "1.4.0",
34
- "@zerotal/queue": "1.4.0"
32
+ "@zerotal/core": "1.5.1",
33
+ "@zerotal/orm": "1.5.1",
34
+ "@zerotal/queue": "1.5.1"
35
35
  },
36
36
  "devDependencies": {
37
- "@zerotal/broadcasting": "1.4.0",
37
+ "@zerotal/broadcasting": "1.5.1",
38
38
  "typescript": "^5.8.0"
39
39
  },
40
40
  "description": "Multi-channel notifications for Zerotal — mail (SMTP/Resend), database, broadcast, Slack, and SMS.",
@@ -8,6 +8,8 @@ import { Job, JobRegistry } from "@zerotal/queue";
8
8
  * the whole point of the channel is immediacy. Its payload is the resolved wire
9
9
  * data, so it round-trips through a persistent driver without needing the
10
10
  * notification class.
11
+ *
12
+ * @internal
11
13
  */
12
14
  export class BroadcastNotificationJob extends Job {
13
15
  override readonly queue: string;
package/src/Notifiable.ts CHANGED
@@ -91,5 +91,5 @@ export function Notifiable<TBase extends Constructor>(Base: TBase) {
91
91
  * value (the mixin) and a type (the contract) — it merges with the function above. Extends the
92
92
  * base notifiable contract, so instances pass anywhere a notifiable is expected.
93
93
  */
94
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- the empty body is the point: it merges the name with the mixin function above
94
+ // The empty body is the point: it merges the name with the mixin function above.
95
95
  export interface Notifiable extends NotifiableContract {}
@@ -18,6 +18,8 @@ import {
18
18
  * (SQLite/Redis) it holds only the serialized snapshot written by `payload()`, and
19
19
  * rebuilds both sides in `handle()` — asynchronously, because resolving a
20
20
  * notification class may require importing `app/notifications/`.
21
+ *
22
+ * @internal
21
23
  */
22
24
  export class SendNotificationJob extends Job {
23
25
  override readonly queue = "notifications";
@@ -8,6 +8,8 @@ import type { NotificationManager } from "../NotificationManager.ts";
8
8
  * The database channel never removes anything on its own, so an app that has
9
9
  * been notifying users for a year is carrying a year of rows. Run this on a
10
10
  * schedule.
11
+ *
12
+ * @internal
11
13
  */
12
14
  export class NotificationsPruneCommand extends Command {
13
15
  static commandName = "notifications:prune";
@@ -28,6 +28,8 @@ class TestNotification extends Notification {
28
28
  * Mail configuration fails in ways unit tests cannot reach: a wrong port, a
29
29
  * refused STARTTLS upgrade, credentials the server rejects. This exercises the
30
30
  * whole path and prints what the server said.
31
+ *
32
+ * @internal
31
33
  */
32
34
  export class NotificationsTestCommand extends Command {
33
35
  static commandName = "notifications:test";
package/src/config.ts CHANGED
@@ -59,6 +59,8 @@ export function NotificationConfig(
59
59
  * naming the key — rather than on the first password-reset email of the day.
60
60
  *
61
61
  * @throws {NotificationConfigError} on the first inconsistency found.
62
+ *
63
+ * @internal
62
64
  */
63
65
  export function validateNotificationConfig(config: NotificationConfigShape): void {
64
66
  const { mail, sms } = config;