@arkstack/notifications 0.16.11 → 0.16.13

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/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { Model } from "@arkstack/database";
4
4
  import { User } from "@app/models/User";
5
5
  import { User as User$1 } from "@arkstack/auth";
6
6
  import { PhoneNumber } from "@kanun-hq/plugin-phone";
7
+ import { ArkormCollection, LengthAwarePaginator } from "arkormx";
7
8
 
8
9
  //#region src/Contracts/UserNotification.d.ts
9
10
  declare abstract class UserNotification extends Model {
@@ -214,13 +215,29 @@ declare abstract class NotificationContract<TResult = DriverResult> {
214
215
  declare class DbNotification extends NotificationContract<UserNotification> {
215
216
  private user?;
216
217
  private payload;
218
+ private realtime;
217
219
  from(_from: string): this;
218
220
  subject(subject: string): this;
219
221
  recipient(recipient: NotificationRecipient | User): this;
220
222
  type(type: DbNotificationPayload['type']): this;
221
223
  action(text?: string | null, link?: string | null): this;
222
224
  meta(meta?: NotificationData | null): this;
225
+ /**
226
+ * Broadcast the notification using the default realtime driver.
227
+ *
228
+ * @param realtime Set to false to disable realtime broadcast
229
+ */
230
+ broadcast(realtime?: boolean): void;
223
231
  create(user: User, payload: DbNotificationPayload): Promise<UserNotification>;
232
+ /**
233
+ * Send the database notification
234
+ *
235
+ * @param message
236
+ * @param subject
237
+ * @param _recipient
238
+ * @param data
239
+ * @returns
240
+ */
224
241
  send(message: string, subject?: string, _recipient?: NotificationRecipient, data?: NotificationData): Promise<UserNotification>;
225
242
  }
226
243
  //#endregion
@@ -357,10 +374,19 @@ declare class RealtimeNotification extends NotificationContract<RealtimeBroadcas
357
374
  * @returns
358
375
  */
359
376
  store(store?: boolean): this;
360
- type(type: DbNotificationType | null): this;
377
+ type(type?: DbNotificationType | null): this;
361
378
  action(text?: string | null, link?: string | null): this;
362
379
  meta(meta?: NotificationData | null): this;
363
380
  private resolveChannel;
381
+ /**
382
+ * Send a realtime notification using the default realtime driver
383
+ *
384
+ * @param message
385
+ * @param subject
386
+ * @param _recipient
387
+ * @param data
388
+ * @returns
389
+ */
364
390
  send(message: string, subject?: string, _recipient?: NotificationRecipient, data?: NotificationData): Promise<RealtimeBroadcastResult>;
365
391
  }
366
392
  //#endregion
@@ -421,12 +447,53 @@ declare class Notification<D extends keyof DriverMap = keyof DriverMap> {
421
447
  //#region src/UserNotificationCenter.d.ts
422
448
  declare class UserNotificationCenter {
423
449
  private static getModel;
450
+ /**
451
+ * Create a database notification then broadcast it using the configured realtime driver
452
+ *
453
+ * @param user
454
+ * @param payload
455
+ */
456
+ static send(user: User, payload: DbNotificationPayload, channel?: string[]): Promise<RealtimeBroadcastResult>;
457
+ private static resolvePushTokens;
458
+ /**
459
+ * Create a database notification
460
+ *
461
+ * @param user
462
+ * @param payload
463
+ */
424
464
  static create(user: User, payload: DbNotificationPayload): Promise<UserNotification>;
425
- static forUser(user: User): Promise<import("arkormx").ArkormCollection<UserNotification, UserNotification[]>>;
426
- static unreadForUser(user: User): Promise<import("arkormx").ArkormCollection<UserNotification, UserNotification[]>>;
427
- static markRead(notification: UserNotification | UserNotification['id']): Promise<void>;
428
- static markAllRead(user: User): Promise<void>;
429
- static delete(notification: UserNotification | UserNotification['id']): Promise<void>;
465
+ static forUser(user: User): Promise<ArkormCollection<UserNotification, UserNotification[]>>;
466
+ /**
467
+ * Fetch all the users unread messages
468
+ *
469
+ * @param user
470
+ */
471
+ static unreadForUser(user: User): Promise<ArkormCollection<UserNotification, UserNotification[]>>;
472
+ /**
473
+ * Fetch all the users unread messages with a lenght aware paginator instance
474
+ *
475
+ * @param user
476
+ * @param perPage
477
+ */
478
+ static unreadForUser(user: User, perPage: number): Promise<LengthAwarePaginator<UserNotification>>;
479
+ /**
480
+ * Mark the notification as read
481
+ *
482
+ * @param notification
483
+ */
484
+ static markRead(notification: UserNotification | string | number): Promise<void>;
485
+ /**
486
+ * Mark all unread notifications as read
487
+ *
488
+ * @param user
489
+ */
490
+ static markAllRead(user: User, ids?: string[] | number[]): Promise<void>;
491
+ /**
492
+ * Delete the indicated notifications
493
+ *
494
+ * @param notification
495
+ */
496
+ static delete(notification: UserNotification | string | number | UserNotification[] | string[] | number[]): Promise<void>;
430
497
  }
431
498
  //#endregion
432
499
  //#region src/config.d.ts
package/dist/index.js CHANGED
@@ -29,6 +29,26 @@ var UserNotificationCenter = class {
29
29
  static async getModel() {
30
30
  return await getModel("UserNotification");
31
31
  }
32
+ /**
33
+ * Create a database notification then broadcast it using the configured realtime driver
34
+ *
35
+ * @param user
36
+ * @param payload
37
+ */
38
+ static async send(user, payload, channel = []) {
39
+ return await Notification.realtime().store().channel(this.resolvePushTokens(user.pushTokens ?? channel)).meta(payload.meta).type(payload.type).subject(payload.title).action(payload.actionText, payload.actionLink).send(payload.description, payload.title, void 0, payload);
40
+ }
41
+ static resolvePushTokens(pushTokens) {
42
+ if (!pushTokens) return [];
43
+ if (Array.isArray(pushTokens)) return pushTokens.map((e) => typeof e === "string" ? e : e.token);
44
+ return [typeof pushTokens === "string" ? pushTokens : pushTokens.token];
45
+ }
46
+ /**
47
+ * Create a database notification
48
+ *
49
+ * @param user
50
+ * @param payload
51
+ */
32
52
  static async create(user, payload) {
33
53
  return await (await this.getModel()).query().create({
34
54
  userId: user.id,
@@ -43,12 +63,19 @@ var UserNotificationCenter = class {
43
63
  static async forUser(user) {
44
64
  return await (await this.getModel()).query().where({ userId: user.id }).get();
45
65
  }
46
- static async unreadForUser(user) {
47
- return await (await this.getModel()).query().where({
66
+ static async unreadForUser(user, perPage) {
67
+ const query = (await this.getModel()).query().where({
48
68
  userId: user.id,
49
69
  readAt: null
50
- }).get();
70
+ });
71
+ if (perPage) return await query.paginate();
72
+ return await query.get();
51
73
  }
74
+ /**
75
+ * Mark the notification as read
76
+ *
77
+ * @param notification
78
+ */
52
79
  static async markRead(notification) {
53
80
  const Model = await this.getModel();
54
81
  const id = typeof notification === "object" ? notification.id : notification;
@@ -56,16 +83,33 @@ var UserNotificationCenter = class {
56
83
  await Model.query().where({ id }).update({ readAt });
57
84
  if (typeof notification === "object") notification.readAt = readAt;
58
85
  }
59
- static async markAllRead(user) {
60
- await (await this.getModel()).query().where({
86
+ /**
87
+ * Mark all unread notifications as read
88
+ *
89
+ * @param user
90
+ */
91
+ static async markAllRead(user, ids) {
92
+ const query = (await this.getModel()).query().where({
61
93
  userId: user.id,
62
94
  readAt: null
63
- }).update({ readAt: /* @__PURE__ */ new Date() });
95
+ });
96
+ if (ids) query.whereIn("id", ids);
97
+ await query.update({ readAt: /* @__PURE__ */ new Date() });
64
98
  }
99
+ /**
100
+ * Delete the indicated notifications
101
+ *
102
+ * @param notification
103
+ */
65
104
  static async delete(notification) {
66
105
  const Model = await this.getModel();
67
- const id = typeof notification === "object" ? notification.id : notification;
68
- await Model.query().where({ id }).delete();
106
+ if (Array.isArray(notification)) {
107
+ const ids = notification.map((e) => typeof e === "object" ? e.id : e);
108
+ await Model.query().whereIn("id", ids).delete();
109
+ } else {
110
+ const id = typeof notification === "object" ? notification.id : notification;
111
+ await Model.query().where({ id }).delete();
112
+ }
69
113
  }
70
114
  };
71
115
  //#endregion
@@ -81,6 +125,7 @@ const interpolate = (value, data = {}) => {
81
125
  var DbNotification = class extends NotificationContract {
82
126
  user;
83
127
  payload = {};
128
+ realtime = false;
84
129
  from(_from) {
85
130
  return this;
86
131
  }
@@ -108,10 +153,28 @@ var DbNotification = class extends NotificationContract {
108
153
  this.payload.meta = meta;
109
154
  return this;
110
155
  }
156
+ /**
157
+ * Broadcast the notification using the default realtime driver.
158
+ *
159
+ * @param realtime Set to false to disable realtime broadcast
160
+ */
161
+ broadcast(realtime = true) {
162
+ this.realtime = realtime;
163
+ }
111
164
  async create(user, payload) {
112
165
  await getModel("UserNotification");
166
+ if (this.realtime) return await UserNotificationCenter.send(user, payload);
113
167
  return await UserNotificationCenter.create(user, payload);
114
168
  }
169
+ /**
170
+ * Send the database notification
171
+ *
172
+ * @param message
173
+ * @param subject
174
+ * @param _recipient
175
+ * @param data
176
+ * @returns
177
+ */
115
178
  async send(message, subject, _recipient, data) {
116
179
  if (!this.user) throw new Error("No user recipient provided for database notification");
117
180
  const mergedData = this.mergeData(data);
@@ -545,6 +608,15 @@ var RealtimeNotification = class extends NotificationContract {
545
608
  if (this.user) return `${this.channelPrefix}${this.user.id}`;
546
609
  throw new Error("No channel resolved for realtime notification (provide a user or channel)");
547
610
  }
611
+ /**
612
+ * Send a realtime notification using the default realtime driver
613
+ *
614
+ * @param message
615
+ * @param subject
616
+ * @param _recipient
617
+ * @param data
618
+ * @returns
619
+ */
548
620
  async send(message, subject, _recipient, data) {
549
621
  const channel = this.resolveChannel();
550
622
  const mergedData = this.mergeData(data);
@@ -568,7 +640,7 @@ var RealtimeNotification = class extends NotificationContract {
568
640
  read_at: stored?.readAt ? new Date(stored.readAt).toISOString() : null,
569
641
  created_at: stored?.createdAt ? new Date(stored.createdAt).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
570
642
  };
571
- await this.driver.broadcast(channel, this.eventName, payload);
643
+ if (channel && channel.length > 0) await this.driver.broadcast(channel, this.eventName, payload);
572
644
  return {
573
645
  channel,
574
646
  event: this.eventName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkstack/notifications",
3
- "version": "0.16.11",
3
+ "version": "0.16.13",
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,14 +34,14 @@
34
34
  "africastalking": "^0.8.0",
35
35
  "nodemailer": "^8.0.7",
36
36
  "twilio": "^6.0.0",
37
- "@arkstack/common": "^0.16.11"
37
+ "@arkstack/common": "^0.16.13"
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.16.11",
44
- "@arkstack/database": "^0.16.11"
43
+ "@arkstack/contract": "^0.16.13",
44
+ "@arkstack/database": "^0.16.13"
45
45
  },
46
46
  "peerDependenciesMeta": {
47
47
  "pusher": {