@dereekb/firebase 13.2.2 → 13.3.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 (135) hide show
  1. package/index.cjs.js +12893 -4062
  2. package/index.esm.js +12872 -4065
  3. package/package.json +5 -5
  4. package/src/lib/client/error/error.d.ts +18 -3
  5. package/src/lib/client/firestore/array.d.ts +16 -3
  6. package/src/lib/client/firestore/driver.accessor.batch.d.ts +35 -4
  7. package/src/lib/client/firestore/driver.accessor.create.d.ts +15 -0
  8. package/src/lib/client/firestore/driver.accessor.d.ts +15 -0
  9. package/src/lib/client/firestore/driver.accessor.default.d.ts +32 -0
  10. package/src/lib/client/firestore/driver.accessor.transaction.d.ts +35 -4
  11. package/src/lib/client/firestore/driver.d.ts +16 -0
  12. package/src/lib/client/firestore/driver.query.d.ts +36 -0
  13. package/src/lib/client/firestore/firestore.d.ts +11 -1
  14. package/src/lib/client/firestore/increment.d.ts +12 -3
  15. package/src/lib/client/function/development.function.factory.d.ts +27 -2
  16. package/src/lib/client/function/error.d.ts +27 -0
  17. package/src/lib/client/function/function.callable.d.ts +50 -5
  18. package/src/lib/client/function/function.factory.d.ts +70 -4
  19. package/src/lib/client/function/model.function.factory.d.ts +64 -9
  20. package/src/lib/client/storage/driver.accessor.d.ts +93 -0
  21. package/src/lib/client/storage/driver.d.ts +15 -0
  22. package/src/lib/client/storage/storage.d.ts +10 -1
  23. package/src/lib/common/auth/auth.context.d.ts +17 -2
  24. package/src/lib/common/auth/auth.d.ts +38 -9
  25. package/src/lib/common/auth/auth.error.d.ts +25 -0
  26. package/src/lib/common/auth/auth.server.error.d.ts +6 -2
  27. package/src/lib/common/development/function.d.ts +17 -6
  28. package/src/lib/common/development/function.schedule.d.ts +30 -1
  29. package/src/lib/common/firestore/accessor/accessor.wrap.modify.d.ts +36 -12
  30. package/src/lib/common/firestore/accessor/array.d.ts +14 -4
  31. package/src/lib/common/firestore/accessor/document.d.ts +77 -2
  32. package/src/lib/common/firestore/accessor/increment.d.ts +15 -3
  33. package/src/lib/common/firestore/collection/collection.d.ts +22 -4
  34. package/src/lib/common/firestore/collection/collection.util.d.ts +12 -2
  35. package/src/lib/common/firestore/driver/accessor.d.ts +28 -1
  36. package/src/lib/common/firestore/driver/batch.d.ts +6 -4
  37. package/src/lib/common/firestore/driver/driver.d.ts +18 -1
  38. package/src/lib/common/firestore/driver/query.d.ts +20 -1
  39. package/src/lib/common/firestore/driver/query.handler.d.ts +23 -0
  40. package/src/lib/common/firestore/driver/transaction.d.ts +18 -6
  41. package/src/lib/common/firestore/error.d.ts +16 -4
  42. package/src/lib/common/firestore/query/iterator.d.ts +11 -0
  43. package/src/lib/common/firestore/reference.d.ts +11 -6
  44. package/src/lib/common/firestore/snapshot/snapshot.d.ts +4 -0
  45. package/src/lib/common/firestore/snapshot/snapshot.field.d.ts +263 -63
  46. package/src/lib/common/firestore/types.d.ts +39 -1
  47. package/src/lib/common/firestore/util/id.batch.d.ts +55 -3
  48. package/src/lib/common/function/action.d.ts +35 -0
  49. package/src/lib/common/model/context.d.ts +11 -1
  50. package/src/lib/common/model/function.d.ts +45 -9
  51. package/src/lib/common/model/model/model.loader.d.ts +37 -0
  52. package/src/lib/common/model/model/model.param.d.ts +24 -2
  53. package/src/lib/common/model/model.service.d.ts +126 -4
  54. package/src/lib/common/model/permission/permission.context.d.ts +15 -0
  55. package/src/lib/common/model/permission/permission.d.ts +16 -0
  56. package/src/lib/common/model/permission/permission.service.d.ts +24 -1
  57. package/src/lib/common/model/permission/permission.service.grant.d.ts +72 -28
  58. package/src/lib/common/model/permission/permission.service.role.d.ts +15 -0
  59. package/src/lib/common/storage/accessor/path.model.d.ts +25 -8
  60. package/src/lib/common/storage/context.d.ts +23 -6
  61. package/src/lib/common/storage/driver/accessor.d.ts +15 -4
  62. package/src/lib/common/storage/driver/accessor.iterate.d.ts +31 -8
  63. package/src/lib/common/storage/driver/accessor.util.d.ts +13 -6
  64. package/src/lib/common/storage/driver/driver.d.ts +10 -1
  65. package/src/lib/common/storage/driver/error.d.ts +16 -0
  66. package/src/lib/common/storage/driver/list.d.ts +30 -0
  67. package/src/lib/common/storage/storage.d.ts +76 -19
  68. package/src/lib/common/storage/types.d.ts +23 -5
  69. package/src/lib/model/index.d.ts +1 -0
  70. package/src/lib/model/notification/notification.action.d.ts +8 -0
  71. package/src/lib/model/notification/notification.api.d.ts +26 -0
  72. package/src/lib/model/notification/notification.api.error.d.ts +15 -0
  73. package/src/lib/model/notification/notification.api.util.d.ts +27 -12
  74. package/src/lib/model/notification/notification.config.d.ts +193 -64
  75. package/src/lib/model/notification/notification.create.d.ts +62 -13
  76. package/src/lib/model/notification/notification.create.task.d.ts +25 -4
  77. package/src/lib/model/notification/notification.d.ts +258 -99
  78. package/src/lib/model/notification/notification.details.d.ts +66 -18
  79. package/src/lib/model/notification/notification.id.d.ts +90 -12
  80. package/src/lib/model/notification/notification.item.d.ts +57 -16
  81. package/src/lib/model/notification/notification.message.d.ts +84 -18
  82. package/src/lib/model/notification/notification.query.d.ts +21 -24
  83. package/src/lib/model/notification/notification.send.d.ts +38 -5
  84. package/src/lib/model/notification/notification.task.d.ts +87 -16
  85. package/src/lib/model/notification/notification.task.subtask.d.ts +42 -13
  86. package/src/lib/model/notification/notification.util.d.ts +68 -18
  87. package/src/lib/model/oidcmodel/index.d.ts +8 -0
  88. package/src/lib/model/oidcmodel/oidcmodel.action.d.ts +37 -0
  89. package/src/lib/model/oidcmodel/oidcmodel.api.d.ts +131 -0
  90. package/src/lib/model/oidcmodel/oidcmodel.d.ts +114 -0
  91. package/src/lib/model/oidcmodel/oidcmodel.data.d.ts +17 -0
  92. package/src/lib/model/oidcmodel/oidcmodel.id.d.ts +18 -0
  93. package/src/lib/model/oidcmodel/oidcmodel.interaction.d.ts +40 -0
  94. package/src/lib/model/oidcmodel/oidcmodel.interaction.oauth.d.ts +73 -0
  95. package/src/lib/model/oidcmodel/oidcmodel.query.d.ts +21 -0
  96. package/src/lib/model/storagefile/storagefile.action.d.ts +47 -0
  97. package/src/lib/model/storagefile/storagefile.api.d.ts +54 -4
  98. package/src/lib/model/storagefile/storagefile.create.d.ts +40 -3
  99. package/src/lib/model/storagefile/storagefile.d.ts +153 -16
  100. package/src/lib/model/storagefile/storagefile.file.d.ts +22 -7
  101. package/src/lib/model/storagefile/storagefile.group.d.ts +30 -1
  102. package/src/lib/model/storagefile/storagefile.group.processing.d.ts +20 -2
  103. package/src/lib/model/storagefile/storagefile.id.d.ts +44 -5
  104. package/src/lib/model/storagefile/storagefile.permission.d.ts +23 -4
  105. package/src/lib/model/storagefile/storagefile.query.d.ts +63 -11
  106. package/src/lib/model/storagefile/storagefile.task.d.ts +47 -4
  107. package/src/lib/model/storagefile/storagefile.upload.claims.d.ts +21 -4
  108. package/src/lib/model/storagefile/storagefile.upload.d.ts +41 -9
  109. package/src/lib/model/storagefile/storagefile.upload.determiner.d.ts +112 -20
  110. package/src/lib/model/storagefile/storagefile.util.d.ts +66 -3
  111. package/src/lib/model/system/system.action.d.ts +25 -0
  112. package/src/lib/model/system/system.d.ts +80 -4
  113. package/src/lib/model/user.d.ts +8 -2
  114. package/test/index.cjs.js +11168 -3295
  115. package/test/index.esm.js +11176 -3303
  116. package/test/package.json +6 -6
  117. package/test/src/lib/client/firebase.authorized.d.ts +18 -0
  118. package/test/src/lib/client/firebase.d.ts +60 -0
  119. package/test/src/lib/common/firebase.instance.d.ts +21 -0
  120. package/test/src/lib/common/firestore/firestore.d.ts +40 -0
  121. package/test/src/lib/common/firestore/firestore.instance.d.ts +16 -0
  122. package/test/src/lib/common/firestore/test.driver.accessor.d.ts +39 -2
  123. package/test/src/lib/common/firestore/test.driver.utility.d.ts +8 -2
  124. package/test/src/lib/common/firestore/test.iterator.d.ts +7 -2
  125. package/test/src/lib/common/mock/mock.item.collection.fixture.d.ts +29 -1
  126. package/test/src/lib/common/mock/mock.item.d.ts +219 -5
  127. package/test/src/lib/common/mock/mock.item.id.d.ts +6 -0
  128. package/test/src/lib/common/mock/mock.item.query.d.ts +12 -0
  129. package/test/src/lib/common/mock/mock.item.service.d.ts +60 -0
  130. package/test/src/lib/common/mock/mock.item.storage.fixture.d.ts +28 -1
  131. package/test/src/lib/common/storage/storage.d.ts +30 -0
  132. package/test/src/lib/common/storage/storage.instance.d.ts +22 -0
  133. package/test/src/lib/common/storage/test.driver.accessor.d.ts +7 -2
  134. package/index.cjs.js.map +0 -1
  135. package/index.esm.js.map +0 -1
@@ -1,12 +1,21 @@
1
+ /**
2
+ * @module notification.details
3
+ *
4
+ * Template type metadata for the notification system. Each {@link NotificationTemplateType} is described by a
5
+ * {@link NotificationTemplateTypeInfo} entry that maps it to model identities, display info, and delivery rules.
6
+ *
7
+ * The {@link AppNotificationTemplateTypeInfoRecordService} provides runtime lookup of template types by model,
8
+ * enabling the server to discover which notification types apply to a given Firestore model.
9
+ */
1
10
  import { type Maybe, type ArrayOrValue } from '@dereekb/util';
2
11
  import { type FirestoreModelIdentity, type ReadFirestoreModelKeyInput } from '../../common';
3
12
  import { type NotificationTemplateType } from './notification.id';
4
13
  /**
5
- * NotificationTemplateTypeInfoIdentityInfo alternative/derivative identity.
6
- *
7
- * For example, this model may be directly related to the identity in "notificationModelIdentity" but notifications are actually attached to the corresponding "altNotificationModelIdentity" or "altTargetModelIdentity".
14
+ * Alternative model identity pair for cases where notifications are attached to a different model
15
+ * than the one defined in {@link NotificationTemplateTypeInfoIdentityInfo.notificationModelIdentity}.
8
16
  *
9
- * The alternative model should always have a NotificationBox associated with it.
17
+ * For example, a notification may be defined for a "project" model but actually delivered via
18
+ * a "team" model's NotificationBox. The alternative model must always have a NotificationBox.
10
19
  */
11
20
  export interface NotificationTemplateTypeInfoIdentityInfoAlternativeModelIdentityPair {
12
21
  /**
@@ -19,7 +28,8 @@ export interface NotificationTemplateTypeInfoIdentityInfoAlternativeModelIdentit
19
28
  readonly altTargetModelIdentity?: Maybe<FirestoreModelIdentity>;
20
29
  }
21
30
  /**
22
- * NotificationTemplateTypeInfo identity info
31
+ * Model identity mapping for a notification template type. Defines which Firestore models
32
+ * are associated with this notification type and which one owns the NotificationBox.
23
33
  */
24
34
  export interface NotificationTemplateTypeInfoIdentityInfo {
25
35
  /**
@@ -48,31 +58,37 @@ export interface NotificationTemplateTypeInfoIdentityInfo {
48
58
  readonly sendToNotificationModelIdentity?: Maybe<boolean>;
49
59
  }
50
60
  /**
51
- * Template type identifier of the notification.
61
+ * Complete metadata for a notification template type. Defines display info, model associations,
62
+ * and delivery rules for a specific {@link NotificationTemplateType}.
52
63
  *
53
- * Provides default information for the notification.
54
- *
55
- * Types are generally intended to be handled case-insensitively by notification services.
64
+ * Registered in the application's {@link NotificationTemplateTypeInfoRecord} and accessed at runtime
65
+ * via the {@link AppNotificationTemplateTypeInfoRecordService}.
56
66
  */
57
67
  export interface NotificationTemplateTypeInfo extends NotificationTemplateTypeInfoIdentityInfo {
58
68
  /**
59
- * Notification type
69
+ * Template type identifier (e.g., `'comment'`, `'invite'`). Should be short to minimize Firestore storage.
60
70
  */
61
71
  readonly type: NotificationTemplateType;
62
72
  /**
63
- * The notification's name
73
+ * Human-readable name for display in notification preference UIs.
64
74
  */
65
75
  readonly name: string;
66
76
  /**
67
- * Description of the notification's content.
77
+ * Description of what this notification type conveys, shown in preference management UIs.
68
78
  */
69
79
  readonly description: string;
70
80
  /**
71
- * If true, this notification will only be sent to recipients that explicitly enable recieving via respective NotificationBoxRecipientTemplateConfig for this type.
81
+ * When true, only sends to recipients who have explicitly enabled this template type in their
82
+ * {@link NotificationBoxRecipientTemplateConfig}. Recipients without an explicit opt-in are skipped.
83
+ *
84
+ * Overridable per-notification via {@link Notification.ois}.
72
85
  */
73
86
  readonly onlySendToExplicitlyEnabledRecipients?: boolean;
74
87
  /**
75
- * If false, this notification will send sms/texts to all recipients, even if they have not explicitly opted in to recieving sms/texts.
88
+ * When false, sends text/SMS to all recipients regardless of explicit opt-in status
89
+ * (still respects explicit opt-outs).
90
+ *
91
+ * Overridable per-notification via {@link Notification.ots}.
76
92
  */
77
93
  readonly onlyTextExplicitlyEnabledRecipients?: boolean;
78
94
  }
@@ -81,18 +97,34 @@ export interface NotificationTemplateTypeInfo extends NotificationTemplateTypeIn
81
97
  */
82
98
  export type NotificationTemplateTypeInfoRecord = Record<NotificationTemplateType, NotificationTemplateTypeInfo>;
83
99
  /**
84
- * Creates a NotificationTemplateTypeInfoRecord from the input info array.
100
+ * Creates a {@link NotificationTemplateTypeInfoRecord} from an array of template type info entries.
101
+ *
102
+ * @throws {Error} When duplicate template types are found in the input array.
85
103
  *
86
- * @param infoArray
87
- * @returns
104
+ * @example
105
+ * ```ts
106
+ * const record = notificationTemplateTypeInfoRecord([
107
+ * { type: 'comment', name: 'Comment', description: 'New comment notifications', notificationModelIdentity: projectIdentity },
108
+ * { type: 'invite', name: 'Invite', description: 'Team invite notifications', notificationModelIdentity: teamIdentity }
109
+ * ]);
110
+ * ```
88
111
  */
89
112
  export declare function notificationTemplateTypeInfoRecord(infoArray: NotificationTemplateTypeInfo[]): NotificationTemplateTypeInfoRecord;
90
113
  /**
91
- * Reference to a NotificationTemplateTypeInfoRecord that contains a AppNotificationTemplateTypeInfoRecordService
114
+ * Reference to an {@link AppNotificationTemplateTypeInfoRecordService} instance.
115
+ *
116
+ * Used for dependency injection in modules that need access to the template type registry.
92
117
  */
93
118
  export interface AppNotificationTemplateTypeInfoRecordServiceRef {
94
119
  readonly appNotificationTemplateTypeInfoRecordService: AppNotificationTemplateTypeInfoRecordService;
95
120
  }
121
+ /**
122
+ * Runtime service for looking up {@link NotificationTemplateTypeInfo} by model identity or template type.
123
+ *
124
+ * Built from a {@link NotificationTemplateTypeInfoRecord} via {@link appNotificationTemplateTypeInfoRecordService}.
125
+ * Provides indexed lookups for the server-side notification pipeline to discover which template types
126
+ * apply to a given model.
127
+ */
96
128
  export declare abstract class AppNotificationTemplateTypeInfoRecordService {
97
129
  /**
98
130
  * All records for this app.
@@ -147,4 +179,20 @@ export declare abstract class AppNotificationTemplateTypeInfoRecordService {
147
179
  */
148
180
  abstract getTemplateTypeInfosForTargetModelIdentity(identity: FirestoreModelIdentity): NotificationTemplateTypeInfo[];
149
181
  }
182
+ /**
183
+ * Creates an {@link AppNotificationTemplateTypeInfoRecordService} from the given template type record.
184
+ *
185
+ * Builds internal indexes for fast lookup by notification model identity and target model identity.
186
+ * Handles alternative model identities defined in {@link NotificationTemplateTypeInfoIdentityInfoAlternativeModelIdentityPair}.
187
+ *
188
+ * @param appNotificationTemplateTypeInfoRecord - the complete template type registry for the application
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * const service = appNotificationTemplateTypeInfoRecordService(
193
+ * notificationTemplateTypeInfoRecord([commentInfo, inviteInfo])
194
+ * );
195
+ * const types = service.getTemplateTypesForNotificationModel('project/abc123');
196
+ * ```
197
+ */
150
198
  export declare function appNotificationTemplateTypeInfoRecordService(appNotificationTemplateTypeInfoRecord: NotificationTemplateTypeInfoRecord): AppNotificationTemplateTypeInfoRecordService;
@@ -1,49 +1,127 @@
1
+ /**
2
+ * @module notification.id
3
+ *
4
+ * ID types and generation functions for notification model documents.
5
+ *
6
+ * Notification documents use "two-way flat keys" as their document IDs. A two-way flat key
7
+ * encodes a hierarchical Firestore model key (e.g., `'collection/id'`) into a flat string
8
+ * (e.g., `'collection_id'`) that can be used as a document ID while remaining reversible
9
+ * back to the original key via {@link inferNotificationBoxRelatedModelKey}.
10
+ *
11
+ * This pattern allows {@link NotificationBox} and {@link NotificationSummary} documents
12
+ * to be stored in top-level collections while maintaining a bidirectional link to the
13
+ * model they represent.
14
+ */
1
15
  import { type FactoryWithRequiredInput } from '@dereekb/util';
2
16
  import { type FirestoreModelId, type FirestoreModelKey, type FlatFirestoreModelKey, twoWayFlatFirestoreModelKey, inferKeyFromTwoWayFlatFirestoreModelKey, type FirebaseAuthUserId, type RootFirestoreModelIdentity, type FirestoreModelIdInput, type FirestoreCollectionName } from '../../common';
3
17
  /**
4
- * The NotificationBox's id is the two way flat firestore model key of the object that it represents.
18
+ * Document ID for a {@link NotificationBox}. Encoded as a two-way flat key of the model it represents.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const boxId: NotificationBoxId = notificationBoxIdForModel('project/abc123');
23
+ * // boxId === 'project_abc123'
24
+ * ```
5
25
  */
6
26
  export type NotificationBoxId = FlatFirestoreModelKey;
27
+ /**
28
+ * Full Firestore model key path for a {@link NotificationBox} document (e.g., `'notificationBox/project_abc123'`).
29
+ */
7
30
  export type NotificationBoxKey = FirestoreModelKey;
8
31
  /**
9
- * A notification box id (or firestore collection name) that is used to exclude a user from receiving notifications from that box or any notification boxes that start with the same prefix.
32
+ * A box ID or collection name prefix used to exclude a user from receiving notifications.
10
33
  *
11
- * This is used in cases where a user might be removed from access temporarily and should not recieve any notifications from that box or any child boxes.
34
+ * Supports prefix matching: excluding `'ab_123'` also excludes child boxes like `'ab_123_cd_456'`.
35
+ * Used when a user temporarily loses access to a resource and should stop receiving its notifications.
12
36
  *
13
- * For example, if a box with id ab_123 is excluded, then any notifications to child boxes that start with ab_123 (e.g. ab_123_cd_456) will also be excluded.
37
+ * @see {@link NotificationUser.x} where exclusions are stored
14
38
  */
15
39
  export type NotificationBoxSendExclusion = FirestoreCollectionName | NotificationBoxId;
16
40
  /**
17
- * List of notification box exclusions.
41
+ * List of {@link NotificationBoxSendExclusion} entries for a user.
18
42
  */
19
43
  export type NotificationBoxSendExclusionList = NotificationBoxSendExclusion[];
20
44
  /**
21
- * Creates a NotificationBoxId from the input FirestoreModelKey.
45
+ * Converts a Firestore model key to a {@link NotificationBoxId} using two-way flat key encoding.
22
46
  *
23
- * @param modelKey
24
- * @returns
47
+ * @example
48
+ * ```ts
49
+ * const boxId = notificationBoxIdForModel('project/abc123');
50
+ * // boxId === 'project_abc123'
51
+ * ```
25
52
  */
26
53
  export declare const notificationBoxIdForModel: typeof twoWayFlatFirestoreModelKey;
54
+ /**
55
+ * Reverses a {@link NotificationBoxId} back to the original Firestore model key.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const modelKey = inferNotificationBoxRelatedModelKey('project_abc123');
60
+ * // modelKey === 'project/abc123'
61
+ * ```
62
+ */
27
63
  export declare const inferNotificationBoxRelatedModelKey: typeof inferKeyFromTwoWayFlatFirestoreModelKey;
64
+ /**
65
+ * Document ID for a {@link NotificationUser}. Encoded as a flat key derived from the user's auth identity.
66
+ */
28
67
  export type NotificationUserId = FlatFirestoreModelKey;
68
+ /**
69
+ * Full Firestore model key path for a {@link NotificationUser} document.
70
+ */
29
71
  export type NotificationUserKey = FirestoreModelKey;
72
+ /**
73
+ * Document ID for a {@link NotificationSummary}. Encoded as a two-way flat key of the model it represents.
74
+ */
30
75
  export type NotificationSummaryId = FlatFirestoreModelKey;
76
+ /**
77
+ * Full Firestore model key path for a {@link NotificationSummary} document.
78
+ */
31
79
  export type NotificationSummaryKey = FirestoreModelKey;
32
80
  /**
33
- * Creates a NotificationSummaryId from the input FirestoreModelKey.
81
+ * Converts a Firestore model key to a {@link NotificationSummaryId} using two-way flat key encoding.
34
82
  *
35
- * @param modelKey
36
- * @returns
83
+ * @example
84
+ * ```ts
85
+ * const summaryId = notificationSummaryIdForModel('project/abc123');
86
+ * // summaryId === 'project_abc123'
87
+ * ```
37
88
  */
38
89
  export declare const notificationSummaryIdForModel: typeof twoWayFlatFirestoreModelKey;
39
90
  /**
40
- * Function used to retrieve a NotificationSummaryId given the input FirestoreAuthUserId.
91
+ * Factory function that produces a {@link NotificationSummaryId} from a user's auth UID.
92
+ *
93
+ * Used to find the notification summary for a specific user's model identity.
41
94
  */
42
95
  export type NotificationSummaryIdForUidFunction = FactoryWithRequiredInput<NotificationSummaryId, FirebaseAuthUserId>;
96
+ /**
97
+ * Creates a {@link NotificationSummaryIdForUidFunction} that generates summary IDs
98
+ * by combining the given user model identity with the provided UID.
99
+ *
100
+ * @param userModelIdentity - the root identity for user models (e.g., `profileIdentity`)
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * const summaryIdForUid = notificationSummaryIdForUidFunctionForRootFirestoreModelIdentity(profileIdentity);
105
+ * const summaryId = summaryIdForUid('user-uid-123');
106
+ * // summaryId === 'profile_user-uid-123'
107
+ * ```
108
+ */
43
109
  export declare function notificationSummaryIdForUidFunctionForRootFirestoreModelIdentity(userModelIdentity: RootFirestoreModelIdentity): NotificationSummaryIdForUidFunction;
110
+ /**
111
+ * Document ID for a {@link NotificationWeek} (a {@link YearWeekCode} string).
112
+ */
44
113
  export type NotificationWeekId = FirestoreModelId;
114
+ /**
115
+ * Full Firestore model key path for a {@link NotificationWeek} document.
116
+ */
45
117
  export type NotificationWeekKey = FirestoreModelKey;
118
+ /**
119
+ * Document ID for a {@link Notification}.
120
+ */
46
121
  export type NotificationId = FirestoreModelId;
122
+ /**
123
+ * Full Firestore model key path for a {@link Notification} document.
124
+ */
47
125
  export type NotificationKey = FirestoreModelKey;
48
126
  /**
49
127
  * Equivalent to NotificationId, but can be used to more specifically refer to a Notification with a task type.
@@ -1,10 +1,21 @@
1
+ /**
2
+ * @module notification.item
3
+ *
4
+ * Defines the {@link NotificationItem} embedded data structure that carries notification content
5
+ * across multiple document types ({@link Notification}, {@link NotificationWeek}, {@link NotificationSummary}).
6
+ */
1
7
  import { type Maybe } from '@dereekb/util';
2
8
  import { type FirebaseAuthUserId, type FirestoreModelKey, type SavedToFirestoreIfTrue } from '../../common';
3
9
  import { type NotificationTaskType, type NotificationId, type NotificationTemplateType } from './notification.id';
4
10
  /**
5
- * Arbitrary metadata for a job. Derived/managed by the concrete job type.
11
+ * Arbitrary metadata attached to a {@link NotificationItem}. Content is defined by the concrete notification/task type.
12
+ *
13
+ * Stored directly in Firestore, so values must be Firestore-compatible (no class instances, functions, etc.).
6
14
  */
7
15
  export type NotificationItemMetadata = Readonly<Record<string, any>>;
16
+ /**
17
+ * Pairs a {@link NotificationItem} with its resolved subject and message strings for display.
18
+ */
8
19
  export interface NotificationItemSubjectMessagePair<D extends NotificationItemMetadata = {}> {
9
20
  readonly item: NotificationItem<D>;
10
21
  readonly subject: string;
@@ -12,51 +23,67 @@ export interface NotificationItemSubjectMessagePair<D extends NotificationItemMe
12
23
  readonly date: Date;
13
24
  }
14
25
  /**
15
- * A notification item.
26
+ * Embeddable notification content carried inside {@link Notification}, {@link NotificationWeek}, and {@link NotificationSummary} documents.
16
27
  *
17
- * Is embedded within a Notification, NotificationWeek, and NotificationSummary.
28
+ * Each item has a template/task type (`t`) that determines how the notification is rendered and delivered.
29
+ * The optional `s` (subject) and `g` (message) fields can override the template's defaults.
30
+ *
31
+ * Field abbreviations:
32
+ * - `cat` — created-at timestamp
33
+ * - `t` — template or task type identifier
34
+ * - `cb` — created-by user UID
35
+ * - `m` — target model key
36
+ * - `s` — subject override
37
+ * - `g` — message override
38
+ * - `d` — metadata payload
39
+ * - `v` — viewed/read flag
18
40
  */
19
41
  export interface NotificationItem<D extends NotificationItemMetadata = {}> {
20
42
  /**
21
- * Unique identifier
43
+ * Unique notification item identifier.
22
44
  */
23
45
  id: NotificationId;
24
46
  /**
25
- * Notification date/time
47
+ * Creation timestamp of this notification item.
26
48
  */
27
49
  cat: Date;
28
50
  /**
29
- * Notification task/template type.
51
+ * Template type (for standard notifications) or task type (for task notifications).
52
+ * Determines how the notification is rendered and which handler processes it.
30
53
  */
31
54
  t: NotificationTemplateType | NotificationTaskType;
32
55
  /**
33
- * User who created this notification, if applicable.
56
+ * UID of the user who triggered this notification, if applicable.
34
57
  */
35
58
  cb?: Maybe<FirebaseAuthUserId>;
36
59
  /**
37
- * Model/object that this notification item is targeting.
60
+ * Model key of the target object this notification relates to.
38
61
  */
39
62
  m?: Maybe<FirestoreModelKey>;
40
63
  /**
41
- * Subject. Used to overwrite the template's default subject.
64
+ * Subject text override. Replaces the template's default subject when present.
42
65
  */
43
66
  s?: Maybe<string>;
44
67
  /**
45
- * Message. Used to overwrite the template's default message.
68
+ * Message text override. Replaces the template's default message when present.
46
69
  */
47
70
  g?: Maybe<string>;
48
71
  /**
49
- * Arbitrary metadata attached to the notification item.
50
- *
51
- * This is stored directly into Firestore, so be cautious about what is stored.
72
+ * Arbitrary metadata payload. Stored directly in Firestore — keep values serializable and small.
52
73
  */
53
74
  d?: Maybe<D>;
54
75
  /**
55
- * True if this notification item is marked as read/viewed.
76
+ * Read/viewed flag. True if the recipient has seen this notification item.
56
77
  */
57
78
  v?: Maybe<SavedToFirestoreIfTrue>;
58
79
  }
80
+ /**
81
+ * Firestore sub-object converter for embedding {@link NotificationItem} within parent documents.
82
+ */
59
83
  export declare const firestoreNotificationItem: import("../..").FirestoreSubObjectFieldMapFunctionsConfig<NotificationItem<{}>, Partial<import("@dereekb/util").ReplaceType<NotificationItem<{}>, import("@dereekb/util").MaybeMap<object>, any>>>;
84
+ /**
85
+ * Result of splitting {@link NotificationItem} entries into read and unread groups.
86
+ */
60
87
  export interface UnreadNotificationItemsResult<D extends NotificationItemMetadata = {}> {
61
88
  readonly items: NotificationItem<D>[];
62
89
  readonly considerReadIfCreatedBefore?: Maybe<Date>;
@@ -64,9 +91,23 @@ export interface UnreadNotificationItemsResult<D extends NotificationItemMetadat
64
91
  readonly unread: NotificationItem<D>[];
65
92
  }
66
93
  /**
67
- * Returns an object containing input notification items split up by their determined read/unread state.
94
+ * Separates notification items into read and unread groups based on the `v` (viewed) flag
95
+ * and an optional cutoff date.
96
+ *
97
+ * Items are considered read if their `v` flag is true OR if they were created before the `considerReadIfCreatedBefore` date.
98
+ * This is used with {@link NotificationSummary.rat} to mark all older items as read.
68
99
  *
69
- * @param items
100
+ * @param items - notification items to classify
101
+ * @param considerReadIfCreatedBefore - optional cutoff date; items created at or before this date are treated as read
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * const result = unreadNotificationItems(summary.n, summary.rat);
106
+ * console.log(result.unread.length); // number of unread items
107
+ * ```
70
108
  */
71
109
  export declare function unreadNotificationItems<D extends NotificationItemMetadata = {}>(items: NotificationItem<D>[], considerReadIfCreatedBefore?: Maybe<Date>): UnreadNotificationItemsResult<D>;
110
+ /**
111
+ * Sort comparator for {@link NotificationItem} arrays. Sorts ascending by creation date (`cat`).
112
+ */
72
113
  export declare const sortNotificationItemsFunction: import("@dereekb/date").SortByDateFunction<NotificationItem<any>>;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * @module notification.message
3
+ *
4
+ * Defines the message factory pattern for the notification system. A {@link NotificationMessageFunctionFactory}
5
+ * creates per-recipient {@link NotificationMessageFunction} instances that produce channel-specific content
6
+ * (email, text, push, summary) from a {@link NotificationItem}.
7
+ *
8
+ * The server's notification send pipeline calls these factories to expand each notification into concrete messages
9
+ * before dispatching them through the configured delivery channels.
10
+ */
1
11
  import { type PromiseOrValue, type Maybe, type WebsiteUrl, type NameEmailPair, type ArrayOrValue } from '@dereekb/util';
2
12
  import { type NotificationRecipient, type NotificationRecipientWithConfig } from './notification.config';
3
13
  import { type NotificationSendFlags, type Notification, type NotificationBox } from './notification';
@@ -5,7 +15,7 @@ import { type NotificationItem, type NotificationItemMetadata } from './notifica
5
15
  import { type DocumentDataWithIdAndKey } from '../../common';
6
16
  import { type NotificationSendEmailMessagesResult, type NotificationSendTextMessagesResult, type NotificationSendNotificationSummaryMessagesResult } from './notification.send';
7
17
  /**
8
- * Contextual information when
18
+ * Per-recipient context passed to a {@link NotificationMessageFunction} when generating message content.
9
19
  */
10
20
  export interface NotificationMessageInputContext {
11
21
  /**
@@ -116,26 +126,32 @@ export interface NotificationMessageEmailContent extends NotificationMessageCont
116
126
  }
117
127
  export interface NotificationMessageNotificationSummaryContent {
118
128
  }
129
+ /**
130
+ * Flags controlling whether a generated {@link NotificationMessage} should be delivered.
131
+ */
119
132
  export declare enum NotificationMessageFlag {
120
133
  /**
121
- * No flag
134
+ * Normal delivery — message has content and should be sent.
122
135
  */
123
136
  NONE = 0,
124
137
  /**
125
- * Special flag to indicate there is no content. Should not be sent.
138
+ * Message factory produced no content for this recipient. Delivery is skipped.
126
139
  */
127
140
  NO_CONTENT = 1,
128
141
  /**
129
- * Special flag to not send the notification.
142
+ * Explicitly suppress delivery. Used when the factory determines the notification should not be sent.
130
143
  */
131
144
  DO_NOT_SEND = 2
132
145
  }
133
146
  /**
134
- * A NotificationMessage is the final result of the expanded notification.
147
+ * Expanded notification content for a single recipient, produced by a {@link NotificationMessageFunction}.
148
+ *
149
+ * Contains the base content plus optional channel-specific overrides for email, text, and notification summary.
150
+ * The `flag` field can suppress delivery if the factory determined no content or opted out.
135
151
  */
136
152
  export interface NotificationMessage<D extends NotificationItemMetadata = {}> {
137
153
  /**
138
- * Optional flag
154
+ * Delivery control flag. When set to `NO_CONTENT` or `DO_NOT_SEND`, this message is skipped.
139
155
  */
140
156
  readonly flag?: NotificationMessageFlag;
141
157
  /**
@@ -165,24 +181,34 @@ export interface NotificationMessage<D extends NotificationItemMetadata = {}> {
165
181
  */
166
182
  readonly notificationSummaryContent?: NotificationMessageNotificationSummaryContent;
167
183
  }
184
+ /**
185
+ * Configuration input for a {@link NotificationMessageFunctionFactory}, providing the notification context
186
+ * needed to create a per-recipient message function.
187
+ */
168
188
  export interface NotificationMessageFunctionFactoryConfig<D extends NotificationItemMetadata = {}> {
169
189
  /**
170
- * Notification item.
190
+ * The notification item containing content and metadata.
171
191
  */
172
192
  readonly item: NotificationItem<D>;
173
193
  /**
174
- * NotificationBox details for this message.
194
+ * Parent NotificationBox context (model key for the box's associated model).
175
195
  */
176
196
  readonly notificationBox: Pick<NotificationBox, 'm'>;
177
197
  /**
178
- * Full Notification for this message.
198
+ * Full Notification document data with its Firestore ID and key.
179
199
  */
180
200
  readonly notification: DocumentDataWithIdAndKey<Notification>;
181
201
  }
182
202
  /**
183
- * Creates a NotificationMessageFunction from the input config.
203
+ * Async factory that creates a {@link NotificationMessageFunction} for a specific notification.
204
+ *
205
+ * Registered per-template-type in the application's notification configuration. The server calls this
206
+ * factory once per notification, then invokes the returned function once per recipient.
184
207
  */
185
208
  export type NotificationMessageFunctionFactory<D extends NotificationItemMetadata = {}> = (config: NotificationMessageFunctionFactoryConfig<D>) => Promise<NotificationMessageFunction>;
209
+ /**
210
+ * Details passed to {@link NotificationMessageFunctionExtras} lifecycle callbacks after a send attempt.
211
+ */
186
212
  export interface NotificationMessageFunctionExtrasCallbackDetails {
187
213
  readonly success: boolean;
188
214
  readonly updatedSendFlags: NotificationSendFlags;
@@ -190,32 +216,72 @@ export interface NotificationMessageFunctionExtrasCallbackDetails {
190
216
  readonly sendTextsResult?: Maybe<NotificationSendTextMessagesResult>;
191
217
  readonly sendNotificationSummaryResult?: Maybe<NotificationSendNotificationSummaryMessagesResult>;
192
218
  }
219
+ /**
220
+ * Callback function invoked by the send pipeline with delivery results.
221
+ */
193
222
  export type NotificationMessageFunctionExtrasCallbackFunction = (callbackDetails: NotificationMessageFunctionExtrasCallbackDetails) => PromiseOrValue<unknown>;
223
+ /**
224
+ * Optional extensions attached to a {@link NotificationMessageFunction} to customize delivery behavior.
225
+ *
226
+ * Allows message factories to inject additional recipients and hook into the send lifecycle
227
+ * for side effects like logging, analytics, or cascading updates.
228
+ */
194
229
  export interface NotificationMessageFunctionExtras {
195
230
  /**
196
- * Any global/additional recipient(s) that should be added to all Notifications associated with this NotificationMessageFunctionExtras.
231
+ * Additional recipients appended to every notification using this message function.
232
+ * Useful for always-CC recipients like admin accounts or audit logs.
197
233
  */
198
234
  readonly globalRecipients?: Maybe<NotificationRecipientWithConfig[]>;
199
235
  /**
200
- * Called each time the notification attempts to send something.
236
+ * Called after each send attempt (whether successful or not) with the delivery results.
201
237
  */
202
238
  readonly onSendAttempted?: NotificationMessageFunctionExtrasCallbackFunction;
203
239
  /**
204
- * Called when the notification has is marked as done after sending to all recipients.
240
+ * Called when all channels have completed delivery and the notification is marked done.
205
241
  */
206
242
  readonly onSendSuccess?: NotificationMessageFunctionExtrasCallbackFunction;
207
243
  }
244
+ /**
245
+ * Core message generation function that produces a {@link NotificationMessage} for a single recipient.
246
+ */
208
247
  export type NotificationMessageFunctionWithoutExtras = (inputContext: NotificationMessageInputContext) => Promise<NotificationMessage>;
209
248
  /**
210
- * Converts a NotificationMessageContext to a NotificationMessage.
249
+ * Combined message function type: a callable that generates per-recipient content,
250
+ * plus optional {@link NotificationMessageFunctionExtras} for delivery customization.
251
+ *
252
+ * Created by {@link notificationMessageFunction} or returned from a {@link NotificationMessageFunctionFactory}.
211
253
  */
212
254
  export type NotificationMessageFunction = NotificationMessageFunctionWithoutExtras & NotificationMessageFunctionExtras;
213
255
  /**
214
- * Creates a NotificationMessageFunction from the input.
256
+ * Creates a {@link NotificationMessageFunction} by attaching optional {@link NotificationMessageFunctionExtras}
257
+ * (global recipients, lifecycle callbacks) to a base message generation function.
258
+ *
259
+ * @param fn - base function that generates message content per recipient
260
+ * @param extras - optional delivery customization (global recipients, send callbacks)
215
261
  *
216
- * @param fn
217
- * @param extras
218
- * @returns
262
+ * @example
263
+ * ```ts
264
+ * const msgFn = notificationMessageFunction(
265
+ * async (ctx) => ({
266
+ * inputContext: ctx,
267
+ * content: { title: 'New comment', openingMessage: 'Someone commented on your post' }
268
+ * }),
269
+ * { globalRecipients: [adminRecipient] }
270
+ * );
271
+ * ```
219
272
  */
220
273
  export declare function notificationMessageFunction(fn: NotificationMessageFunctionWithoutExtras, extras?: NotificationMessageFunctionExtras): NotificationMessageFunction;
274
+ /**
275
+ * Creates a {@link NotificationMessageFunctionFactory} that always returns `NO_CONTENT` messages.
276
+ *
277
+ * Useful as a placeholder factory for template types that should not produce deliverable content.
278
+ *
279
+ * @example
280
+ * ```ts
281
+ * const factory = noContentNotificationMessageFunctionFactory();
282
+ * const msgFn = await factory(config);
283
+ * const msg = await msgFn(inputContext);
284
+ * // msg.flag === NotificationMessageFlag.NO_CONTENT
285
+ * ```
286
+ */
221
287
  export declare function noContentNotificationMessageFunctionFactory<D extends NotificationItemMetadata = any>(): NotificationMessageFunctionFactory<D>;