mailchannels-sdk 1.1.0 → 1.3.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/.agents/skills/mailchannels-js/resources/custom-tracking-domains.md +83 -0
- package/.agents/skills/mailchannels-js/resources/error-handling.md +1 -0
- package/.agents/skills/mailchannels-js/resources/metrics-and-usage.md +3 -2
- package/.agents/skills/mailchannels-js/resources/sending.md +26 -0
- package/.agents/skills/mailchannels-js/resources/sub-accounts.md +1 -1
- package/.agents/skills/mailchannels-js/resources/suppressions.md +7 -7
- package/README.md +6 -4
- package/dist/_chunks/simulator.mjs +127 -24
- package/dist/mailchannels.d.mts +289 -23
- package/dist/mailchannels.mjs +294 -18
- package/package.json +8 -8
package/dist/mailchannels.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { $fetch } from "ofetch";
|
|
|
2
2
|
import { subtle } from "node:crypto";
|
|
3
3
|
import { Buffer } from "node:buffer";
|
|
4
4
|
import mime from "mime";
|
|
5
|
-
var version = "1.
|
|
5
|
+
var version = "1.3.0";
|
|
6
6
|
var MailChannelsClient = class MailChannelsClient {
|
|
7
7
|
static DEFAULT_BASE_URL = "https://api.mailchannels.net";
|
|
8
8
|
static DEFAULT_TIMEOUT = 12e4;
|
|
@@ -79,21 +79,26 @@ const STATUS_ERROR_TYPE_MAP = {
|
|
|
79
79
|
[429]: "rate_limit_error",
|
|
80
80
|
[500]: "internal_server_error"
|
|
81
81
|
};
|
|
82
|
-
const createError = (message, statusCode = null, type) => {
|
|
82
|
+
const createError = (message, statusCode = null, type, response = null) => {
|
|
83
83
|
return {
|
|
84
84
|
message,
|
|
85
85
|
statusCode,
|
|
86
|
-
type
|
|
86
|
+
type,
|
|
87
|
+
response
|
|
87
88
|
};
|
|
88
89
|
};
|
|
89
90
|
const getStatusError = (response, errors = {}) => {
|
|
90
91
|
const statusText = errors[response.status] || "Unknown error.";
|
|
91
92
|
const payload = response._data ?? response.data;
|
|
92
93
|
let details;
|
|
94
|
+
let errorResponse = null;
|
|
93
95
|
if (typeof payload === "string") details = payload;
|
|
94
|
-
else if (payload
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
else if (typeof payload === "object" && payload !== null) {
|
|
97
|
+
if (typeof payload.message === "string") details = payload.message;
|
|
98
|
+
else if (Array.isArray(payload.errors) && payload.errors.length) details = payload.errors.join(", ");
|
|
99
|
+
errorResponse = payload;
|
|
100
|
+
}
|
|
101
|
+
return createError(details ? `${statusText} ${details}` : statusText, response.status ?? null, STATUS_ERROR_TYPE_MAP[response.status] || "api_error", errorResponse);
|
|
97
102
|
};
|
|
98
103
|
const getResultError = (e, fallback) => {
|
|
99
104
|
return createError(e instanceof Error ? e.message : fallback, null, "application_error");
|
|
@@ -107,6 +112,12 @@ const validatePagination = (pagination = {}) => {
|
|
|
107
112
|
if (typeof offset === "number" && offset < 0) return createValidationError("Offset must be greater than or equal to 0.");
|
|
108
113
|
return null;
|
|
109
114
|
};
|
|
115
|
+
const CUSTOM_TRACKING_NAME_PATTERN = /^[a-z0-9-]+$/;
|
|
116
|
+
const validateCustomTrackingName = (name) => {
|
|
117
|
+
if (!name || name.length < 1 || name.length > 64) return createValidationError("The custom tracking domain name must be between 1 and 64 characters.");
|
|
118
|
+
if (!CUSTOM_TRACKING_NAME_PATTERN.test(name)) return createValidationError("The custom tracking domain name must match ^[a-z0-9-]+$");
|
|
119
|
+
return null;
|
|
120
|
+
};
|
|
110
121
|
const clean = (data) => {
|
|
111
122
|
if (Array.isArray(data)) {
|
|
112
123
|
const result = [];
|
|
@@ -305,6 +316,18 @@ const buildSendPayload = async (options) => {
|
|
|
305
316
|
return getRecipientCount(personalization.to) + getRecipientCount(personalization.cc) + getRecipientCount(personalization.bcc) !== 1;
|
|
306
317
|
})) return "Non-transactional messages must have exactly one recipient per personalization.";
|
|
307
318
|
}
|
|
319
|
+
if (options.tracking?.click?.customDomainName !== void 0) {
|
|
320
|
+
const clickCustomTrackingNameError = validateCustomTrackingName(options.tracking.click.customDomainName);
|
|
321
|
+
if (clickCustomTrackingNameError) return `Invalid click tracking: ${clickCustomTrackingNameError.message}`;
|
|
322
|
+
}
|
|
323
|
+
if (options.tracking?.open?.customDomainName !== void 0) {
|
|
324
|
+
const openCustomTrackingNameError = validateCustomTrackingName(options.tracking.open.customDomainName);
|
|
325
|
+
if (openCustomTrackingNameError) return `Invalid open tracking: ${openCustomTrackingNameError.message}`;
|
|
326
|
+
}
|
|
327
|
+
if (options.unsubscribe?.customDomainName !== void 0) {
|
|
328
|
+
const unsubscribeCustomTrackingNameError = validateCustomTrackingName(options.unsubscribe.customDomainName);
|
|
329
|
+
if (unsubscribeCustomTrackingNameError) return `Invalid unsubscribe settings: ${unsubscribeCustomTrackingNameError.message}`;
|
|
330
|
+
}
|
|
308
331
|
const content = [];
|
|
309
332
|
const template_type = options.template?.type;
|
|
310
333
|
if (text) content.push({
|
|
@@ -335,11 +358,18 @@ const buildSendPayload = async (options) => {
|
|
|
335
358
|
from: parsedFrom,
|
|
336
359
|
subject: options.subject,
|
|
337
360
|
content,
|
|
338
|
-
tracking_settings: options.tracking
|
|
339
|
-
click_tracking: options.tracking.click
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
361
|
+
tracking_settings: options.tracking && {
|
|
362
|
+
click_tracking: options.tracking.click && {
|
|
363
|
+
custom_domain_name: options.tracking.click.customDomainName,
|
|
364
|
+
enable: options.tracking.click.enable
|
|
365
|
+
},
|
|
366
|
+
open_tracking: options.tracking.open && {
|
|
367
|
+
custom_domain_name: options.tracking.open.customDomainName,
|
|
368
|
+
enable: options.tracking.open.enable
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
transactional: options.transactional,
|
|
372
|
+
unsubscribe_settings: options.unsubscribe && { custom_domain_name: options.unsubscribe.customDomainName }
|
|
343
373
|
};
|
|
344
374
|
};
|
|
345
375
|
var Emails = class {
|
|
@@ -603,12 +633,245 @@ var DomainsDkim = class {
|
|
|
603
633
|
};
|
|
604
634
|
}
|
|
605
635
|
};
|
|
636
|
+
var DomainsCustomTracking = class DomainsCustomTracking {
|
|
637
|
+
mailchannels;
|
|
638
|
+
static SCOPE_VALUES = /* @__PURE__ */ new Set([
|
|
639
|
+
"click",
|
|
640
|
+
"open",
|
|
641
|
+
"unsubscribe"
|
|
642
|
+
]);
|
|
643
|
+
constructor(mailchannels) {
|
|
644
|
+
this.mailchannels = mailchannels;
|
|
645
|
+
}
|
|
646
|
+
async list(options) {
|
|
647
|
+
let error = null;
|
|
648
|
+
error = validatePagination({
|
|
649
|
+
...options,
|
|
650
|
+
max: 1e3
|
|
651
|
+
});
|
|
652
|
+
if (error) return {
|
|
653
|
+
data: null,
|
|
654
|
+
error
|
|
655
|
+
};
|
|
656
|
+
const response = await this.mailchannels.get("/tx/v1/custom-tracking-domains", {
|
|
657
|
+
query: options,
|
|
658
|
+
onResponseError: async ({ response }) => {
|
|
659
|
+
error = getStatusError(response, { [400]: "Bad Request." });
|
|
660
|
+
}
|
|
661
|
+
}).catch((e) => {
|
|
662
|
+
error ||= getResultError(e, "Failed to fetch custom tracking domains.");
|
|
663
|
+
return null;
|
|
664
|
+
});
|
|
665
|
+
if (!response) return {
|
|
666
|
+
data: null,
|
|
667
|
+
error
|
|
668
|
+
};
|
|
669
|
+
return {
|
|
670
|
+
data: clean({
|
|
671
|
+
customTrackingDomains: response.custom_tracking_domains.map((d) => ({
|
|
672
|
+
name: d.name,
|
|
673
|
+
hostname: d.hostname,
|
|
674
|
+
scope: d.scope,
|
|
675
|
+
status: d.status,
|
|
676
|
+
createdAt: d.created_at
|
|
677
|
+
})),
|
|
678
|
+
total: response.total
|
|
679
|
+
}),
|
|
680
|
+
error: null
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
async create(name, hostname, scope) {
|
|
684
|
+
let error = null;
|
|
685
|
+
error = validateCustomTrackingName(name);
|
|
686
|
+
if (error) return {
|
|
687
|
+
data: null,
|
|
688
|
+
error
|
|
689
|
+
};
|
|
690
|
+
if (!hostname) {
|
|
691
|
+
error = createValidationError("Hostname is required.");
|
|
692
|
+
return {
|
|
693
|
+
data: null,
|
|
694
|
+
error
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
if (!scope || !DomainsCustomTracking.SCOPE_VALUES.has(scope)) {
|
|
698
|
+
error = createValidationError("Scope must be one of 'click', 'open', or 'unsubscribe'.");
|
|
699
|
+
return {
|
|
700
|
+
data: null,
|
|
701
|
+
error
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
const payload = {
|
|
705
|
+
name,
|
|
706
|
+
hostname,
|
|
707
|
+
scope
|
|
708
|
+
};
|
|
709
|
+
let statusCode = null;
|
|
710
|
+
const response = await this.mailchannels.post("/tx/v1/custom-tracking-domains", {
|
|
711
|
+
body: payload,
|
|
712
|
+
onResponse: async ({ response }) => {
|
|
713
|
+
statusCode = response.status;
|
|
714
|
+
},
|
|
715
|
+
onResponseError: async ({ response }) => {
|
|
716
|
+
error = getStatusError(response, {
|
|
717
|
+
[400]: "Invalid request body.",
|
|
718
|
+
[403]: "No permission to register this domain.",
|
|
719
|
+
[409]: "A domain with the same name already exists, or the hostname and scope combination is already registered.",
|
|
720
|
+
[422]: "DNS verification incomplete. Either the TXT ownership record has not propagated yet or the hostname CNAME does not point to the required target."
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
}).catch((e) => {
|
|
724
|
+
error ||= getResultError(e, "Failed to create custom tracking domain.");
|
|
725
|
+
return null;
|
|
726
|
+
});
|
|
727
|
+
if (!response) return {
|
|
728
|
+
data: null,
|
|
729
|
+
error
|
|
730
|
+
};
|
|
731
|
+
if (statusCode === 202) {
|
|
732
|
+
const dnsSetupRequiredResponse = response;
|
|
733
|
+
return {
|
|
734
|
+
data: clean({
|
|
735
|
+
dnsSetupRequired: true,
|
|
736
|
+
token: dnsSetupRequiredResponse.token,
|
|
737
|
+
txtRecordName: dnsSetupRequiredResponse.txt_record_name,
|
|
738
|
+
txtRecordValue: dnsSetupRequiredResponse.txt_record_value,
|
|
739
|
+
instructions: dnsSetupRequiredResponse.instructions
|
|
740
|
+
}),
|
|
741
|
+
error: null
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
const createResponse = response;
|
|
745
|
+
return {
|
|
746
|
+
data: clean({
|
|
747
|
+
dnsSetupRequired: false,
|
|
748
|
+
name: createResponse.name,
|
|
749
|
+
hostname: createResponse.hostname,
|
|
750
|
+
scope: createResponse.scope,
|
|
751
|
+
status: createResponse.status,
|
|
752
|
+
createdAt: createResponse.created_at
|
|
753
|
+
}),
|
|
754
|
+
error: null
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
async update(hostname, scope, options) {
|
|
758
|
+
let error = null;
|
|
759
|
+
if (!hostname) {
|
|
760
|
+
error = createValidationError("Hostname is required.");
|
|
761
|
+
return {
|
|
762
|
+
data: null,
|
|
763
|
+
error
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
if (!scope || !DomainsCustomTracking.SCOPE_VALUES.has(scope)) {
|
|
767
|
+
error = createValidationError("Scope must be one of 'click', 'open', or 'unsubscribe'.");
|
|
768
|
+
return {
|
|
769
|
+
data: null,
|
|
770
|
+
error
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
if (options.name !== void 0) {
|
|
774
|
+
error = validateCustomTrackingName(options.name);
|
|
775
|
+
if (error) return {
|
|
776
|
+
data: null,
|
|
777
|
+
error
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
if (options.name === void 0 && options.status === void 0) {
|
|
781
|
+
error = createValidationError("At least one of 'name' or 'status' must be provided.");
|
|
782
|
+
return {
|
|
783
|
+
data: null,
|
|
784
|
+
error
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
const payload = {
|
|
788
|
+
name: options.name,
|
|
789
|
+
status: options.status
|
|
790
|
+
};
|
|
791
|
+
let statusCode = null;
|
|
792
|
+
const response = await this.mailchannels.patch(`/tx/v1/custom-tracking-domains/${encodeURIComponent(hostname)}/${encodeURIComponent(scope)}`, {
|
|
793
|
+
body: payload,
|
|
794
|
+
onResponse: async ({ response }) => {
|
|
795
|
+
statusCode = response.status;
|
|
796
|
+
},
|
|
797
|
+
onResponseError: async ({ response }) => {
|
|
798
|
+
error = getStatusError(response, {
|
|
799
|
+
[400]: "Bad Request.",
|
|
800
|
+
[403]: "No permission to update this domain.",
|
|
801
|
+
[404]: `Custom tracking domain for hostname '${hostname}' and scope '${scope}' not found.`,
|
|
802
|
+
[409]: "Name already used by another domain.",
|
|
803
|
+
[422]: "DNS verification incomplete. Either the TXT ownership record has not propagated yet or the hostname CNAME does not point to the required target."
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
}).catch((e) => {
|
|
807
|
+
error ||= getResultError(e, "Failed to update custom tracking domain.");
|
|
808
|
+
return null;
|
|
809
|
+
});
|
|
810
|
+
if (!response) return {
|
|
811
|
+
data: null,
|
|
812
|
+
error
|
|
813
|
+
};
|
|
814
|
+
if (statusCode === 202) {
|
|
815
|
+
const dnsSetupRequiredResponse = response;
|
|
816
|
+
return {
|
|
817
|
+
data: clean({
|
|
818
|
+
dnsSetupRequired: true,
|
|
819
|
+
token: dnsSetupRequiredResponse.token,
|
|
820
|
+
txtRecordName: dnsSetupRequiredResponse.txt_record_name,
|
|
821
|
+
txtRecordValue: dnsSetupRequiredResponse.txt_record_value,
|
|
822
|
+
instructions: dnsSetupRequiredResponse.instructions
|
|
823
|
+
}),
|
|
824
|
+
error: null
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
const updateResponse = response;
|
|
828
|
+
return {
|
|
829
|
+
data: clean({
|
|
830
|
+
dnsSetupRequired: false,
|
|
831
|
+
name: updateResponse.name,
|
|
832
|
+
hostname: updateResponse.hostname,
|
|
833
|
+
scope: updateResponse.scope,
|
|
834
|
+
status: updateResponse.status,
|
|
835
|
+
createdAt: updateResponse.created_at
|
|
836
|
+
}),
|
|
837
|
+
error: null
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
async delete(hostname, scope) {
|
|
841
|
+
let error = null;
|
|
842
|
+
if (!hostname) {
|
|
843
|
+
error = createValidationError("Hostname is required.");
|
|
844
|
+
return {
|
|
845
|
+
success: false,
|
|
846
|
+
error
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
if (!scope || !DomainsCustomTracking.SCOPE_VALUES.has(scope)) {
|
|
850
|
+
error = createValidationError("Scope must be one of 'click', 'open', or 'unsubscribe'.");
|
|
851
|
+
return {
|
|
852
|
+
success: false,
|
|
853
|
+
error
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
await this.mailchannels.delete(`/tx/v1/custom-tracking-domains/${encodeURIComponent(hostname)}/${encodeURIComponent(scope)}`, { onResponseError: async ({ response }) => {
|
|
857
|
+
error = getStatusError(response, { [400]: "Invalid hostname or scope value" });
|
|
858
|
+
} }).catch((e) => {
|
|
859
|
+
error ||= getResultError(e, "Failed to delete custom tracking domain.");
|
|
860
|
+
});
|
|
861
|
+
return {
|
|
862
|
+
success: !error,
|
|
863
|
+
error
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
};
|
|
606
867
|
var Domains = class {
|
|
607
868
|
mailchannels;
|
|
608
869
|
dkim;
|
|
870
|
+
customTracking;
|
|
609
871
|
constructor(mailchannels) {
|
|
610
872
|
this.mailchannels = mailchannels;
|
|
611
873
|
this.dkim = new DomainsDkim(mailchannels);
|
|
874
|
+
this.customTracking = new DomainsCustomTracking(mailchannels);
|
|
612
875
|
}
|
|
613
876
|
async check(domain, options) {
|
|
614
877
|
let error = null;
|
|
@@ -1480,7 +1743,8 @@ var SubAccounts = class SubAccounts {
|
|
|
1480
1743
|
data: clean({
|
|
1481
1744
|
endDate: response.period_end_date,
|
|
1482
1745
|
startDate: response.period_start_date,
|
|
1483
|
-
total: response.total_usage
|
|
1746
|
+
total: response.total_usage,
|
|
1747
|
+
monthlyLimit: response.monthly_limit
|
|
1484
1748
|
}),
|
|
1485
1749
|
error: null
|
|
1486
1750
|
};
|
|
@@ -1558,14 +1822,22 @@ var Metrics = class {
|
|
|
1558
1822
|
click: response.buckets.click.map(mapBucket),
|
|
1559
1823
|
clickTrackingDelivered: response.buckets.click_tracking_delivered.map(mapBucket),
|
|
1560
1824
|
open: response.buckets.open.map(mapBucket),
|
|
1561
|
-
openTrackingDelivered: response.buckets.open_tracking_delivered.map(mapBucket)
|
|
1825
|
+
openTrackingDelivered: response.buckets.open_tracking_delivered.map(mapBucket),
|
|
1826
|
+
uniqueClick: response.buckets.unique_click?.map(mapBucket),
|
|
1827
|
+
uniqueClickTrackingDelivered: response.buckets.unique_click_tracking_delivered?.map(mapBucket),
|
|
1828
|
+
uniqueOpen: response.buckets.unique_open?.map(mapBucket),
|
|
1829
|
+
uniqueOpenTrackingDelivered: response.buckets.unique_open_tracking_delivered?.map(mapBucket)
|
|
1562
1830
|
},
|
|
1563
1831
|
click: response.click,
|
|
1564
1832
|
clickTrackingDelivered: response.click_tracking_delivered,
|
|
1565
1833
|
endTime: response.end_time,
|
|
1566
1834
|
open: response.open,
|
|
1567
1835
|
openTrackingDelivered: response.open_tracking_delivered,
|
|
1568
|
-
startTime: response.start_time
|
|
1836
|
+
startTime: response.start_time,
|
|
1837
|
+
uniqueClick: response.unique_click,
|
|
1838
|
+
uniqueClickTrackingDelivered: response.unique_click_tracking_delivered,
|
|
1839
|
+
uniqueOpen: response.unique_open,
|
|
1840
|
+
uniqueOpenTrackingDelivered: response.unique_open_tracking_delivered
|
|
1569
1841
|
}),
|
|
1570
1842
|
error: null
|
|
1571
1843
|
};
|
|
@@ -1601,8 +1873,10 @@ var Metrics = class {
|
|
|
1601
1873
|
return {
|
|
1602
1874
|
data: clean({
|
|
1603
1875
|
bounced: response.bounced,
|
|
1876
|
+
complained: response.complained,
|
|
1604
1877
|
buckets: {
|
|
1605
1878
|
bounced: response.buckets.bounced.map(mapBucket),
|
|
1879
|
+
complained: response.buckets.complained.map(mapBucket),
|
|
1606
1880
|
delivered: response.buckets.delivered.map(mapBucket),
|
|
1607
1881
|
processed: response.buckets.processed.map(mapBucket)
|
|
1608
1882
|
},
|
|
@@ -1716,7 +1990,8 @@ var Metrics = class {
|
|
|
1716
1990
|
data: clean({
|
|
1717
1991
|
endDate: response.period_end_date,
|
|
1718
1992
|
startDate: response.period_start_date,
|
|
1719
|
-
total: response.total_usage
|
|
1993
|
+
total: response.total_usage,
|
|
1994
|
+
monthlyLimit: response.monthly_limit
|
|
1720
1995
|
}),
|
|
1721
1996
|
error: null
|
|
1722
1997
|
};
|
|
@@ -1776,9 +2051,10 @@ var Suppressions = class {
|
|
|
1776
2051
|
constructor(mailchannels) {
|
|
1777
2052
|
this.mailchannels = mailchannels;
|
|
1778
2053
|
}
|
|
1779
|
-
async create(options) {
|
|
2054
|
+
async create(entriesOrOptions, options) {
|
|
1780
2055
|
let error = null;
|
|
1781
|
-
const
|
|
2056
|
+
const entries = Array.isArray(entriesOrOptions) ? entriesOrOptions : entriesOrOptions.entries;
|
|
2057
|
+
const createOptions = Array.isArray(entriesOrOptions) ? options : entriesOrOptions;
|
|
1782
2058
|
if (entries.length > 1e3) {
|
|
1783
2059
|
error = createValidationError("The number of suppression entries must not exceed 1000.");
|
|
1784
2060
|
return {
|
|
@@ -1787,7 +2063,7 @@ var Suppressions = class {
|
|
|
1787
2063
|
};
|
|
1788
2064
|
}
|
|
1789
2065
|
const payload = {
|
|
1790
|
-
add_to_sub_accounts: addToSubAccounts,
|
|
2066
|
+
add_to_sub_accounts: createOptions?.addToSubAccounts,
|
|
1791
2067
|
suppression_entries: entries.map((entry) => ({
|
|
1792
2068
|
notes: entry.notes,
|
|
1793
2069
|
recipient: entry.recipient,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mailchannels-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.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",
|
|
@@ -43,17 +43,17 @@
|
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
45
45
|
"@types/markdown-it": "^14.1.2",
|
|
46
|
-
"@types/node": "^
|
|
47
|
-
"@vitest/coverage-v8": "^4.1.
|
|
46
|
+
"@types/node": "^26.1.1",
|
|
47
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
48
48
|
"changelogen": "^0.6.2",
|
|
49
|
-
"obuild": "^0.4.
|
|
50
|
-
"oxlint": "^1.
|
|
49
|
+
"obuild": "^0.4.38",
|
|
50
|
+
"oxlint": "^1.74.0",
|
|
51
51
|
"scule": "^1.3.0",
|
|
52
52
|
"typescript": "^6.0.3",
|
|
53
|
-
"vitepress": "^2.0.0-alpha.
|
|
53
|
+
"vitepress": "^2.0.0-alpha.18",
|
|
54
54
|
"vitepress-plugin-group-icons": "^1.7.5",
|
|
55
|
-
"vitepress-plugin-llms": "^1.13.
|
|
56
|
-
"vitest": "^4.1.
|
|
55
|
+
"vitepress-plugin-llms": "^1.13.3",
|
|
56
|
+
"vitest": "^4.1.10"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">=20"
|