@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,52 +1,49 @@
1
+ /**
2
+ * @module notification.query
3
+ *
4
+ * Firestore query constraint builders for notification model documents.
5
+ * Used by the server-side action service to find documents that need processing.
6
+ */
1
7
  import { type FirestoreQueryConstraint } from '../../common/firestore';
2
8
  import { type NotificationBoxSendExclusion } from './notification.id';
3
9
  import { type ArrayOrValue } from '@dereekb/util';
4
10
  /**
5
- * Query for notificationUsers that are flagged for initialization.
11
+ * Query constraints for finding {@link NotificationUser} documents that have pending config syncs (`ns == true`).
6
12
  *
7
- * @param now
8
- * @returns
13
+ * Used by the server to discover users whose configs need to be synced to their NotificationBox recipients.
9
14
  */
10
15
  export declare function notificationUsersFlaggedForNeedsSyncQuery(): FirestoreQueryConstraint[];
11
16
  /**
12
- * Query for notificationUsers that have excluded any of the input notification box ids.
17
+ * Query constraints for finding {@link NotificationUser} documents that have any of the given exclusion IDs in their `x` array.
13
18
  *
14
- * @param now
15
- * @returns
19
+ * @param exclusionId - one or more box IDs or collection name prefixes to match against
16
20
  */
17
21
  export declare function notificationUserHasExclusionQuery(exclusionId: ArrayOrValue<NotificationBoxSendExclusion>): FirestoreQueryConstraint[];
18
22
  /**
19
- * Query for notificationSummaries that are flagged for initialization.
20
- *
21
- * @param now
22
- * @returns
23
+ * Query constraints for finding {@link NotificationSummary} documents that need server-side initialization (`s == true`).
23
24
  */
24
25
  export declare function notificationSummariesFlaggedForNeedsInitializationQuery(): FirestoreQueryConstraint[];
25
26
  /**
26
- * Query for notificationBoxes that are flagged for initialization.
27
- *
28
- * @param now
29
- * @returns
27
+ * Query constraints for finding {@link NotificationBox} documents that need server-side initialization (`s == true`).
30
28
  */
31
29
  export declare function notificationBoxesFlaggedForNeedsInitializationQuery(): FirestoreQueryConstraint[];
32
30
  /**
33
- * Query for notificationBoxes that are flagged as invalid.
31
+ * Query constraints for finding {@link NotificationBox} documents flagged as invalid (`fi == true`).
34
32
  *
35
- * @param now
36
- * @returns
33
+ * Used by the server to clean up boxes that could not be initialized.
37
34
  */
38
35
  export declare function notificationBoxesFlaggedInvalidQuery(): FirestoreQueryConstraint[];
39
36
  /**
40
- * Query for notifications that are not done and the send at time is in the past.
37
+ * Query constraints for finding {@link Notification} documents that are ready to be sent
38
+ * (not done and `sat` is in the past).
39
+ *
40
+ * This is the primary query used by the send queue processor.
41
41
  *
42
- * @param now
43
- * @returns
42
+ * @param now - reference time for the `sat` comparison (defaults to current time)
44
43
  */
45
44
  export declare function notificationsPastSendAtTimeQuery(now?: Date): FirestoreQueryConstraint[];
46
45
  /**
47
- * Query for notifications that are marked ready for cleanup/deletion.
48
- *
49
- * @param now
50
- * @returns
46
+ * Query constraints for finding {@link Notification} documents marked as done (`d == true`)
47
+ * and ready to be archived to {@link NotificationWeek} and then deleted.
51
48
  */
52
49
  export declare function notificationsReadyForCleanupQuery(): FirestoreQueryConstraint[];
@@ -1,22 +1,55 @@
1
+ /**
2
+ * @module notification.send
3
+ *
4
+ * Result types for notification delivery across each channel (email, text/SMS, in-app summary).
5
+ * These types are returned by the server's send pipeline and used to update {@link NotificationSendCheckpoints}
6
+ * for idempotent retry tracking.
7
+ */
1
8
  import { type Maybe, type EmailAddress, type E164PhoneNumber } from '@dereekb/util';
2
9
  import { type NotificationSummaryId } from './notification.id';
10
+ /**
11
+ * Per-channel delivery result tracking which recipients succeeded, failed, or were ignored.
12
+ *
13
+ * - `success` — delivery confirmed for these recipients
14
+ * - `failed` — temporary failure; these recipients should be retried on the next send attempt
15
+ * - `ignored` — recipients that were skipped (e.g., invalid address, duplicate, opted out)
16
+ *
17
+ * @template K - recipient identifier type (email address, phone number, or summary ID)
18
+ */
3
19
  export interface NotificationSendMessagesResult<K> {
4
20
  /**
5
- * Set of all successful recipients.
21
+ * Recipients where delivery succeeded.
6
22
  */
7
23
  readonly success: K[];
8
24
  /**
9
- * Set of all failed recipients.
10
- *
11
- * A failed recipient is a valid recipient that failed due to a temporary error and should be retried again it the future.
25
+ * Recipients where delivery failed due to a temporary error. Will be retried on subsequent attempts.
12
26
  */
13
27
  readonly failed: K[];
14
28
  /**
15
- * Set of all ignored recipients, if applicable..
29
+ * Recipients that were skipped (invalid, duplicate, or opted out).
16
30
  */
17
31
  readonly ignored: K[];
18
32
  }
33
+ /**
34
+ * Merges two {@link NotificationSendMessagesResult} objects by concatenating their recipient lists.
35
+ *
36
+ * Used when combining results from multiple send batches within the same channel.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const combined = mergeNotificationSendMessagesResult(firstBatchResult, secondBatchResult);
41
+ * ```
42
+ */
19
43
  export declare function mergeNotificationSendMessagesResult<K>(a: Maybe<NotificationSendMessagesResult<K>>, b: Maybe<NotificationSendMessagesResult<K>>): NotificationSendMessagesResult<K>;
44
+ /**
45
+ * Email channel delivery result, keyed by recipient email address.
46
+ */
20
47
  export type NotificationSendEmailMessagesResult = NotificationSendMessagesResult<EmailAddress>;
48
+ /**
49
+ * Text/SMS channel delivery result, keyed by recipient phone number in E.164 format.
50
+ */
21
51
  export type NotificationSendTextMessagesResult = NotificationSendMessagesResult<E164PhoneNumber>;
52
+ /**
53
+ * In-app notification summary channel delivery result, keyed by {@link NotificationSummaryId}.
54
+ */
22
55
  export type NotificationSendNotificationSummaryMessagesResult = NotificationSendMessagesResult<NotificationSummaryId>;
@@ -1,9 +1,26 @@
1
+ /**
2
+ * @module notification.task
3
+ *
4
+ * Checkpoint-based async task system built on top of the notification infrastructure.
5
+ *
6
+ * Task notifications use `NotificationSendType.TASK_NOTIFICATION` and run server-side async workflows
7
+ * with progress tracked via checkpoint strings. Each task handler returns a {@link NotificationTaskServiceHandleNotificationTaskResult}
8
+ * that tells the server whether the task is complete, partially done, failed, or should be delayed.
9
+ *
10
+ * Task lifecycle:
11
+ * 1. Task notification is created with a task type and optional checkpoint strings
12
+ * 2. Server picks it up via the send queue and routes to the registered handler
13
+ * 3. Handler returns a result indicating completion, partial progress, delay, or failure
14
+ * 4. Server updates the notification document accordingly and re-queues if not done
15
+ * 5. On completion (`true`), the notification document is deleted
16
+ */
1
17
  import { type NotificationItem, type NotificationItemMetadata } from './notification.item';
2
18
  import { type NotificationTaskType } from './notification.id';
3
19
  import { type NotificationDocument, type NotificationTaskCheckpointString } from './notification';
4
20
  import { type ArrayOrValue, type Maybe, type Milliseconds } from '@dereekb/util';
5
21
  /**
6
- * A NotificationTask is the final result of the expanded notification with a task type.
22
+ * Expanded task context passed to a task handler. Provides the notification document, item,
23
+ * and current checkpoint progress for the handler to make decisions.
7
24
  */
8
25
  export interface NotificationTask<D extends NotificationItemMetadata = {}> {
9
26
  /**
@@ -56,33 +73,84 @@ export interface NotificationTask<D extends NotificationItemMetadata = {}> {
56
73
  readonly unique: boolean;
57
74
  }
58
75
  /**
59
- * Returns an empty array, which is used to signal that the task did not fail but has not complete the current checkpoint.
76
+ * Returns an empty checkpoint array, signaling the task is not done but hasn't failed.
77
+ *
78
+ * Use this when the handler needs more time but doesn't want to increment the failure counter.
79
+ * The task will be re-queued without counting as an error attempt.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * // Waiting for an external process — delay without failing
84
+ * return { completion: delayCompletion(), delayUntil: 60000 };
85
+ * ```
60
86
  */
61
87
  export declare function delayCompletion<S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString>(): NotificationTaskServiceTaskHandlerCompletionType<S>;
62
88
  /**
63
- * Convenience function for returning a NotificationTaskServiceHandleNotificationTaskResult that says the task should be retried after the specified delay.
89
+ * Returns a result that re-queues the task after a delay without incrementing the error counter.
90
+ *
91
+ * Use when the task needs to wait (e.g., for an external API to complete) but hasn't failed.
64
92
  *
65
- * This does not affect the failure/retry count for a notification task.
93
+ * @param delayUntil - absolute date or relative milliseconds from the task's run start time
94
+ * @param updateMetadata - optional metadata updates to merge into the notification item
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * // Poll again in 30 seconds
99
+ * return notificationTaskDelayRetry(30000, { pollCount: task.data?.pollCount + 1 });
100
+ * ```
66
101
  */
67
102
  export declare function notificationTaskDelayRetry<D extends NotificationItemMetadata = {}, S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString>(delayUntil: Date | Milliseconds, updateMetadata?: Maybe<Partial<D>>): NotificationTaskServiceHandleNotificationTaskResult<D, S>;
68
103
  /**
69
- * Convenience function for returning a NotificationTaskServiceHandleNotificationTaskResult that says the task was partially completed, and to process the next part in the future.
104
+ * Returns a result indicating one or more checkpoints completed, with more work remaining.
105
+ *
106
+ * The completed checkpoint strings are added to the notification's `tpr` set. The task is re-queued
107
+ * for the next checkpoint.
108
+ *
109
+ * @param completedParts - checkpoint string(s) that were just completed
110
+ * @param updateMetadata - optional metadata updates to merge into the notification item
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * // Mark 'validate' checkpoint done, continue to 'process'
115
+ * return notificationTaskPartiallyComplete('validate');
116
+ * ```
70
117
  */
71
118
  export declare function notificationTaskPartiallyComplete<D extends NotificationItemMetadata = {}, S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString>(completedParts: ArrayOrValue<S>, updateMetadata?: Maybe<Partial<D>>): NotificationTaskServiceHandleNotificationTaskResult<D, S>;
72
119
  /**
73
- * Convenience function for returning a NotificationTaskServiceHandleNotificationTaskResult that says the task was completed successfully.
120
+ * Returns a result indicating the task completed successfully. The notification document will be deleted.
121
+ *
122
+ * @param updateMetadata - optional final metadata update (applied before deletion if subtasks need it)
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * // All done
127
+ * return notificationTaskComplete();
128
+ * ```
74
129
  */
75
130
  export declare function notificationTaskComplete<D extends NotificationItemMetadata = {}, S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString>(updateMetadata?: Maybe<Partial<D>>): NotificationTaskServiceHandleNotificationTaskResult<D, S>;
76
131
  /**
77
- * Convenience function for returning a NotificationTaskServiceHandleNotificationTaskResult that says the task failed.
132
+ * Returns a result indicating the task failed. Increments the error attempt counter.
133
+ *
134
+ * After exceeding the maximum retry attempts, the task will be permanently deleted.
135
+ *
136
+ * @param updateMetadata - optional metadata updates
137
+ * @param removeFromCompletedCheckpoints - checkpoint(s) to remove from the completed set (e.g., to retry a checkpoint)
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * // Task failed, retry with rolled-back checkpoint
142
+ * return notificationTaskFailed(undefined, 'process');
143
+ * ```
78
144
  */
79
145
  export declare function notificationTaskFailed<D extends NotificationItemMetadata = {}, S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString>(updateMetadata?: Maybe<Partial<D>>, removeFromCompletedCheckpoints?: Maybe<ArrayOrValue<S>>): NotificationTaskServiceHandleNotificationTaskResult<D, S>;
80
146
  /**
81
- * Wraps an existing NotificationTaskServiceHandleNotificationTaskResult<D> and sets canRunNextCheckpoint to true if it is undefined.
147
+ * Wraps a task result to allow immediate execution of the next checkpoint within the same run.
82
148
  *
83
- * @param result The result to use as a template.
84
- * @param force If true, then canRunNextCheckpoint will be set to true even if it is already defined.
85
- * @returns A new result.
149
+ * By default, only sets `canRunNextCheckpoint` if it isn't already defined.
150
+ * Use `force: true` to override an existing value.
151
+ *
152
+ * @param result - the task result to wrap
153
+ * @param force - when true, overrides any existing `canRunNextCheckpoint` value
86
154
  */
87
155
  export declare function notificationTaskCanRunNextCheckpoint<D extends NotificationItemMetadata = {}, S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString>(result: NotificationTaskServiceHandleNotificationTaskResult<D, S>, force?: Maybe<boolean>): NotificationTaskServiceHandleNotificationTaskResult<D, S>;
88
156
  /**
@@ -90,15 +158,18 @@ export declare function notificationTaskCanRunNextCheckpoint<D extends Notificat
90
158
  */
91
159
  export type NotificationTaskServiceTaskHandlerCompletionTypeCheckpoint<S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString> = ArrayOrValue<S>;
92
160
  /**
93
- * Result type of a NotificationTaskServiceTaskHandler.handleNotificationTask() call.
161
+ * Completion status returned by a task handler:
94
162
  *
95
- * true: The task was completed successfully and can now be discarded.
96
- * false: The task was not completed successfully and should be retried again in the future. Note there are a maximum number of retry attempts before the task is deleted. Use delayCompletion() to avoid increasing the attempt count.
97
- * NotificationTaskCheckpointString(s): The task has successfully completed this/these particular checkpoint(s) but is not complete and should be continued again in the future. Return an empty array to signal that the task did not fail but has not reached the next checkpoint.
163
+ * - `true` task completed successfully; notification document will be deleted
164
+ * - `false` task failed; error counter incremented, re-queued for retry (up to max attempts)
165
+ * - `string | string[]` checkpoint(s) completed; added to `tpr` set, task continues
166
+ * - `[]` (empty array) — task is in progress but no checkpoint reached; re-queued without error increment
98
167
  */
99
168
  export type NotificationTaskServiceTaskHandlerCompletionType<S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString> = true | false | NotificationTaskServiceTaskHandlerCompletionTypeCheckpoint<S>;
100
169
  /**
101
- * Result of a NotificationTaskServiceTaskHandler.handleNotificationTask() call.
170
+ * Full result object returned by a task handler to the server-side task runner.
171
+ *
172
+ * Combines the completion status with optional metadata updates, delay scheduling, and checkpoint management.
102
173
  */
103
174
  export interface NotificationTaskServiceHandleNotificationTaskResult<D extends NotificationItemMetadata = {}, S extends NotificationTaskCheckpointString = NotificationTaskCheckpointString> {
104
175
  /**
@@ -1,37 +1,54 @@
1
+ /**
2
+ * @module notification.task.subtask
3
+ *
4
+ * Subtask system for breaking complex notification tasks into "processing" and "cleanup" phases.
5
+ *
6
+ * A subtask wraps a notification task with two ordered checkpoints:
7
+ * 1. `'processing'` — the main work (e.g., external API calls, file generation)
8
+ * 2. `'cleanup'` — post-processing cleanup (e.g., updating related documents, deleting temporary files)
9
+ *
10
+ * Each subtask maintains its own checkpoint progress and metadata within the parent task's data payload.
11
+ */
1
12
  import { type Maybe } from '@dereekb/util';
2
13
  import { type NotificationTaskCheckpointString } from './notification';
3
14
  import { type NotificationItemMetadata } from './notification.item';
4
15
  import { type NotificationTaskServiceHandleNotificationTaskResult } from './notification.task';
5
16
  /**
6
- * Used as a descriminator to determine which processing configuration to run for the input value.
17
+ * Discriminator string that routes the subtask to the correct processing configuration.
7
18
  */
8
19
  export type NotificationTaskSubtaskTarget = string;
9
20
  /**
10
- * A subtask checkpoint.
11
- *
12
- * It is similar to NotificationTaskCheckpointString, but is stored within the subtask data.
21
+ * Checkpoint string for subtask-level progress, stored within the {@link NotificationTaskSubtaskData}.
13
22
  */
14
23
  export type NotificationTaskSubtaskCheckpointString = NotificationTaskCheckpointString;
15
24
  /**
16
- * Metadata for a subtask.
17
- *
18
- * It is similar to NotificationItemMetadata, but is stored within the subtask data.
25
+ * Metadata type for subtask-level state, stored within the {@link NotificationTaskSubtaskData}.
19
26
  */
20
27
  export type NotificationTaskSubtaskMetadata = NotificationItemMetadata;
21
28
  /**
22
- * A base NotificationTask's subtask data structure.
29
+ * Data structure embedded in the parent task's {@link NotificationItem} metadata to track subtask progress.
30
+ *
31
+ * Field abbreviations:
32
+ * - `sfps` — subtask finished processing steps (completed checkpoint strings)
33
+ * - `sd` — subtask data (arbitrary metadata for the subtask handler)
23
34
  */
24
35
  export interface NotificationTaskSubtaskData<M extends NotificationTaskSubtaskMetadata = NotificationTaskSubtaskMetadata, S extends NotificationTaskSubtaskCheckpointString = NotificationTaskSubtaskCheckpointString> {
25
36
  /**
26
- * The steps of the underlying subtask that have already been completed.
37
+ * Completed subtask checkpoint strings.
27
38
  */
28
39
  readonly sfps?: Maybe<S[]>;
29
40
  /**
30
- * Arbitrary metadata that is stored by the underlying subtask.
41
+ * Arbitrary metadata managed by the subtask handler.
31
42
  */
32
43
  readonly sd?: Maybe<M>;
33
44
  }
45
+ /**
46
+ * Checkpoint string for the main processing phase of a subtask.
47
+ */
34
48
  export declare const NOTIFICATION_TASK_SUBTASK_CHECKPOINT_PROCESSING: NotificationTaskCheckpointString;
49
+ /**
50
+ * Checkpoint string for the cleanup phase that runs after processing completes.
51
+ */
35
52
  export declare const NOTIFICATION_TASK_SUBTASK_CHECKPOINT_CLEANUP: NotificationTaskCheckpointString;
36
53
  /**
37
54
  * The maximum number of times to delay the cleanup step of a StorageFileProcessingNotificationTask.
@@ -51,12 +68,24 @@ export declare const DEFAULT_NOTIFICATION_TASK_SUBTASK_CLEANUP_RETRY_DELAY: numb
51
68
  */
52
69
  export type NotificationTaskSubtaskCheckpoint = typeof NOTIFICATION_TASK_SUBTASK_CHECKPOINT_PROCESSING | typeof NOTIFICATION_TASK_SUBTASK_CHECKPOINT_CLEANUP;
53
70
  /**
54
- * Returned by a subtask to complete the processing step and schedule the cleanup step.
71
+ * Internal helper that marks the `'processing'` checkpoint complete and schedules the `'cleanup'` phase.
55
72
  *
56
- * This is used internally in subtask running. Do not use this directly. Use of notificationSubtaskComplete() is preferred.
73
+ * Prefer using {@link notificationSubtaskComplete} in subtask handlers instead of calling this directly.
57
74
  */
58
75
  export declare function completeSubtaskProcessingAndScheduleCleanupTaskResult<D extends NotificationTaskSubtaskData>(): NotificationTaskServiceHandleNotificationTaskResult<D, NotificationTaskSubtaskCheckpoint>;
59
76
  /**
60
- * Similar to notificationTaskComplete, but is customized for a subtask with the intent of running the cleanup checkpoint.
77
+ * Returns a completion result for a subtask that has finished its processing.
78
+ *
79
+ * Unlike {@link notificationTaskComplete}, this signals that the cleanup checkpoint should still run.
80
+ * Use `canRunNextCheckpoint: true` in options to run cleanup immediately in the same execution.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * // Processing done, schedule cleanup for next run
85
+ * return notificationSubtaskComplete();
86
+ *
87
+ * // Processing done, run cleanup immediately
88
+ * return notificationSubtaskComplete({ canRunNextCheckpoint: true });
89
+ * ```
61
90
  */
62
91
  export declare function notificationSubtaskComplete<D extends NotificationTaskSubtaskData>(options?: Maybe<Pick<NotificationTaskServiceHandleNotificationTaskResult<D, NotificationTaskSubtaskCheckpoint>, 'updateMetadata' | 'canRunNextCheckpoint'>>): NotificationTaskServiceHandleNotificationTaskResult<D, NotificationTaskSubtaskCheckpoint>;
@@ -1,9 +1,19 @@
1
+ /**
2
+ * @module notification.util
3
+ *
4
+ * Server-side utility functions for notification config resolution, exclusion management,
5
+ * send state evaluation, and recipient merging.
6
+ */
1
7
  import { type ArrayOrValue, type Maybe } from '@dereekb/util';
2
8
  import { type Notification, type NotificationBox, type NotificationBoxDocument, NotificationRecipientSendFlag, type NotificationSendFlags, NotificationSendState, type NotificationUser } from './notification';
3
9
  import { type NotificationUserNotificationBoxRecipientConfig, type NotificationBoxRecipient, type NotificationUserDefaultNotificationBoxRecipientConfig } from './notification.config';
4
10
  import { type AppNotificationTemplateTypeInfoRecordService } from './notification.details';
5
11
  import { type FirebaseAuthUserId, type FirestoreDocumentAccessor, type FirestoreModelKey } from '../../common';
6
12
  import { type NotificationBoxId, type NotificationId, type NotificationBoxSendExclusionList, type NotificationBoxSendExclusion } from './notification.id';
13
+ /**
14
+ * Input for computing the effective {@link NotificationBoxRecipient} by merging the 3-level config hierarchy:
15
+ * recipient entry → user's per-box config → user's global config.
16
+ */
7
17
  export interface EffectiveNotificationBoxRecipientConfigInput {
8
18
  readonly uid: FirebaseAuthUserId;
9
19
  readonly m?: FirestoreModelKey;
@@ -12,7 +22,17 @@ export interface EffectiveNotificationBoxRecipientConfigInput {
12
22
  readonly boxConfig: NotificationUserNotificationBoxRecipientConfig;
13
23
  readonly recipient?: Maybe<NotificationBoxRecipient>;
14
24
  }
25
+ /**
26
+ * Computes the effective {@link NotificationBoxRecipient} by merging configs from highest to lowest priority:
27
+ * global config (`gc`) → per-box user config (`boxConfig`) → existing box recipient.
28
+ *
29
+ * Filters template configs to only include types applicable to the notification box's model.
30
+ * Used during the server-side sync process to update box recipient entries from user configs.
31
+ */
15
32
  export declare function effectiveNotificationBoxRecipientConfig(input: EffectiveNotificationBoxRecipientConfigInput): NotificationBoxRecipient;
33
+ /**
34
+ * Input for adding/removing send exclusions on a {@link NotificationUser}.
35
+ */
16
36
  export interface UpdateNotificationUserNotificationSendExclusionsInput {
17
37
  readonly notificationUser: Pick<NotificationUser, 'b' | 'x' | 'bc'>;
18
38
  readonly addExclusions?: ArrayOrValue<NotificationBoxSendExclusion>;
@@ -22,7 +42,16 @@ export interface UpdateNotificationUserNotificationSendExclusionsResult {
22
42
  readonly nextExclusions: NotificationBoxSendExclusionList;
23
43
  readonly update: Pick<NotificationUser, 'x' | 'ns' | 'bc'>;
24
44
  }
45
+ /**
46
+ * Adds and/or removes send exclusions from a {@link NotificationUser}, validates them against associated boxes,
47
+ * and propagates exclusion flags to the per-box configs.
48
+ *
49
+ * Exclusions not matching any associated notification box are automatically filtered out.
50
+ */
25
51
  export declare function updateNotificationUserNotificationSendExclusions(input: UpdateNotificationUserNotificationSendExclusionsInput): UpdateNotificationUserNotificationSendExclusionsResult;
52
+ /**
53
+ * Input for applying exclusion flags to per-box configs, updating the `x` and `ns` fields on each config.
54
+ */
26
55
  export interface ApplyExclusionsToNotificationUserNotificationBoxRecipientConfigsParams {
27
56
  readonly x?: NotificationBoxSendExclusionList;
28
57
  readonly bc?: Maybe<NotificationUserNotificationBoxRecipientConfig[]>;
@@ -30,52 +59,68 @@ export interface ApplyExclusionsToNotificationUserNotificationBoxRecipientConfig
30
59
  readonly recalculateNs?: boolean;
31
60
  }
32
61
  export type ApplyExclusionsToNotificationUserNotificationBoxRecipientConfigsResult = Pick<NotificationUser, 'bc' | 'ns'>;
62
+ /**
63
+ * Applies the current exclusion list to per-box configs, setting/clearing the `x` flag and marking
64
+ * changed configs as needing sync (`ns = true`).
65
+ */
33
66
  export declare function applyExclusionsToNotificationUserNotificationBoxRecipientConfigs(params: ApplyExclusionsToNotificationUserNotificationBoxRecipientConfigsParams): ApplyExclusionsToNotificationUserNotificationBoxRecipientConfigsResult;
67
+ /**
68
+ * Returns true if any of the per-box configs need syncing (`ns == true`).
69
+ */
34
70
  export declare function calculateNsForNotificationUserNotificationBoxRecipientConfigs(configs: NotificationUserNotificationBoxRecipientConfig[]): boolean;
35
71
  /**
36
- * Function that returns true if the notification is not excluded from being sent.
72
+ * Predicate function that returns true if the given notification/box ID is NOT excluded from delivery.
73
+ * Uses prefix matching against the exclusion list.
37
74
  */
38
75
  export type NotificationSendExclusionCanSendFunction = ((notification: NotificationId | NotificationBoxId) => boolean) & {
39
76
  readonly _exclusions: NotificationBoxSendExclusionList;
40
77
  };
78
+ /**
79
+ * Creates a {@link NotificationSendExclusionCanSendFunction} from the given exclusion list.
80
+ * Returns true for IDs that don't match any exclusion prefix.
81
+ */
41
82
  export declare const notificationSendExclusionCanSendFunction: (exclusions: NotificationBoxSendExclusionList) => NotificationSendExclusionCanSendFunction;
42
83
  /**
43
- * Returns true if the notification's send types are all marked as sent.
44
- *
45
- * @param input
46
- * @returns
84
+ * Returns true if all channels on the notification have reached a terminal state
85
+ * (NONE, NO_TRY, SENT, or SKIPPED). Used to determine if the notification can be marked done.
47
86
  */
48
87
  export declare function notificationSendFlagsImplyIsComplete(input: NotificationSendFlags): boolean;
49
88
  /**
50
- * Returns true if the state implies completion of sending (not necessarily success, but that attempts to send are done)
51
- *
52
- * @param input
53
- * @returns
89
+ * Returns true if the given send state is terminal no further send attempts will be made.
90
+ * Terminal states: NONE, NO_TRY, SENT, SKIPPED.
54
91
  */
55
92
  export declare function isCompleteNotificationSendState(input: NotificationSendState): boolean;
93
+ /**
94
+ * Resolved recipient group flags based on a {@link NotificationRecipientSendFlag}.
95
+ */
56
96
  export interface AllowedNotificationRecipients {
57
97
  readonly canSendToGlobalRecipients: boolean;
58
98
  readonly canSendToBoxRecipients: boolean;
59
99
  readonly canSendToExplicitRecipients: boolean;
60
100
  }
61
101
  /**
62
- * Returns a AllowedNotificationRecipients from the input NotificationRecipientSendFlag.
63
- *
64
- * @param flag
65
- * @returns
102
+ * Resolves which recipient groups (global, box, explicit) are allowed based on the {@link NotificationRecipientSendFlag}.
66
103
  */
67
104
  export declare function allowedNotificationRecipients(flag?: Maybe<NotificationRecipientSendFlag>): AllowedNotificationRecipients;
68
105
  /**
69
- * Whether or not the Notification should be saved to the NotificationWeek.
70
- *
71
- * A Notification should only be saved when the notification can be sent to box recipients.
106
+ * Returns true if the notification should be archived to a {@link NotificationWeek} after delivery.
72
107
  *
73
- * @param notification
74
- * @returns
108
+ * Only notifications that can be sent to box recipients are archived (notifications restricted
109
+ * to only explicit or only global recipients are not saved to the weekly archive).
75
110
  */
76
111
  export declare function shouldSaveNotificationToNotificationWeek(notification: Notification): boolean;
112
+ /**
113
+ * Merges a partial update into a {@link NotificationUserNotificationBoxRecipientConfig},
114
+ * preserving user-controlled fields (`nb`, `rm`, `ns`, `lk`, `bk`) and respecting OPT_OUT state.
115
+ */
77
116
  export declare function mergeNotificationUserNotificationBoxRecipientConfigs(a: NotificationUserNotificationBoxRecipientConfig, b: Partial<NotificationUserNotificationBoxRecipientConfig>): NotificationUserNotificationBoxRecipientConfig;
117
+ /**
118
+ * Merges a partial update into a {@link NotificationBoxRecipient}, deeply merging the `c` (config record) field.
119
+ */
78
120
  export declare function mergeNotificationBoxRecipients<T extends NotificationBoxRecipient>(a: T, b: Partial<T>): T;
121
+ /**
122
+ * Input for resolving a {@link NotificationBoxDocument}, either directly or by computing its ID from a model key.
123
+ */
79
124
  export interface NotificationBoxDocumentReferencePair {
80
125
  /**
81
126
  * NotificationBoxDocument to update.
@@ -88,4 +133,9 @@ export interface NotificationBoxDocumentReferencePair {
88
133
  */
89
134
  readonly notificationBoxRelatedModelKey?: Maybe<FirestoreModelKey>;
90
135
  }
136
+ /**
137
+ * Resolves a {@link NotificationBoxDocument} from a reference pair, loading by model key if no document is provided directly.
138
+ *
139
+ * @throws {Error} When neither a document nor a model key is provided.
140
+ */
91
141
  export declare function loadNotificationBoxDocumentForReferencePair(input: NotificationBoxDocumentReferencePair, accessor: FirestoreDocumentAccessor<NotificationBox, NotificationBoxDocument>): NotificationBoxDocument;
@@ -0,0 +1,8 @@
1
+ export * from './oidcmodel';
2
+ export * from './oidcmodel.id';
3
+ export * from './oidcmodel.query';
4
+ export * from './oidcmodel.api';
5
+ export * from './oidcmodel.action';
6
+ export * from './oidcmodel.data';
7
+ export * from './oidcmodel.interaction';
8
+ export * from './oidcmodel.interaction.oauth';
@@ -0,0 +1,37 @@
1
+ import { type AsyncFirebaseFunctionDeleteAction, type FirebaseFunctionDeleteAction, type AsyncFirebaseFunctionCreateAction, type AsyncFirebaseFunctionUpdateAction, type FirebaseFunctionCreateAction, type FirebaseFunctionUpdateAction } from '../../common';
2
+ import { type OidcEntryDocument } from './oidcmodel';
3
+ /**
4
+ * @module oidcmodel.action
5
+ *
6
+ * Type aliases for OidcEntry server action functions.
7
+ *
8
+ * These connect API parameter types to their target document types, following the same
9
+ * pattern as storagefile actions. See `@dereekb/firebase-server/oidc` for the
10
+ * server-side action service implementations.
11
+ *
12
+ * @template P - the API parameter type for the action
13
+ */
14
+ /**
15
+ * Synchronous create action targeting an {@link OidcEntryDocument}.
16
+ */
17
+ export type OidcEntryCreateAction<P extends object> = FirebaseFunctionCreateAction<P, OidcEntryDocument>;
18
+ /**
19
+ * Async create action targeting an {@link OidcEntryDocument}.
20
+ */
21
+ export type AsyncOidcEntryCreateAction<P extends object> = AsyncFirebaseFunctionCreateAction<P, OidcEntryDocument>;
22
+ /**
23
+ * Synchronous update action targeting an {@link OidcEntryDocument}.
24
+ */
25
+ export type OidcEntryUpdateAction<P extends object> = FirebaseFunctionUpdateAction<P, OidcEntryDocument>;
26
+ /**
27
+ * Async update action targeting an {@link OidcEntryDocument}.
28
+ */
29
+ export type AsyncOidcEntryUpdateAction<P extends object> = AsyncFirebaseFunctionUpdateAction<P, OidcEntryDocument>;
30
+ /**
31
+ * Synchronous delete action targeting an {@link OidcEntryDocument}.
32
+ */
33
+ export type OidcEntryDeleteAction<P extends object> = FirebaseFunctionDeleteAction<P, OidcEntryDocument>;
34
+ /**
35
+ * Async delete action targeting an {@link OidcEntryDocument}.
36
+ */
37
+ export type AsyncOidcEntryDeleteAction<P extends object> = AsyncFirebaseFunctionDeleteAction<P, OidcEntryDocument>;