mailchannels-sdk 1.5.1 → 1.6.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.
package/README.md CHANGED
@@ -205,13 +205,13 @@ The SDK provides a transport for Nodemailer that allows you to send emails using
205
205
 
206
206
  ```sh
207
207
  # npm
208
- npm i mailchannels-sdk nodemailer && npm i -D @types/nodemailer
208
+ npm i mailchannels-sdk nodemailer
209
209
 
210
210
  # yarn
211
- yarn add mailchannels-sdk nodemailer && yarn add -D @types/nodemailer
211
+ yarn add mailchannels-sdk nodemailer
212
212
 
213
213
  # pnpm
214
- pnpm add mailchannels-sdk nodemailer && pnpm add -D @types/nodemailer
214
+ pnpm add mailchannels-sdk nodemailer
215
215
  ```
216
216
 
217
217
  ### Sending
@@ -1,5 +1,5 @@
1
1
  import { FetchOptions } from "ofetch";
2
- interface MailChannelsClientOptions {
2
+ export interface MailChannelsClientOptions {
3
3
  /**
4
4
  * Override the MailChannels API base URL.
5
5
  * Useful for local testing against a simulator.
@@ -31,7 +31,7 @@ interface MailChannelsClientOptions {
31
31
  */
32
32
  signal?: AbortSignal;
33
33
  }
34
- declare class MailChannelsClient {
34
+ export declare class MailChannelsClient {
35
35
  #private;
36
36
  private static readonly DEFAULT_BASE_URL;
37
37
  private static readonly DEFAULT_TIMEOUT;
@@ -44,8 +44,8 @@ declare class MailChannelsClient {
44
44
  put<T>(path: string, options?: Omit<FetchOptions<"json">, "method">): Promise<T>;
45
45
  patch<T>(path: string, options?: Omit<FetchOptions<"json">, "method">): Promise<T>;
46
46
  }
47
- type ErrorType = "invalid_request_error" | "authentication_error" | "permission_error" | "not_found" | "conflict_error" | "payload_too_large_error" | "unprocessable_entity_error" | "rate_limit_error" | "internal_server_error" | "validation_error" | "application_error" | "api_error";
48
- interface ErrorResponse {
47
+ export type ErrorType = "invalid_request_error" | "authentication_error" | "permission_error" | "not_found" | "conflict_error" | "payload_too_large_error" | "unprocessable_entity_error" | "rate_limit_error" | "internal_server_error" | "validation_error" | "application_error" | "api_error";
48
+ export interface ErrorResponse {
49
49
  /**
50
50
  * A human-readable description of the error.
51
51
  */
@@ -68,7 +68,7 @@ interface ErrorResponse {
68
68
  */
69
69
  response: Record<string, unknown> | null;
70
70
  }
71
- interface SuccessResponse {
71
+ export interface SuccessResponse {
72
72
  /**
73
73
  * Whether the operation was successful.
74
74
  */
@@ -78,7 +78,7 @@ interface SuccessResponse {
78
78
  */
79
79
  error: ErrorResponse | null;
80
80
  }
81
- type DataResponse<T> = {
81
+ export type DataResponse<T> = {
82
82
  /**
83
83
  * The response data.
84
84
  */
@@ -97,7 +97,7 @@ type DataResponse<T> = {
97
97
  */
98
98
  error: ErrorResponse;
99
99
  };
100
- interface EmailsSendRecipient {
100
+ export interface EmailsSendRecipient {
101
101
  /**
102
102
  * The email address of the recipient.
103
103
  */
@@ -107,7 +107,7 @@ interface EmailsSendRecipient {
107
107
  */
108
108
  name?: string;
109
109
  }
110
- interface EmailsSendAttachment {
110
+ export interface EmailsSendAttachment {
111
111
  /**
112
112
  * The attachment data, encoded in base64.
113
113
  */
@@ -127,7 +127,7 @@ interface EmailsSendAttachment {
127
127
  */
128
128
  contentId?: string;
129
129
  }
130
- interface EmailsSendTracking {
130
+ export interface EmailsSendTracking {
131
131
  /**
132
132
  * Track when a recipient clicks a link in your email.
133
133
  */
@@ -159,11 +159,11 @@ interface EmailsSendTracking {
159
159
  enable?: boolean;
160
160
  };
161
161
  }
162
- type EmailsSendTemplateType = "mustache";
163
- type EmailsSendTemplateValue = string | boolean | number | EmailsSendTemplateValue[] | {
162
+ export type EmailsSendTemplateType = "mustache";
163
+ export type EmailsSendTemplateValue = string | boolean | number | EmailsSendTemplateValue[] | {
164
164
  [key: string]: EmailsSendTemplateValue;
165
165
  };
166
- interface EmailsSendTemplate {
166
+ export interface EmailsSendTemplate {
167
167
  /**
168
168
  * The template type of the content
169
169
  */
@@ -181,7 +181,7 @@ interface EmailsSendTemplate {
181
181
  */
182
182
  data?: Record<string, EmailsSendTemplateValue>;
183
183
  }
184
- interface EmailsSendContent {
184
+ export interface EmailsSendContent {
185
185
  /**
186
186
  * The MIME type of the content you are including in your email.
187
187
  */
@@ -191,8 +191,8 @@ interface EmailsSendContent {
191
191
  */
192
192
  value: string;
193
193
  }
194
- type EmailsSendRecipientInput = EmailsSendRecipient | string | (EmailsSendRecipient | string)[];
195
- interface EmailsSendDkim {
194
+ export type EmailsSendRecipientInput = EmailsSendRecipient | string | (EmailsSendRecipient | string)[];
195
+ export interface EmailsSendDkim {
196
196
  /**
197
197
  * Domain used for DKIM signing.
198
198
  */
@@ -206,7 +206,7 @@ interface EmailsSendDkim {
206
206
  */
207
207
  selector?: string;
208
208
  }
209
- interface EmailsSendPersonalization {
209
+ export interface EmailsSendPersonalization {
210
210
  /**
211
211
  * The BCC recipients for this personalization.
212
212
  */
@@ -410,7 +410,7 @@ type EmailsSendTargetOptions = {
410
410
  cc?: EmailsSendRecipientInput;
411
411
  bcc?: EmailsSendRecipientInput;
412
412
  };
413
- type EmailsSendOptions = EmailsSendOptionsBase & EmailsSendTargetOptions & ({
413
+ export type EmailsSendOptions = EmailsSendOptionsBase & EmailsSendTargetOptions & ({
414
414
  /**
415
415
  * The HTML content of the email.
416
416
  * @example
@@ -462,7 +462,7 @@ type EmailsSendOptions = EmailsSendOptionsBase & EmailsSendTargetOptions & ({
462
462
  */
463
463
  content: EmailsSendContent[];
464
464
  });
465
- type EmailsSendResponse = DataResponse<{
465
+ export type EmailsSendResponse = DataResponse<{
466
466
  /**
467
467
  * Fully rendered message if `dryRun` was set to `true`. A string representation of a rendered message, one per personalization in the request.
468
468
  */
@@ -490,7 +490,7 @@ type EmailsSendResponse = DataResponse<{
490
490
  status: "sent" | "failed";
491
491
  }[];
492
492
  }>;
493
- type EmailsQueueResponse = DataResponse<{
493
+ export type EmailsQueueResponse = DataResponse<{
494
494
  /**
495
495
  * ISO 8601 timestamp when the request was queued for processing.
496
496
  */
@@ -501,8 +501,8 @@ type EmailsQueueResponse = DataResponse<{
501
501
  requestId: string;
502
502
  }>;
503
503
  /** @deprecated Use `EmailsQueueResponse` instead. */
504
- type EmailsSendAsyncResponse = EmailsQueueResponse;
505
- declare class Emails {
504
+ export type EmailsSendAsyncResponse = EmailsQueueResponse;
505
+ export declare class Emails {
506
506
  protected mailchannels: MailChannelsClient;
507
507
  constructor(mailchannels: MailChannelsClient);
508
508
  private _sendEmail;
@@ -546,7 +546,7 @@ declare class Emails {
546
546
  */
547
547
  sendAsync(options: EmailsSendOptions): Promise<EmailsQueueResponse>;
548
548
  }
549
- interface DomainsDkimCreateOptions {
549
+ export interface DomainsDkimCreateOptions {
550
550
  /**
551
551
  * Algorithm used for the new key pair Currently, only RSA is supported.
552
552
  * @default "rsa"
@@ -562,8 +562,8 @@ interface DomainsDkimCreateOptions {
562
562
  */
563
563
  selector: string;
564
564
  }
565
- type DomainsDkimKeyStatus = "active" | "retired" | "revoked" | "rotated";
566
- interface DomainsDkimKey {
565
+ export type DomainsDkimKeyStatus = "active" | "retired" | "revoked" | "rotated";
566
+ export interface DomainsDkimKey {
567
567
  /**
568
568
  * Algorithm used for the key pair.
569
569
  */
@@ -610,8 +610,8 @@ interface DomainsDkimKey {
610
610
  */
611
611
  statusModifiedAt?: string;
612
612
  }
613
- type DomainsDkimCreateResponse = DataResponse<DomainsDkimKey>;
614
- interface DomainsDkimListOptions {
613
+ export type DomainsDkimCreateResponse = DataResponse<DomainsDkimKey>;
614
+ export interface DomainsDkimListOptions {
615
615
  /**
616
616
  * Selector to filter keys by. Must be a maximum of 63 characters.
617
617
  */
@@ -637,8 +637,8 @@ interface DomainsDkimListOptions {
637
637
  includeDnsRecord?: boolean;
638
638
  }
639
639
  type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
640
- type DomainsDkimListResponse = DataResponse<Optional<DomainsDkimKey, "dnsRecords">[]>;
641
- interface DomainsDkimUpdateStatusOptions {
640
+ export type DomainsDkimListResponse = DataResponse<Optional<DomainsDkimKey, "dnsRecords">[]>;
641
+ export interface DomainsDkimUpdateStatusOptions {
642
642
  /**
643
643
  * Selector of the DKIM key pair to update. Must be a maximum of 63 characters.
644
644
  */
@@ -651,7 +651,7 @@ interface DomainsDkimUpdateStatusOptions {
651
651
  */
652
652
  status: Exclude<DomainsDkimKey["status"], "active">;
653
653
  }
654
- interface DomainsDkimRotateOptions {
654
+ export interface DomainsDkimRotateOptions {
655
655
  newKey: {
656
656
  /**
657
657
  * Selector for the new key pair. Must be a maximum of 63 characters.
@@ -659,12 +659,14 @@ interface DomainsDkimRotateOptions {
659
659
  selector: string;
660
660
  };
661
661
  }
662
- type DomainsDkimRotateResponse = DataResponse<{
662
+ export type DomainsDkimRotateResponse = DataResponse<{
663
663
  new: DomainsDkimKey;
664
664
  rotated: DomainsDkimKey;
665
665
  }>;
666
666
  declare class DomainsDkim {
667
667
  private mailchannels;
668
+ private static readonly UPDATE_STATUS_VALUES;
669
+ private static readonly STATUS_VALUES;
668
670
  constructor(mailchannels: MailChannelsClient);
669
671
  /**
670
672
  * Create a DKIM key pair for a specified domain and selector using the specified algorithm and key length, for the current customer.
@@ -723,8 +725,8 @@ declare class DomainsDkim {
723
725
  */
724
726
  rotate(domain: string, selector: string, options: DomainsDkimRotateOptions): Promise<DomainsDkimRotateResponse>;
725
727
  }
726
- type DomainsCustomTrackingScope = "click" | "open" | "unsubscribe";
727
- interface DomainsCustomTrackingDomain {
728
+ export type DomainsCustomTrackingScope = "click" | "open" | "unsubscribe";
729
+ export interface DomainsCustomTrackingDomain {
728
730
  /**
729
731
  * The label for this custom tracking domain.
730
732
  */
@@ -746,7 +748,7 @@ interface DomainsCustomTrackingDomain {
746
748
  */
747
749
  createdAt: string;
748
750
  }
749
- interface DomainsCustomTrackingDnsSetupRequired {
751
+ export interface DomainsCustomTrackingDnsSetupRequired {
750
752
  /**
751
753
  * UUID v4 nonce; also the TXT record value to set. Present only when TXT ownership verification is pending.
752
754
  * @example "550e8400-e29b-41d4-a716-446655440000"
@@ -767,7 +769,7 @@ interface DomainsCustomTrackingDnsSetupRequired {
767
769
  */
768
770
  instructions?: string;
769
771
  }
770
- type DomainsCustomTrackingWithDnsSetupRequired<T extends 202 | 201 | 200 | undefined = undefined> = T extends undefined ? DomainsCustomTrackingDomain & {
772
+ export type DomainsCustomTrackingWithDnsSetupRequired<T extends 202 | 201 | 200 | undefined = undefined> = T extends undefined ? DomainsCustomTrackingDomain & {
771
773
  dnsSetupRequired: false;
772
774
  } | DomainsCustomTrackingDnsSetupRequired & {
773
775
  dnsSetupRequired: true;
@@ -776,8 +778,8 @@ type DomainsCustomTrackingWithDnsSetupRequired<T extends 202 | 201 | 200 | undef
776
778
  } : DomainsCustomTrackingDomain & {
777
779
  dnsSetupRequired: false;
778
780
  };
779
- type DomainsCustomTrackingCreateResponse = DataResponse<DomainsCustomTrackingWithDnsSetupRequired>;
780
- interface DomainsCustomTrackingListOptions {
781
+ export type DomainsCustomTrackingCreateResponse = DataResponse<DomainsCustomTrackingWithDnsSetupRequired>;
782
+ export interface DomainsCustomTrackingListOptions {
781
783
  /**
782
784
  * Filter by custom tracking domain label.
783
785
  */
@@ -801,7 +803,7 @@ interface DomainsCustomTrackingListOptions {
801
803
  */
802
804
  offset?: number;
803
805
  }
804
- type DomainsCustomTrackingListResponse = DataResponse<{
806
+ export type DomainsCustomTrackingListResponse = DataResponse<{
805
807
  /**
806
808
  * List of custom tracking domains matching the filter criteria.
807
809
  */
@@ -811,7 +813,7 @@ type DomainsCustomTrackingListResponse = DataResponse<{
811
813
  */
812
814
  total: number;
813
815
  }>;
814
- interface DomainsCustomTrackingUpdateOptions {
816
+ export interface DomainsCustomTrackingUpdateOptions {
815
817
  /**
816
818
  * New label for this custom tracking domain. Maximum length is `64` characters. Must match the pattern `^[a-z0-9-]+$`.
817
819
  */
@@ -821,7 +823,7 @@ interface DomainsCustomTrackingUpdateOptions {
821
823
  */
822
824
  status?: "active" | "disabled";
823
825
  }
824
- type DomainsCustomTrackingUpdateResponse = DataResponse<DomainsCustomTrackingWithDnsSetupRequired>;
826
+ export type DomainsCustomTrackingUpdateResponse = DataResponse<DomainsCustomTrackingWithDnsSetupRequired>;
825
827
  declare class DomainsCustomTracking {
826
828
  private mailchannels;
827
829
  private static readonly SCOPE_VALUES;
@@ -902,7 +904,7 @@ interface DomainsCheckDkim {
902
904
  */
903
905
  selector?: string;
904
906
  }
905
- interface DomainsCheckOptions {
907
+ export interface DomainsCheckOptions {
906
908
  /**
907
909
  * Each item may include DKIM `domain`, `selector` and `privateKey`. Up to 10 items are allowed. The absence or presence of these fields affects how DKIM settings are validated:
908
910
  * 1. If `domain`, `selector`, and `privateKey` are all present, verify using the provided domain, selector, and key.
@@ -925,8 +927,8 @@ interface DomainsCheckOptions {
925
927
  */
926
928
  senderId?: string;
927
929
  }
928
- type DomainsCheckVerdict = "passed" | "failed" | "soft failed" | "temporary error" | "permanent error" | "neutral" | "none" | "unknown";
929
- type DomainsCheckResponse = DataResponse<{
930
+ export type DomainsCheckVerdict = "passed" | "failed" | "soft failed" | "temporary error" | "permanent error" | "neutral" | "none" | "unknown";
931
+ export type DomainsCheckResponse = DataResponse<{
930
932
  dkim: {
931
933
  domain: string;
932
934
  /**
@@ -987,7 +989,7 @@ type DomainsCheckResponse = DataResponse<{
987
989
  };
988
990
  references?: string[];
989
991
  }>;
990
- declare class Domains {
992
+ export declare class Domains {
991
993
  protected mailchannels: MailChannelsClient;
992
994
  readonly dkim: DomainsDkim;
993
995
  readonly customTracking: DomainsCustomTracking;
@@ -1011,13 +1013,13 @@ declare class Domains {
1011
1013
  */
1012
1014
  check(domain: string, options?: DomainsCheckOptions): Promise<DomainsCheckResponse>;
1013
1015
  }
1014
- type WebhooksListResponse = DataResponse<{
1016
+ export type WebhooksListResponse = DataResponse<{
1015
1017
  /**
1016
1018
  * A customer's webhook that events will be sent to
1017
1019
  */
1018
1020
  webhook: string;
1019
1021
  }[]>;
1020
- type WebhooksSigningKeyResponse = DataResponse<{
1022
+ export type WebhooksSigningKeyResponse = DataResponse<{
1021
1023
  /**
1022
1024
  * The ID of the key.
1023
1025
  */
@@ -1027,7 +1029,7 @@ type WebhooksSigningKeyResponse = DataResponse<{
1027
1029
  */
1028
1030
  key: string;
1029
1031
  }>;
1030
- type WebhooksValidateResponse = DataResponse<{
1032
+ export type WebhooksValidateResponse = DataResponse<{
1031
1033
  /**
1032
1034
  * Indicates whether all webhook validations passed.
1033
1035
  */
@@ -1059,7 +1061,7 @@ type WebhooksValidateResponse = DataResponse<{
1059
1061
  } | null;
1060
1062
  }[];
1061
1063
  }>;
1062
- type WebhookEventType = "processed" | "delivered" | "open" | "click" | "hard-bounced" | "soft-bounced" | "dropped" | "complained" | "unsubscribed" | "test";
1064
+ export type WebhookEventType = "processed" | "delivered" | "open" | "click" | "hard-bounced" | "soft-bounced" | "dropped" | "complained" | "unsubscribed" | "test";
1063
1065
  interface WebhookEventBase<T extends WebhookEventType> {
1064
1066
  /**
1065
1067
  * The sender's email address
@@ -1095,8 +1097,8 @@ interface WebhookEventBase<T extends WebhookEventType> {
1095
1097
  */
1096
1098
  recipients?: string[];
1097
1099
  }
1098
- interface WebhookEventProcessed extends WebhookEventBase<"processed"> {}
1099
- interface WebhookEventDelivered extends WebhookEventBase<"delivered"> {}
1100
+ export interface WebhookEventProcessed extends WebhookEventBase<"processed"> {}
1101
+ export interface WebhookEventDelivered extends WebhookEventBase<"delivered"> {}
1100
1102
  interface WebhookEventWithTracking {
1101
1103
  /**
1102
1104
  * The User-Agent header given when the recipient opened the message
@@ -1107,8 +1109,8 @@ interface WebhookEventWithTracking {
1107
1109
  */
1108
1110
  ip?: string;
1109
1111
  }
1110
- interface WebhookEventOpen extends WebhookEventBase<"open">, WebhookEventWithTracking {}
1111
- interface WebhookEventClick extends WebhookEventBase<"click">, WebhookEventWithTracking {
1112
+ export interface WebhookEventOpen extends WebhookEventBase<"open">, WebhookEventWithTracking {}
1113
+ export interface WebhookEventClick extends WebhookEventBase<"click">, WebhookEventWithTracking {
1112
1114
  /**
1113
1115
  * The URL that was clicked by the recipient
1114
1116
  */
@@ -1124,14 +1126,14 @@ interface WebhookEventWithStatus {
1124
1126
  */
1125
1127
  reason?: string;
1126
1128
  }
1127
- interface WebhookEventHardBounced extends WebhookEventBase<"hard-bounced">, WebhookEventWithStatus {}
1128
- interface WebhookEventSoftBounced extends WebhookEventBase<"soft-bounced">, WebhookEventWithStatus {}
1129
- interface WebhookEventDropped extends WebhookEventBase<"dropped">, WebhookEventWithStatus {}
1130
- interface WebhookEventComplained extends WebhookEventBase<"complained"> {}
1131
- interface WebhookEventUnsubscribed extends WebhookEventBase<"unsubscribed"> {}
1132
- interface WebhookEventTest extends Omit<WebhookEventBase<"test">, "recipients" | "campaignId"> {}
1133
- type WebhookEvent = WebhookEventProcessed | WebhookEventDelivered | WebhookEventOpen | WebhookEventClick | WebhookEventHardBounced | WebhookEventSoftBounced | WebhookEventDropped | WebhookEventComplained | WebhookEventUnsubscribed | WebhookEventTest;
1134
- interface WebhooksVerifyOptions {
1129
+ export interface WebhookEventHardBounced extends WebhookEventBase<"hard-bounced">, WebhookEventWithStatus {}
1130
+ export interface WebhookEventSoftBounced extends WebhookEventBase<"soft-bounced">, WebhookEventWithStatus {}
1131
+ export interface WebhookEventDropped extends WebhookEventBase<"dropped">, WebhookEventWithStatus {}
1132
+ export interface WebhookEventComplained extends WebhookEventBase<"complained"> {}
1133
+ export interface WebhookEventUnsubscribed extends WebhookEventBase<"unsubscribed"> {}
1134
+ export interface WebhookEventTest extends Omit<WebhookEventBase<"test">, "recipients" | "campaignId"> {}
1135
+ export type WebhookEvent = WebhookEventProcessed | WebhookEventDelivered | WebhookEventOpen | WebhookEventClick | WebhookEventHardBounced | WebhookEventSoftBounced | WebhookEventDropped | WebhookEventComplained | WebhookEventUnsubscribed | WebhookEventTest;
1136
+ export interface WebhooksVerifyOptions {
1135
1137
  /**
1136
1138
  * The raw body of the incoming webhook request as a string. This should be the exact payload received from the webhook, without any modifications or parsing, to ensure accurate signature verification.
1137
1139
  */
@@ -1154,10 +1156,10 @@ interface WebhooksVerifyOptions {
1154
1156
  */
1155
1157
  cache?: boolean;
1156
1158
  }
1157
- type WebhooksVerifyResponse = DataResponse<WebhookEvent[]>;
1158
- type WebhooksBatchStatus = "1xx" | "2xx" | "3xx" | "4xx" | "5xx" | "no_response";
1159
- type WebhooksBatchResponseStatus = "1xx_response" | "2xx_response" | "3xx_response" | "4xx_response" | "5xx_response" | "no_response";
1160
- interface WebhooksBatchesOptions {
1159
+ export type WebhooksVerifyResponse = DataResponse<WebhookEvent[]>;
1160
+ export type WebhooksBatchStatus = "1xx" | "2xx" | "3xx" | "4xx" | "5xx" | "no_response";
1161
+ export type WebhooksBatchResponseStatus = "1xx_response" | "2xx_response" | "3xx_response" | "4xx_response" | "5xx_response" | "no_response";
1162
+ export interface WebhooksBatchesOptions {
1161
1163
  /**
1162
1164
  * Inclusive lower bound (UTC) for filtering webhook batches by creation time. Formats: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SSZ` or a `Date` object.
1163
1165
  */
@@ -1185,7 +1187,7 @@ interface WebhooksBatchesOptions {
1185
1187
  */
1186
1188
  offset?: number;
1187
1189
  }
1188
- interface WebhooksBatch {
1190
+ export interface WebhooksBatch {
1189
1191
  /**
1190
1192
  * Unique identifier for the webhook batch.
1191
1193
  */
@@ -1222,8 +1224,8 @@ interface WebhooksBatch {
1222
1224
  */
1223
1225
  webhook: string;
1224
1226
  }
1225
- type WebhooksBatchesResponse = DataResponse<WebhooksBatch[]>;
1226
- interface WebhooksResendBatch {
1227
+ export type WebhooksBatchesResponse = DataResponse<WebhooksBatch[]>;
1228
+ export interface WebhooksResendBatch {
1227
1229
  /**
1228
1230
  * Unique identifier for the webhook batch.
1229
1231
  */
@@ -1253,9 +1255,10 @@ interface WebhooksResendBatch {
1253
1255
  */
1254
1256
  statusCode: number | null;
1255
1257
  }
1256
- type WebhooksResendBatchResponse = DataResponse<WebhooksResendBatch>;
1257
- declare class Webhooks {
1258
+ export type WebhooksResendBatchResponse = DataResponse<WebhooksResendBatch>;
1259
+ export declare class Webhooks {
1258
1260
  protected mailchannels: MailChannelsClient;
1261
+ private static readonly STATUS_VALUES;
1259
1262
  constructor(mailchannels: MailChannelsClient);
1260
1263
  /**
1261
1264
  * Enrolls the customer to receive event notifications via webhooks.
@@ -1345,7 +1348,7 @@ declare class Webhooks {
1345
1348
  */
1346
1349
  resendBatch(batchId: number): Promise<WebhooksResendBatchResponse>;
1347
1350
  }
1348
- interface SubAccount {
1351
+ export interface SubAccount {
1349
1352
  /**
1350
1353
  * The name of the company associated with the sub-account.
1351
1354
  */
@@ -1359,10 +1362,10 @@ interface SubAccount {
1359
1362
  */
1360
1363
  handle: string;
1361
1364
  }
1362
- type SubAccountsCreateResponse = DataResponse<SubAccount>;
1365
+ export type SubAccountsCreateResponse = DataResponse<SubAccount>;
1363
1366
  /** @deprecated Use `SubAccount` instead. */
1364
- type SubAccountsAccount = SubAccount;
1365
- interface SubAccountsListOptions {
1367
+ export type SubAccountsAccount = SubAccount;
1368
+ export interface SubAccountsListOptions {
1366
1369
  /**
1367
1370
  * Possible values are `1` to `1000`.
1368
1371
  * @default 1000
@@ -1374,8 +1377,8 @@ interface SubAccountsListOptions {
1374
1377
  */
1375
1378
  offset?: number;
1376
1379
  }
1377
- type SubAccountsListResponse = DataResponse<SubAccount[]>;
1378
- interface SubAccountsApiKey {
1380
+ export type SubAccountsListResponse = DataResponse<SubAccount[]>;
1381
+ export interface SubAccountsApiKey {
1379
1382
  /**
1380
1383
  * The API key ID for the sub-account.
1381
1384
  */
@@ -1385,8 +1388,8 @@ interface SubAccountsApiKey {
1385
1388
  */
1386
1389
  key: string;
1387
1390
  }
1388
- type SubAccountsApiKeysCreateResponse = DataResponse<SubAccountsApiKey>;
1389
- interface SubAccountsApiKeysListOptions {
1391
+ export type SubAccountsApiKeysCreateResponse = DataResponse<SubAccountsApiKey>;
1392
+ export interface SubAccountsApiKeysListOptions {
1390
1393
  /**
1391
1394
  * The maximum number of API keys included in the response. Possible values are `1` to `1000`.
1392
1395
  * @default 100
@@ -1398,14 +1401,14 @@ interface SubAccountsApiKeysListOptions {
1398
1401
  */
1399
1402
  offset?: number;
1400
1403
  }
1401
- type SubAccountsApiKeysListResponse = DataResponse<SubAccountsApiKey[]>;
1404
+ export type SubAccountsApiKeysListResponse = DataResponse<SubAccountsApiKey[]>;
1402
1405
  /** @deprecated Use `SubAccountsApiKeysCreateResponse` instead. */
1403
- type SubAccountsCreateApiKeyResponse = SubAccountsApiKeysCreateResponse;
1406
+ export type SubAccountsCreateApiKeyResponse = SubAccountsApiKeysCreateResponse;
1404
1407
  /** @deprecated Use `SubAccountsApiKeysListOptions` instead. */
1405
- type SubAccountsListApiKeyOptions = SubAccountsApiKeysListOptions;
1408
+ export type SubAccountsListApiKeyOptions = SubAccountsApiKeysListOptions;
1406
1409
  /** @deprecated Use `SubAccountsApiKeysListResponse` instead. */
1407
- type SubAccountsListApiKeyResponse = SubAccountsApiKeysListResponse;
1408
- interface SubAccountsSmtpPassword {
1410
+ export type SubAccountsListApiKeyResponse = SubAccountsApiKeysListResponse;
1411
+ export interface SubAccountsSmtpPassword {
1409
1412
  /**
1410
1413
  * Whether the SMTP password is enabled.
1411
1414
  */
@@ -1419,20 +1422,20 @@ interface SubAccountsSmtpPassword {
1419
1422
  */
1420
1423
  smtpPassword: string;
1421
1424
  }
1422
- type SubAccountsSmtpPasswordsCreateResponse = DataResponse<SubAccountsSmtpPassword>;
1423
- type SubAccountsSmtpPasswordsListResponse = DataResponse<SubAccountsSmtpPassword[]>;
1425
+ export type SubAccountsSmtpPasswordsCreateResponse = DataResponse<SubAccountsSmtpPassword>;
1426
+ export type SubAccountsSmtpPasswordsListResponse = DataResponse<SubAccountsSmtpPassword[]>;
1424
1427
  /** @deprecated Use `SubAccountsSmtpPasswordsCreateResponse` instead. */
1425
- type SubAccountsCreateSmtpPasswordResponse = SubAccountsSmtpPasswordsCreateResponse;
1428
+ export type SubAccountsCreateSmtpPasswordResponse = SubAccountsSmtpPasswordsCreateResponse;
1426
1429
  /** @deprecated Use `SubAccountsSmtpPasswordsListResponse` instead. */
1427
- type SubAccountsListSmtpPasswordResponse = SubAccountsSmtpPasswordsListResponse;
1428
- interface SubAccountsLimit {
1430
+ export type SubAccountsListSmtpPasswordResponse = SubAccountsSmtpPasswordsListResponse;
1431
+ export interface SubAccountsLimit {
1429
1432
  sends: number;
1430
1433
  }
1431
- interface SubAccountsLimitsSetOptions extends SubAccountsLimit {}
1432
- type SubAccountsLimitsGetResponse = DataResponse<SubAccountsLimit>;
1434
+ export interface SubAccountsLimitsSetOptions extends SubAccountsLimit {}
1435
+ export type SubAccountsLimitsGetResponse = DataResponse<SubAccountsLimit>;
1433
1436
  /** @deprecated Use `SubAccountsLimitsGetResponse` instead. */
1434
- type SubAccountsLimitResponse = SubAccountsLimitsGetResponse;
1435
- interface SubAccountsUsage {
1437
+ export type SubAccountsLimitResponse = SubAccountsLimitsGetResponse;
1438
+ export interface SubAccountsUsage {
1436
1439
  /**
1437
1440
  * The end date of the current billing period (ISO 8601 format).
1438
1441
  * @example "2025-04-11"
@@ -1455,8 +1458,8 @@ interface SubAccountsUsage {
1455
1458
  */
1456
1459
  monthlyLimit: number;
1457
1460
  }
1458
- type SubAccountsUsageResponse = DataResponse<SubAccountsUsage>;
1459
- interface MetricsEngagement {
1461
+ export type SubAccountsUsageResponse = DataResponse<SubAccountsUsage>;
1462
+ export interface MetricsEngagement {
1460
1463
  /**
1461
1464
  * A series of metrics aggregations bucketed by time interval (e.g. hour, day).
1462
1465
  */
@@ -1517,8 +1520,8 @@ interface MetricsEngagement {
1517
1520
  */
1518
1521
  uniqueOpenTrackingDelivered?: number;
1519
1522
  }
1520
- type MetricsEngagementResponse = DataResponse<MetricsEngagement>;
1521
- interface MetricsPerformance {
1523
+ export type MetricsEngagementResponse = DataResponse<MetricsEngagement>;
1524
+ export interface MetricsPerformance {
1522
1525
  /**
1523
1526
  * Count of messages hard-bounced during the specified time range.
1524
1527
  */
@@ -1553,8 +1556,8 @@ interface MetricsPerformance {
1553
1556
  */
1554
1557
  startTime: string;
1555
1558
  }
1556
- type MetricsPerformanceResponse = DataResponse<MetricsPerformance>;
1557
- interface MetricsRecipientBehaviour {
1559
+ export type MetricsPerformanceResponse = DataResponse<MetricsPerformance>;
1560
+ export interface MetricsRecipientBehaviour {
1558
1561
  /**
1559
1562
  * A series of metrics aggregations bucketed by time interval (e.g. hour, day).
1560
1563
  */
@@ -1579,8 +1582,8 @@ interface MetricsRecipientBehaviour {
1579
1582
  */
1580
1583
  unsubscribed: number;
1581
1584
  }
1582
- type MetricsRecipientBehaviourResponse = DataResponse<MetricsRecipientBehaviour>;
1583
- interface MetricsVolume {
1585
+ export type MetricsRecipientBehaviourResponse = DataResponse<MetricsRecipientBehaviour>;
1586
+ export interface MetricsVolume {
1584
1587
  /**
1585
1588
  * A series of metrics aggregations bucketed by time interval (e.g. hour, day).
1586
1589
  */
@@ -1610,8 +1613,8 @@ interface MetricsVolume {
1610
1613
  */
1611
1614
  startTime: string;
1612
1615
  }
1613
- type MetricsVolumeResponse = DataResponse<MetricsVolume>;
1614
- type MetricsUsageResponse = DataResponse<{
1616
+ export type MetricsVolumeResponse = DataResponse<MetricsVolume>;
1617
+ export type MetricsUsageResponse = DataResponse<{
1615
1618
  /**
1616
1619
  * The end date of the current billing period (ISO 8601 format).
1617
1620
  * @example "2025-04-11"
@@ -1634,8 +1637,8 @@ type MetricsUsageResponse = DataResponse<{
1634
1637
  */
1635
1638
  monthlyLimit: number;
1636
1639
  }>;
1637
- type MetricsSendersType = "sub-accounts" | "campaigns";
1638
- interface MetricsSendersOptions {
1640
+ export type MetricsSendersType = "sub-accounts" | "campaigns";
1641
+ export interface MetricsSendersOptions {
1639
1642
  /**
1640
1643
  * The beginning of the time range for retrieving top senders metrics (inclusive). Formats: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SSZ` or a `Date` object. Defaults to one month ago if not provided.
1641
1644
  * @example "2025-11-02T03:13:35.761763554Z"
@@ -1662,7 +1665,7 @@ interface MetricsSendersOptions {
1662
1665
  */
1663
1666
  sortOrder?: "asc" | "desc";
1664
1667
  }
1665
- interface MetricsSenders {
1668
+ export interface MetricsSenders {
1666
1669
  endTime: string;
1667
1670
  limit: number;
1668
1671
  offset: number;
@@ -1682,8 +1685,8 @@ interface MetricsSenders {
1682
1685
  */
1683
1686
  total: number;
1684
1687
  }
1685
- type MetricsSendersResponse = DataResponse<MetricsSenders>;
1686
- interface MetricsBucket {
1688
+ export type MetricsSendersResponse = DataResponse<MetricsSenders>;
1689
+ export interface MetricsBucket {
1687
1690
  /**
1688
1691
  * The number of events or occurrences aggregated within this time period.
1689
1692
  */
@@ -1693,7 +1696,7 @@ interface MetricsBucket {
1693
1696
  */
1694
1697
  periodStart: string;
1695
1698
  }
1696
- interface MetricsOptions {
1699
+ export interface MetricsOptions {
1697
1700
  /**
1698
1701
  * The beginning of the time range for retrieving message metrics (inclusive). Formats: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SSZ` or a `Date` object. Defaults to one month ago if not provided.
1699
1702
  * @example "2025-05-26"
@@ -1714,8 +1717,8 @@ interface MetricsOptions {
1714
1717
  */
1715
1718
  interval?: "hour" | "day" | "week" | "month";
1716
1719
  }
1717
- type SuppressionsTypes = "transactional" | "non-transactional";
1718
- interface SuppressionsCreateEntry {
1720
+ export type SuppressionsTypes = "transactional" | "non-transactional";
1721
+ export interface SuppressionsCreateEntry {
1719
1722
  /**
1720
1723
  * Must be less than `1024` characters.
1721
1724
  */
@@ -1730,7 +1733,7 @@ interface SuppressionsCreateEntry {
1730
1733
  */
1731
1734
  types?: SuppressionsTypes[];
1732
1735
  }
1733
- interface SuppressionsCreateOptions {
1736
+ export interface SuppressionsCreateOptions {
1734
1737
  /**
1735
1738
  * If true, the parent account creates suppression entries for all associated sub-accounts. This field is only applicable to parent accounts. Sub-accounts cannot create entries for other sub-accounts.
1736
1739
  * @default false
@@ -1742,8 +1745,8 @@ interface SuppressionsCreateOptions {
1742
1745
  */
1743
1746
  entries: SuppressionsCreateEntry[];
1744
1747
  }
1745
- type SuppressionsSource = "api" | "unsubscribe_link" | "list_unsubscribe" | "hard_bounce" | "spam_complaint" | "all";
1746
- interface SuppressionsListOptions {
1748
+ export type SuppressionsSource = "api" | "unsubscribe_link" | "list_unsubscribe" | "hard_bounce" | "spam_complaint";
1749
+ export interface SuppressionsListOptions {
1747
1750
  /**
1748
1751
  * The email address of the suppression entry to search for. If provided, the search will return the suppression entry associated with this recipient. If not provided, the search will return all suppression entries for the account.
1749
1752
  */
@@ -1751,7 +1754,7 @@ interface SuppressionsListOptions {
1751
1754
  /**
1752
1755
  * The source of the suppression entries to filter by. If not provided, suppression entries from all sources will be returned.
1753
1756
  */
1754
- source?: Exclude<SuppressionsSource, "all">;
1757
+ source?: SuppressionsSource;
1755
1758
  /**
1756
1759
  * The date and/or time before which the suppression entries were created. Format: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SSZ` or a `Date` object.
1757
1760
  */
@@ -1771,7 +1774,7 @@ interface SuppressionsListOptions {
1771
1774
  */
1772
1775
  offset?: number;
1773
1776
  }
1774
- interface SuppressionsListEntry {
1777
+ export interface SuppressionsListEntry {
1775
1778
  createdAt: string;
1776
1779
  notes?: string;
1777
1780
  /**
@@ -1782,7 +1785,7 @@ interface SuppressionsListEntry {
1782
1785
  source: SuppressionsSource;
1783
1786
  types: SuppressionsTypes[];
1784
1787
  }
1785
- type SuppressionsListResponse = DataResponse<SuppressionsListEntry[]>;
1788
+ export type SuppressionsListResponse = DataResponse<SuppressionsListEntry[]>;
1786
1789
  declare class SubAccountsApiKeys {
1787
1790
  private mailchannels;
1788
1791
  constructor(mailchannels: MailChannelsClient);
@@ -1889,7 +1892,7 @@ declare class SubAccountsLimits {
1889
1892
  */
1890
1893
  delete(handle: string): Promise<SuccessResponse>;
1891
1894
  }
1892
- declare class SubAccounts {
1895
+ export declare class SubAccounts {
1893
1896
  protected mailchannels: MailChannelsClient;
1894
1897
  private static readonly COMPANY_PATTERN;
1895
1898
  private static readonly HANDLE_PATTERN;
@@ -1977,7 +1980,7 @@ declare class SubAccounts {
1977
1980
  /** @deprecated Use `limits.delete` instead. */
1978
1981
  deleteLimit(...args: Parameters<SubAccountsLimits["delete"]>): Promise<SuccessResponse>;
1979
1982
  }
1980
- declare class Metrics {
1983
+ export declare class Metrics {
1981
1984
  protected mailchannels: MailChannelsClient;
1982
1985
  constructor(mailchannels: MailChannelsClient);
1983
1986
  /**
@@ -2041,8 +2044,10 @@ declare class Metrics {
2041
2044
  */
2042
2045
  senders(type: MetricsSendersType, options?: MetricsSendersOptions): Promise<MetricsSendersResponse>;
2043
2046
  }
2044
- declare class Suppressions {
2047
+ export declare class Suppressions {
2045
2048
  protected mailchannels: MailChannelsClient;
2049
+ private static readonly SOURCE_VALUES;
2050
+ private static readonly DELETE_SOURCE_VALUES;
2046
2051
  constructor(mailchannels: MailChannelsClient);
2047
2052
  /**
2048
2053
  * Creates suppression entries for the specified account. Parent accounts can create suppression entries for all associated sub-accounts. If `types` is not provided, it defaults to `non-transactional`. The operation is atomic, meaning all entries are successfully added or none are added if an error occurs.
@@ -2072,7 +2077,7 @@ declare class Suppressions {
2072
2077
  * const { success, error } = await mailchannels.suppressions.delete('name@example.com', 'api');
2073
2078
  * ```
2074
2079
  */
2075
- delete(recipient: string, source?: SuppressionsSource): Promise<SuccessResponse>;
2080
+ delete(recipient: string, source?: SuppressionsSource | "all"): Promise<SuccessResponse>;
2076
2081
  /**
2077
2082
  * Retrieve suppression entries associated with the specified account. Supports filtering by recipient, source and creation date range. The response is paginated, with a default limit of `1000` entries per page and an offset of `0`.
2078
2083
  * @param options - Options to filter and customize the suppression entries retrieval.
@@ -2085,11 +2090,11 @@ declare class Suppressions {
2085
2090
  list(options?: SuppressionsListOptions): Promise<SuppressionsListResponse>;
2086
2091
  }
2087
2092
  type AttachmentOptions = Omit<EmailsSendAttachment, "content">;
2088
- declare class Attachment {
2093
+ export declare class Attachment {
2089
2094
  static fromBytes(data: ArrayBuffer | Uint8Array, options: AttachmentOptions): EmailsSendAttachment;
2090
2095
  static fromBlob(blob: Blob, options: AttachmentOptions): Promise<EmailsSendAttachment>;
2091
2096
  }
2092
- declare class MailChannels extends MailChannelsClient {
2097
+ export declare class MailChannels extends MailChannelsClient {
2093
2098
  readonly emails: Emails;
2094
2099
  readonly domains: Domains;
2095
2100
  readonly webhooks: Webhooks;
@@ -2097,5 +2102,4 @@ declare class MailChannels extends MailChannelsClient {
2097
2102
  readonly metrics: Metrics;
2098
2103
  readonly suppressions: Suppressions;
2099
2104
  constructor(key: string, options?: MailChannelsClientOptions);
2100
- }
2101
- export { Attachment, DataResponse, Domains, DomainsCheckOptions, DomainsCheckResponse, DomainsCheckVerdict, DomainsCustomTrackingCreateResponse, DomainsCustomTrackingDnsSetupRequired, DomainsCustomTrackingDomain, DomainsCustomTrackingListOptions, DomainsCustomTrackingListResponse, DomainsCustomTrackingScope, DomainsCustomTrackingUpdateOptions, DomainsCustomTrackingUpdateResponse, DomainsCustomTrackingWithDnsSetupRequired, DomainsDkimCreateOptions, DomainsDkimCreateResponse, DomainsDkimKey, DomainsDkimKeyStatus, DomainsDkimListOptions, DomainsDkimListResponse, DomainsDkimRotateOptions, DomainsDkimRotateResponse, DomainsDkimUpdateStatusOptions, Emails, EmailsQueueResponse, EmailsSendAsyncResponse, EmailsSendAttachment, EmailsSendContent, EmailsSendDkim, EmailsSendOptions, EmailsSendPersonalization, EmailsSendRecipient, EmailsSendRecipientInput, EmailsSendResponse, EmailsSendTemplate, EmailsSendTemplateType, EmailsSendTemplateValue, EmailsSendTracking, ErrorResponse, ErrorType, MailChannels, MailChannelsClient, MailChannelsClientOptions, Metrics, MetricsBucket, MetricsEngagement, MetricsEngagementResponse, MetricsOptions, MetricsPerformance, MetricsPerformanceResponse, MetricsRecipientBehaviour, MetricsRecipientBehaviourResponse, MetricsSenders, MetricsSendersOptions, MetricsSendersResponse, MetricsSendersType, MetricsUsageResponse, MetricsVolume, MetricsVolumeResponse, SubAccount, SubAccounts, SubAccountsAccount, SubAccountsApiKey, SubAccountsApiKeysCreateResponse, SubAccountsApiKeysListOptions, SubAccountsApiKeysListResponse, SubAccountsCreateApiKeyResponse, SubAccountsCreateResponse, SubAccountsCreateSmtpPasswordResponse, SubAccountsLimit, SubAccountsLimitResponse, SubAccountsLimitsGetResponse, SubAccountsLimitsSetOptions, SubAccountsListApiKeyOptions, SubAccountsListApiKeyResponse, SubAccountsListOptions, SubAccountsListResponse, SubAccountsListSmtpPasswordResponse, SubAccountsSmtpPassword, SubAccountsSmtpPasswordsCreateResponse, SubAccountsSmtpPasswordsListResponse, SubAccountsUsage, SubAccountsUsageResponse, SuccessResponse, Suppressions, SuppressionsCreateEntry, SuppressionsCreateOptions, SuppressionsListEntry, SuppressionsListOptions, SuppressionsListResponse, SuppressionsSource, SuppressionsTypes, WebhookEvent, WebhookEventClick, WebhookEventComplained, WebhookEventDelivered, WebhookEventDropped, WebhookEventHardBounced, WebhookEventOpen, WebhookEventProcessed, WebhookEventSoftBounced, WebhookEventTest, WebhookEventType, WebhookEventUnsubscribed, Webhooks, WebhooksBatch, WebhooksBatchResponseStatus, WebhooksBatchStatus, WebhooksBatchesOptions, WebhooksBatchesResponse, WebhooksListResponse, WebhooksResendBatch, WebhooksResendBatchResponse, WebhooksSigningKeyResponse, WebhooksValidateResponse, WebhooksVerifyOptions, WebhooksVerifyResponse };
2105
+ }
@@ -3,7 +3,7 @@ import { subtle } from "node:crypto";
3
3
  import { Buffer } from "node:buffer";
4
4
  import mime from "mime";
5
5
  var name = "mailchannels-sdk";
6
- var version = "1.5.1";
6
+ var version = "1.6.0";
7
7
  var MailChannelsClient = class MailChannelsClient {
8
8
  static DEFAULT_BASE_URL = "https://api.mailchannels.net";
9
9
  static DEFAULT_TIMEOUT = 12e4;
@@ -80,6 +80,10 @@ const STATUS_ERROR_TYPE_MAP = {
80
80
  [429]: "rate_limit_error",
81
81
  [500]: "internal_server_error"
82
82
  };
83
+ const STATUS_DEFAULT_TEXT_MAP = {
84
+ [400]: "Bad request.",
85
+ [401]: "Invalid API key."
86
+ };
83
87
  const createError = (message, statusCode = null, type, response = null) => {
84
88
  return {
85
89
  message,
@@ -89,11 +93,12 @@ const createError = (message, statusCode = null, type, response = null) => {
89
93
  };
90
94
  };
91
95
  const getStatusError = (response, errors = {}) => {
92
- const statusText = errors[response.status] || "Unknown error.";
96
+ const statusText = errors[response.status] || STATUS_DEFAULT_TEXT_MAP[response.status] || "Unknown error.";
97
+ const contentType = response.headers?.get("content-type")?.toLowerCase();
93
98
  const payload = response._data ?? response.data;
94
99
  let details;
95
100
  let errorResponse = null;
96
- if (typeof payload === "string") details = payload;
101
+ if (typeof payload === "string" && !contentType?.includes("text/html")) details = payload;
97
102
  else if (typeof payload === "object" && payload !== null) {
98
103
  if (typeof payload.message === "string") details = payload.message;
99
104
  else if (Array.isArray(payload.errors) && payload.errors.length) details = payload.errors.join(", ");
@@ -109,8 +114,14 @@ const createValidationError = (message) => {
109
114
  };
110
115
  const validatePagination = (pagination = {}) => {
111
116
  const { limit, offset, max } = pagination;
112
- if (typeof limit === "number" && (limit < 1 || max && limit > max)) return createValidationError("The limit value " + (max ? `must be between 1 and ${max}.` : "is invalid. Only positive values are allowed."));
113
- if (typeof offset === "number" && offset < 0) return createValidationError("Offset must be greater than or equal to 0.");
117
+ if (limit !== void 0) {
118
+ if (!Number.isInteger(limit)) return createValidationError("The limit value must be an integer.");
119
+ if (limit < 1 || max != null && limit > max) return createValidationError("The limit value " + (max != null ? `must be between 1 and ${max}.` : "is invalid. Only positive values are allowed."));
120
+ }
121
+ if (offset !== void 0) {
122
+ if (!Number.isInteger(offset)) return createValidationError("The offset value must be an integer.");
123
+ if (offset < 0) return createValidationError("The offset value must be greater than or equal to 0.");
124
+ }
114
125
  return null;
115
126
  };
116
127
  const CUSTOM_TRACKING_NAME_PATTERN = /^[a-z0-9-]+$/;
@@ -393,7 +404,6 @@ var Emails = class {
393
404
  body: payload,
394
405
  onResponseError: async ({ response }) => {
395
406
  error = getStatusError(response, {
396
- [400]: "Bad Request.",
397
407
  [403]: "User does not have access to this feature.",
398
408
  [413]: "The total message size should not exceed 30MB. This includes the message itself, headers, and the combined size of any attachments."
399
409
  });
@@ -454,8 +464,17 @@ const mapDkimKey = (key) => ({
454
464
  status: key.status,
455
465
  statusModifiedAt: key.status_modified_at
456
466
  });
457
- var DomainsDkim = class {
467
+ const quoteValues = (values) => {
468
+ return Array.from(values).map((value) => `'${value}'`).join(", ");
469
+ };
470
+ var DomainsDkim = class DomainsDkim {
458
471
  mailchannels;
472
+ static UPDATE_STATUS_VALUES = /* @__PURE__ */ new Set([
473
+ "retired",
474
+ "revoked",
475
+ "rotated"
476
+ ]);
477
+ static STATUS_VALUES = /* @__PURE__ */ new Set(["active", ...DomainsDkim.UPDATE_STATUS_VALUES]);
459
478
  constructor(mailchannels) {
460
479
  this.mailchannels = mailchannels;
461
480
  }
@@ -483,10 +502,7 @@ var DomainsDkim = class {
483
502
  const response = await this.mailchannels.post(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys`, {
484
503
  body: payload,
485
504
  onResponseError: async ({ response }) => {
486
- error = getStatusError(response, {
487
- [400]: "Bad Request.",
488
- [409]: "Key pair already created for domain, and selector."
489
- });
505
+ error = getStatusError(response, { [409]: "Key pair already created for domain, and selector." });
490
506
  }
491
507
  }).catch((e) => {
492
508
  error ||= getResultError(e, "Failed to create DKIM key.");
@@ -517,6 +533,13 @@ var DomainsDkim = class {
517
533
  error
518
534
  };
519
535
  }
536
+ if (options?.status !== void 0 && !DomainsDkim.STATUS_VALUES.has(options.status)) {
537
+ error = createValidationError(`Status must be one of ${quoteValues(DomainsDkim.STATUS_VALUES)}.`);
538
+ return {
539
+ data: null,
540
+ error
541
+ };
542
+ }
520
543
  error = validatePagination({
521
544
  ...options,
522
545
  max: 100
@@ -535,7 +558,7 @@ var DomainsDkim = class {
535
558
  const response = await this.mailchannels.get(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys`, {
536
559
  query: payload,
537
560
  onResponseError: async ({ response }) => {
538
- error = getStatusError(response, { [400]: "Bad Request." });
561
+ error = getStatusError(response);
539
562
  }
540
563
  }).catch((e) => {
541
564
  error ||= getResultError(e, "Failed to fetch DKIM keys.");
@@ -566,14 +589,18 @@ var DomainsDkim = class {
566
589
  error
567
590
  };
568
591
  }
592
+ if (options?.status !== void 0 && !DomainsDkim.UPDATE_STATUS_VALUES.has(options.status)) {
593
+ error = createValidationError(`Status must be one of ${quoteValues(DomainsDkim.UPDATE_STATUS_VALUES)}.`);
594
+ return {
595
+ success: false,
596
+ error
597
+ };
598
+ }
569
599
  const payload = { status: options.status };
570
600
  await this.mailchannels.patch(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys/${encodeURIComponent(options.selector)}`, {
571
601
  body: payload,
572
602
  onResponseError: async ({ response }) => {
573
- error = getStatusError(response, {
574
- [400]: "Bad Request.",
575
- [404]: "Specified key pair not found, or no active key for rotation. This may also occur if the DKIM domain or selector path parameter is missing."
576
- });
603
+ error = getStatusError(response, { [404]: "Specified key pair not found, or no active key for rotation. This may also occur if the DKIM domain or selector path parameter is missing." });
577
604
  }
578
605
  }).catch((e) => {
579
606
  error ||= getResultError(e, "Failed to update status of DKIM key.");
@@ -611,7 +638,6 @@ var DomainsDkim = class {
611
638
  body: payload,
612
639
  onResponseError: async ({ response }) => {
613
640
  error = getStatusError(response, {
614
- [400]: "Bad Request.",
615
641
  [404]: "Specified key pair not found.",
616
642
  [409]: "Key pair already created for domain, and provided new key selector."
617
643
  });
@@ -656,7 +682,7 @@ var DomainsCustomTracking = class DomainsCustomTracking {
656
682
  const response = await this.mailchannels.get("/tx/v1/custom-tracking-domains", {
657
683
  query: options,
658
684
  onResponseError: async ({ response }) => {
659
- error = getStatusError(response, { [400]: "Bad Request." });
685
+ error = getStatusError(response);
660
686
  }
661
687
  }).catch((e) => {
662
688
  error ||= getResultError(e, "Failed to fetch custom tracking domains.");
@@ -714,7 +740,6 @@ var DomainsCustomTracking = class DomainsCustomTracking {
714
740
  },
715
741
  onResponseError: async ({ response }) => {
716
742
  error = getStatusError(response, {
717
- [400]: "Invalid request body.",
718
743
  [403]: "No permission to register this domain.",
719
744
  [409]: "A domain with the same name already exists, or the hostname and scope combination is already registered.",
720
745
  [422]: "DNS verification incomplete. Either the TXT ownership record has not propagated yet or the hostname CNAME does not point to the required target."
@@ -764,7 +789,7 @@ var DomainsCustomTracking = class DomainsCustomTracking {
764
789
  };
765
790
  }
766
791
  if (!scope || !DomainsCustomTracking.SCOPE_VALUES.has(scope)) {
767
- error = createValidationError("Scope must be one of 'click', 'open', or 'unsubscribe'.");
792
+ error = createValidationError(`Scope must be one of ${quoteValues(DomainsCustomTracking.SCOPE_VALUES)}.`);
768
793
  return {
769
794
  data: null,
770
795
  error
@@ -796,7 +821,6 @@ var DomainsCustomTracking = class DomainsCustomTracking {
796
821
  },
797
822
  onResponseError: async ({ response }) => {
798
823
  error = getStatusError(response, {
799
- [400]: "Bad Request.",
800
824
  [403]: "No permission to update this domain.",
801
825
  [404]: `Custom tracking domain for hostname '${hostname}' and scope '${scope}' not found.`,
802
826
  [409]: "Name already used by another domain.",
@@ -910,10 +934,7 @@ var Domains = class {
910
934
  const response = await this.mailchannels.post("/tx/v1/check-domain", {
911
935
  body: payload,
912
936
  onResponseError: async ({ response }) => {
913
- error = getStatusError(response, {
914
- [400]: "Bad Request.",
915
- [403]: "User does not have access to this feature."
916
- });
937
+ error = getStatusError(response, { [403]: "User does not have access to this feature." });
917
938
  }
918
939
  }).catch((e) => {
919
940
  error ||= getResultError(e, "Failed to check domain.");
@@ -1044,6 +1065,14 @@ const parseDateInputs = (options) => {
1044
1065
  };
1045
1066
  var Webhooks = class Webhooks {
1046
1067
  mailchannels;
1068
+ static STATUS_VALUES = /* @__PURE__ */ new Set([
1069
+ "1xx",
1070
+ "2xx",
1071
+ "3xx",
1072
+ "4xx",
1073
+ "5xx",
1074
+ "no_response"
1075
+ ]);
1047
1076
  constructor(mailchannels) {
1048
1077
  this.mailchannels = mailchannels;
1049
1078
  }
@@ -1110,10 +1139,7 @@ var Webhooks = class Webhooks {
1110
1139
  const response = await this.mailchannels.get("/tx/v1/webhook/public-key", {
1111
1140
  query: { id },
1112
1141
  onResponseError: async ({ response }) => {
1113
- error = getStatusError(response, {
1114
- [400]: "Bad Request.",
1115
- [404]: `The key '${id}' is not found.`
1116
- });
1142
+ error = getStatusError(response, { [404]: `The key '${id}' is not found.` });
1117
1143
  }
1118
1144
  }).catch((e) => {
1119
1145
  error ||= getResultError(e, "Failed to get signing key.");
@@ -1143,10 +1169,7 @@ var Webhooks = class Webhooks {
1143
1169
  const response = await this.mailchannels.post("/tx/v1/webhook/validate", {
1144
1170
  body: { request_id: requestId },
1145
1171
  onResponseError: async ({ response }) => {
1146
- error = getStatusError(response, {
1147
- [400]: "Bad Request.",
1148
- [404]: "No webhooks found for the account."
1149
- });
1172
+ error = getStatusError(response, { [404]: "No webhooks found for the account." });
1150
1173
  }
1151
1174
  }).catch((e) => {
1152
1175
  error ||= getResultError(e, "Failed to validate webhooks.");
@@ -1221,14 +1244,27 @@ var Webhooks = class Webhooks {
1221
1244
  data: null,
1222
1245
  error
1223
1246
  };
1224
- if (options?.statuses && options.statuses.length > 6) return {
1225
- data: null,
1226
- error: createValidationError("A maximum of 6 status filters can be provided.")
1227
- };
1228
- if (options?.statuses && new Set(options.statuses).size !== options.statuses.length) return {
1229
- data: null,
1230
- error: createValidationError("Status filters must be unique.")
1231
- };
1247
+ if (options?.statuses !== void 0) {
1248
+ if (!Array.isArray(options.statuses)) return {
1249
+ data: null,
1250
+ error: createValidationError("Status filters must be an array.")
1251
+ };
1252
+ if (options.statuses.length > 6) return {
1253
+ data: null,
1254
+ error: createValidationError("A maximum of 6 status filters can be provided.")
1255
+ };
1256
+ if (new Set(options.statuses).size !== options.statuses.length) return {
1257
+ data: null,
1258
+ error: createValidationError("Status filters must be unique.")
1259
+ };
1260
+ if (!options.statuses.every((status) => Webhooks.STATUS_VALUES.has(status))) {
1261
+ const validValues = quoteValues(Webhooks.STATUS_VALUES);
1262
+ return {
1263
+ data: null,
1264
+ error: createValidationError(`Invalid status filter provided. Valid values are: ${validValues}.`)
1265
+ };
1266
+ }
1267
+ }
1232
1268
  const { dates, error: dateError } = parseDateInputs({
1233
1269
  createdAfter: options?.createdAfter,
1234
1270
  createdBefore: options?.createdBefore
@@ -1254,13 +1290,13 @@ var Webhooks = class Webhooks {
1254
1290
  query: {
1255
1291
  created_after: dates.createdAfter,
1256
1292
  created_before: dates.createdBefore,
1257
- statuses: options?.statuses,
1293
+ statuses: options?.statuses?.join(","),
1258
1294
  webhook: options?.webhook,
1259
1295
  limit: options?.limit,
1260
1296
  offset: options?.offset
1261
1297
  },
1262
1298
  onResponseError: async ({ response }) => {
1263
- error = getStatusError(response, { [400]: "Bad Request." });
1299
+ error = getStatusError(response);
1264
1300
  }
1265
1301
  }).catch((e) => {
1266
1302
  error ||= getResultError(e, "Failed to fetch webhook batches.");
@@ -1288,7 +1324,7 @@ var Webhooks = class Webhooks {
1288
1324
  let error = null;
1289
1325
  const response = await this.mailchannels.post(`/tx/v1/webhook-batch/${encodeURIComponent(batchId)}/resend`, { onResponseError: async ({ response }) => {
1290
1326
  error = getStatusError(response, {
1291
- [400]: "Bad Request. The batch ID is invalid.",
1327
+ [400]: "The batch ID is invalid.",
1292
1328
  [404]: `The batch '${batchId}' is not found for the customer.`
1293
1329
  });
1294
1330
  } }).catch((e) => {
@@ -1537,10 +1573,7 @@ var SubAccountsLimits = class {
1537
1573
  await this.mailchannels.put(`/tx/v1/sub-account/${encodeURIComponent(handle)}/limit`, {
1538
1574
  body: options,
1539
1575
  onResponseError: async ({ response }) => {
1540
- error = getStatusError(response, {
1541
- [400]: "Bad Request.",
1542
- [404]: `Sub-account with handle '${handle}' not found.`
1543
- });
1576
+ error = getStatusError(response, { [404]: `Sub-account with handle '${handle}' not found.` });
1544
1577
  }
1545
1578
  }).catch((e) => {
1546
1579
  error ||= getResultError(e, "Failed to set sub-account limit.");
@@ -1807,7 +1840,7 @@ var Metrics = class {
1807
1840
  interval: options?.interval
1808
1841
  },
1809
1842
  onResponseError: async ({ response }) => {
1810
- error = getStatusError(response, { [400]: "Bad Request." });
1843
+ error = getStatusError(response);
1811
1844
  }
1812
1845
  }).catch((e) => {
1813
1846
  error ||= getResultError(e, "Failed to fetch engagement metrics.");
@@ -1861,7 +1894,7 @@ var Metrics = class {
1861
1894
  interval: options?.interval
1862
1895
  },
1863
1896
  onResponseError: async ({ response }) => {
1864
- error = getStatusError(response, { [400]: "Bad Request." });
1897
+ error = getStatusError(response);
1865
1898
  }
1866
1899
  }).catch((e) => {
1867
1900
  error ||= getResultError(e, "Failed to fetch performance metrics.");
@@ -1907,7 +1940,7 @@ var Metrics = class {
1907
1940
  interval: options?.interval
1908
1941
  },
1909
1942
  onResponseError: async ({ response }) => {
1910
- error = getStatusError(response, { [400]: "Bad Request." });
1943
+ error = getStatusError(response);
1911
1944
  }
1912
1945
  }).catch((e) => {
1913
1946
  error ||= getResultError(e, "Failed to fetch recipient behaviour metrics.");
@@ -1949,7 +1982,7 @@ var Metrics = class {
1949
1982
  interval: options?.interval
1950
1983
  },
1951
1984
  onResponseError: async ({ response }) => {
1952
- error = getStatusError(response, { [400]: "Bad Request." });
1985
+ error = getStatusError(response);
1953
1986
  }
1954
1987
  }).catch((e) => {
1955
1988
  error ||= getResultError(e, "Failed to fetch volume metrics.");
@@ -2024,7 +2057,7 @@ var Metrics = class {
2024
2057
  sort_order: options?.sortOrder
2025
2058
  },
2026
2059
  onResponseError: async ({ response }) => {
2027
- error = getStatusError(response, { [400]: "Bad Request." });
2060
+ error = getStatusError(response);
2028
2061
  }
2029
2062
  }).catch((e) => {
2030
2063
  error ||= getResultError(e, "Failed to fetch senders metrics.");
@@ -2047,8 +2080,16 @@ var Metrics = class {
2047
2080
  };
2048
2081
  }
2049
2082
  };
2050
- var Suppressions = class {
2083
+ var Suppressions = class Suppressions {
2051
2084
  mailchannels;
2085
+ static SOURCE_VALUES = /* @__PURE__ */ new Set([
2086
+ "api",
2087
+ "unsubscribe_link",
2088
+ "list_unsubscribe",
2089
+ "hard_bounce",
2090
+ "spam_complaint"
2091
+ ]);
2092
+ static DELETE_SOURCE_VALUES = /* @__PURE__ */ new Set([...Suppressions.SOURCE_VALUES, "all"]);
2052
2093
  constructor(mailchannels) {
2053
2094
  this.mailchannels = mailchannels;
2054
2095
  }
@@ -2075,7 +2116,6 @@ var Suppressions = class {
2075
2116
  body: payload,
2076
2117
  onResponseError: async ({ response }) => {
2077
2118
  error = getStatusError(response, {
2078
- [400]: "Bad Request.",
2079
2119
  [409]: "Conflict. One or more suppression entries in the request already exist and cannot be created again.",
2080
2120
  [413]: "Payload too large. The request exceeds the maximum allowed total of 1000 suppression entries for the parent account and/or its sub-accounts."
2081
2121
  });
@@ -2090,10 +2130,17 @@ var Suppressions = class {
2090
2130
  }
2091
2131
  async delete(recipient, source) {
2092
2132
  let error = null;
2133
+ if (source !== void 0 && !Suppressions.DELETE_SOURCE_VALUES.has(source)) {
2134
+ error = createValidationError(`Source must be one of ${quoteValues(Suppressions.DELETE_SOURCE_VALUES)}.`);
2135
+ return {
2136
+ success: false,
2137
+ error
2138
+ };
2139
+ }
2093
2140
  await this.mailchannels.delete(`/tx/v1/suppression-list/recipients/${encodeURIComponent(recipient)}`, {
2094
2141
  query: { source },
2095
2142
  onResponseError: async ({ response }) => {
2096
- error = getStatusError(response, { [400]: "Bad Request." });
2143
+ error = getStatusError(response);
2097
2144
  }
2098
2145
  }).catch((e) => {
2099
2146
  error ||= getResultError(e, "Failed to delete suppression entry.");
@@ -2112,6 +2159,13 @@ var Suppressions = class {
2112
2159
  error
2113
2160
  };
2114
2161
  }
2162
+ if (options?.source !== void 0 && !Suppressions.SOURCE_VALUES.has(options.source)) {
2163
+ error = createValidationError(`Source must be one of ${quoteValues(Suppressions.SOURCE_VALUES)}.`);
2164
+ return {
2165
+ data: null,
2166
+ error
2167
+ };
2168
+ }
2115
2169
  const { dates, error: dateError } = parseDateInputs({
2116
2170
  createdBefore: options?.createdBefore,
2117
2171
  createdAfter: options?.createdAfter
@@ -2139,7 +2193,7 @@ var Suppressions = class {
2139
2193
  const response = await this.mailchannels.get("/tx/v1/suppression-list", {
2140
2194
  query: payload,
2141
2195
  onResponseError: async ({ response }) => {
2142
- error = getStatusError(response, { [400]: "Bad Request." });
2196
+ error = getStatusError(response);
2143
2197
  }
2144
2198
  }).catch((e) => {
2145
2199
  error ||= getResultError(e, "Failed to fetch suppression entries.");
@@ -1,9 +1,9 @@
1
1
  import { EmailsQueueResponse, EmailsSendOptions, EmailsSendResponse, MailChannelsClientOptions } from "../../_chunks/mailchannels.mjs";
2
- import { Transport as Transport$1 } from "nodemailer";
2
+ import { Transport, TransportOptions, Transporter } from "nodemailer";
3
3
  import MimeNode from "nodemailer/lib/mime-node";
4
- type MailChannelsTransportSendOptions = Pick<EmailsSendOptions, "campaignId" | "tracking" | "transactional" | "unsubscribe">;
5
- type MailChannelsTransportSendMode = "sync" | "async";
6
- interface MailChannelsTransportOptions<T extends MailChannelsTransportSendMode = "async"> extends MailChannelsClientOptions {
4
+ export type MailChannelsTransportSendOptions = Pick<EmailsSendOptions, "campaignId" | "tracking" | "transactional" | "unsubscribe">;
5
+ export type MailChannelsTransportSendMode = "sync" | "async";
6
+ export interface MailChannelsTransportOptions<T extends MailChannelsTransportSendMode = "async"> extends MailChannelsClientOptions {
7
7
  /**
8
8
  * The MailChannels Email API key.
9
9
  */
@@ -14,7 +14,7 @@ interface MailChannelsTransportOptions<T extends MailChannelsTransportSendMode =
14
14
  */
15
15
  sendMode?: T;
16
16
  }
17
- interface MailChannelsTransportInfo<T extends MailChannelsTransportSendMode> {
17
+ export interface MailChannelsTransportInfo<T extends MailChannelsTransportSendMode> {
18
18
  messageId: string | null;
19
19
  accepted: string[];
20
20
  rejected: string[];
@@ -22,12 +22,14 @@ interface MailChannelsTransportInfo<T extends MailChannelsTransportSendMode> {
22
22
  response: (T extends "sync" ? EmailsSendResponse : EmailsQueueResponse) | null;
23
23
  }
24
24
  declare module "nodemailer" {
25
- function createTransport<T>(transport: Transport<T> | TransportOptions, defaults?: TransportOptions): Transporter<T, TransportOptions>;
25
+ function createTransport<T>(transport: Transport<T> | TransportOptions, defaults?: TransportOptions): Transporter<T>;
26
+ interface SendMailOptions {
27
+ mailchannels?: MailChannelsTransportSendOptions;
28
+ }
26
29
  }
27
30
  declare module "nodemailer/lib/mailer" {
28
31
  interface Options {
29
32
  mailchannels?: MailChannelsTransportSendOptions;
30
33
  }
31
34
  }
32
- declare const mailchannelsTransport: <T extends MailChannelsTransportSendMode = "async">(options: MailChannelsTransportOptions<T>) => Transport$1<MailChannelsTransportInfo<T>>;
33
- export { MailChannelsTransportInfo, MailChannelsTransportOptions, MailChannelsTransportSendMode, MailChannelsTransportSendOptions, mailchannelsTransport };
35
+ export declare const mailchannelsTransport: <T extends MailChannelsTransportSendMode = "async">(options: MailChannelsTransportOptions<T>) => Transport<MailChannelsTransportInfo<T>>;
@@ -5,9 +5,10 @@ const parseAddress = (address) => {
5
5
  if (!address) return "";
6
6
  if (Array.isArray(address)) return parseAddress(address[0]);
7
7
  if (typeof address === "string") return address;
8
+ if (!address.address) return "";
8
9
  return {
9
10
  email: address.address,
10
- name: address.name || void 0
11
+ name: address.name
11
12
  };
12
13
  };
13
14
  const parseAddresses = (addresses) => {
@@ -41,7 +42,7 @@ const parseDkim = (dkim) => {
41
42
  if ("keys" in dkim) throw new Error("Multiple DKIM signatures are not supported");
42
43
  let privateKey;
43
44
  if (typeof dkim.privateKey === "string") privateKey = dkim.privateKey;
44
- else if (dkim.privateKey?.key && dkim.privateKey?.passphrase) try {
45
+ else if (dkim.privateKey && "key" in dkim.privateKey && "passphrase" in dkim.privateKey) try {
45
46
  privateKey = createPrivateKey({
46
47
  key: dkim.privateKey.key,
47
48
  passphrase: dkim.privateKey.passphrase
@@ -62,7 +63,8 @@ const parseDkim = (dkim) => {
62
63
  const parseHeaders = (headers) => {
63
64
  if (!headers) return;
64
65
  if (Array.isArray(headers)) return headers.reduce((acc, { key, value }) => {
65
- acc[key] = value;
66
+ if (value == void 0) return acc;
67
+ acc[key] = value.toString();
66
68
  return acc;
67
69
  }, {});
68
70
  return Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, Array.isArray(value) ? value.join(",") : value && typeof value === "object" && "value" in value ? String(value.value) : String(value)]));
@@ -94,7 +96,10 @@ const mailchannelsTransport = (options) => {
94
96
  messageId: null,
95
97
  accepted: [],
96
98
  rejected: [],
97
- envelope: mail.message.getEnvelope(),
99
+ envelope: mail.message?.getEnvelope() ?? {
100
+ from: false,
101
+ to: []
102
+ },
98
103
  response: null
99
104
  };
100
105
  mail.normalize(async (err, data) => {
@@ -1,4 +1,4 @@
1
- declare const createSimulator: (options?: {
1
+ export declare const createSimulator: (options?: {
2
2
  host?: string;
3
3
  port?: number;
4
4
  silent?: boolean;
@@ -16,5 +16,4 @@ declare const createSimulator: (options?: {
16
16
  host?: string;
17
17
  port?: number;
18
18
  }): Promise<string>;
19
- };
20
- export { createSimulator };
19
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mailchannels-sdk",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Node.js SDK to integrate MailChannels Email API into your JavaScript or TypeScript server-side applications.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -52,19 +52,18 @@
52
52
  "devDependencies": {
53
53
  "@stylistic/eslint-plugin": "^5.10.0",
54
54
  "@types/markdown-it": "^14.2.0",
55
- "@types/node": "^26.2.0",
56
- "@types/nodemailer": "^8.0.1",
57
- "@vitest/coverage-v8": "^4.1.11",
55
+ "@types/node": "^26.5.0",
56
+ "@vitest/coverage-v8": "^5.0.0",
58
57
  "changelogen": "^0.6.2",
59
- "nodemailer": "^9.0.5",
60
- "obuild": "^0.4.38",
61
- "oxlint": "^1.79.0",
58
+ "nodemailer": "^10.0.1",
59
+ "obuild": "^0.4.39",
60
+ "oxlint": "^1.82.0",
62
61
  "scule": "^1.3.0",
63
62
  "typescript": "^6.0.3",
64
- "vitepress": "^2.0.0-alpha.19",
63
+ "vitepress": "^2.0.0-alpha.20",
65
64
  "vitepress-plugin-group-icons": "^1.7.6",
66
65
  "vitepress-plugin-llms": "^1.13.5",
67
- "vitest": "^4.1.11"
66
+ "vitest": "^5.0.0"
68
67
  },
69
68
  "engines": {
70
69
  "node": ">=20"
@@ -72,7 +71,7 @@
72
71
  "scripts": {
73
72
  "build": "obuild",
74
73
  "parity:fixtures": "node scripts/generate-parity-fixtures.ts",
75
- "release": "pnpm lint && pnpm test && pnpm build && changelogen --bump",
74
+ "release": "pnpm lint && pnpm test && pnpm build && changelogen --bump && node scripts/update-examples-sdk-version.ts",
76
75
  "cli": "pnpx jiti src/cli/index.ts",
77
76
  "simulate": "pnpx jiti src/cli/index.ts simulate",
78
77
  "lint": "oxlint",