mailchannels-sdk 1.5.1 → 1.5.2
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/CHANGELOG.md +1572 -0
- package/dist/_chunks/mailchannels.mjs +25 -43
- package/package.json +4 -4
|
@@ -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.
|
|
6
|
+
var version = "1.5.2";
|
|
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(", ");
|
|
@@ -393,7 +398,6 @@ var Emails = class {
|
|
|
393
398
|
body: payload,
|
|
394
399
|
onResponseError: async ({ response }) => {
|
|
395
400
|
error = getStatusError(response, {
|
|
396
|
-
[400]: "Bad Request.",
|
|
397
401
|
[403]: "User does not have access to this feature.",
|
|
398
402
|
[413]: "The total message size should not exceed 30MB. This includes the message itself, headers, and the combined size of any attachments."
|
|
399
403
|
});
|
|
@@ -483,10 +487,7 @@ var DomainsDkim = class {
|
|
|
483
487
|
const response = await this.mailchannels.post(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys`, {
|
|
484
488
|
body: payload,
|
|
485
489
|
onResponseError: async ({ response }) => {
|
|
486
|
-
error = getStatusError(response, {
|
|
487
|
-
[400]: "Bad Request.",
|
|
488
|
-
[409]: "Key pair already created for domain, and selector."
|
|
489
|
-
});
|
|
490
|
+
error = getStatusError(response, { [409]: "Key pair already created for domain, and selector." });
|
|
490
491
|
}
|
|
491
492
|
}).catch((e) => {
|
|
492
493
|
error ||= getResultError(e, "Failed to create DKIM key.");
|
|
@@ -535,7 +536,7 @@ var DomainsDkim = class {
|
|
|
535
536
|
const response = await this.mailchannels.get(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys`, {
|
|
536
537
|
query: payload,
|
|
537
538
|
onResponseError: async ({ response }) => {
|
|
538
|
-
error = getStatusError(response
|
|
539
|
+
error = getStatusError(response);
|
|
539
540
|
}
|
|
540
541
|
}).catch((e) => {
|
|
541
542
|
error ||= getResultError(e, "Failed to fetch DKIM keys.");
|
|
@@ -570,10 +571,7 @@ var DomainsDkim = class {
|
|
|
570
571
|
await this.mailchannels.patch(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys/${encodeURIComponent(options.selector)}`, {
|
|
571
572
|
body: payload,
|
|
572
573
|
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
|
-
});
|
|
574
|
+
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
575
|
}
|
|
578
576
|
}).catch((e) => {
|
|
579
577
|
error ||= getResultError(e, "Failed to update status of DKIM key.");
|
|
@@ -611,7 +609,6 @@ var DomainsDkim = class {
|
|
|
611
609
|
body: payload,
|
|
612
610
|
onResponseError: async ({ response }) => {
|
|
613
611
|
error = getStatusError(response, {
|
|
614
|
-
[400]: "Bad Request.",
|
|
615
612
|
[404]: "Specified key pair not found.",
|
|
616
613
|
[409]: "Key pair already created for domain, and provided new key selector."
|
|
617
614
|
});
|
|
@@ -656,7 +653,7 @@ var DomainsCustomTracking = class DomainsCustomTracking {
|
|
|
656
653
|
const response = await this.mailchannels.get("/tx/v1/custom-tracking-domains", {
|
|
657
654
|
query: options,
|
|
658
655
|
onResponseError: async ({ response }) => {
|
|
659
|
-
error = getStatusError(response
|
|
656
|
+
error = getStatusError(response);
|
|
660
657
|
}
|
|
661
658
|
}).catch((e) => {
|
|
662
659
|
error ||= getResultError(e, "Failed to fetch custom tracking domains.");
|
|
@@ -714,7 +711,6 @@ var DomainsCustomTracking = class DomainsCustomTracking {
|
|
|
714
711
|
},
|
|
715
712
|
onResponseError: async ({ response }) => {
|
|
716
713
|
error = getStatusError(response, {
|
|
717
|
-
[400]: "Invalid request body.",
|
|
718
714
|
[403]: "No permission to register this domain.",
|
|
719
715
|
[409]: "A domain with the same name already exists, or the hostname and scope combination is already registered.",
|
|
720
716
|
[422]: "DNS verification incomplete. Either the TXT ownership record has not propagated yet or the hostname CNAME does not point to the required target."
|
|
@@ -796,7 +792,6 @@ var DomainsCustomTracking = class DomainsCustomTracking {
|
|
|
796
792
|
},
|
|
797
793
|
onResponseError: async ({ response }) => {
|
|
798
794
|
error = getStatusError(response, {
|
|
799
|
-
[400]: "Bad Request.",
|
|
800
795
|
[403]: "No permission to update this domain.",
|
|
801
796
|
[404]: `Custom tracking domain for hostname '${hostname}' and scope '${scope}' not found.`,
|
|
802
797
|
[409]: "Name already used by another domain.",
|
|
@@ -910,10 +905,7 @@ var Domains = class {
|
|
|
910
905
|
const response = await this.mailchannels.post("/tx/v1/check-domain", {
|
|
911
906
|
body: payload,
|
|
912
907
|
onResponseError: async ({ response }) => {
|
|
913
|
-
error = getStatusError(response, {
|
|
914
|
-
[400]: "Bad Request.",
|
|
915
|
-
[403]: "User does not have access to this feature."
|
|
916
|
-
});
|
|
908
|
+
error = getStatusError(response, { [403]: "User does not have access to this feature." });
|
|
917
909
|
}
|
|
918
910
|
}).catch((e) => {
|
|
919
911
|
error ||= getResultError(e, "Failed to check domain.");
|
|
@@ -1110,10 +1102,7 @@ var Webhooks = class Webhooks {
|
|
|
1110
1102
|
const response = await this.mailchannels.get("/tx/v1/webhook/public-key", {
|
|
1111
1103
|
query: { id },
|
|
1112
1104
|
onResponseError: async ({ response }) => {
|
|
1113
|
-
error = getStatusError(response, {
|
|
1114
|
-
[400]: "Bad Request.",
|
|
1115
|
-
[404]: `The key '${id}' is not found.`
|
|
1116
|
-
});
|
|
1105
|
+
error = getStatusError(response, { [404]: `The key '${id}' is not found.` });
|
|
1117
1106
|
}
|
|
1118
1107
|
}).catch((e) => {
|
|
1119
1108
|
error ||= getResultError(e, "Failed to get signing key.");
|
|
@@ -1143,10 +1132,7 @@ var Webhooks = class Webhooks {
|
|
|
1143
1132
|
const response = await this.mailchannels.post("/tx/v1/webhook/validate", {
|
|
1144
1133
|
body: { request_id: requestId },
|
|
1145
1134
|
onResponseError: async ({ response }) => {
|
|
1146
|
-
error = getStatusError(response, {
|
|
1147
|
-
[400]: "Bad Request.",
|
|
1148
|
-
[404]: "No webhooks found for the account."
|
|
1149
|
-
});
|
|
1135
|
+
error = getStatusError(response, { [404]: "No webhooks found for the account." });
|
|
1150
1136
|
}
|
|
1151
1137
|
}).catch((e) => {
|
|
1152
1138
|
error ||= getResultError(e, "Failed to validate webhooks.");
|
|
@@ -1260,7 +1246,7 @@ var Webhooks = class Webhooks {
|
|
|
1260
1246
|
offset: options?.offset
|
|
1261
1247
|
},
|
|
1262
1248
|
onResponseError: async ({ response }) => {
|
|
1263
|
-
error = getStatusError(response
|
|
1249
|
+
error = getStatusError(response);
|
|
1264
1250
|
}
|
|
1265
1251
|
}).catch((e) => {
|
|
1266
1252
|
error ||= getResultError(e, "Failed to fetch webhook batches.");
|
|
@@ -1288,7 +1274,7 @@ var Webhooks = class Webhooks {
|
|
|
1288
1274
|
let error = null;
|
|
1289
1275
|
const response = await this.mailchannels.post(`/tx/v1/webhook-batch/${encodeURIComponent(batchId)}/resend`, { onResponseError: async ({ response }) => {
|
|
1290
1276
|
error = getStatusError(response, {
|
|
1291
|
-
[400]: "
|
|
1277
|
+
[400]: "The batch ID is invalid.",
|
|
1292
1278
|
[404]: `The batch '${batchId}' is not found for the customer.`
|
|
1293
1279
|
});
|
|
1294
1280
|
} }).catch((e) => {
|
|
@@ -1537,10 +1523,7 @@ var SubAccountsLimits = class {
|
|
|
1537
1523
|
await this.mailchannels.put(`/tx/v1/sub-account/${encodeURIComponent(handle)}/limit`, {
|
|
1538
1524
|
body: options,
|
|
1539
1525
|
onResponseError: async ({ response }) => {
|
|
1540
|
-
error = getStatusError(response, {
|
|
1541
|
-
[400]: "Bad Request.",
|
|
1542
|
-
[404]: `Sub-account with handle '${handle}' not found.`
|
|
1543
|
-
});
|
|
1526
|
+
error = getStatusError(response, { [404]: `Sub-account with handle '${handle}' not found.` });
|
|
1544
1527
|
}
|
|
1545
1528
|
}).catch((e) => {
|
|
1546
1529
|
error ||= getResultError(e, "Failed to set sub-account limit.");
|
|
@@ -1807,7 +1790,7 @@ var Metrics = class {
|
|
|
1807
1790
|
interval: options?.interval
|
|
1808
1791
|
},
|
|
1809
1792
|
onResponseError: async ({ response }) => {
|
|
1810
|
-
error = getStatusError(response
|
|
1793
|
+
error = getStatusError(response);
|
|
1811
1794
|
}
|
|
1812
1795
|
}).catch((e) => {
|
|
1813
1796
|
error ||= getResultError(e, "Failed to fetch engagement metrics.");
|
|
@@ -1861,7 +1844,7 @@ var Metrics = class {
|
|
|
1861
1844
|
interval: options?.interval
|
|
1862
1845
|
},
|
|
1863
1846
|
onResponseError: async ({ response }) => {
|
|
1864
|
-
error = getStatusError(response
|
|
1847
|
+
error = getStatusError(response);
|
|
1865
1848
|
}
|
|
1866
1849
|
}).catch((e) => {
|
|
1867
1850
|
error ||= getResultError(e, "Failed to fetch performance metrics.");
|
|
@@ -1907,7 +1890,7 @@ var Metrics = class {
|
|
|
1907
1890
|
interval: options?.interval
|
|
1908
1891
|
},
|
|
1909
1892
|
onResponseError: async ({ response }) => {
|
|
1910
|
-
error = getStatusError(response
|
|
1893
|
+
error = getStatusError(response);
|
|
1911
1894
|
}
|
|
1912
1895
|
}).catch((e) => {
|
|
1913
1896
|
error ||= getResultError(e, "Failed to fetch recipient behaviour metrics.");
|
|
@@ -1949,7 +1932,7 @@ var Metrics = class {
|
|
|
1949
1932
|
interval: options?.interval
|
|
1950
1933
|
},
|
|
1951
1934
|
onResponseError: async ({ response }) => {
|
|
1952
|
-
error = getStatusError(response
|
|
1935
|
+
error = getStatusError(response);
|
|
1953
1936
|
}
|
|
1954
1937
|
}).catch((e) => {
|
|
1955
1938
|
error ||= getResultError(e, "Failed to fetch volume metrics.");
|
|
@@ -2024,7 +2007,7 @@ var Metrics = class {
|
|
|
2024
2007
|
sort_order: options?.sortOrder
|
|
2025
2008
|
},
|
|
2026
2009
|
onResponseError: async ({ response }) => {
|
|
2027
|
-
error = getStatusError(response
|
|
2010
|
+
error = getStatusError(response);
|
|
2028
2011
|
}
|
|
2029
2012
|
}).catch((e) => {
|
|
2030
2013
|
error ||= getResultError(e, "Failed to fetch senders metrics.");
|
|
@@ -2075,7 +2058,6 @@ var Suppressions = class {
|
|
|
2075
2058
|
body: payload,
|
|
2076
2059
|
onResponseError: async ({ response }) => {
|
|
2077
2060
|
error = getStatusError(response, {
|
|
2078
|
-
[400]: "Bad Request.",
|
|
2079
2061
|
[409]: "Conflict. One or more suppression entries in the request already exist and cannot be created again.",
|
|
2080
2062
|
[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
2063
|
});
|
|
@@ -2093,7 +2075,7 @@ var Suppressions = class {
|
|
|
2093
2075
|
await this.mailchannels.delete(`/tx/v1/suppression-list/recipients/${encodeURIComponent(recipient)}`, {
|
|
2094
2076
|
query: { source },
|
|
2095
2077
|
onResponseError: async ({ response }) => {
|
|
2096
|
-
error = getStatusError(response
|
|
2078
|
+
error = getStatusError(response);
|
|
2097
2079
|
}
|
|
2098
2080
|
}).catch((e) => {
|
|
2099
2081
|
error ||= getResultError(e, "Failed to delete suppression entry.");
|
|
@@ -2139,7 +2121,7 @@ var Suppressions = class {
|
|
|
2139
2121
|
const response = await this.mailchannels.get("/tx/v1/suppression-list", {
|
|
2140
2122
|
query: payload,
|
|
2141
2123
|
onResponseError: async ({ response }) => {
|
|
2142
|
-
error = getStatusError(response
|
|
2124
|
+
error = getStatusError(response);
|
|
2143
2125
|
}
|
|
2144
2126
|
}).catch((e) => {
|
|
2145
2127
|
error ||= getResultError(e, "Failed to fetch suppression entries.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mailchannels-sdk",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
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,13 +52,13 @@
|
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
54
54
|
"@types/markdown-it": "^14.2.0",
|
|
55
|
-
"@types/node": "^26.
|
|
55
|
+
"@types/node": "^26.4.0",
|
|
56
56
|
"@types/nodemailer": "^8.0.1",
|
|
57
57
|
"@vitest/coverage-v8": "^4.1.11",
|
|
58
58
|
"changelogen": "^0.6.2",
|
|
59
|
-
"nodemailer": "^9.0.
|
|
59
|
+
"nodemailer": "^9.0.6",
|
|
60
60
|
"obuild": "^0.4.38",
|
|
61
|
-
"oxlint": "^1.
|
|
61
|
+
"oxlint": "^1.80.0",
|
|
62
62
|
"scule": "^1.3.0",
|
|
63
63
|
"typescript": "^6.0.3",
|
|
64
64
|
"vitepress": "^2.0.0-alpha.19",
|