@dereekb/nestjs 14.14.0 → 14.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs/eslint",
3
- "version": "14.14.0",
3
+ "version": "14.15.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
- "@dereekb/util": "14.14.0",
7
+ "@dereekb/util": "14.15.0",
8
8
  "@typescript-eslint/utils": "8.69.0"
9
9
  },
10
10
  "devDependencies": {
@@ -772,6 +772,22 @@ function _unsupported_iterable_to_array$1(o, minLen) {
772
772
  MailgunEventSeverity["PERMANENT"] = "permanent";
773
773
  MailgunEventSeverity["TEMPORARY"] = "temporary";
774
774
  })(MailgunEventSeverity || (MailgunEventSeverity = {}));
775
+ /**
776
+ * The domain suppression lists an address can be on.
777
+ *
778
+ * The values are the list names the Mailgun Suppressions API takes.
779
+ */ var MailgunSuppressionList;
780
+ (function(MailgunSuppressionList) {
781
+ /**
782
+ * Addresses a previous message hard-bounced from.
783
+ */ MailgunSuppressionList["BOUNCES"] = "bounces";
784
+ /**
785
+ * Addresses that reported a message as spam.
786
+ */ MailgunSuppressionList["COMPLAINTS"] = "complaints";
787
+ /**
788
+ * Addresses that unsubscribed, from all mail or from specific tags.
789
+ */ MailgunSuppressionList["UNSUBSCRIBES"] = "unsubscribes";
790
+ })(MailgunSuppressionList || (MailgunSuppressionList = {}));
775
791
  /**
776
792
  * True if any suppression record was found for the address.
777
793
  *
@@ -853,13 +869,13 @@ function _unsupported_iterable_to_array$1(o, minLen) {
853
869
  Promise.all([
854
870
  //
855
871
  readSuppression(function() {
856
- return suppressions.get(domain, 'bounces', email);
872
+ return suppressions.get(domain, MailgunSuppressionList.BOUNCES, email);
857
873
  }),
858
874
  readSuppression(function() {
859
- return suppressions.get(domain, 'complaints', email);
875
+ return suppressions.get(domain, MailgunSuppressionList.COMPLAINTS, email);
860
876
  }),
861
877
  readSuppression(function() {
862
- return suppressions.get(domain, 'unsubscribes', email);
878
+ return suppressions.get(domain, MailgunSuppressionList.UNSUBSCRIBES, email);
863
879
  })
864
880
  ])
865
881
  ];
@@ -880,6 +896,79 @@ function _unsupported_iterable_to_array$1(o, minLen) {
880
896
  });
881
897
  })();
882
898
  }
899
+ /**
900
+ * Removes an address from one of the domain's suppression lists, so Mailgun delivers to it again.
901
+ *
902
+ * An unsubscribe record is removed in full, including every tag it covers.
903
+ *
904
+ * Failure-tolerant like the read helpers in this module. Mailgun responds 404 when the address is not on
905
+ * the list, and that counts as cleared, since the goal (the address is not suppressed) is already met. Any
906
+ * other failure is returned as `cleared: false` with the error.
907
+ *
908
+ * @param api - The Mailgun API.
909
+ * @param email - The address to remove.
910
+ * @param list - The suppression list to remove it from.
911
+ * @returns What happened to the address on that list.
912
+ *
913
+ * @example
914
+ * ```ts
915
+ * const result = await mailgunRemoveSuppressionForRecipient(api, 'user@example.com', MailgunSuppressionList.UNSUBSCRIBES);
916
+ *
917
+ * if (!result.cleared) {
918
+ * console.log(`could not resubscribe: ${result.error}`);
919
+ * }
920
+ * ```
921
+ */ function mailgunRemoveSuppressionForRecipient(api, email, list) {
922
+ return _async_to_generator$1(function() {
923
+ var result, e, notFound;
924
+ return _ts_generator$1(this, function(_state) {
925
+ switch(_state.label){
926
+ case 0:
927
+ _state.trys.push([
928
+ 0,
929
+ 2,
930
+ ,
931
+ 3
932
+ ]);
933
+ return [
934
+ 4,
935
+ api.suppressions.destroy(api.domain, list, email)
936
+ ];
937
+ case 1:
938
+ _state.sent();
939
+ result = {
940
+ list: list,
941
+ cleared: true
942
+ };
943
+ return [
944
+ 3,
945
+ 3
946
+ ];
947
+ case 2:
948
+ e = _state.sent();
949
+ notFound = (e === null || e === void 0 ? void 0 : e.status) === 404;
950
+ result = notFound ? {
951
+ list: list,
952
+ cleared: true,
953
+ notFound: notFound
954
+ } : {
955
+ list: list,
956
+ cleared: false,
957
+ error: "".concat(e)
958
+ };
959
+ return [
960
+ 3,
961
+ 3
962
+ ];
963
+ case 3:
964
+ return [
965
+ 2,
966
+ result
967
+ ];
968
+ }
969
+ });
970
+ })();
971
+ }
883
972
  /**
884
973
  * Reads the most recent Mailgun events for a recipient address, newest first.
885
974
  *
@@ -915,6 +1004,61 @@ function _unsupported_iterable_to_array$1(o, minLen) {
915
1004
  });
916
1005
  })();
917
1006
  }
1007
+ /**
1008
+ * The default distance from the reference time that {@link mailgunEventForRecipientNear} searches.
1009
+ */ var DEFAULT_MAILGUN_EVENT_NEAR_WINDOW_MINUTES = 60;
1010
+ /**
1011
+ * Finds the recipient's event of a given kind closest to a point in time.
1012
+ *
1013
+ * Used to connect a suppression record to the event that created it. A suppression only records when it
1014
+ * happened, while the `unsubscribed` / `complained` event that triggered it also carries the message it
1015
+ * was triggered from, such as that message's subject.
1016
+ *
1017
+ * The search sends both `begin` and `end`, so Mailgun reads the range in ascending order and does not rely
1018
+ * on the `ascending` flag. An empty result is normal. Mailgun keeps events only for the plan's retention
1019
+ * period, and a suppression added through the API or the dashboard has no event at all.
1020
+ *
1021
+ * @param api - The Mailgun API.
1022
+ * @param email - The recipient address.
1023
+ * @param config - The event name, the time to search around, and the window.
1024
+ * @returns The matching event closest to `at`, or undefined if there is none or the lookup failed.
1025
+ */ function mailgunEventForRecipientNear(api, email, config) {
1026
+ return _async_to_generator$1(function() {
1027
+ var event, at, inputWindowMinutes, windowMs, atTime, events, closest, closestDistance;
1028
+ return _ts_generator$1(this, function(_state) {
1029
+ switch(_state.label){
1030
+ case 0:
1031
+ event = config.event, at = config.at, inputWindowMinutes = config.windowMinutes;
1032
+ windowMs = (inputWindowMinutes !== null && inputWindowMinutes !== void 0 ? inputWindowMinutes : DEFAULT_MAILGUN_EVENT_NEAR_WINDOW_MINUTES) * 60 * 1000;
1033
+ atTime = at.getTime();
1034
+ return [
1035
+ 4,
1036
+ mailgunEventsForQuery(api, {
1037
+ recipient: email,
1038
+ event: event,
1039
+ begin: new Date(atTime - windowMs).toUTCString(),
1040
+ end: new Date(atTime + windowMs).toUTCString(),
1041
+ limit: 25
1042
+ })
1043
+ ];
1044
+ case 1:
1045
+ events = _state.sent();
1046
+ closestDistance = Number.POSITIVE_INFINITY;
1047
+ events.forEach(function(x) {
1048
+ var distance = Math.abs(mailgunDomainEventDate(x).getTime() - atTime);
1049
+ if (distance < closestDistance) {
1050
+ closest = x;
1051
+ closestDistance = distance;
1052
+ }
1053
+ });
1054
+ return [
1055
+ 2,
1056
+ closest
1057
+ ];
1058
+ }
1059
+ });
1060
+ })();
1061
+ }
918
1062
  /**
919
1063
  * Strips the angle brackets Mailgun's send response wraps a message id in.
920
1064
  *
@@ -1828,4 +1972,4 @@ function _unsupported_iterable_to_array(o, minLen) {
1828
1972
  };
1829
1973
  }
1830
1974
 
1831
- export { DEFAULT_MAILGUN_RECENT_EVENTS_LIMIT, DEFAULT_MAILGUN_RECENT_EVENTS_WINDOW_DAYS, DEFAULT_RECIPIENT_VARIABLE_PREFIX, MAILGUN_BATCH_SEND_RECIPIENT_SUBJECT_TEMPLATE, MAILGUN_REPLY_TO_EMAIL_HEADER_DATA_VARIABLE_KEY, MAX_BATCH_SEND_RECIPIENTS, MailgunApi, MailgunEventName, MailgunEventSeverity, MailgunService, MailgunServiceModule, bareMailgunMessageId, convertMailgunRecipientToString, convertMailgunRecipientsToStrings, convertMailgunTemplateEmailRequestToMailgunMessageData, encodeMailgunTemplateVariableValue, expandMailgunRecipientBatchSendTargetRequestFactory, hasAnyMailgunRecipientSuppression, mailgunDomainEventAge, mailgunDomainEventDate, mailgunDomainEventFailureReason, mailgunDomainState, mailgunEventsForMessageId, mailgunEventsForQuery, mailgunRecentEventsForRecipient, mailgunRecipientBatchSendTargetEntityKeyRecipientLookup, mailgunRecipientBatchSendTargetFromReplyToBatchGroupKey, mailgunServiceConfigFactory, mailgunSuppressionsForRecipient, mailgunValidateEmail };
1975
+ export { DEFAULT_MAILGUN_EVENT_NEAR_WINDOW_MINUTES, DEFAULT_MAILGUN_RECENT_EVENTS_LIMIT, DEFAULT_MAILGUN_RECENT_EVENTS_WINDOW_DAYS, DEFAULT_RECIPIENT_VARIABLE_PREFIX, MAILGUN_BATCH_SEND_RECIPIENT_SUBJECT_TEMPLATE, MAILGUN_REPLY_TO_EMAIL_HEADER_DATA_VARIABLE_KEY, MAX_BATCH_SEND_RECIPIENTS, MailgunApi, MailgunEventName, MailgunEventSeverity, MailgunService, MailgunServiceModule, MailgunSuppressionList, bareMailgunMessageId, convertMailgunRecipientToString, convertMailgunRecipientsToStrings, convertMailgunTemplateEmailRequestToMailgunMessageData, encodeMailgunTemplateVariableValue, expandMailgunRecipientBatchSendTargetRequestFactory, hasAnyMailgunRecipientSuppression, mailgunDomainEventAge, mailgunDomainEventDate, mailgunDomainEventFailureReason, mailgunDomainState, mailgunEventForRecipientNear, mailgunEventsForMessageId, mailgunEventsForQuery, mailgunRecentEventsForRecipient, mailgunRecipientBatchSendTargetEntityKeyRecipientLookup, mailgunRecipientBatchSendTargetFromReplyToBatchGroupKey, mailgunRemoveSuppressionForRecipient, mailgunServiceConfigFactory, mailgunSuppressionsForRecipient, mailgunValidateEmail };
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs/mailgun",
3
- "version": "14.14.0",
3
+ "version": "14.15.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
- "@dereekb/date": "14.14.0",
8
- "@dereekb/model": "14.14.0",
9
- "@dereekb/nestjs": "14.14.0",
10
- "@dereekb/rxjs": "14.14.0",
11
- "@dereekb/util": "14.14.0",
7
+ "@dereekb/date": "14.15.0",
8
+ "@dereekb/model": "14.15.0",
9
+ "@dereekb/nestjs": "14.15.0",
10
+ "@dereekb/rxjs": "14.15.0",
11
+ "@dereekb/util": "14.15.0",
12
12
  "@nestjs/common": "^12.0.1",
13
13
  "@nestjs/config": "^12.0.0",
14
14
  "form-data": "^4.0.5",
@@ -7,8 +7,12 @@
7
7
  * anything. They are all failure-tolerant: a missing suppression record or an
8
8
  * unreachable API surfaces as an absent/empty result rather than a thrown error, so a
9
9
  * diagnostic routine can report what it could learn instead of aborting.
10
+ *
11
+ * The one write here is {@link mailgunRemoveSuppressionForRecipient}, the remedy for a
12
+ * suppression the diagnosis found. It is failure-tolerant in the same way, reporting what
13
+ * happened instead of throwing.
10
14
  */
11
- import { type EmailAddress, type Maybe, type Milliseconds } from '@dereekb/util';
15
+ import { type EmailAddress, type Maybe, type Milliseconds, type Minutes } from '@dereekb/util';
12
16
  import { type MailgunApi } from './mailgun.api';
13
17
  import { type MailgunBounceSuppression, type MailgunComplaintSuppression, type MailgunDomainEvent, type MailgunEmailValidationResult, type MailgunEventsQuery, type MailgunUnsubscribeSuppression } from './mailgun.type';
14
18
  /**
@@ -44,6 +48,25 @@ export declare enum MailgunEventSeverity {
44
48
  PERMANENT = "permanent",
45
49
  TEMPORARY = "temporary"
46
50
  }
51
+ /**
52
+ * The domain suppression lists an address can be on.
53
+ *
54
+ * The values are the list names the Mailgun Suppressions API takes.
55
+ */
56
+ export declare enum MailgunSuppressionList {
57
+ /**
58
+ * Addresses a previous message hard-bounced from.
59
+ */
60
+ BOUNCES = "bounces",
61
+ /**
62
+ * Addresses that reported a message as spam.
63
+ */
64
+ COMPLAINTS = "complaints",
65
+ /**
66
+ * Addresses that unsubscribed, from all mail or from specific tags.
67
+ */
68
+ UNSUBSCRIBES = "unsubscribes"
69
+ }
47
70
  /**
48
71
  * The suppression records found for a single address across a domain's suppression lists.
49
72
  *
@@ -79,6 +102,52 @@ export declare function hasAnyMailgunRecipientSuppression(suppressions: MailgunR
79
102
  * ```
80
103
  */
81
104
  export declare function mailgunSuppressionsForRecipient(api: MailgunApi, email: EmailAddress): Promise<MailgunRecipientSuppressions>;
105
+ /**
106
+ * The outcome of {@link mailgunRemoveSuppressionForRecipient}.
107
+ */
108
+ export interface MailgunRemoveSuppressionForRecipientResult {
109
+ /**
110
+ * The list the address was removed from.
111
+ */
112
+ readonly list: MailgunSuppressionList;
113
+ /**
114
+ * True when the address is no longer on the list, either because it was just removed or because it was
115
+ * not on the list in the first place.
116
+ */
117
+ readonly cleared: boolean;
118
+ /**
119
+ * True when the address was not on the list to begin with.
120
+ */
121
+ readonly notFound?: Maybe<boolean>;
122
+ /**
123
+ * Why the removal failed, when it did.
124
+ */
125
+ readonly error?: Maybe<string>;
126
+ }
127
+ /**
128
+ * Removes an address from one of the domain's suppression lists, so Mailgun delivers to it again.
129
+ *
130
+ * An unsubscribe record is removed in full, including every tag it covers.
131
+ *
132
+ * Failure-tolerant like the read helpers in this module. Mailgun responds 404 when the address is not on
133
+ * the list, and that counts as cleared, since the goal (the address is not suppressed) is already met. Any
134
+ * other failure is returned as `cleared: false` with the error.
135
+ *
136
+ * @param api - The Mailgun API.
137
+ * @param email - The address to remove.
138
+ * @param list - The suppression list to remove it from.
139
+ * @returns What happened to the address on that list.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const result = await mailgunRemoveSuppressionForRecipient(api, 'user@example.com', MailgunSuppressionList.UNSUBSCRIBES);
144
+ *
145
+ * if (!result.cleared) {
146
+ * console.log(`could not resubscribe: ${result.error}`);
147
+ * }
148
+ * ```
149
+ */
150
+ export declare function mailgunRemoveSuppressionForRecipient(api: MailgunApi, email: EmailAddress, list: MailgunSuppressionList): Promise<MailgunRemoveSuppressionForRecipientResult>;
82
151
  /**
83
152
  * Configuration for reading a recipient's recent Mailgun events.
84
153
  */
@@ -115,6 +184,46 @@ export interface MailgunRecentEventsForRecipientConfig {
115
184
  * ```
116
185
  */
117
186
  export declare function mailgunRecentEventsForRecipient(api: MailgunApi, email: EmailAddress, config?: Maybe<MailgunRecentEventsForRecipientConfig>): Promise<MailgunDomainEvent[]>;
187
+ /**
188
+ * The default distance from the reference time that {@link mailgunEventForRecipientNear} searches.
189
+ */
190
+ export declare const DEFAULT_MAILGUN_EVENT_NEAR_WINDOW_MINUTES: Minutes;
191
+ /**
192
+ * Configuration for {@link mailgunEventForRecipientNear}.
193
+ */
194
+ export interface MailgunEventForRecipientNearConfig {
195
+ /**
196
+ * The event name to look for, e.g. {@link MailgunEventName.UNSUBSCRIBED}.
197
+ */
198
+ readonly event: string;
199
+ /**
200
+ * The time the event is expected to have happened.
201
+ */
202
+ readonly at: Date;
203
+ /**
204
+ * How far either side of `at` to search.
205
+ *
206
+ * Defaults to {@link DEFAULT_MAILGUN_EVENT_NEAR_WINDOW_MINUTES}.
207
+ */
208
+ readonly windowMinutes?: Maybe<Minutes>;
209
+ }
210
+ /**
211
+ * Finds the recipient's event of a given kind closest to a point in time.
212
+ *
213
+ * Used to connect a suppression record to the event that created it. A suppression only records when it
214
+ * happened, while the `unsubscribed` / `complained` event that triggered it also carries the message it
215
+ * was triggered from, such as that message's subject.
216
+ *
217
+ * The search sends both `begin` and `end`, so Mailgun reads the range in ascending order and does not rely
218
+ * on the `ascending` flag. An empty result is normal. Mailgun keeps events only for the plan's retention
219
+ * period, and a suppression added through the API or the dashboard has no event at all.
220
+ *
221
+ * @param api - The Mailgun API.
222
+ * @param email - The recipient address.
223
+ * @param config - The event name, the time to search around, and the window.
224
+ * @returns The matching event closest to `at`, or undefined if there is none or the lookup failed.
225
+ */
226
+ export declare function mailgunEventForRecipientNear(api: MailgunApi, email: EmailAddress, config: MailgunEventForRecipientNearConfig): Promise<Maybe<MailgunDomainEvent>>;
118
227
  /**
119
228
  * Strips the angle brackets Mailgun's send response wraps a message id in.
120
229
  *
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs/openai",
3
- "version": "14.14.0",
3
+ "version": "14.15.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
- "@dereekb/date": "14.14.0",
8
- "@dereekb/model": "14.14.0",
9
- "@dereekb/nestjs": "14.14.0",
10
- "@dereekb/rxjs": "14.14.0",
11
- "@dereekb/util": "14.14.0",
7
+ "@dereekb/date": "14.15.0",
8
+ "@dereekb/model": "14.15.0",
9
+ "@dereekb/nestjs": "14.15.0",
10
+ "@dereekb/rxjs": "14.15.0",
11
+ "@dereekb/util": "14.15.0",
12
12
  "@nestjs/common": "^12.0.1",
13
13
  "@nestjs/config": "^12.0.0",
14
14
  "express": "^5.2.1",
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs/openrouter",
3
- "version": "14.14.0",
3
+ "version": "14.15.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
- "@dereekb/util": "14.14.0",
8
- "@dereekb/nestjs": "14.14.0",
7
+ "@dereekb/util": "14.15.0",
8
+ "@dereekb/nestjs": "14.15.0",
9
9
  "@nestjs/common": "^12.0.1",
10
10
  "@nestjs/config": "^12.0.0",
11
11
  "express": "^5.2.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs",
3
- "version": "14.14.0",
3
+ "version": "14.15.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -52,8 +52,8 @@
52
52
  }
53
53
  },
54
54
  "peerDependencies": {
55
- "@dereekb/rxjs": "14.14.0",
56
- "@dereekb/util": "14.14.0",
55
+ "@dereekb/rxjs": "14.15.0",
56
+ "@dereekb/util": "14.15.0",
57
57
  "@nestjs/common": "^12.0.1",
58
58
  "@nestjs/config": "^12.0.0",
59
59
  "@typeform/api-client": "^2.10.2",
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs/stripe",
3
- "version": "14.14.0",
3
+ "version": "14.15.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "peerDependencies": {
7
- "@dereekb/date": "14.14.0",
8
- "@dereekb/model": "14.14.0",
9
- "@dereekb/nestjs": "14.14.0",
10
- "@dereekb/rxjs": "14.14.0",
11
- "@dereekb/util": "14.14.0",
7
+ "@dereekb/date": "14.15.0",
8
+ "@dereekb/model": "14.15.0",
9
+ "@dereekb/nestjs": "14.15.0",
10
+ "@dereekb/rxjs": "14.15.0",
11
+ "@dereekb/util": "14.15.0",
12
12
  "@nestjs/common": "^12.0.1",
13
13
  "@nestjs/config": "^12.0.0",
14
14
  "express": "^5.2.1",