@clipboard-health/notifications 2.4.15 → 2.4.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/package.json +5 -5
- package/src/lib/internal/triggerIdempotencyKeyParamsToHash.d.ts +2 -2
- package/src/lib/internal/triggerIdempotencyKeyParamsToHash.js +5 -1
- package/src/lib/internal/triggerIdempotencyKeyParamsToHash.js.map +1 -1
- package/src/lib/notificationJobEnqueuer.d.ts +41 -21
- package/src/lib/notificationJobEnqueuer.js +7 -3
- package/src/lib/notificationJobEnqueuer.js.map +1 -1
- package/src/lib/triggerIdempotencyKey.d.ts +3 -3
- package/src/lib/triggerIdempotencyKey.js.map +1 -1
package/README.md
CHANGED
|
@@ -86,9 +86,12 @@ Send notifications through third-party providers.
|
|
|
86
86
|
* service instead of this manual calculation.
|
|
87
87
|
*/
|
|
88
88
|
expiresAt: new Date(Date.now() + 60 * 60_000).toISOString(),
|
|
89
|
-
// Set
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
// Set idempotencyKeyParts at enqueue-time so it remains stable across job retries.
|
|
90
|
+
idempotencyKeyParts: {
|
|
91
|
+
resource: {
|
|
92
|
+
type: "account",
|
|
93
|
+
id: "4e3ffeec-1426-4e54-ad28-83246f8f4e7c",
|
|
94
|
+
},
|
|
92
95
|
},
|
|
93
96
|
// Set recipients at enqueue-time so they respect our notification provider's limits.
|
|
94
97
|
recipients: ["userId-1"],
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipboard-health/notifications",
|
|
3
3
|
"description": "Send notifications through third-party providers.",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.19",
|
|
5
5
|
"bugs": "https://github.com/ClipboardHealth/core-utils/issues",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@clipboard-health/background-jobs-adapter": "1.4.
|
|
8
|
-
"@clipboard-health/phone-number": "1.4.
|
|
9
|
-
"@clipboard-health/util-ts": "4.4.
|
|
7
|
+
"@clipboard-health/background-jobs-adapter": "1.4.19",
|
|
8
|
+
"@clipboard-health/phone-number": "1.4.19",
|
|
9
|
+
"@clipboard-health/util-ts": "4.4.19",
|
|
10
10
|
"@knocklabs/node": "1.24.0",
|
|
11
11
|
"tslib": "2.8.1"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@clipboard-health/testing-core": "1.4.
|
|
14
|
+
"@clipboard-health/testing-core": "1.4.19",
|
|
15
15
|
"type-fest": "5.2.0"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type TriggerIdempotencyKeyParams } from "../triggerIdempotencyKey";
|
|
2
|
-
|
|
2
|
+
type HashParams = TriggerIdempotencyKeyParams & {
|
|
3
3
|
workplaceId?: string | undefined;
|
|
4
|
-
}
|
|
4
|
+
};
|
|
5
5
|
export declare function triggerIdempotencyKeyParamsToHash(params: HashParams): string;
|
|
6
6
|
export {};
|
|
@@ -10,7 +10,11 @@ function toSorted(params) {
|
|
|
10
10
|
chunk: params.chunk,
|
|
11
11
|
eventOccurredAt: params.eventOccurredAt,
|
|
12
12
|
recipients: [...params.recipients].sort(),
|
|
13
|
-
resourceId: params
|
|
13
|
+
resourceId: "resourceId" in params
|
|
14
|
+
? params.resourceId
|
|
15
|
+
: "resource" in params && params.resource && "id" in params.resource
|
|
16
|
+
? params.resource.id
|
|
17
|
+
: undefined,
|
|
14
18
|
workflowKey: params.workflowKey,
|
|
15
19
|
workplaceId: params.workplaceId,
|
|
16
20
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggerIdempotencyKeyParamsToHash.js","sourceRoot":"","sources":["../../../../../../packages/notifications/src/lib/internal/triggerIdempotencyKeyParamsToHash.ts"],"names":[],"mappings":";;AAOA,8EAEC;AARD,uEAAoE;AAMpE,SAAgB,iCAAiC,CAAC,MAAkB;IAClE,OAAO,IAAA,iDAAuB,EAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,QAAQ,CAAC,MAAkB;IAClC,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE;QACzC,UAAU,
|
|
1
|
+
{"version":3,"file":"triggerIdempotencyKeyParamsToHash.js","sourceRoot":"","sources":["../../../../../../packages/notifications/src/lib/internal/triggerIdempotencyKeyParamsToHash.ts"],"names":[],"mappings":";;AAOA,8EAEC;AARD,uEAAoE;AAMpE,SAAgB,iCAAiC,CAAC,MAAkB;IAClE,OAAO,IAAA,iDAAuB,EAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,QAAQ,CAAC,MAAkB;IAClC,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE;QACzC,UAAU,EACR,YAAY,IAAI,MAAM;YACpB,CAAC,CAAC,MAAM,CAAC,UAAU;YACnB,CAAC,CAAC,UAAU,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ;gBAClE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;gBACpB,CAAC,CAAC,SAAS;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { type BackgroundJobsAdapter, type EnqueueOptions, type MongoEnqueueOptions, type PostgresEnqueueOptions } from "@clipboard-health/background-jobs-adapter";
|
|
2
2
|
import { type TriggerIdempotencyKey } from "./triggerIdempotencyKey";
|
|
3
3
|
type EnqueueParameters = Parameters<BackgroundJobsAdapter["enqueue"]>;
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated Use `IdempotencyKeyParts` instead.
|
|
6
|
+
*/
|
|
4
7
|
export interface IdempotencyKey {
|
|
8
|
+
eventOccurredAt?: string | undefined;
|
|
9
|
+
resourceId?: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
export type IdempotencyKeyParts = {
|
|
5
12
|
/**
|
|
6
13
|
* Prefer `resourceId` over `eventOccurredAt`; it's harder to misuse.
|
|
7
14
|
*
|
|
@@ -10,39 +17,49 @@ export interface IdempotencyKey {
|
|
|
10
17
|
*
|
|
11
18
|
* Use `.toISOString()`.
|
|
12
19
|
*/
|
|
13
|
-
eventOccurredAt
|
|
20
|
+
eventOccurredAt: string;
|
|
21
|
+
resource?: undefined;
|
|
22
|
+
} | {
|
|
23
|
+
eventOccurredAt?: undefined;
|
|
14
24
|
/**
|
|
15
|
-
*
|
|
25
|
+
* Do not include `workflowKey`, `recipients`, or `workplaceId`; they are included
|
|
26
|
+
* automatically.
|
|
16
27
|
*
|
|
17
|
-
*
|
|
18
|
-
* included in the idempotency key automatically.
|
|
28
|
+
* If a resource triggered your workflow, include its unique ID.
|
|
19
29
|
*
|
|
20
30
|
* @example
|
|
21
31
|
* 1. For a "meeting starts in one hour" notification, set resourceId to the meeting ID.
|
|
22
32
|
* 2. For a payout notification, set resourceId to the payment ID.
|
|
23
33
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
resource: {
|
|
35
|
+
type: string;
|
|
36
|
+
id: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
26
39
|
export interface NotificationEnqueueData {
|
|
27
40
|
/**
|
|
41
|
+
* @deprecated Use `idempotencyKeyParts` instead.
|
|
42
|
+
*/
|
|
43
|
+
idempotencyKey?: IdempotencyKey;
|
|
44
|
+
/**
|
|
45
|
+
* Do not include `workflowKey`, `recipients`, or `workplaceId`; they are included
|
|
46
|
+
* automatically.
|
|
47
|
+
*
|
|
28
48
|
* Idempotency keys prevent duplicate notifications. They should be deterministic and remain the
|
|
29
49
|
* same across retry logic.
|
|
30
50
|
*
|
|
31
|
-
* If you retry a request with the same idempotency key within 24 hours, the client returns the
|
|
32
|
-
* response as the original request.
|
|
33
|
-
*
|
|
34
|
-
* Note: `workflowKey`, `recipients`, and `workplaceId` (if it exists in the trigger body) are
|
|
35
|
-
* included in the idempotency key automatically.
|
|
51
|
+
* If you retry a request with the same idempotency key within 24 hours, the client returns the
|
|
52
|
+
* same response as the original request.
|
|
36
53
|
*
|
|
37
54
|
* We provide this class because idempotency keys can be difficult to use correctly. If the key
|
|
38
|
-
* changes on each retry (e.g., Date.now() or uuid.v4()), it won't prevent duplicate
|
|
39
|
-
* Conversely, if you don't provide enough information, you prevent recipients from
|
|
40
|
-
* notifications they otherwise should have. For example, if you use the trigger key and
|
|
41
|
-
* recipient's ID as the idempotency key, but it's possible the recipient could receive the
|
|
42
|
-
* notification multiple times within the idempotency key's validity window, the recipient
|
|
43
|
-
* receive the first notification.
|
|
55
|
+
* changes on each retry (e.g., Date.now() or uuid.v4()), it won't prevent duplicate
|
|
56
|
+
* notifications. Conversely, if you don't provide enough information, you prevent recipients from
|
|
57
|
+
* receiving notifications they otherwise should have. For example, if you use the trigger key and
|
|
58
|
+
* the recipient's ID as the idempotency key, but it's possible the recipient could receive the
|
|
59
|
+
* same notification multiple times within the idempotency key's validity window, the recipient
|
|
60
|
+
* will only receive the first notification.
|
|
44
61
|
*/
|
|
45
|
-
|
|
62
|
+
idempotencyKeyParts?: IdempotencyKeyParts;
|
|
46
63
|
/** @see {@link TriggerRequest.expiresAt} */
|
|
47
64
|
expiresAt: string;
|
|
48
65
|
/** @see {@link TriggerBody.recipients} */
|
|
@@ -141,9 +158,12 @@ export declare class NotificationJobEnqueuer {
|
|
|
141
158
|
* * service instead of this manual calculation.
|
|
142
159
|
* *\/
|
|
143
160
|
* expiresAt: new Date(Date.now() + 60 * 60_000).toISOString(),
|
|
144
|
-
* // Set
|
|
145
|
-
*
|
|
146
|
-
*
|
|
161
|
+
* // Set idempotencyKeyParts at enqueue-time so it remains stable across job retries.
|
|
162
|
+
* idempotencyKeyParts: {
|
|
163
|
+
* resource: {
|
|
164
|
+
* type: "account",
|
|
165
|
+
* id: "4e3ffeec-1426-4e54-ad28-83246f8f4e7c",
|
|
166
|
+
* },
|
|
147
167
|
* },
|
|
148
168
|
* // Set recipients at enqueue-time so they respect our notification provider's limits.
|
|
149
169
|
* recipients: ["userId-1"],
|
|
@@ -59,9 +59,12 @@ class NotificationJobEnqueuer {
|
|
|
59
59
|
* * service instead of this manual calculation.
|
|
60
60
|
* *\/
|
|
61
61
|
* expiresAt: new Date(Date.now() + 60 * 60_000).toISOString(),
|
|
62
|
-
* // Set
|
|
63
|
-
*
|
|
64
|
-
*
|
|
62
|
+
* // Set idempotencyKeyParts at enqueue-time so it remains stable across job retries.
|
|
63
|
+
* idempotencyKeyParts: {
|
|
64
|
+
* resource: {
|
|
65
|
+
* type: "account",
|
|
66
|
+
* id: "4e3ffeec-1426-4e54-ad28-83246f8f4e7c",
|
|
67
|
+
* },
|
|
65
68
|
* },
|
|
66
69
|
* // Set recipients at enqueue-time so they respect our notification provider's limits.
|
|
67
70
|
* recipients: ["userId-1"],
|
|
@@ -84,6 +87,7 @@ class NotificationJobEnqueuer {
|
|
|
84
87
|
await Promise.all((0, chunkRecipients_1.chunkRecipients)({ recipients: data.recipients }).map(async ({ number, recipients }) => {
|
|
85
88
|
const idempotencyKeyParams = {
|
|
86
89
|
...data.idempotencyKey,
|
|
90
|
+
...data.idempotencyKeyParts,
|
|
87
91
|
chunk: number,
|
|
88
92
|
recipients,
|
|
89
93
|
workflowKey: data.workflowKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notificationJobEnqueuer.js","sourceRoot":"","sources":["../../../../../packages/notifications/src/lib/notificationJobEnqueuer.ts"],"names":[],"mappings":";;;AAAA,uFAMmD;AAEnD,gEAA6D;AAC7D,oGAAiG;AACjG,mEAIiC;
|
|
1
|
+
{"version":3,"file":"notificationJobEnqueuer.js","sourceRoot":"","sources":["../../../../../packages/notifications/src/lib/notificationJobEnqueuer.ts"],"names":[],"mappings":";;;AAAA,uFAMmD;AAEnD,gEAA6D;AAC7D,oGAAiG;AACjG,mEAIiC;AAoIjC,MAAa,uBAAuB;IACjB,OAAO,CAA2C;IAEnE,YAAY,MAAqC;QAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAE3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuEG;IACH,KAAK,CAAC,gBAAgB,CACpB,sBAA4C,EAC5C,IAAkB,EAClB,OAAiC;QAEjC,MAAM,OAAO,CAAC,GAAG,CACf,IAAA,iCAAe,EAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE;YACpF,MAAM,oBAAoB,GAAgC;gBACxD,GAAG,IAAI,CAAC,cAAc;gBACtB,GAAG,IAAI,CAAC,mBAAmB;gBAC3B,KAAK,EAAE,MAAM;gBACb,UAAU;gBACV,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC;YAEF,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CACxB,sBAAsB,EACtB;gBACE,GAAG,IAAI;gBACP,UAAU;gBACV,cAAc,EAAE,IAAA,yDAAiC,EAAC,oBAAoB,CAAC;aACxE,EACD;gBACE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClC,CAAC,6CAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,EAC/D,IAAA,qEAAiC,EAAC,oBAAoB,CAAC;aAC1D,CACF,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAhHD,0DAgHC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Tagged } from "type-fest";
|
|
2
|
-
import { type IdempotencyKey } from "./notificationJobEnqueuer";
|
|
2
|
+
import { type IdempotencyKey, type IdempotencyKeyParts } from "./notificationJobEnqueuer";
|
|
3
3
|
/**
|
|
4
4
|
* Idempotency keys prevent duplicate notifications. `NotificationClient.trigger` should be called
|
|
5
5
|
* after properly enqueuing a job using `NotificationJobEnqueuer.enqueueOneOrMore` to help ensure
|
|
@@ -10,7 +10,7 @@ import { type IdempotencyKey } from "./notificationJobEnqueuer";
|
|
|
10
10
|
* unnecessary.
|
|
11
11
|
*/
|
|
12
12
|
export type TriggerIdempotencyKey = Tagged<string, "TriggerIdempotencyKey">;
|
|
13
|
-
export
|
|
13
|
+
export type TriggerIdempotencyKeyParams = (IdempotencyKey | IdempotencyKeyParts) & {
|
|
14
14
|
/**
|
|
15
15
|
* The recipient chunk number.
|
|
16
16
|
*/
|
|
@@ -23,7 +23,7 @@ export interface TriggerIdempotencyKeyParams extends IdempotencyKey {
|
|
|
23
23
|
* The workflow key.
|
|
24
24
|
*/
|
|
25
25
|
workflowKey: string;
|
|
26
|
-
}
|
|
26
|
+
};
|
|
27
27
|
/**
|
|
28
28
|
* Type guard to check if a value is a valid TriggerIdempotencyKeyParams object.
|
|
29
29
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggerIdempotencyKey.js","sourceRoot":"","sources":["../../../../../packages/notifications/src/lib/triggerIdempotencyKey.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"triggerIdempotencyKey.js","sourceRoot":"","sources":["../../../../../packages/notifications/src/lib/triggerIdempotencyKey.ts"],"names":[],"mappings":";;AAyCA,sEAeC;AAMD,8EAKC;AAnED,uDAAkD;AAsClD;;GAEG;AACH,SAAgB,6BAA6B,CAC3C,KAAc;IAEd,IAAI,IAAA,eAAK,EAAC,KAAK,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,KAAoC,CAAC;IACpD,OAAO,CACL,OAAO,IAAI,MAAM;QACjB,aAAa,IAAI,MAAM;QACvB,YAAY,IAAI,MAAM;QACtB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;QAChC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,SAAS,KAAK,QAAQ,CAAC,CACtE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,iCAAiC,CAC/C,MAAmC;IAEnC,oEAAoE;IACpE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAA0B,CAAC;AACzD,CAAC"}
|