vintasend-prisma 0.3.0 → 0.4.0

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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PrismaNotificationBackendFactory = exports.PrismaNotificationBackend = exports.NotificationTypeEnum = exports.NotificationStatusEnum = void 0;
4
+ const attachment_1 = require("vintasend/dist/types/attachment");
4
5
  exports.NotificationStatusEnum = {
5
6
  PENDING_SEND: 'PENDING_SEND',
6
7
  SENT: 'SENT',
@@ -14,6 +15,14 @@ exports.NotificationTypeEnum = {
14
15
  SMS: 'SMS',
15
16
  IN_APP: 'IN_APP',
16
17
  };
18
+ // Centralized attachment include shape for DRY
19
+ const notificationWithAttachmentsInclude = {
20
+ attachments: {
21
+ include: {
22
+ attachmentFile: true,
23
+ },
24
+ },
25
+ };
17
26
  function convertJsonValueToRecord(jsonValue) {
18
27
  if (typeof jsonValue === 'object' && !Array.isArray(jsonValue)) {
19
28
  return jsonValue;
@@ -21,8 +30,15 @@ function convertJsonValueToRecord(jsonValue) {
21
30
  throw new Error('Invalid JSON value. It should be an object.');
22
31
  }
23
32
  class PrismaNotificationBackend {
24
- constructor(prismaClient) {
33
+ constructor(prismaClient, attachmentManager) {
25
34
  this.prismaClient = prismaClient;
35
+ this.attachmentManager = attachmentManager;
36
+ }
37
+ /**
38
+ * Inject attachment manager (called by VintaSend when both service and backend exist)
39
+ */
40
+ injectAttachmentManager(manager) {
41
+ this.attachmentManager = manager;
26
42
  }
27
43
  /**
28
44
  * Build a where clause for status-based updates
@@ -62,6 +78,10 @@ class PrismaNotificationBackend {
62
78
  readAt: notification.readAt,
63
79
  createdAt: notification.createdAt,
64
80
  updatedAt: notification.updatedAt,
81
+ // Serialize attachments if present and attachmentManager is available
82
+ attachments: notification.attachments && this.attachmentManager
83
+ ? notification.attachments.map((att) => this.serializeStoredAttachment(att))
84
+ : undefined,
65
85
  };
66
86
  // Check if this is a one-off notification (has emailOrPhone but no userId)
67
87
  // Use explicit null checks to avoid misclassification with empty strings or other falsy values
@@ -125,21 +145,26 @@ class PrismaNotificationBackend {
125
145
  sendAfter: notification.sendAfter,
126
146
  subjectTemplate: notification.subjectTemplate,
127
147
  extraParams: notification.extraParams,
148
+ // Only include one-off fields if this is actually a one-off notification
149
+ ...(isOneOff && {
150
+ emailOrPhone: 'emailOrPhone' in notification ? notification.emailOrPhone : null,
151
+ firstName: 'firstName' in notification ? (_a = notification.firstName) !== null && _a !== void 0 ? _a : null : null,
152
+ lastName: 'lastName' in notification ? (_b = notification.lastName) !== null && _b !== void 0 ? _b : null : null,
153
+ }),
128
154
  };
129
155
  if (isOneOff) {
130
156
  return {
131
157
  ...base,
132
158
  userId: null,
133
- emailOrPhone: 'emailOrPhone' in notification ? notification.emailOrPhone : '',
134
- firstName: (_a = ('firstName' in notification ? notification.firstName : null)) !== null && _a !== void 0 ? _a : null,
135
- lastName: (_b = ('lastName' in notification ? notification.lastName : null)) !== null && _b !== void 0 ? _b : null,
136
159
  status: exports.NotificationStatusEnum.PENDING_SEND,
160
+ user: undefined,
137
161
  };
138
162
  }
139
163
  // At this point we know hasUserId is true, so userId exists and is not null
140
164
  const userId = ('userId' in notification ? notification.userId : null);
141
165
  return {
142
166
  ...base,
167
+ userId,
143
168
  user: {
144
169
  connect: { id: userId },
145
170
  },
@@ -240,6 +265,123 @@ class PrismaNotificationBackend {
240
265
  }
241
266
  return data;
242
267
  }
268
+ /**
269
+ * Get or create file record for attachment upload with deduplication (transaction-aware)
270
+ * @private
271
+ */
272
+ async getOrCreateFileRecordForUploadInTransaction(tx, att) {
273
+ const manager = this.getAttachmentManager();
274
+ const buffer = await manager.fileToBuffer(att.file);
275
+ const checksum = manager.calculateChecksum(buffer);
276
+ let fileRecord = await this.findAttachmentFileByChecksumInTransaction(tx, checksum);
277
+ if (!fileRecord) {
278
+ fileRecord = await manager.uploadFile(att.file, att.filename, att.contentType);
279
+ await tx.attachmentFile.create({
280
+ data: {
281
+ id: fileRecord.id,
282
+ filename: fileRecord.filename,
283
+ contentType: fileRecord.contentType,
284
+ size: fileRecord.size,
285
+ checksum: fileRecord.checksum,
286
+ storageMetadata: fileRecord.storageMetadata,
287
+ },
288
+ });
289
+ }
290
+ return fileRecord;
291
+ }
292
+ /**
293
+ * Get or create file record for attachment upload with deduplication (non-transactional)
294
+ * @private
295
+ */
296
+ async getOrCreateFileRecordForUpload(att) {
297
+ return this.getOrCreateFileRecordForUploadInTransaction(this.prismaClient, att);
298
+ }
299
+ /**
300
+ * Create notification attachment link (transaction-aware)
301
+ * @private
302
+ */
303
+ async createNotificationAttachmentLinkInTransaction(tx, notificationId, fileId, description) {
304
+ await tx.notificationAttachment.create({
305
+ data: {
306
+ notificationId,
307
+ fileId,
308
+ description: description !== null && description !== void 0 ? description : null,
309
+ },
310
+ });
311
+ }
312
+ /**
313
+ * Create notification attachment link (non-transactional)
314
+ * @private
315
+ */
316
+ async createNotificationAttachmentLink(notificationId, fileId, description) {
317
+ return this.createNotificationAttachmentLinkInTransaction(this.prismaClient, notificationId, fileId, description);
318
+ }
319
+ /**
320
+ * Get attachment file by ID (transaction-aware)
321
+ * @private
322
+ */
323
+ async getAttachmentFileInTransaction(tx, fileId) {
324
+ const file = await tx.attachmentFile.findUnique({
325
+ where: { id: fileId },
326
+ });
327
+ if (!file)
328
+ return null;
329
+ return this.serializeAttachmentFileRecord(file);
330
+ }
331
+ /**
332
+ * Find attachment file by checksum (transaction-aware)
333
+ * @private
334
+ */
335
+ async findAttachmentFileByChecksumInTransaction(tx, checksum) {
336
+ const file = await tx.attachmentFile.findUnique({
337
+ where: { checksum },
338
+ });
339
+ if (!file)
340
+ return null;
341
+ return this.serializeAttachmentFileRecord(file);
342
+ }
343
+ /**
344
+ * Core helper for creating notifications with attachments (both regular and one-off)
345
+ * Uses transactions to ensure atomicity - if attachment processing fails, the notification won't be created
346
+ * @private
347
+ */
348
+ async createNotificationWithAttachments(input, buildData, serialize) {
349
+ const { attachments, ...notificationData } = input;
350
+ // If no attachments, skip transaction overhead
351
+ if (!attachments || attachments.length === 0) {
352
+ const created = await this.prismaClient.notification.create({
353
+ data: buildData(notificationData),
354
+ include: notificationWithAttachmentsInclude,
355
+ });
356
+ return serialize(created);
357
+ }
358
+ // Use transaction to ensure atomicity of notification + attachments
359
+ return await this.prismaClient.$transaction(async (tx) => {
360
+ const created = await tx.notification.create({
361
+ data: buildData(notificationData),
362
+ include: notificationWithAttachmentsInclude,
363
+ });
364
+ await this.processAndStoreAttachmentsInTransaction(tx, created.id, attachments);
365
+ const withAttachments = await tx.notification.findUnique({
366
+ where: { id: created.id },
367
+ include: notificationWithAttachmentsInclude,
368
+ });
369
+ if (!withAttachments) {
370
+ throw new Error('Failed to retrieve notification after creating attachments');
371
+ }
372
+ return serialize(withAttachments);
373
+ });
374
+ }
375
+ /**
376
+ * Get attachment manager with null check
377
+ * @private
378
+ */
379
+ getAttachmentManager() {
380
+ if (!this.attachmentManager) {
381
+ throw new Error('AttachmentManager is required but not provided');
382
+ }
383
+ return this.attachmentManager;
384
+ }
243
385
  deserializeNotification(notification) {
244
386
  return this.buildCreateData(notification);
245
387
  }
@@ -342,10 +484,7 @@ class PrismaNotificationBackend {
342
484
  return notifications.map((n) => this.serializeAnyNotification(n));
343
485
  }
344
486
  async persistNotification(notification) {
345
- const created = await this.prismaClient.notification.create({
346
- data: this.deserializeRegularNotification(notification),
347
- });
348
- return this.serializeRegularNotification(created);
487
+ return this.createNotificationWithAttachments(notification, (n) => this.deserializeRegularNotification(n), (db) => this.serializeRegularNotification(db));
349
488
  }
350
489
  async persistNotificationUpdate(notificationId, notification) {
351
490
  const updated = await this.prismaClient.notification.update({
@@ -358,10 +497,7 @@ class PrismaNotificationBackend {
358
497
  }
359
498
  /* One-off notification persistence and query methods */
360
499
  async persistOneOffNotification(notification) {
361
- const created = await this.prismaClient.notification.create({
362
- data: this.buildOneOffNotificationData(notification),
363
- });
364
- return this.serializeOneOffNotification(created);
500
+ return this.createNotificationWithAttachments(notification, (n) => this.buildOneOffNotificationData(n), (db) => this.serializeOneOffNotification(db));
365
501
  }
366
502
  async persistOneOffNotificationUpdate(notificationId, notification) {
367
503
  const updated = await this.prismaClient.notification.update({
@@ -460,6 +596,7 @@ class PrismaNotificationBackend {
460
596
  async getNotification(notificationId, _forUpdate) {
461
597
  const notification = await this.prismaClient.notification.findUnique({
462
598
  where: { id: notificationId },
599
+ include: notificationWithAttachmentsInclude,
463
600
  });
464
601
  if (!notification)
465
602
  return null;
@@ -502,19 +639,158 @@ class PrismaNotificationBackend {
502
639
  async storeContextUsed(notificationId, context) {
503
640
  await this.prismaClient.notification.update({
504
641
  where: { id: notificationId },
505
- data: { contextUsed: context }
642
+ data: { contextUsed: context },
506
643
  });
507
644
  }
508
645
  async bulkPersistNotifications(notifications) {
509
- return this.prismaClient.notification.createMany({
646
+ const created = await this.prismaClient.notification.createManyAndReturn({
510
647
  data: notifications.map((notification) => this.deserializeNotification(notification)),
511
648
  });
649
+ return created.map((n) => n.id);
650
+ }
651
+ /* Attachment management methods */
652
+ async getAttachmentFile(fileId) {
653
+ const file = await this.prismaClient.attachmentFile.findUnique({
654
+ where: { id: fileId },
655
+ });
656
+ if (!file)
657
+ return null;
658
+ return this.serializeAttachmentFileRecord(file);
659
+ }
660
+ /**
661
+ * Find an attachment file by checksum for deduplication.
662
+ * This allows the backend to check if a file already exists before uploading.
663
+ */
664
+ async findAttachmentFileByChecksum(checksum) {
665
+ const file = await this.prismaClient.attachmentFile.findUnique({
666
+ where: { checksum },
667
+ });
668
+ if (!file)
669
+ return null;
670
+ return this.serializeAttachmentFileRecord(file);
671
+ }
672
+ async deleteAttachmentFile(fileId) {
673
+ const file = await this.prismaClient.attachmentFile.findUnique({
674
+ where: { id: fileId },
675
+ });
676
+ // If there's no DB record, there's nothing to delete
677
+ if (!file)
678
+ return;
679
+ // First delete the underlying stored file so DB and storage stay in sync
680
+ const manager = this.getAttachmentManager();
681
+ await manager.deleteFile(fileId);
682
+ // Only after successful storage deletion, remove the DB record
683
+ await this.prismaClient.attachmentFile.delete({
684
+ where: { id: fileId },
685
+ });
686
+ }
687
+ async getOrphanedAttachmentFiles() {
688
+ const orphanedFiles = await this.prismaClient.attachmentFile.findMany({
689
+ where: {
690
+ notificationAttachments: { none: {} },
691
+ },
692
+ });
693
+ return orphanedFiles.map((file) => this.serializeAttachmentFileRecord(file));
694
+ }
695
+ async getAttachments(notificationId) {
696
+ const attachments = await this.prismaClient.notificationAttachment.findMany({
697
+ where: { notificationId },
698
+ include: { attachmentFile: true },
699
+ });
700
+ this.getAttachmentManager(); // Validate attachment manager exists
701
+ return attachments.map((att) => this.serializeStoredAttachment(att));
702
+ }
703
+ async deleteNotificationAttachment(notificationId, attachmentId) {
704
+ const result = await this.prismaClient.notificationAttachment.deleteMany({
705
+ where: {
706
+ id: attachmentId,
707
+ notificationId,
708
+ },
709
+ });
710
+ if (result.count === 0) {
711
+ throw new Error(`Attachment ${attachmentId} not found for notification ${notificationId}`);
712
+ }
713
+ }
714
+ /**
715
+ * Process and store attachments for a notification within a transaction.
716
+ * Handles both new file uploads and references to existing files.
717
+ * Uses attachmentManager for checksum calculation and storage operations.
718
+ * @private
719
+ */
720
+ async processAndStoreAttachmentsInTransaction(tx, notificationId, attachments) {
721
+ this.getAttachmentManager(); // Validate attachment manager exists
722
+ // Process each attachment
723
+ for (const att of attachments) {
724
+ if ((0, attachment_1.isAttachmentReference)(att)) {
725
+ // Reference existing file - just create the notification link
726
+ const fileRecord = await this.getAttachmentFileInTransaction(tx, att.fileId);
727
+ if (!fileRecord) {
728
+ throw new Error(`Referenced file ${att.fileId} not found`);
729
+ }
730
+ await this.createNotificationAttachmentLinkInTransaction(tx, notificationId, att.fileId, att.description);
731
+ }
732
+ else {
733
+ // Upload new file with deduplication
734
+ const fileRecord = await this.getOrCreateFileRecordForUploadInTransaction(tx, att);
735
+ await this.createNotificationAttachmentLinkInTransaction(tx, notificationId, fileRecord.id, att.description);
736
+ }
737
+ }
738
+ }
739
+ /**
740
+ * Process and store attachments for a notification (non-transactional version).
741
+ * Handles both new file uploads and references to existing files.
742
+ * Uses attachmentManager for checksum calculation and storage operations.
743
+ * @private
744
+ */
745
+ async processAndStoreAttachments(notificationId, attachments) {
746
+ return this.processAndStoreAttachmentsInTransaction(this.prismaClient, notificationId, attachments);
747
+ }
748
+ /**
749
+ * Serialize a Prisma attachment file model to AttachmentFileRecord
750
+ * @private
751
+ */
752
+ serializeAttachmentFileRecord(file) {
753
+ return {
754
+ id: file.id,
755
+ filename: file.filename,
756
+ contentType: file.contentType,
757
+ size: file.size,
758
+ checksum: file.checksum,
759
+ storageMetadata: file.storageMetadata,
760
+ createdAt: file.createdAt,
761
+ updatedAt: file.updatedAt,
762
+ };
763
+ }
764
+ /**
765
+ * Serialize a Prisma notification attachment model to StoredAttachment
766
+ * @private
767
+ */
768
+ serializeStoredAttachment(attachment) {
769
+ var _a;
770
+ const manager = this.getAttachmentManager();
771
+ if (!attachment.attachmentFile) {
772
+ throw new Error('AttachmentFile is required to reconstruct stored attachment');
773
+ }
774
+ const fileRecord = this.serializeAttachmentFileRecord(attachment.attachmentFile);
775
+ const attachmentFile = manager.reconstructAttachmentFile(fileRecord.storageMetadata);
776
+ return {
777
+ id: attachment.id,
778
+ fileId: attachment.fileId,
779
+ filename: fileRecord.filename,
780
+ contentType: fileRecord.contentType,
781
+ size: fileRecord.size,
782
+ checksum: fileRecord.checksum,
783
+ createdAt: attachment.createdAt,
784
+ file: attachmentFile,
785
+ description: (_a = attachment.description) !== null && _a !== void 0 ? _a : undefined,
786
+ storageMetadata: fileRecord.storageMetadata,
787
+ };
512
788
  }
513
789
  }
514
790
  exports.PrismaNotificationBackend = PrismaNotificationBackend;
515
791
  class PrismaNotificationBackendFactory {
516
- create(prismaClient) {
517
- return new PrismaNotificationBackend(prismaClient);
792
+ create(prismaClient, attachmentManager) {
793
+ return new PrismaNotificationBackend(prismaClient, attachmentManager);
518
794
  }
519
795
  }
520
796
  exports.PrismaNotificationBackendFactory = PrismaNotificationBackendFactory;
@@ -1,30 +1,89 @@
1
1
  import type { InputJsonValue } from '../../types/json-values';
2
- import type { DatabaseNotification, Notification, DatabaseOneOffNotification, OneOffNotificationInput, AnyDatabaseNotification } from '../../types/notification';
2
+ import type {
3
+ AnyDatabaseNotification,
4
+ DatabaseNotification,
5
+ DatabaseOneOffNotification,
6
+ Notification,
7
+ OneOffNotificationInput,
8
+ } from '../../types/notification';
3
9
  import type { BaseNotificationTypeConfig } from '../../types/notification-type-config';
4
10
  export interface BaseNotificationBackend<Config extends BaseNotificationTypeConfig> {
5
- getAllPendingNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
6
- getPendingNotifications(page: number, pageSize: number): Promise<AnyDatabaseNotification<Config>[]>;
7
- getAllFutureNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
8
- getFutureNotifications(page: number, pageSize: number): Promise<AnyDatabaseNotification<Config>[]>;
9
- getAllFutureNotificationsFromUser(userId: Config['UserIdType']): Promise<DatabaseNotification<Config>[]>;
10
- getFutureNotificationsFromUser(userId: Config['UserIdType'], page: number, pageSize: number): Promise<DatabaseNotification<Config>[]>;
11
- persistNotification(notification: Omit<Notification<Config>, 'id'>): Promise<DatabaseNotification<Config>>;
12
- getAllNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
13
- getNotifications(page: number, pageSize: number): Promise<AnyDatabaseNotification<Config>[]>;
14
- bulkPersistNotifications(notifications: Omit<Notification<Config>, 'id'>[]): Promise<Config['NotificationIdType'][]>;
15
- persistNotificationUpdate(notificationId: Config['NotificationIdType'], notification: Partial<Omit<Notification<Config>, 'id'>>): Promise<DatabaseNotification<Config>>;
16
- markAsSent(notificationId: Config['NotificationIdType'], checkIsPending: boolean): Promise<AnyDatabaseNotification<Config>>;
17
- markAsFailed(notificationId: Config['NotificationIdType'], checkIsPending: boolean): Promise<AnyDatabaseNotification<Config>>;
18
- markAsRead(notificationId: Config['NotificationIdType'], checkIsSent: boolean): Promise<DatabaseNotification<Config>>;
19
- cancelNotification(notificationId: Config['NotificationIdType']): Promise<void>;
20
- getNotification(notificationId: Config['NotificationIdType'], forUpdate: boolean): Promise<AnyDatabaseNotification<Config> | null>;
21
- filterAllInAppUnreadNotifications(userId: Config['UserIdType']): Promise<DatabaseNotification<Config>[]>;
22
- filterInAppUnreadNotifications(userId: Config['UserIdType'], page: number, pageSize: number): Promise<DatabaseNotification<Config>[]>;
23
- getUserEmailFromNotification(notificationId: Config['NotificationIdType']): Promise<string | undefined>;
24
- storeContextUsed(notificationId: Config['NotificationIdType'], context: InputJsonValue): Promise<void>;
25
- persistOneOffNotification(notification: Omit<OneOffNotificationInput<Config>, 'id'>): Promise<DatabaseOneOffNotification<Config>>;
26
- persistOneOffNotificationUpdate(notificationId: Config['NotificationIdType'], notification: Partial<Omit<OneOffNotificationInput<Config>, 'id'>>): Promise<DatabaseOneOffNotification<Config>>;
27
- getOneOffNotification(notificationId: Config['NotificationIdType'], forUpdate: boolean): Promise<DatabaseOneOffNotification<Config> | null>;
28
- getAllOneOffNotifications(): Promise<DatabaseOneOffNotification<Config>[]>;
29
- getOneOffNotifications(page: number, pageSize: number): Promise<DatabaseOneOffNotification<Config>[]>;
11
+ getAllPendingNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
12
+ getPendingNotifications(
13
+ page: number,
14
+ pageSize: number,
15
+ ): Promise<AnyDatabaseNotification<Config>[]>;
16
+ getAllFutureNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
17
+ getFutureNotifications(
18
+ page: number,
19
+ pageSize: number,
20
+ ): Promise<AnyDatabaseNotification<Config>[]>;
21
+ getAllFutureNotificationsFromUser(
22
+ userId: Config['UserIdType'],
23
+ ): Promise<DatabaseNotification<Config>[]>;
24
+ getFutureNotificationsFromUser(
25
+ userId: Config['UserIdType'],
26
+ page: number,
27
+ pageSize: number,
28
+ ): Promise<DatabaseNotification<Config>[]>;
29
+ persistNotification(
30
+ notification: Omit<Notification<Config>, 'id'>,
31
+ ): Promise<DatabaseNotification<Config>>;
32
+ getAllNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
33
+ getNotifications(page: number, pageSize: number): Promise<AnyDatabaseNotification<Config>[]>;
34
+ bulkPersistNotifications(
35
+ notifications: Omit<Notification<Config>, 'id'>[],
36
+ ): Promise<Config['NotificationIdType'][]>;
37
+ persistNotificationUpdate(
38
+ notificationId: Config['NotificationIdType'],
39
+ notification: Partial<Omit<Notification<Config>, 'id'>>,
40
+ ): Promise<DatabaseNotification<Config>>;
41
+ markAsSent(
42
+ notificationId: Config['NotificationIdType'],
43
+ checkIsPending: boolean,
44
+ ): Promise<AnyDatabaseNotification<Config>>;
45
+ markAsFailed(
46
+ notificationId: Config['NotificationIdType'],
47
+ checkIsPending: boolean,
48
+ ): Promise<AnyDatabaseNotification<Config>>;
49
+ markAsRead(
50
+ notificationId: Config['NotificationIdType'],
51
+ checkIsSent: boolean,
52
+ ): Promise<DatabaseNotification<Config>>;
53
+ cancelNotification(notificationId: Config['NotificationIdType']): Promise<void>;
54
+ getNotification(
55
+ notificationId: Config['NotificationIdType'],
56
+ forUpdate: boolean,
57
+ ): Promise<AnyDatabaseNotification<Config> | null>;
58
+ filterAllInAppUnreadNotifications(
59
+ userId: Config['UserIdType'],
60
+ ): Promise<DatabaseNotification<Config>[]>;
61
+ filterInAppUnreadNotifications(
62
+ userId: Config['UserIdType'],
63
+ page: number,
64
+ pageSize: number,
65
+ ): Promise<DatabaseNotification<Config>[]>;
66
+ getUserEmailFromNotification(
67
+ notificationId: Config['NotificationIdType'],
68
+ ): Promise<string | undefined>;
69
+ storeContextUsed(
70
+ notificationId: Config['NotificationIdType'],
71
+ context: InputJsonValue,
72
+ ): Promise<void>;
73
+ persistOneOffNotification(
74
+ notification: Omit<OneOffNotificationInput<Config>, 'id'>,
75
+ ): Promise<DatabaseOneOffNotification<Config>>;
76
+ persistOneOffNotificationUpdate(
77
+ notificationId: Config['NotificationIdType'],
78
+ notification: Partial<Omit<OneOffNotificationInput<Config>, 'id'>>,
79
+ ): Promise<DatabaseOneOffNotification<Config>>;
80
+ getOneOffNotification(
81
+ notificationId: Config['NotificationIdType'],
82
+ forUpdate: boolean,
83
+ ): Promise<DatabaseOneOffNotification<Config> | null>;
84
+ getAllOneOffNotifications(): Promise<DatabaseOneOffNotification<Config>[]>;
85
+ getOneOffNotifications(
86
+ page: number,
87
+ pageSize: number,
88
+ ): Promise<DatabaseOneOffNotification<Config>[]>;
30
89
  }
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ Object.defineProperty(exports, '__esModule', { value: true });
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ Object.defineProperty(exports, '__esModule', { value: true });
@@ -1,15 +1,19 @@
1
1
  export type JsonPrimitive = string | number | boolean | null;
2
- export interface JsonArray extends Array<JsonValue> {
3
- }
2
+ export interface JsonArray extends Array<JsonValue> {}
4
3
  export type JsonObject = {
5
- [Key in string]?: JsonValue;
4
+ [Key in string]?: JsonValue;
6
5
  };
7
6
  export type JsonValue = string | number | boolean | JsonObject | JsonArray | null;
8
7
  export type InputJsonObject = {
9
- readonly [Key in string]?: InputJsonValue | null;
10
- };
11
- export interface InputJsonArray extends ReadonlyArray<InputJsonValue | null> {
12
- }
13
- export type InputJsonValue = string | number | boolean | InputJsonObject | InputJsonArray | {
14
- toJSON(): unknown;
8
+ readonly [Key in string]?: InputJsonValue | null;
15
9
  };
10
+ export interface InputJsonArray extends ReadonlyArray<InputJsonValue | null> {}
11
+ export type InputJsonValue =
12
+ | string
13
+ | number
14
+ | boolean
15
+ | InputJsonObject
16
+ | InputJsonArray
17
+ | {
18
+ toJSON(): unknown;
19
+ };
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ Object.defineProperty(exports, '__esModule', { value: true });
@@ -1,4 +1,6 @@
1
1
  import type { JsonObject, JsonPrimitive } from './json-values';
2
- export interface ContextGenerator<Params extends Record<string, JsonPrimitive> = Record<string, JsonPrimitive>> {
3
- generate(params: Params): JsonObject | Promise<JsonObject>;
2
+ export interface ContextGenerator<
3
+ Params extends Record<string, JsonPrimitive> = Record<string, JsonPrimitive>,
4
+ > {
5
+ generate(params: Params): JsonObject | Promise<JsonObject>;
4
6
  }
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ Object.defineProperty(exports, '__esModule', { value: true });
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ Object.defineProperty(exports, '__esModule', { value: true });
@@ -1,7 +1,7 @@
1
- import type { ContextGenerator } from "./notification-context-generators";
2
- import type { Identifier } from "./identifier";
1
+ import type { Identifier } from './identifier';
2
+ import type { ContextGenerator } from './notification-context-generators';
3
3
  export type BaseNotificationTypeConfig = {
4
- ContextMap: Record<string, ContextGenerator>;
5
- NotificationIdType: Identifier;
6
- UserIdType: Identifier;
4
+ ContextMap: Record<string, ContextGenerator>;
5
+ NotificationIdType: Identifier;
6
+ UserIdType: Identifier;
7
7
  };
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ Object.defineProperty(exports, '__esModule', { value: true });
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ Object.defineProperty(exports, '__esModule', { value: true });