mailchannels-sdk 0.7.4 → 0.7.5

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.
@@ -637,6 +637,13 @@ type WebhooksListResponse = DataResponse<string[]>;
637
637
  //#endregion
638
638
  //#region src/types/webhooks/signing-key.d.ts
639
639
  type WebhooksSigningKeyResponse = DataResponse<{
640
+ /**
641
+ * The ID of the key.
642
+ */
643
+ id: string;
644
+ /**
645
+ * The public key used to verify webhook signatures.
646
+ */
640
647
  key: string;
641
648
  }>;
642
649
  //#endregion
@@ -674,6 +681,26 @@ type WebhooksValidateResponse = DataResponse<{
674
681
  }[];
675
682
  }>;
676
683
  //#endregion
684
+ //#region src/types/webhooks/verify.d.ts
685
+ interface WebhooksVerifyOptions {
686
+ /**
687
+ * 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.
688
+ */
689
+ payload: string;
690
+ /**
691
+ * The headers of the incoming webhook request as a record of key-value pairs. These headers should include `content-digest`, `signature`, and `signature-input` required for validating the authenticity of the webhook request.
692
+ */
693
+ headers: Record<string, string> | {
694
+ "content-digest": string;
695
+ "signature": string;
696
+ "signature-input": string;
697
+ };
698
+ /**
699
+ * The public key used to verify the webhook signature. If not provided, the SDK will attempt to retrieve the appropriate public key based on the `keyId` specified in the `signature-input` header.
700
+ */
701
+ publicKey?: string;
702
+ }
703
+ //#endregion
677
704
  //#region src/modules/webhooks.d.ts
678
705
  declare class Webhooks {
679
706
  protected mailchannels: MailChannelsClient;
@@ -726,6 +753,25 @@ declare class Webhooks {
726
753
  * ```
727
754
  */
728
755
  validate(requestId?: string): Promise<WebhooksValidateResponse>;
756
+ /**
757
+ * Verifies the authenticity of incoming webhook requests by validating their signatures using the provided options.
758
+ * @param options - The options for verifying the webhook.
759
+ * @example
760
+ * ```ts
761
+ * const isValid = await Webhooks.verify({ payload: rawBody, headers })
762
+ * ```
763
+ */
764
+ static verify(options: WebhooksVerifyOptions): Promise<boolean>;
765
+ /**
766
+ * Verifies the authenticity of incoming webhook requests by validating their signatures using the provided options.
767
+ * @param options - The options for verifying the webhook.
768
+ * @example
769
+ * ```ts
770
+ * const mailchannels = new MailChannels('your-api-key')
771
+ * const isValid = await mailchannels.webhooks.verify({ payload: rawBody, headers })
772
+ * ```
773
+ */
774
+ verify(options: WebhooksVerifyOptions): Promise<boolean>;
729
775
  }
730
776
  //#endregion
731
777
  //#region src/types/sub-accounts/create.d.ts
@@ -859,6 +905,7 @@ declare class SubAccounts {
859
905
  /**
860
906
  * Deletes the sub-account identified by its handle.
861
907
  * @param handle - Handle of sub-account to be deleted.
908
+ * @example
862
909
  * ```ts
863
910
  * const mailchannels = new MailChannels('your-api-key')
864
911
  * const { success, error } = await mailchannels.subAccounts.delete('validhandle123')
@@ -1372,12 +1419,12 @@ declare class Suppressions {
1372
1419
  delete(recipient: string, source?: SuppressionsSource): Promise<SuccessResponse>;
1373
1420
  /**
1374
1421
  * 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`.
1422
+ * @param options - Options to filter and customize the suppression entries retrieval.
1375
1423
  * @example
1376
1424
  * ```ts
1377
1425
  * const mailchannels = new MailChannels('your-api-key')
1378
1426
  * const { data, error } = await mailchannels.suppressions.list();
1379
1427
  * ```
1380
- * @param options - Options to filter and customize the suppression entries retrieval.
1381
1428
  */
1382
1429
  list(options?: SuppressionsListOptions): Promise<SuppressionsListResponse>;
1383
1430
  }
@@ -1914,15 +1961,15 @@ interface ServiceReportOptions {
1914
1961
  * The SMTP envelope information.
1915
1962
  */
1916
1963
  smtpEnvelopeInformation?: {
1917
- ehlo: string;
1918
- mailFrom: string;
1919
- rcptTo: string;
1964
+ ehlo?: string;
1965
+ mailFrom?: string;
1966
+ rcptTo?: string;
1920
1967
  };
1921
1968
  /**
1922
1969
  * The sending host information.
1923
1970
  */
1924
1971
  sendingHostInformation?: {
1925
- name: string;
1972
+ name?: string;
1926
1973
  };
1927
1974
  }
1928
1975
  //#endregion
@@ -1962,6 +2009,81 @@ declare class Service {
1962
2009
  report(options: ServiceReportOptions): Promise<SuccessResponse>;
1963
2010
  }
1964
2011
  //#endregion
2012
+ //#region src/types/webhooks/events.d.ts
2013
+ type WebhookEventType = "processed" | "delivered" | "open" | "click" | "hard-bounced" | "soft-bounced" | "dropped" | "complained" | "unsubscribed" | "test";
2014
+ interface WebhookEventBase<T extends WebhookEventType> {
2015
+ /**
2016
+ * The sender's email address
2017
+ */
2018
+ email?: string;
2019
+ /**
2020
+ * The MailChannels account ID that generated the webhook.
2021
+ * If the message was sent by a sub-account, this field contains the sub-account handle.
2022
+ */
2023
+ customer_handle: string;
2024
+ /**
2025
+ * The Unix timestamp (in seconds) when the event occurred; the timezone is always UTC
2026
+ */
2027
+ timestamp: number;
2028
+ /**
2029
+ * The Message-Id of the message that generated the event
2030
+ */
2031
+ smtp_id?: string;
2032
+ /**
2033
+ * The type of event that occurred
2034
+ */
2035
+ event: T;
2036
+ /**
2037
+ * A unique identifier generated to track the original HTTP request
2038
+ */
2039
+ request_id?: string;
2040
+ /**
2041
+ * The campaign identifier for the message that generated the event
2042
+ */
2043
+ campaign_id?: string;
2044
+ /**
2045
+ * The recipients of the message
2046
+ */
2047
+ recipients?: string[];
2048
+ }
2049
+ interface WebhookEventProcessed extends WebhookEventBase<"processed"> {}
2050
+ interface WebhookEventDelivered extends WebhookEventBase<"delivered"> {}
2051
+ interface WebhookEventWithTracking {
2052
+ /**
2053
+ * The User-Agent header given when the recipient opened the message
2054
+ */
2055
+ user_agent?: string;
2056
+ /**
2057
+ * The IP address of the host that made the HTTP request
2058
+ */
2059
+ ip?: string;
2060
+ }
2061
+ interface WebhookEventOpen extends WebhookEventBase<"open">, WebhookEventWithTracking {}
2062
+ interface WebhookEventClick extends WebhookEventBase<"click">, WebhookEventWithTracking {
2063
+ /**
2064
+ * The URL that was clicked by the recipient
2065
+ */
2066
+ url?: string;
2067
+ }
2068
+ interface WebhookEventWithStatus {
2069
+ /**
2070
+ * The SMTP status code that caused the bounce
2071
+ */
2072
+ status?: string;
2073
+ /**
2074
+ * A human-readable explanation of why the message hard-bounced
2075
+ */
2076
+ reason?: string;
2077
+ }
2078
+ interface WebhookEventHardBounced extends WebhookEventBase<"hard-bounced">, WebhookEventWithStatus {}
2079
+ interface WebhookEventSoftBounced extends WebhookEventBase<"soft-bounced">, WebhookEventWithStatus {}
2080
+ interface WebhookEventDropped extends WebhookEventBase<"dropped">, WebhookEventWithStatus {}
2081
+ interface WebhookEventComplained extends WebhookEventBase<"complained"> {}
2082
+ interface WebhookEventUnsubscribed extends WebhookEventBase<"unsubscribed"> {}
2083
+ interface WebhookEventTest extends Omit<WebhookEventBase<"test">, "recipients" | "campaign_id"> {}
2084
+ type WebhookEvent = WebhookEventProcessed | WebhookEventDelivered | WebhookEventOpen | WebhookEventClick | WebhookEventHardBounced | WebhookEventSoftBounced | WebhookEventDropped | WebhookEventComplained | WebhookEventUnsubscribed | WebhookEventTest;
2085
+ type WebhookEvents = WebhookEvent[];
2086
+ //#endregion
1965
2087
  //#region src/mailchannels.d.ts
1966
2088
  declare class MailChannels extends MailChannelsClient {
1967
2089
  readonly emails: Emails;
@@ -1976,4 +2098,4 @@ declare class MailChannels extends MailChannelsClient {
1976
2098
  constructor(key: string);
1977
2099
  }
1978
2100
  //#endregion
1979
- export { DataResponse, Domains, DomainsBulkCreateLoginLinks, DomainsBulkCreateLoginLinksResponse, DomainsBulkProvisionOptions, DomainsBulkProvisionResponse, DomainsCreateLoginLink, DomainsCreateLoginLinkResponse, DomainsData, DomainsDownstreamAddress, DomainsListDownstreamAddressesOptions, DomainsListDownstreamAddressesResponse, DomainsListOptions, DomainsListResponse, DomainsProvisionOptions, DomainsProvisionResponse, Emails, EmailsCheckDomainOptions, EmailsCheckDomainResponse, EmailsCheckDomainVerdict, EmailsCreateDkimKeyOptions, EmailsCreateDkimKeyResponse, EmailsDkimKey, EmailsDkimKeyStatus, EmailsGetDkimKeysOptions, EmailsGetDkimKeysResponse, EmailsRotateDkimKeyOptions, EmailsRotateDkimKeyResponse, EmailsSendAsyncResponse, EmailsSendAttachment, EmailsSendOptions, EmailsSendRecipient, EmailsSendResponse, EmailsSendTracking, EmailsUpdateDkimKeyOptions, ErrorResponse, ListEntriesResponse, ListEntry, ListEntryOptions, ListEntryResponse, ListNames, Lists, MailChannels, MailChannelsClient, Metrics, MetricsBucket, MetricsEngagement, MetricsEngagementResponse, MetricsOptions, MetricsPerformance, MetricsPerformanceResponse, MetricsRecipientBehaviour, MetricsRecipientBehaviourResponse, MetricsSenders, MetricsSendersOptions, MetricsSendersResponse, MetricsSendersType, MetricsUsageResponse, MetricsVolume, MetricsVolumeResponse, Service, ServiceReportOptions, ServiceSubscriptionsResponse, SubAccounts, SubAccountsAccount, SubAccountsApiKey, SubAccountsCreateApiKeyResponse, SubAccountsCreateResponse, SubAccountsCreateSmtpPasswordResponse, SubAccountsLimit, SubAccountsLimitResponse, SubAccountsListApiKeyOptions, SubAccountsListApiKeyResponse, SubAccountsListOptions, SubAccountsListResponse, SubAccountsListSmtpPasswordResponse, SubAccountsSmtpPassword, SubAccountsUsage, SubAccountsUsageResponse, SuccessResponse, Suppressions, SuppressionsCreateOptions, SuppressionsListEntry, SuppressionsListOptions, SuppressionsListResponse, SuppressionsSource, SuppressionsTypes, Users, UsersCreateOptions, UsersCreateResponse, Webhooks, WebhooksListResponse, WebhooksSigningKeyResponse, WebhooksValidateResponse };
2101
+ export { DataResponse, Domains, DomainsBulkCreateLoginLinks, DomainsBulkCreateLoginLinksResponse, DomainsBulkProvisionOptions, DomainsBulkProvisionResponse, DomainsCreateLoginLink, DomainsCreateLoginLinkResponse, DomainsData, DomainsDownstreamAddress, DomainsListDownstreamAddressesOptions, DomainsListDownstreamAddressesResponse, DomainsListOptions, DomainsListResponse, DomainsProvisionOptions, DomainsProvisionResponse, Emails, EmailsCheckDomainOptions, EmailsCheckDomainResponse, EmailsCheckDomainVerdict, EmailsCreateDkimKeyOptions, EmailsCreateDkimKeyResponse, EmailsDkimKey, EmailsDkimKeyStatus, EmailsGetDkimKeysOptions, EmailsGetDkimKeysResponse, EmailsRotateDkimKeyOptions, EmailsRotateDkimKeyResponse, EmailsSendAsyncResponse, EmailsSendAttachment, EmailsSendOptions, EmailsSendRecipient, EmailsSendResponse, EmailsSendTracking, EmailsUpdateDkimKeyOptions, ErrorResponse, ListEntriesResponse, ListEntry, ListEntryOptions, ListEntryResponse, ListNames, Lists, MailChannels, MailChannelsClient, Metrics, MetricsBucket, MetricsEngagement, MetricsEngagementResponse, MetricsOptions, MetricsPerformance, MetricsPerformanceResponse, MetricsRecipientBehaviour, MetricsRecipientBehaviourResponse, MetricsSenders, MetricsSendersOptions, MetricsSendersResponse, MetricsSendersType, MetricsUsageResponse, MetricsVolume, MetricsVolumeResponse, Service, ServiceReportOptions, ServiceSubscriptionsResponse, SubAccounts, SubAccountsAccount, SubAccountsApiKey, SubAccountsCreateApiKeyResponse, SubAccountsCreateResponse, SubAccountsCreateSmtpPasswordResponse, SubAccountsLimit, SubAccountsLimitResponse, SubAccountsListApiKeyOptions, SubAccountsListApiKeyResponse, SubAccountsListOptions, SubAccountsListResponse, SubAccountsListSmtpPasswordResponse, SubAccountsSmtpPassword, SubAccountsUsage, SubAccountsUsageResponse, SuccessResponse, Suppressions, SuppressionsCreateOptions, SuppressionsListEntry, SuppressionsListOptions, SuppressionsListResponse, SuppressionsSource, SuppressionsTypes, Users, UsersCreateOptions, UsersCreateResponse, WebhookEvent, WebhookEventClick, WebhookEventComplained, WebhookEventDelivered, WebhookEventDropped, WebhookEventHardBounced, WebhookEventOpen, WebhookEventProcessed, WebhookEventSoftBounced, WebhookEventTest, WebhookEventType, WebhookEventUnsubscribed, WebhookEvents, Webhooks, WebhooksListResponse, WebhooksSigningKeyResponse, WebhooksValidateResponse, WebhooksVerifyOptions };
@@ -1,4 +1,6 @@
1
1
  import { $fetch } from "ofetch";
2
+ import { subtle } from "node:crypto";
3
+ import { Buffer } from "node:buffer";
2
4
  var MailChannelsClient = class MailChannelsClient {
3
5
  static BASE_URL = "https://api.mailchannels.net";
4
6
  #headers;
@@ -85,9 +87,15 @@ const validatePagination = (pagination = {}) => {
85
87
  if (typeof offset === "number" && offset < 0) return createError("Offset must be greater than or equal to 0.");
86
88
  return null;
87
89
  };
90
+ /**
91
+ * Validates if a string is a valid email address
92
+ */
88
93
  const isValidEmail = (email) => {
89
94
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
90
95
  };
96
+ /**
97
+ * Parses name-address pair string to MailChannels format
98
+ */
91
99
  const parseRecipientString = (input) => {
92
100
  const trimmed = input.trim();
93
101
  const match = trimmed.match(/^([^<]*)<([^>]*)>$/);
@@ -102,6 +110,9 @@ const parseRecipientString = (input) => {
102
110
  if (!isValidEmail(trimmed)) return void 0;
103
111
  return { email: trimmed };
104
112
  };
113
+ /**
114
+ * Parses any recipient format to MailChannels format
115
+ */
105
116
  const parseRecipient = (recipient) => {
106
117
  if (typeof recipient === "string") return parseRecipientString(recipient);
107
118
  if (!recipient?.email || !isValidEmail(recipient.email)) return void 0;
@@ -110,12 +121,20 @@ const parseRecipient = (recipient) => {
110
121
  name: recipient.name
111
122
  };
112
123
  };
124
+ /**
125
+ * Parses any array of recipients format to MailChannels format
126
+ */
113
127
  const parseArrayRecipients = (recipients) => {
114
128
  if (!recipients) return void 0;
115
129
  const filtered = (typeof recipients === "string" ? [parseRecipientString(recipients)] : Array.isArray(recipients) ? recipients.map(parseRecipient) : [recipients]).filter((recipient) => Boolean(recipient));
116
130
  return filtered.length > 0 ? filtered : void 0;
117
131
  };
118
132
  const stripPemHeaders = (pem) => pem.replace(/-----[^-]+-----|\s|#.*$/gm, "");
133
+ /**
134
+ * Recursively removes undefined values from objects and arrays.
135
+ * @param data - The data to clean
136
+ * @returns The cleaned data with `undefined` properties removed
137
+ */
119
138
  const clean = (data) => {
120
139
  if (Array.isArray(data)) {
121
140
  const result = [];
@@ -260,12 +279,62 @@ var Emails = class {
260
279
  error: null
261
280
  };
262
281
  }
282
+ /**
283
+ * Sends an email message to one or more recipients.
284
+ * @param options - The email options to send.
285
+ * @param dryRun - When set to `true`, the message will not be sent. Instead, the fully rendered message will be returned in the `data` property of the response. The default value is `false`.
286
+ * @example
287
+ * ```ts
288
+ * const mailchannels = new MailChannels('your-api-key')
289
+ * const { success, data, error } = await mailchannels.emails.send({
290
+ * to: 'to@example.com',
291
+ * from: 'from@example.com',
292
+ * subject: 'Test',
293
+ * html: 'Test'
294
+ * })
295
+ * ```
296
+ */
263
297
  async send(options, dryRun = false) {
264
298
  return this._sendEmail(options, { dryRun });
265
299
  }
300
+ /**
301
+ * Queues an email message for asynchronous processing and returns immediately with a request ID.
302
+ *
303
+ * The email will be processed in the background, and you'll receive webhook events for all delivery status updates (e.g. `dropped`, `processed`, `delivered`, `hard-bounced`). These webhook events are identical to those sent for the synchronous /send endpoint.
304
+ *
305
+ * Use this endpoint when you need to send emails without waiting for processing to complete. This can improve your application's response time, especially when sending to multiple recipients.
306
+ * @param options - The email options to send.
307
+ * @example
308
+ * ```ts
309
+ * const mailchannels = new MailChannels('your-api-key')
310
+ * const { data, error } = await mailchannels.emails.sendAsync({
311
+ * to: 'to@example.com',
312
+ * from: 'from@example.com',
313
+ * subject: 'Test',
314
+ * html: 'Test'
315
+ * })
316
+ * ```
317
+ */
266
318
  async sendAsync(options) {
267
319
  return this._sendEmail(options, { async: true });
268
320
  }
321
+ /**
322
+ * Validates a domain's email authentication setup by retrieving its DKIM, SPF, and Domain Lockdown status. This endpoint checks whether the domain is properly configured for secure email delivery.
323
+ * @param options - The domain options to check.
324
+ * @example
325
+ * ```ts
326
+ * const mailchannels = new MailChannels('your-api-key')
327
+ * const { data, error } = await mailchannels.emails.checkDomain({
328
+ * dkim: [{
329
+ * domain: 'example.com',
330
+ * privateKey: 'your-private-key',
331
+ * selector: 'mailchannels'
332
+ * }],
333
+ * domain: 'example.com',
334
+ * senderId: 'sender-id'
335
+ * })
336
+ * ```
337
+ */
269
338
  async checkDomain(options) {
270
339
  let error = null;
271
340
  const { dkim, domain, senderId } = options;
@@ -311,6 +380,18 @@ var Emails = class {
311
380
  error: null
312
381
  };
313
382
  }
383
+ /**
384
+ * Create a DKIM key pair for a specified domain and selector using the specified algorithm and key length, for the current customer.
385
+ * @param domain - The domain to create the DKIM key for.
386
+ * @param options - DKIM key creation options.
387
+ * @example
388
+ * ```ts
389
+ * const mailchannels = new MailChannels('your-api-key')
390
+ * const { data, error } = await mailchannels.emails.createDkimKey('example.com', {
391
+ * selector: 'mailchannels'
392
+ * })
393
+ * ```
394
+ */
314
395
  async createDkimKey(domain, options) {
315
396
  let error = null;
316
397
  if (!options.selector || options.selector.length > 63) {
@@ -358,6 +439,18 @@ var Emails = class {
358
439
  error: null
359
440
  };
360
441
  }
442
+ /**
443
+ * Search for DKIM keys by domain, with optional filters. If selector is provided, at most one key will be returned.
444
+ * @param domain - The domain to search DKIM keys for.
445
+ * @param options - The options to filter DKIM keys by.
446
+ * @example
447
+ * ```ts
448
+ * const mailchannels = new MailChannels('your-api-key')
449
+ * const { data, error } = await mailchannels.getDkimKeys('example.com', {
450
+ * includeDnsRecord: true
451
+ * })
452
+ * ```
453
+ */
361
454
  async getDkimKeys(domain, options) {
362
455
  let error = null;
363
456
  if (options?.selector && options.selector.length > 63) {
@@ -412,6 +505,18 @@ var Emails = class {
412
505
  error: null
413
506
  };
414
507
  }
508
+ /**
509
+ * Update fields of an existing DKIM key pair for the specified domain and selector, for the current customer. Currently, only the `status` field can be updated.
510
+ * @param domain - The domain the DKIM key belongs to.
511
+ * @param options - The options to update the DKIM key.
512
+ * @example
513
+ * ```ts
514
+ * const mailchannels = new MailChannels('your-api-key')
515
+ * const { success, error } = await mailchannels.emails.updateDkimKey('example.com', {
516
+ * selector: 'mailchannels',
517
+ * status: 'retired'
518
+ * })
519
+ */
415
520
  async updateDkimKey(domain, options) {
416
521
  let error = null;
417
522
  if (!options.selector || options.selector.length > 63) {
@@ -438,6 +543,22 @@ var Emails = class {
438
543
  error
439
544
  };
440
545
  }
546
+ /**
547
+ * Rotate an active DKIM key pair. Mark the original key as `rotated`, and create a new key pair with the required new key selector, reusing the same algorithm and key length. The rotated key remains valid for signing for a 3-day grace period, and is automatically changed to `retired` 2 weeks after rotation. Publish the new key to its DNS TXT record before rotated key expires for signing as emails sent with an unpublished key will fail DKIM validation by receiving providers. After the grace period, only the new key is valid for signing if published.
548
+ * @param domain - The domain the DKIM key belongs to.
549
+ * @param selector - The selector of the DKIM key to rotate.
550
+ * @param options - The options to rotate the DKIM key.
551
+ * @param options.newKey.selector - The selector for the new key pair. Must be a maximum of 63 characters.
552
+ * @example
553
+ * ```ts
554
+ * const mailchannels = new MailChannels('your-api-key')
555
+ * const { data, error } = await mailchannels.emails.rotateDkimKey('example.com', 'mailchannels', {
556
+ * newKey: {
557
+ * selector: 'new-selector'
558
+ * }
559
+ * })
560
+ * ```
561
+ */
441
562
  async rotateDkimKey(domain, selector, options) {
442
563
  let error = null;
443
564
  if (!selector || selector.length > 63) {
@@ -505,10 +626,86 @@ var Emails = class {
505
626
  };
506
627
  }
507
628
  };
508
- var Webhooks = class {
629
+ const HMAC_SHA256 = {
630
+ name: "HMAC",
631
+ hash: "SHA-256"
632
+ };
633
+ const ED25519 = {
634
+ name: "Ed25519",
635
+ namedCurve: "Ed25519"
636
+ };
637
+ const encoder = new TextEncoder();
638
+ const DEFAULT_TOLERANCE = 300;
639
+ const HEADER_CONTENT_DIGEST = "content-digest";
640
+ const HEADER_SIGNATURE = "signature";
641
+ const HEADER_SIGNATURE_INPUT = "signature-input";
642
+ const validateContentDigest = async (header, body) => {
643
+ const match = header.match(/^(.*?)=:(.*?):$/);
644
+ if (!match) return false;
645
+ const [, algorithm, hash] = match;
646
+ if (!algorithm || !hash) return false;
647
+ const normalizedAlgorithm = algorithm.replace("-", "").toLowerCase();
648
+ if (!["sha256"].includes(normalizedAlgorithm)) return false;
649
+ const signatureBuffer = await subtle.digest(HMAC_SHA256.hash, encoder.encode(body));
650
+ return Buffer.from(signatureBuffer).toString("base64") === hash;
651
+ };
652
+ const extractSignature = (signatureHeader) => {
653
+ const signatureMatch = signatureHeader.match(/sig_\d+=:([^:]+):/);
654
+ return signatureMatch && signatureMatch[1] ? signatureMatch[1] : null;
655
+ };
656
+ const extractInputValues = (header) => {
657
+ const match = header.match(/^(\w+)=\(([^)]+)\);created=(\d+);alg="([^"]+)";keyid="([^"]+)"$/);
658
+ if (!match) return null;
659
+ return {
660
+ name: match[1],
661
+ timestamp: Number.parseInt(match[3], 10),
662
+ algorithm: match[4],
663
+ keyId: match[5]
664
+ };
665
+ };
666
+ async function isValidWebhook(options) {
667
+ const { payload, headers } = options;
668
+ const contentDigest = headers[HEADER_CONTENT_DIGEST];
669
+ const messageSignature = headers[HEADER_SIGNATURE];
670
+ const signatureInput = headers[HEADER_SIGNATURE_INPUT];
671
+ if (!payload || !contentDigest || !messageSignature || !signatureInput || !await validateContentDigest(contentDigest, payload)) return false;
672
+ const signature = extractSignature(messageSignature);
673
+ if (!signature) return false;
674
+ const values = extractInputValues(signatureInput);
675
+ if (!values) return false;
676
+ if (Math.floor(Date.now() / 1e3) - values.timestamp > DEFAULT_TOLERANCE) return false;
677
+ const signingString = `"content-digest": ${contentDigest}
678
+ "@signature-params": ("content-digest");created=${values.timestamp};alg="${values.algorithm}";keyid="${values.keyId}"`;
679
+ let publicKey = options.publicKey;
680
+ if (!publicKey) {
681
+ const publicKeyResponse = await $fetch("/tx/v1/webhook/public-key", {
682
+ baseURL: "https://api.mailchannels.net",
683
+ query: { id: values.keyId }
684
+ }).catch(() => null);
685
+ if (!publicKeyResponse) return false;
686
+ publicKey = publicKeyResponse.key;
687
+ }
688
+ publicKey = stripPemHeaders(publicKey);
689
+ const encoding = "base64";
690
+ const format = "spki";
691
+ const publicKeyBuffer = Buffer.from(publicKey, encoding);
692
+ const webhookSignatureBuffer = Buffer.from(signature, encoding);
693
+ const key = await subtle.importKey(format, publicKeyBuffer, ED25519, false, ["verify"]);
694
+ return subtle.verify(ED25519.name, key, webhookSignatureBuffer, encoder.encode(signingString));
695
+ }
696
+ var Webhooks = class Webhooks {
509
697
  constructor(mailchannels) {
510
698
  this.mailchannels = mailchannels;
511
699
  }
700
+ /**
701
+ * Enrolls the customer to receive event notifications via webhooks.
702
+ * @param endpoint - The URL to receive event notifications. Must be no longer than `8000` characters.
703
+ * @example
704
+ * ```ts
705
+ * const mailchannels = new MailChannels('your-api-key')
706
+ * const { success, error } = mailchannels.webhooks.enroll('https://example.com/api/webhooks/mailchannels')
707
+ * ```
708
+ */
512
709
  async enroll(endpoint) {
513
710
  let error = null;
514
711
  if (!endpoint) {
@@ -538,6 +735,14 @@ var Webhooks = class {
538
735
  error
539
736
  };
540
737
  }
738
+ /**
739
+ * Retrieves all registered webhook endpoints associated with the customer.
740
+ * @example
741
+ * ```ts
742
+ * const mailchannels = new MailChannels('your-api-key')
743
+ * const { data, error } = await mailchannels.webhooks.list()
744
+ * ```
745
+ */
541
746
  async list() {
542
747
  let error = null;
543
748
  const response = await this.mailchannels.get("/tx/v1/webhook", { onResponseError: async ({ response }) => {
@@ -555,6 +760,14 @@ var Webhooks = class {
555
760
  error: null
556
761
  };
557
762
  }
763
+ /**
764
+ * Deletes all registered webhook endpoints for the customer.
765
+ * @example
766
+ * ```ts
767
+ * const mailchannels = new MailChannels('your-api-key')
768
+ * const { success, error } = await mailchannels.webhooks.delete()
769
+ * ```
770
+ */
558
771
  async delete() {
559
772
  let error = null;
560
773
  await this.mailchannels.delete("/tx/v1/webhook", { onResponseError: async ({ response }) => {
@@ -567,6 +780,15 @@ var Webhooks = class {
567
780
  error
568
781
  };
569
782
  }
783
+ /**
784
+ * Retrieves the public key used to verify signatures on incoming webhook payloads.
785
+ * @param id - The ID of the key.
786
+ * @example
787
+ * ```ts
788
+ * const mailchannels = new MailChannels('your-api-key')
789
+ * const { data, error } = await mailchannels.webhooks.getSigningKey('key-id')
790
+ * ```
791
+ */
570
792
  async getSigningKey(id) {
571
793
  let error = null;
572
794
  const response = await this.mailchannels.get("/tx/v1/webhook/public-key", {
@@ -586,10 +808,22 @@ var Webhooks = class {
586
808
  error
587
809
  };
588
810
  return {
589
- data: clean({ key: response.key }),
811
+ data: clean({
812
+ id: response.id,
813
+ key: response.key
814
+ }),
590
815
  error: null
591
816
  };
592
817
  }
818
+ /**
819
+ * Validates whether your enrolled webhook(s) respond with an HTTP `2xx` status code. Sends a test request to each webhook containing your customer handle, a hardcoded event type (`test`), a hardcoded sender email (`test@mailchannels.com`), a timestamp, a request ID (provided or generated), and an SMTP ID. The response includes the HTTP status code and body returned by each webhook.
820
+ * @param requestId - Optional identifier in the webhook payload. If not provided, a value will be automatically generated. Must not exceed 28 characters.
821
+ * @example
822
+ * ```ts
823
+ * const mailchannels = new MailChannels('your-api-key')
824
+ * const { data, error } = await mailchannels.webhooks.validate('optional-request-id')
825
+ * ```
826
+ */
593
827
  async validate(requestId) {
594
828
  let error = null;
595
829
  if (requestId && requestId.length > 28) {
@@ -623,6 +857,29 @@ var Webhooks = class {
623
857
  error: null
624
858
  };
625
859
  }
860
+ /**
861
+ * Verifies the authenticity of incoming webhook requests by validating their signatures using the provided options.
862
+ * @param options - The options for verifying the webhook.
863
+ * @example
864
+ * ```ts
865
+ * const isValid = await Webhooks.verify({ payload: rawBody, headers })
866
+ * ```
867
+ */
868
+ static async verify(options) {
869
+ return isValidWebhook(options).catch(() => false);
870
+ }
871
+ /**
872
+ * Verifies the authenticity of incoming webhook requests by validating their signatures using the provided options.
873
+ * @param options - The options for verifying the webhook.
874
+ * @example
875
+ * ```ts
876
+ * const mailchannels = new MailChannels('your-api-key')
877
+ * const isValid = await mailchannels.webhooks.verify({ payload: rawBody, headers })
878
+ * ```
879
+ */
880
+ async verify(options) {
881
+ return Webhooks.verify(options);
882
+ }
626
883
  };
627
884
  var SubAccounts = class SubAccounts {
628
885
  static COMPANY_PATTERN = /^.{3,128}$/;
@@ -630,6 +887,16 @@ var SubAccounts = class SubAccounts {
630
887
  constructor(mailchannels) {
631
888
  this.mailchannels = mailchannels;
632
889
  }
890
+ /**
891
+ * Creates a new sub-account under the parent account. Each sub-account must have a unique handle composed solely of lowercase alphanumeric characters. If no handle is provided, a random handle will be generated. Note that Sub-accounts are only available to parent accounts on 100K and higher plans.
892
+ * @param companyName - The name of the company associated with the sub-account. This name is used for display purposes only and does not affect the functionality of the sub-account. The length must be between 3 and 128 characters.
893
+ * @param handle - A unique name for the sub-account to be created. The length must be between 3 and 128 characters, and it may contain only lowercase letters and numbers. If not provided, a random handle will be generated.
894
+ * @example
895
+ * ```ts
896
+ * const mailchannels = new MailChannels('your-api-key')
897
+ * const { data, error } = await mailchannels.subAccounts.create('My Company', 'validhandle123')
898
+ * ```
899
+ */
633
900
  async create(companyName, handle) {
634
901
  let error = null;
635
902
  if (!SubAccounts.COMPANY_PATTERN.test(companyName)) {
@@ -676,6 +943,15 @@ var SubAccounts = class SubAccounts {
676
943
  error: null
677
944
  };
678
945
  }
946
+ /**
947
+ * Retrieves all sub-accounts associated with the parent account. The response is paginated with a default limit of 1000 sub-accounts per page and an offset of 0.
948
+ * @param options - The options to filter the list of sub-accounts.
949
+ * @example
950
+ * ```ts
951
+ * const mailchannels = new MailChannels('your-api-key')
952
+ * const { data, error } = await mailchannels.subAccounts.list()
953
+ * ```
954
+ */
679
955
  async list(options) {
680
956
  let error = null;
681
957
  error = validatePagination({
@@ -708,6 +984,15 @@ var SubAccounts = class SubAccounts {
708
984
  error: null
709
985
  };
710
986
  }
987
+ /**
988
+ * Deletes the sub-account identified by its handle.
989
+ * @param handle - Handle of sub-account to be deleted.
990
+ * @example
991
+ * ```ts
992
+ * const mailchannels = new MailChannels('your-api-key')
993
+ * const { success, error } = await mailchannels.subAccounts.delete('validhandle123')
994
+ * ```
995
+ */
711
996
  async delete(handle) {
712
997
  let error = null;
713
998
  if (!handle) {
@@ -727,6 +1012,15 @@ var SubAccounts = class SubAccounts {
727
1012
  error
728
1013
  };
729
1014
  }
1015
+ /**
1016
+ * Suspends the sub-account identified by its handle. This action disables the account, preventing it from sending any emails until it is reactivated.
1017
+ * @param handle - Handle of sub-account to be suspended.
1018
+ * @example
1019
+ * ```ts
1020
+ * const mailchannels = new MailChannels('your-api-key')
1021
+ * const { success, error } = await mailchannels.subAccounts.suspend('validhandle123')
1022
+ * ```
1023
+ */
730
1024
  async suspend(handle) {
731
1025
  let error = null;
732
1026
  if (!handle) {
@@ -746,6 +1040,15 @@ var SubAccounts = class SubAccounts {
746
1040
  error
747
1041
  };
748
1042
  }
1043
+ /**
1044
+ * Activates a suspended sub-account identified by its handle, restoring its ability to send emails.
1045
+ * @param handle - Handle of sub-account to be activated.
1046
+ * @example
1047
+ * ```ts
1048
+ * const mailchannels = new MailChannels('your-api-key')
1049
+ * const { success, error } = await mailchannels.subAccounts.activate('validhandle123')
1050
+ * ```
1051
+ */
749
1052
  async activate(handle) {
750
1053
  let error = null;
751
1054
  if (!handle) {
@@ -768,6 +1071,15 @@ var SubAccounts = class SubAccounts {
768
1071
  error
769
1072
  };
770
1073
  }
1074
+ /**
1075
+ * Creates a new API key for the specified sub-account.
1076
+ * @param handle - Handle of the sub-account to create API key for.
1077
+ * @example
1078
+ * ```ts
1079
+ * const mailchannels = new MailChannels('your-api-key')
1080
+ * const { data, error } = await mailchannels.subAccounts.createApiKey('validhandle123')
1081
+ * ```
1082
+ */
771
1083
  async createApiKey(handle) {
772
1084
  let error = null;
773
1085
  if (!handle) {
@@ -799,6 +1111,16 @@ var SubAccounts = class SubAccounts {
799
1111
  error: null
800
1112
  };
801
1113
  }
1114
+ /**
1115
+ * Retrieves details of all API keys associated with the specified sub-account. For security reasons, the full API key is not returned; only the key ID and a partially redacted version are provided.
1116
+ * @param handle - Handle of the sub-account to retrieve the API key for.
1117
+ * @param options - The options to filter the list of API keys.
1118
+ * @example
1119
+ * ```ts
1120
+ * const mailchannels = new MailChannels('your-api-key')
1121
+ * const { data, error } = await mailchannels.subAccounts.listApiKeys('validhandle123')
1122
+ * ```
1123
+ */
802
1124
  async listApiKeys(handle, options) {
803
1125
  let error = null;
804
1126
  if (!handle) {
@@ -834,6 +1156,16 @@ var SubAccounts = class SubAccounts {
834
1156
  error: null
835
1157
  };
836
1158
  }
1159
+ /**
1160
+ * Deletes the API key identified by its ID for the specified sub-account.
1161
+ * @param handle - Handle of the sub-account for which the API key should be deleted.
1162
+ * @param id - The ID of the API key to delete.
1163
+ * @example
1164
+ * ```ts
1165
+ * const mailchannels = new MailChannels('your-api-key')
1166
+ * const { success, error } = await mailchannels.subAccounts.deleteApiKey('validhandle123', 1)
1167
+ * ```
1168
+ */
837
1169
  async deleteApiKey(handle, id) {
838
1170
  let error = null;
839
1171
  if (!handle) {
@@ -853,6 +1185,15 @@ var SubAccounts = class SubAccounts {
853
1185
  error
854
1186
  };
855
1187
  }
1188
+ /**
1189
+ * Creates a new SMTP password for the specified sub-account.
1190
+ * @param handle - Handle of the sub-account to create SMTP password for.
1191
+ * @example
1192
+ * ```ts
1193
+ * const mailchannels = new MailChannels('your-api-key')
1194
+ * const { data, error } = await mailchannels.subAccounts.createSmtpPassword('validhandle123')
1195
+ * ```
1196
+ */
856
1197
  async createSmtpPassword(handle) {
857
1198
  let error = null;
858
1199
  if (!handle) {
@@ -885,6 +1226,15 @@ var SubAccounts = class SubAccounts {
885
1226
  error: null
886
1227
  };
887
1228
  }
1229
+ /**
1230
+ * Retrieves details of all SMTP passwords associated with the specified sub-account. For security, the full SMTP password is not returned; only the password ID and a partially redacted version are provided.
1231
+ * @param handle - Handle of the sub-account to retrieve the SMTP password for.
1232
+ * @example
1233
+ * ```ts
1234
+ * const mailchannels = new MailChannels('your-api-key')
1235
+ * const { data, error } = await mailchannels.subAccounts.listSmtpPasswords('validhandle123')
1236
+ * ```
1237
+ */
888
1238
  async listSmtpPasswords(handle) {
889
1239
  let error = null;
890
1240
  if (!handle) {
@@ -913,6 +1263,16 @@ var SubAccounts = class SubAccounts {
913
1263
  error: null
914
1264
  };
915
1265
  }
1266
+ /**
1267
+ * Deletes the SMTP password identified by its ID for the specified sub-account.
1268
+ * @param handle - Handle of the sub-account for which the SMTP password should be deleted.
1269
+ * @param id - The ID of the SMTP password to delete.
1270
+ * @example
1271
+ * ```ts
1272
+ * const mailchannels = new MailChannels('your-api-key')
1273
+ * const { success, error } = await mailchannels.subAccounts.deleteSmtpPassword('validhandle123', 1)
1274
+ * ```
1275
+ */
916
1276
  async deleteSmtpPassword(handle, id) {
917
1277
  let error = null;
918
1278
  if (!handle) {
@@ -932,6 +1292,15 @@ var SubAccounts = class SubAccounts {
932
1292
  error
933
1293
  };
934
1294
  }
1295
+ /**
1296
+ * Retrieves the limit of a specified sub-account. A value of `-1` indicates that the sub-account inherits the parent account's limit, allowing the sub-account to utilize any remaining capacity within the parent account's allocation.
1297
+ * @param handle - Handle of the sub-account to retrieve the limit for.
1298
+ * @example
1299
+ * ```ts
1300
+ * const mailchannels = new MailChannels('your-api-key')
1301
+ * const { data, error } = await mailchannels.subAccounts.getLimit('validhandle123')
1302
+ * ```
1303
+ */
935
1304
  async getLimit(handle) {
936
1305
  let error = null;
937
1306
  if (!handle) {
@@ -956,6 +1325,16 @@ var SubAccounts = class SubAccounts {
956
1325
  error: null
957
1326
  };
958
1327
  }
1328
+ /**
1329
+ * Sets the limit for the specified sub-account.
1330
+ * @param handle - Handle of the sub-account to set limit for.
1331
+ * @param limit - The limits to set for the sub-account. The minimum allowed sends is `0`
1332
+ * @example
1333
+ * ```ts
1334
+ * const mailchannels = new MailChannels('your-api-key')
1335
+ * const { success, error } = await mailchannels.subAccounts.setLimit('validhandle123', { sends: 1000 })
1336
+ * ```
1337
+ */
959
1338
  async setLimit(handle, limit) {
960
1339
  let error = null;
961
1340
  if (!handle) {
@@ -981,6 +1360,15 @@ var SubAccounts = class SubAccounts {
981
1360
  error
982
1361
  };
983
1362
  }
1363
+ /**
1364
+ * Deletes the limit for the specified sub-account. After a successful deletion, the specified sub-account will be limited to the parent account's limit.
1365
+ * @param handle - Handle of the sub-account to delete limit for.
1366
+ * @example
1367
+ * ```ts
1368
+ * const mailchannels = new MailChannels('your-api-key')
1369
+ * const { success, error } = await mailchannels.subAccounts.deleteLimit('validhandle123')
1370
+ * ```
1371
+ */
984
1372
  async deleteLimit(handle) {
985
1373
  let error = null;
986
1374
  if (!handle) {
@@ -1000,6 +1388,15 @@ var SubAccounts = class SubAccounts {
1000
1388
  error
1001
1389
  };
1002
1390
  }
1391
+ /**
1392
+ * Retrieves usage statistics for the specified sub-account during the current billing period.
1393
+ * @param handle - Handle of the sub-account to query usage stats for.
1394
+ * @example
1395
+ * ```ts
1396
+ * const mailchannels = new MailChannels('your-api-key')
1397
+ * const { data, error } = await mailchannels.subAccounts.getUsage('validhandle123')
1398
+ * ```
1399
+ */
1003
1400
  async getUsage(handle) {
1004
1401
  let error = null;
1005
1402
  if (!handle) {
@@ -1033,6 +1430,15 @@ var Metrics = class {
1033
1430
  constructor(mailchannels) {
1034
1431
  this.mailchannels = mailchannels;
1035
1432
  }
1433
+ /**
1434
+ * Retrieve engagement metrics for messages sent from your account, including counts of open and click events. Supports optional filters for time range, and campaign ID.
1435
+ * @param options - Options to filter and customize the engagement metrics retrieval.
1436
+ * @example
1437
+ * ```ts
1438
+ * const mailchannels = new MailChannels('your-api-key')
1439
+ * const { data, error } = await mailchannels.metrics.engagement()
1440
+ * ```
1441
+ */
1036
1442
  async engagement(options) {
1037
1443
  let error = null;
1038
1444
  const response = await this.mailchannels.get("/tx/v1/metrics/engagement", {
@@ -1071,6 +1477,15 @@ var Metrics = class {
1071
1477
  error: null
1072
1478
  };
1073
1479
  }
1480
+ /**
1481
+ * Retrieve performance metrics for messages sent from your account, including counts of processed, delivered, hard-bounced events. Supports optional filters for time range, and campaign ID.
1482
+ * @param options - Options to filter and customize the performance metrics retrieval.
1483
+ * @example
1484
+ * ```ts
1485
+ * const mailchannels = new MailChannels('your-api-key')
1486
+ * const { data, error } = await mailchannels.metrics.performance()
1487
+ * ```
1488
+ */
1074
1489
  async performance(options) {
1075
1490
  let error = null;
1076
1491
  const response = await this.mailchannels.get("/tx/v1/metrics/performance", {
@@ -1107,6 +1522,15 @@ var Metrics = class {
1107
1522
  error: null
1108
1523
  };
1109
1524
  }
1525
+ /**
1526
+ * Retrieve recipient behaviour metrics for messages sent from your account, including counts of unsubscribed events. Supports optional filters for time range, and campaign ID.
1527
+ * @param options - Options to filter and customize the recipient behaviour metrics retrieval.
1528
+ * @example
1529
+ * ```ts
1530
+ * const mailchannels = new MailChannels('your-api-key')
1531
+ * const { data, error } = await mailchannels.metrics.recipientBehaviour()
1532
+ * ```
1533
+ */
1110
1534
  async recipientBehaviour(options) {
1111
1535
  let error = null;
1112
1536
  const response = await this.mailchannels.get("/tx/v1/metrics/recipient-behaviour", {
@@ -1141,6 +1565,15 @@ var Metrics = class {
1141
1565
  error: null
1142
1566
  };
1143
1567
  }
1568
+ /**
1569
+ * Retrieve volume metrics for messages sent from your account, including counts of processed, delivered and dropped events. Supports optional filters for time range and campaign ID.
1570
+ * @param options - Options to filter and customize the volume metrics retrieval.
1571
+ * @example
1572
+ * ```ts
1573
+ * const mailchannels = new MailChannels('your-api-key')
1574
+ * const { data, error } = await mailchannels.metrics.volume()
1575
+ * ```
1576
+ */
1144
1577
  async volume(options) {
1145
1578
  let error = null;
1146
1579
  const response = await this.mailchannels.get("/tx/v1/metrics/volume", {
@@ -1177,6 +1610,14 @@ var Metrics = class {
1177
1610
  error: null
1178
1611
  };
1179
1612
  }
1613
+ /**
1614
+ * Retrieves usage statistics during the current billing period.
1615
+ * @example
1616
+ * ```ts
1617
+ * const mailchannels = new MailChannels('your-api-key')
1618
+ * const { data, error } = await mailchannels.metrics.usage()
1619
+ * ```
1620
+ */
1180
1621
  async usage() {
1181
1622
  let error = null;
1182
1623
  const response = await this.mailchannels.get("/tx/v1/usage", { onResponseError: async ({ response }) => {
@@ -1198,6 +1639,16 @@ var Metrics = class {
1198
1639
  error: null
1199
1640
  };
1200
1641
  }
1642
+ /**
1643
+ * Retrieves a list of senders, either sub-accounts or campaigns, with their associated message metrics. Sorted by total # of sent messages (processed + dropped). Supports optional filter for time range, and optional settings for limit, offset, and sort order. Note: senders without any messages in the given time range will not be included in the results. The default time range is from one month ago to now, and the default sort order is descending.
1644
+ * @param type - The type of senders to retrieve metrics for. Can be either `sub-accounts` or `campaigns`.
1645
+ * @param options - Optional filter options for time range, limit, offset, and sort order.
1646
+ * @example
1647
+ * ```ts
1648
+ * const mailchannels = new MailChannels('your-api-key')
1649
+ * const { data, error } = await mailchannels.metrics.senders('campaigns')
1650
+ * ```
1651
+ */
1201
1652
  async senders(type, options) {
1202
1653
  let error = null;
1203
1654
  error = validatePagination({
@@ -1244,6 +1695,16 @@ var Suppressions = class {
1244
1695
  constructor(mailchannels) {
1245
1696
  this.mailchannels = mailchannels;
1246
1697
  }
1698
+ /**
1699
+ * 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.
1700
+ * @param options - The details of the suppression entries to create.
1701
+ * @example
1702
+ * ```ts
1703
+ * const mailchannels = new MailChannels('your-api-key')
1704
+ * const { success, error } = await mailchannels.suppressions.create({
1705
+ * // ...
1706
+ * });
1707
+ */
1247
1708
  async create(options) {
1248
1709
  let error = null;
1249
1710
  const { addToSubAccounts, entries } = options;
@@ -1272,6 +1733,16 @@ var Suppressions = class {
1272
1733
  error
1273
1734
  };
1274
1735
  }
1736
+ /**
1737
+ * Deletes suppression entry associated with the account based on the specified recipient and source.
1738
+ * @param recipient - The email address of the suppression entry to delete.
1739
+ * @param source - The source of the suppression entry to be deleted. If source is not provided, it defaults to `api`. If source is set to `all`, all suppression entries related to the specified recipient will be deleted.
1740
+ * @example
1741
+ * ```ts
1742
+ * const mailchannels = new MailChannels('your-api-key')
1743
+ * const { success, error } = await mailchannels.suppressions.delete('name@example.com', 'api');
1744
+ * ```
1745
+ */
1275
1746
  async delete(recipient, source) {
1276
1747
  let error = null;
1277
1748
  await this.mailchannels.delete(`/tx/v1/suppression-list/recipients/${recipient}`, {
@@ -1287,6 +1758,15 @@ var Suppressions = class {
1287
1758
  error
1288
1759
  };
1289
1760
  }
1761
+ /**
1762
+ * 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`.
1763
+ * @param options - Options to filter and customize the suppression entries retrieval.
1764
+ * @example
1765
+ * ```ts
1766
+ * const mailchannels = new MailChannels('your-api-key')
1767
+ * const { data, error } = await mailchannels.suppressions.list();
1768
+ * ```
1769
+ */
1290
1770
  async list(options) {
1291
1771
  let error = null;
1292
1772
  error = validatePagination({
@@ -1335,6 +1815,18 @@ var Domains = class {
1335
1815
  constructor(mailchannels) {
1336
1816
  this.mailchannels = mailchannels;
1337
1817
  }
1818
+ /**
1819
+ * Provision a single domain to use MailChannels Inbound.
1820
+ * @param options - The provision options and domain data.
1821
+ * @example
1822
+ * ```ts
1823
+ * const mailchannels = new MailChannels('your-api-key')
1824
+ * const { data, error } = await mailchannels.domains.provision({
1825
+ * domain: 'example.com',
1826
+ * subscriptionHandle: 'your-subscription-handle'
1827
+ * })
1828
+ * ```
1829
+ */
1338
1830
  async provision(options) {
1339
1831
  let error = null;
1340
1832
  const { associateKey, overwrite, ...payload } = options;
@@ -1364,6 +1856,26 @@ var Domains = class {
1364
1856
  error: null
1365
1857
  };
1366
1858
  }
1859
+ /**
1860
+ * Provision up to 1000 domains to use MailChannels Inbound.
1861
+ * @param options - The options to provision the domains.
1862
+ * @param domains - A list of domain data to provision.
1863
+ * @example
1864
+ * ```ts
1865
+ * const mailchannels = new MailChannels('your-api-key')
1866
+ * const { data, error } = await mailchannels.domains.bulkProvision({
1867
+ * subscriptionHandle: 'your-subscription-handle'
1868
+ * }, [
1869
+ * {
1870
+ * domain: 'example.com',
1871
+ * admins: ['support@example.com']
1872
+ * },
1873
+ * {
1874
+ * domain: 'example2.com'
1875
+ * }
1876
+ * ])
1877
+ * ```
1878
+ */
1367
1879
  async bulkProvision(options, domains) {
1368
1880
  let error = null;
1369
1881
  const { associateKey, overwrite, subscriptionHandle } = options;
@@ -1407,6 +1919,15 @@ var Domains = class {
1407
1919
  error: null
1408
1920
  };
1409
1921
  }
1922
+ /**
1923
+ * Fetch a list of all domains associated with this API key.
1924
+ * @param options - The options to filter the list of domains.
1925
+ * @example
1926
+ * ```ts
1927
+ * const mailchannels = new MailChannels('your-api-key')
1928
+ * const { data, error } = await mailchannels.domains.list()
1929
+ * ```
1930
+ */
1410
1931
  async list(options) {
1411
1932
  let error = null;
1412
1933
  error = validatePagination({
@@ -1438,6 +1959,15 @@ var Domains = class {
1438
1959
  error: null
1439
1960
  };
1440
1961
  }
1962
+ /**
1963
+ * De-provision a domain to cease protecting it with MailChannels Inbound.
1964
+ * @param domain - The domain name to be removed.
1965
+ * @example
1966
+ * ```ts
1967
+ * const mailchannels = new MailChannels('your-api-key')
1968
+ * const { success, error } = await mailchannels.domains.delete('example.com')
1969
+ * ```
1970
+ */
1441
1971
  async delete(domain) {
1442
1972
  let error = null;
1443
1973
  if (!domain) {
@@ -1460,6 +1990,19 @@ var Domains = class {
1460
1990
  error
1461
1991
  };
1462
1992
  }
1993
+ /**
1994
+ * Add an entry to a domain blocklist or safelist.
1995
+ * @param domain - The domain name.
1996
+ * @param options - The options to add a list entry.
1997
+ * @example
1998
+ * ```ts
1999
+ * const mailchannels = new MailChannels('your-api-key')
2000
+ * const { data, error } = await mailchannels.domains.addListEntry('example.com', {
2001
+ * listName: 'safelist',
2002
+ * item: 'name@domain.com'
2003
+ * })
2004
+ * ```
2005
+ */
1463
2006
  async addListEntry(domain, options) {
1464
2007
  const { listName, item } = options;
1465
2008
  let error = null;
@@ -1502,6 +2045,16 @@ var Domains = class {
1502
2045
  error: null
1503
2046
  };
1504
2047
  }
2048
+ /**
2049
+ * Get domain list entries.
2050
+ * @param domain - The domain name.
2051
+ * @param listName - The name of the list to fetch. This can be a `blocklist`, `safelist`, `blacklist`, or `whitelist`.
2052
+ * @example
2053
+ * ```ts
2054
+ * const mailchannels = new MailChannels('your-api-key')
2055
+ * const { data, error } = await mailchannels.domains.listEntries('example.com', 'safelist')
2056
+ * ```
2057
+ */
1505
2058
  async listEntries(domain, listName) {
1506
2059
  let error = null;
1507
2060
  if (!domain) {
@@ -1540,6 +2093,19 @@ var Domains = class {
1540
2093
  error: null
1541
2094
  };
1542
2095
  }
2096
+ /**
2097
+ * Delete item from domain list.
2098
+ * @param email - The domain name whose list will be modified.
2099
+ * @param options - The options for the list entry to delete.
2100
+ * @example
2101
+ * ```ts
2102
+ * const mailchannels = new MailChannels('your-api-key')
2103
+ * const { success, error } = await mailchannels.domains.deleteListEntry('example.com', {
2104
+ * listName: 'safelist',
2105
+ * item: 'name@domain.com'
2106
+ * })
2107
+ * ```
2108
+ */
1543
2109
  async deleteListEntry(domain, options) {
1544
2110
  const { listName, item } = options;
1545
2111
  let error = null;
@@ -1573,6 +2139,15 @@ var Domains = class {
1573
2139
  error
1574
2140
  };
1575
2141
  }
2142
+ /**
2143
+ * Generate a link that allows a user to log in as a domain administrator.
2144
+ * @param domain - The domain name.
2145
+ * @example
2146
+ * ```ts
2147
+ * const mailchannels = new MailChannels('your-api-key')
2148
+ * const { data, error } = await mailchannels.domains.createLoginLink('example.com')
2149
+ * ```
2150
+ */
1576
2151
  async createLoginLink(domain) {
1577
2152
  let error = null;
1578
2153
  if (!domain) {
@@ -1601,6 +2176,23 @@ var Domains = class {
1601
2176
  error: null
1602
2177
  };
1603
2178
  }
2179
+ /**
2180
+ * Sets the list of downstream addresses for the domain. This action deletes any existing downstream address for the domain before creating new ones. If the `records` parameter is an empty array, all downstream address records will be deleted.
2181
+ * @param domain - The domain name.
2182
+ * @param records - The list of records to set for the domain. A maximum of 10 records can be set.
2183
+ * @example
2184
+ * ```ts
2185
+ * const mailchannels = new MailChannels('your-api-key')
2186
+ * const { success, error } = await mailchannels.domains.setDownstreamAddress('example.com', [
2187
+ * {
2188
+ * port: 25,
2189
+ * priority: 10,
2190
+ * target: 'example.com.',
2191
+ * weight: 10
2192
+ * }
2193
+ * ])
2194
+ * ```
2195
+ */
1604
2196
  async setDownstreamAddress(domain, records) {
1605
2197
  let error = null;
1606
2198
  if (!domain) {
@@ -1640,6 +2232,16 @@ var Domains = class {
1640
2232
  error
1641
2233
  };
1642
2234
  }
2235
+ /**
2236
+ * Retrieve stored downstream addresses for the domain.
2237
+ * @param domain - The domain name.
2238
+ * @param options - The options to filter the list of downstream addresses.
2239
+ * @example
2240
+ * ```ts
2241
+ * const mailchannels = new MailChannels('your-api-key')
2242
+ * const { data, error } = await mailchannels.domains.listDownstreamAddresses('example.com')
2243
+ * ```
2244
+ */
1643
2245
  async listDownstreamAddresses(domain, options) {
1644
2246
  let error = null;
1645
2247
  if (!domain) {
@@ -1675,6 +2277,16 @@ var Domains = class {
1675
2277
  error: null
1676
2278
  };
1677
2279
  }
2280
+ /**
2281
+ * Update the API key that is associated with a domain.
2282
+ * @param domain - The domain name.
2283
+ * @param key - The new API key to associate with this domain.
2284
+ * @example
2285
+ * ```ts
2286
+ * const mailchannels = new MailChannels('your-api-key')
2287
+ * const { success, error } = await mailchannels.domains.updateApiKey('example.com', 'your-api-key')
2288
+ * ```
2289
+ */
1678
2290
  async updateApiKey(domain, key) {
1679
2291
  let error = null;
1680
2292
  if (!domain) {
@@ -1707,6 +2319,15 @@ var Domains = class {
1707
2319
  error
1708
2320
  };
1709
2321
  }
2322
+ /**
2323
+ * Generate a batch of links that allow a user to log in as a domain administrator to their different domains.
2324
+ * @param domains - The list of domain names. Maximum of `1000` links per request.
2325
+ * @example
2326
+ * ```ts
2327
+ * const mailchannels = new MailChannels('your-api-key')
2328
+ * const { data, error } = await mailchannels.domains.bulkCreateLoginLinks(['example.com', 'example2.com'])
2329
+ * ```
2330
+ */
1710
2331
  async bulkCreateLoginLinks(domains) {
1711
2332
  let error = null;
1712
2333
  if (!domains || !domains.length) {
@@ -1746,6 +2367,18 @@ var Lists = class {
1746
2367
  constructor(mailchannels) {
1747
2368
  this.mailchannels = mailchannels;
1748
2369
  }
2370
+ /**
2371
+ * Add item to account-level list
2372
+ * @param options - The options for the list entry to add.
2373
+ * @example
2374
+ * ```ts
2375
+ * const mailchannels = new MailChannels('your-api-key')
2376
+ * const { data, error } = await mailchannels.lists.addListEntry({
2377
+ * listName: 'safelist',
2378
+ * item: 'name@domain.com'
2379
+ * })
2380
+ * ```
2381
+ */
1749
2382
  async addListEntry(options) {
1750
2383
  let error = null;
1751
2384
  const { listName, item } = options;
@@ -1778,6 +2411,15 @@ var Lists = class {
1778
2411
  error: null
1779
2412
  };
1780
2413
  }
2414
+ /**
2415
+ * Get account-level list entries.
2416
+ * @param listName - The name of the list to fetch. This can be a `blocklist`, `safelist`, `blacklist`, or `whitelist`.
2417
+ * @example
2418
+ * ```ts
2419
+ * const mailchannels = new MailChannels('your-api-key')
2420
+ * const { data, error } = await mailchannels.lists.listEntries('safelist')
2421
+ * ```
2422
+ */
1781
2423
  async listEntries(listName) {
1782
2424
  let error = null;
1783
2425
  if (!listName) {
@@ -1806,6 +2448,18 @@ var Lists = class {
1806
2448
  error: null
1807
2449
  };
1808
2450
  }
2451
+ /**
2452
+ * Delete item from account-level list.
2453
+ * @param options - The options for the list entry to delete.
2454
+ * @example
2455
+ * ```ts
2456
+ * const mailchannels = new MailChannels('your-api-key')
2457
+ * const { success, error } = await mailchannels.lists.deleteListEntry({
2458
+ * listName: 'safelist',
2459
+ * item: 'name@domain.com'
2460
+ * })
2461
+ * ```
2462
+ */
1809
2463
  async deleteListEntry(options) {
1810
2464
  const { listName, item } = options;
1811
2465
  let error = null;
@@ -1834,6 +2488,18 @@ var Users = class {
1834
2488
  constructor(mailchannels) {
1835
2489
  this.mailchannels = mailchannels;
1836
2490
  }
2491
+ /**
2492
+ * Create a recipient user.
2493
+ * @param email - The email address of the user to create.
2494
+ * @param options - The options for the user to create.
2495
+ * @example
2496
+ * ```ts
2497
+ * const mailchannels = new MailChannels('your-api-key')
2498
+ * const { data, error } = await mailchannels.users.create("name@example.com", {
2499
+ * admin: true
2500
+ * })
2501
+ * ```
2502
+ */
1837
2503
  async create(email, options) {
1838
2504
  const { admin, filter, listEntries } = options || {};
1839
2505
  let error = null;
@@ -1876,6 +2542,19 @@ var Users = class {
1876
2542
  error: null
1877
2543
  };
1878
2544
  }
2545
+ /**
2546
+ * Add item to recipient user list
2547
+ * @param email - The email address of the recipient whose list will be modified.
2548
+ * @param options - The options for the list entry to add.
2549
+ * @example
2550
+ * ```ts
2551
+ * const mailchannels = new MailChannels('your-api-key')
2552
+ * const { data, error } = await mailchannels.users.addListEntry('name@example.com', {
2553
+ * listName: 'safelist',
2554
+ * item: 'name@domain.com'
2555
+ * })
2556
+ * ```
2557
+ */
1879
2558
  async addListEntry(email, options) {
1880
2559
  const { listName, item } = options;
1881
2560
  let error = null;
@@ -1918,6 +2597,16 @@ var Users = class {
1918
2597
  error: null
1919
2598
  };
1920
2599
  }
2600
+ /**
2601
+ * Get recipient list entries.
2602
+ * @param email - The email address of the recipient whose list will be fetched.
2603
+ * @param listName - The name of the list to fetch. This can be a `blocklist`, `safelist`, `blacklist`, or `whitelist`.
2604
+ * @example
2605
+ * ```ts
2606
+ * const mailchannels = new MailChannels('your-api-key')
2607
+ * const { data, error } = await mailchannels.users.listEntries('name@example.com', 'safelist')
2608
+ * ```
2609
+ */
1921
2610
  async listEntries(email, listName) {
1922
2611
  let error = null;
1923
2612
  if (!email) {
@@ -1956,6 +2645,19 @@ var Users = class {
1956
2645
  error: null
1957
2646
  };
1958
2647
  }
2648
+ /**
2649
+ * Delete item from recipient list.
2650
+ * @param email - The email address of the recipient whose list will be modified.
2651
+ * @param options - The options for the list entry to delete.
2652
+ * @example
2653
+ * ```ts
2654
+ * const mailchannels = new MailChannels('your-api-key')
2655
+ * const { success, error } = await mailchannels.users.deleteListEntry('name@example.com', {
2656
+ * listName: 'safelist',
2657
+ * item: 'name@domain.com'
2658
+ * })
2659
+ * ```
2660
+ */
1959
2661
  async deleteListEntry(email, options) {
1960
2662
  const { listName, item } = options;
1961
2663
  let error = null;
@@ -1994,6 +2696,14 @@ var Service = class {
1994
2696
  constructor(mailchannels) {
1995
2697
  this.mailchannels = mailchannels;
1996
2698
  }
2699
+ /**
2700
+ * Retrieve the condition of the service
2701
+ * @example
2702
+ * ```ts
2703
+ * const mailchannels = new MailChannels('your-api-key')
2704
+ * const { success, error } = await mailchannels.service.status()
2705
+ * ```
2706
+ */
1997
2707
  async status() {
1998
2708
  let error = null;
1999
2709
  await this.mailchannels.get("/inbound/v1/status", { onResponseError: async ({ response }) => {
@@ -2006,6 +2716,14 @@ var Service = class {
2006
2716
  error
2007
2717
  };
2008
2718
  }
2719
+ /**
2720
+ * Get a list of your subscriptions to MailChannels Inbound
2721
+ * @example
2722
+ * ```ts
2723
+ * const mailchannels = new MailChannels('your-api-key')
2724
+ * const { data, error } = await mailchannels.service.subscriptions()
2725
+ * ```
2726
+ */
2009
2727
  async subscriptions() {
2010
2728
  let error = null;
2011
2729
  const response = await this.mailchannels.get("/inbound/v1/subscriptions", { onResponseError: async ({ response }) => {
@@ -2023,6 +2741,17 @@ var Service = class {
2023
2741
  error: null
2024
2742
  };
2025
2743
  }
2744
+ /**
2745
+ * Submit a false negative or false positive report.
2746
+ * @param options - The report options
2747
+ * @example
2748
+ * ```ts
2749
+ * const mailchannels = new MailChannels('your-api-key')
2750
+ * const { success, error } = await mailchannels.service.report({
2751
+ * // ...
2752
+ * })
2753
+ * ```
2754
+ */
2026
2755
  async report(options) {
2027
2756
  let error = null;
2028
2757
  const { type, ...payload } = options;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mailchannels-sdk",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "Node.js SDK to integrate MailChannels API into your JavaScript or TypeScript server-side applications.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,14 +37,14 @@
37
37
  "ofetch": "^2.0.0-alpha.3"
38
38
  },
39
39
  "devDependencies": {
40
- "@stylistic/eslint-plugin": "^5.8.0",
40
+ "@stylistic/eslint-plugin": "^5.9.0",
41
41
  "@types/markdown-it": "^14.1.2",
42
- "@types/node": "^25.2.3",
42
+ "@types/node": "^25.3.0",
43
43
  "@vitest/coverage-v8": "^4.0.18",
44
44
  "changelogen": "^0.6.2",
45
45
  "jiti": "^2.6.1",
46
- "obuild": "^0.4.27",
47
- "oxlint": "^1.47.0",
46
+ "obuild": "^0.4.31",
47
+ "oxlint": "^1.50.0",
48
48
  "scule": "^1.3.0",
49
49
  "typescript": "^5.9.3",
50
50
  "vitepress": "^2.0.0-alpha.16",