@arkstack/notifications 0.19.2 → 0.19.4

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/README.md CHANGED
@@ -5,21 +5,19 @@
5
5
  Framework-agnostic notification module for Arkstack and Nodejs, providing support for multi-channel notification delivery.
6
6
 
7
7
  ```ts
8
- import { Notification } from '@arkstack/notifications';
8
+ import { Notification } from '@arkstack/notifications'
9
9
 
10
10
  await Notification.mail()
11
11
  .recipient({ 'ada@example.com': 'Ada Lovelace' })
12
12
  .subject('Welcome, {name}')
13
13
  .data({ name: 'Ada' })
14
- .send('Hello {name}, thanks for joining.');
14
+ .send('Hello {name}, thanks for joining.')
15
15
 
16
16
  await Notification.sms()
17
17
  .recipient('+2348012345678')
18
- .send('Your code is {code}', undefined, undefined, { code: '123456' });
18
+ .send('Your code is {code}', undefined, undefined, { code: '123456' })
19
19
 
20
- await Notification.db()
21
- .recipient(user)
22
- .send('Your payout has settled', 'Payout settled');
20
+ await Notification.db().recipient(user).send('Your payout has settled', 'Payout settled')
23
21
  ```
24
22
 
25
23
  Apps using database notifications should provide a `UserNotification` model backed by a `user_notifications` table. The starter templates include this model and migration.
@@ -73,7 +71,7 @@ export default () => ({
73
71
  from: env('TWILIO_FROM'),
74
72
  },
75
73
  },
76
- });
74
+ })
77
75
  ```
78
76
 
79
77
  `default_driver` selects the notification channel used by `Notification.channel()`. `drivers.sms.transport` selects the SMS provider transport, either `africastalking` or `twilio`.
package/dist/index.d.ts CHANGED
@@ -281,9 +281,17 @@ declare class PusherRealtimeDriver implements RealtimeDriver {
281
281
  private cluster;
282
282
  private useTLS;
283
283
  private server;
284
+ /**
285
+ * The server address and TLS browsers connect with. Defaults to the address
286
+ * the server uses, which differs when it reaches the server over a private
287
+ * network (e.g. `soketi` inside Docker).
288
+ *
289
+ * @returns
290
+ */
291
+ private publicServer;
284
292
  /**
285
293
  * Public settings a `pusher-js` client needs, including the self-hosted
286
- * server address when `host` is set.
294
+ * server address when one is set.
287
295
  *
288
296
  * @returns
289
297
  */
@@ -450,6 +458,12 @@ type PusherTransportConfig = {
450
458
  */
451
459
  host?: string;
452
460
  port?: number;
461
+ /** The address browsers connect to, when it differs from `host` (defaults to `host`). */
462
+ public_host?: string;
463
+ /** The port browsers connect to (defaults to `port`). */
464
+ public_port?: number;
465
+ /** Whether browsers connect over TLS (defaults to `use_tls`). */
466
+ public_use_tls?: boolean;
453
467
  };
454
468
  type FirebaseTransportConfig = {
455
469
  project_id?: string;
@@ -767,6 +781,9 @@ interface NotificationConfig<T = any> {
767
781
  use_tls?: boolean;
768
782
  host?: string;
769
783
  port?: number;
784
+ public_host?: string;
785
+ public_port?: number;
786
+ public_use_tls?: boolean;
770
787
  };
771
788
  firebase?: ({
772
789
  project_id: string;
package/dist/index.js CHANGED
@@ -49,12 +49,12 @@ var NotificationContract = class {
49
49
  }
50
50
  /**
51
51
  * Send the notification to our configured queue
52
- *
53
- * @param message
54
- * @param subject
55
- * @param recipient
56
- * @param data
57
- * @returns
52
+ *
53
+ * @param message
54
+ * @param subject
55
+ * @param recipient
56
+ * @param data
57
+ * @returns
58
58
  */
59
59
  async queue(message, subject, recipient, data) {
60
60
  const job = SendNotification.dispatch(this, message, subject, recipient, data);
@@ -91,9 +91,9 @@ var UserNotificationCenter = class {
91
91
  }
92
92
  /**
93
93
  * Create a database notification
94
- *
95
- * @param user
96
- * @param payload
94
+ *
95
+ * @param user
96
+ * @param payload
97
97
  */
98
98
  static async create(user, payload) {
99
99
  return await (await this.getModel()).query().create({
@@ -116,8 +116,8 @@ var UserNotificationCenter = class {
116
116
  }
117
117
  /**
118
118
  * Mark the notification as read
119
- *
120
- * @param notification
119
+ *
120
+ * @param notification
121
121
  */
122
122
  static async markRead(notification) {
123
123
  const Model = await this.getModel();
@@ -128,8 +128,8 @@ var UserNotificationCenter = class {
128
128
  }
129
129
  /**
130
130
  * Mark all unread notifications as read
131
- *
132
- * @param user
131
+ *
132
+ * @param user
133
133
  */
134
134
  static async markAllRead(user, ids) {
135
135
  const query = (await this.getModel()).query().where({ userId: user.id }).whereNull("readAt");
@@ -137,8 +137,8 @@ var UserNotificationCenter = class {
137
137
  }
138
138
  /**
139
139
  * Delete the indicated notifications
140
- *
141
- * @param notification
140
+ *
141
+ * @param notification
142
142
  */
143
143
  static async delete(notification) {
144
144
  const Model = await this.getModel();
@@ -194,7 +194,7 @@ var DbNotification = class extends NotificationContract {
194
194
  }
195
195
  /**
196
196
  * Broadcast the notification using the default realtime driver.
197
- *
197
+ *
198
198
  * @param realtime Set to false to disable realtime broadcast
199
199
  * @returns
200
200
  */
@@ -209,12 +209,12 @@ var DbNotification = class extends NotificationContract {
209
209
  }
210
210
  /**
211
211
  * Send the database notification
212
- *
213
- * @param message
214
- * @param subject
215
- * @param _recipient
216
- * @param data
217
- * @returns
212
+ *
213
+ * @param message
214
+ * @param subject
215
+ * @param _recipient
216
+ * @param data
217
+ * @returns
218
218
  */
219
219
  async send(message, subject, _recipient, data) {
220
220
  if (!this.user) throw new Error("No user recipient provided for database notification");
@@ -339,8 +339,8 @@ var MailNotification = class extends NotificationContract {
339
339
  }
340
340
  /**
341
341
  * Attachemnts to send with the mail
342
- *
343
- * @param attachments
342
+ *
343
+ * @param attachments
344
344
  */
345
345
  attachments(attachments) {
346
346
  this.attachmentList = attachments;
@@ -348,7 +348,7 @@ var MailNotification = class extends NotificationContract {
348
348
  }
349
349
  /**
350
350
  * A single attachemnt to send with the mail
351
- *
351
+ *
352
352
  * @param attachment
353
353
  */
354
354
  attachment(attachment) {
@@ -755,9 +755,9 @@ var FirebaseRealtimeDriver = class {
755
755
  * derived only once the message is demonstrably a *visible* push, which a
756
756
  * caller declares through the `apns` escape hatch. Guessing otherwise would
757
757
  * mean sending APNs something it is documented to reject.
758
- *
759
- * @param delivery
760
- * @returns
758
+ *
759
+ * @param delivery
760
+ * @returns
761
761
  */
762
762
  overridesFor(delivery) {
763
763
  const base = this.options.delivery ?? {};
@@ -820,11 +820,11 @@ var FirebaseRealtimeDriver = class {
820
820
  /**
821
821
  * Fold a caller's raw override over the derived settings, dropping the block
822
822
  * entirely when neither contributed anything.
823
- *
824
- * @param key
825
- * @param derived
826
- * @param override
827
- * @returns
823
+ *
824
+ * @param key
825
+ * @param derived
826
+ * @param override
827
+ * @returns
828
828
  */
829
829
  flatBlock(key, derived, override) {
830
830
  const block = {
@@ -836,11 +836,11 @@ var FirebaseRealtimeDriver = class {
836
836
  /**
837
837
  * As `flatBlock`, but for the platforms whose settings live under `headers` —
838
838
  * merged key by key, so an override adding one header keeps the rest.
839
- *
840
- * @param key
841
- * @param derived
842
- * @param override
843
- * @returns
839
+ *
840
+ * @param key
841
+ * @param derived
842
+ * @param override
843
+ * @returns
844
844
  */
845
845
  headerBlock(key, derived, override) {
846
846
  const { headers: overrideHeaders, ...rest } = override ?? {};
@@ -863,27 +863,27 @@ var FirebaseRealtimeDriver = class {
863
863
  }
864
864
  /**
865
865
  * Firebase channels do not require server-side authorization.
866
- *
867
- * @param _socketId
868
- * @param _channel
869
- * @param _data
866
+ *
867
+ * @param _socketId
868
+ * @param _channel
869
+ * @param _data
870
870
  */
871
871
  async auth(_socketId, _channel, _data) {}
872
- /**
872
+ /**
873
873
  * Firebase does not require an authorization route.
874
- *
875
- * @param _authEndpoint
876
- * @param _middleware
877
- * @param _channelPrefix
878
- * @param _config
874
+ *
875
+ * @param _authEndpoint
876
+ * @param _middleware
877
+ * @param _channelPrefix
878
+ * @param _config
879
879
  */
880
880
  static async registerAuthRoute(_authEndpoint = "/realtime/auth", _middleware, _channelPrefix, _config = {}) {}
881
- /**
881
+ /**
882
882
  * Firebase does not require an authorization route.
883
- *
884
- * @param _authEndpoint
885
- * @param _middleware
886
- * @param _channelPrefix
883
+ *
884
+ * @param _authEndpoint
885
+ * @param _middleware
886
+ * @param _channelPrefix
887
887
  */
888
888
  async registerAuthRoute(_authEndpoint = "/realtime/auth", _middleware, _channelPrefix) {}
889
889
  /**
@@ -1032,17 +1032,35 @@ var PusherRealtimeDriver = class PusherRealtimeDriver {
1032
1032
  };
1033
1033
  }
1034
1034
  /**
1035
+ * The server address and TLS browsers connect with. Defaults to the address
1036
+ * the server uses, which differs when it reaches the server over a private
1037
+ * network (e.g. `soketi` inside Docker).
1038
+ *
1039
+ * @returns
1040
+ */
1041
+ publicServer() {
1042
+ const server = this.server();
1043
+ const host = this.options.public_host ?? (env("PUSHER_PUBLIC_HOST", "") || server.host);
1044
+ const port = this.options.public_port ?? (Number(env("PUSHER_PUBLIC_PORT", 0)) || server.port);
1045
+ const tls = env("PUSHER_PUBLIC_USE_TLS", "");
1046
+ return {
1047
+ host,
1048
+ port,
1049
+ useTLS: this.options.public_use_tls ?? (tls === "" ? this.useTLS() : String(tls) === "true")
1050
+ };
1051
+ }
1052
+ /**
1035
1053
  * Public settings a `pusher-js` client needs, including the self-hosted
1036
- * server address when `host` is set.
1054
+ * server address when one is set.
1037
1055
  *
1038
1056
  * @returns
1039
1057
  */
1040
1058
  clientConfig() {
1041
- const { host, port } = this.server();
1059
+ const { host, port, useTLS } = this.publicServer();
1042
1060
  return {
1043
1061
  key: this.key(),
1044
1062
  cluster: this.cluster(),
1045
- forceTLS: this.useTLS(),
1063
+ forceTLS: useTLS,
1046
1064
  ...host ? {
1047
1065
  wsHost: host,
1048
1066
  wsPort: port,
@@ -1054,43 +1072,43 @@ var PusherRealtimeDriver = class PusherRealtimeDriver {
1054
1072
  * `delivery` is accepted for contract parity and ignored: Pusher pushes over a
1055
1073
  * connection the client already holds open, so there is no dozing radio to
1056
1074
  * wake and no per-message priority, TTL or collapse key to set.
1057
- *
1058
- * @param channel
1059
- * @param event
1060
- * @param payload
1061
- * @param _delivery
1062
- * @returns
1075
+ *
1076
+ * @param channel
1077
+ * @param event
1078
+ * @param payload
1079
+ * @param _delivery
1080
+ * @returns
1063
1081
  */
1064
1082
  async broadcast(channel, event, payload, _delivery) {
1065
1083
  return await (await this.client()).trigger(channel, event, payload);
1066
1084
  }
1067
1085
  /**
1068
1086
  * Authourize a pusher channel
1069
- *
1070
- * @param socketId
1071
- * @param channel
1072
- * @returns
1087
+ *
1088
+ * @param socketId
1089
+ * @param channel
1090
+ * @returns
1073
1091
  */
1074
1092
  async auth(socketId, channel, data) {
1075
1093
  return (await this.client()).authorizeChannel(socketId, channel, data);
1076
1094
  }
1077
1095
  /**
1078
1096
  * Register a realtime autorization route
1079
- *
1080
- * @param authEndpoint
1081
- * @param middleware
1082
- * @param config
1083
- * @param channelPrefix
1097
+ *
1098
+ * @param authEndpoint
1099
+ * @param middleware
1100
+ * @param config
1101
+ * @param channelPrefix
1084
1102
  */
1085
1103
  static async registerAuthRoute(authEndpoint = "/realtime/auth", middleware, channelPrefix, config = {}) {
1086
1104
  return new PusherRealtimeDriver(config).registerAuthRoute(authEndpoint, middleware, channelPrefix);
1087
1105
  }
1088
1106
  /**
1089
1107
  * Register a realtime autorization route
1090
- *
1091
- * @param authEndpoint
1092
- * @param middleware
1093
- * @param channelPrefix
1108
+ *
1109
+ * @param authEndpoint
1110
+ * @param middleware
1111
+ * @param channelPrefix
1094
1112
  */
1095
1113
  async registerAuthRoute(authEndpoint = "/realtime/auth", middleware, channelPrefix) {
1096
1114
  for (const path of ["@arkstack/driver-express", "@arkstack/driver-h3"]) try {
@@ -1393,10 +1411,10 @@ var RealtimeNotification = class extends NotificationContract {
1393
1411
  }
1394
1412
  /**
1395
1413
  * Overide the default transport
1396
- *
1397
- * @param transport
1398
- * @param options
1399
- * @returns
1414
+ *
1415
+ * @param transport
1416
+ * @param options
1417
+ * @returns
1400
1418
  */
1401
1419
  transport(transport, options) {
1402
1420
  this.driver = Broadcast.make(transport, options);
@@ -1425,20 +1443,20 @@ var RealtimeNotification = class extends NotificationContract {
1425
1443
  return this;
1426
1444
  }
1427
1445
  /**
1428
- * The event name clients subscribe to (default `notification`).
1429
- *
1430
- * @param channel
1431
- * @returns
1446
+ * The event name clients subscribe to (default `notification`).
1447
+ *
1448
+ * @param channel
1449
+ * @returns
1432
1450
  */
1433
1451
  event(event) {
1434
1452
  this.eventName = event;
1435
1453
  return this;
1436
1454
  }
1437
1455
  /**
1438
- * Also persist the notification (requires a `User` recipient).
1439
- *
1440
- * @param channel
1441
- * @returns
1456
+ * Also persist the notification (requires a `User` recipient).
1457
+ *
1458
+ * @param channel
1459
+ * @returns
1442
1460
  */
1443
1461
  store(store = true) {
1444
1462
  this.shouldStore = store;
@@ -1590,12 +1608,12 @@ var RealtimeNotification = class extends NotificationContract {
1590
1608
  }
1591
1609
  /**
1592
1610
  * Send a realtime notification using the default realtime driver
1593
- *
1594
- * @param message
1595
- * @param subject
1596
- * @param _recipient
1597
- * @param data
1598
- * @returns
1611
+ *
1612
+ * @param message
1613
+ * @param subject
1614
+ * @param _recipient
1615
+ * @param data
1616
+ * @returns
1599
1617
  */
1600
1618
  async send(message = "", subject, _recipient, data) {
1601
1619
  const channel = this.resolveChannel();
@@ -1741,46 +1759,46 @@ var Notification = class Notification {
1741
1759
  }
1742
1760
  /**
1743
1761
  * Send an email notification
1744
- *
1745
- * @param options
1746
- * @returns
1762
+ *
1763
+ * @param options
1764
+ * @returns
1747
1765
  */
1748
1766
  static mail(options) {
1749
1767
  return new MailNotification(options);
1750
1768
  }
1751
1769
  /**
1752
1770
  * Send an email notification
1753
- *
1754
- * @param options
1771
+ *
1772
+ * @param options
1755
1773
  * @alias {@link mail}
1756
- * @returns
1774
+ * @returns
1757
1775
  */
1758
1776
  static email(options) {
1759
1777
  return this.mail(options);
1760
1778
  }
1761
1779
  /**
1762
1780
  * Send an sms notification
1763
- *
1764
- * @param options
1765
- * @returns
1781
+ *
1782
+ * @param options
1783
+ * @returns
1766
1784
  */
1767
1785
  static sms(options) {
1768
1786
  return new SmsNotification(options);
1769
1787
  }
1770
1788
  /**
1771
1789
  * Send a database notification
1772
- *
1773
- * @param options
1774
- * @returns
1790
+ *
1791
+ * @param options
1792
+ * @returns
1775
1793
  */
1776
1794
  static db() {
1777
1795
  return new DbNotification();
1778
1796
  }
1779
1797
  /**
1780
1798
  * Send a realtime notification
1781
- *
1782
- * @param options
1783
- * @returns
1799
+ *
1800
+ * @param options
1801
+ * @returns
1784
1802
  */
1785
1803
  static realtime(options) {
1786
1804
  return new RealtimeNotification(options);
@@ -1791,10 +1809,10 @@ var Notification = class Notification {
1791
1809
  }
1792
1810
  /**
1793
1811
  * Prepare the notification
1794
- *
1795
- * @param recipient
1796
- * @param data
1797
- * @returns
1812
+ *
1813
+ * @param recipient
1814
+ * @param data
1815
+ * @returns
1798
1816
  */
1799
1817
  prepare(recipient, data = {}) {
1800
1818
  this.driver.data(data);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkstack/notifications",
3
- "version": "0.19.2",
3
+ "version": "0.19.4",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic notification module for Arkstack and Nodejs, providing support for multi-channel notification delivery.",
6
6
  "homepage": "https://arkstack.toneflix.net/guide/notifications",
@@ -34,17 +34,17 @@
34
34
  "africastalking": "^0.8.0",
35
35
  "nodemailer": "^9.0.3",
36
36
  "twilio": "^6.0.2",
37
- "@arkstack/common": "^0.19.2"
37
+ "@arkstack/common": "^0.19.4"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@kanun-hq/plugin-phone": "^0.1.8",
41
41
  "firebase-admin": "^13.0.0",
42
42
  "pusher": "^5.2.0",
43
- "@arkstack/contract": "^0.19.2",
44
- "@arkstack/database": "^0.19.2",
45
- "@arkstack/driver-express": "^0.19.2",
46
- "@arkstack/driver-h3": "^0.19.2",
47
- "@arkstack/jobs": "^0.19.2"
43
+ "@arkstack/database": "^0.19.4",
44
+ "@arkstack/driver-h3": "^0.19.4",
45
+ "@arkstack/contract": "^0.19.4",
46
+ "@arkstack/jobs": "^0.19.4",
47
+ "@arkstack/driver-express": "^0.19.4"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "@arkstack/driver-express": {