@aoxborrow/registrar-client 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -43
- package/dist/index.cjs +589 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +589 -47
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/http.ts +26 -2
- package/src/index.ts +1 -0
- package/src/registrars/domain101.ts +709 -0
- package/src/registrars/dynadot.ts +3 -0
- package/src/registrars/index.ts +12 -10
- package/src/registrars/namecheap.ts +11 -5
- package/src/registrars/namecom.ts +8 -12
- package/src/types.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -597,8 +597,8 @@ var HttpClient = class {
|
|
|
597
597
|
case 404:
|
|
598
598
|
return new NotFoundError(message);
|
|
599
599
|
case 429: {
|
|
600
|
-
const retryAfter =
|
|
601
|
-
return new RateLimitError(message,
|
|
600
|
+
const retryAfter = parseRetryAfter(response.headers.get("retry-after")) ?? this.config.rateLimitFallbackSeconds;
|
|
601
|
+
return new RateLimitError(message, retryAfter);
|
|
602
602
|
}
|
|
603
603
|
default: {
|
|
604
604
|
if (response.status >= 500) {
|
|
@@ -611,6 +611,19 @@ var HttpClient = class {
|
|
|
611
611
|
}
|
|
612
612
|
}
|
|
613
613
|
};
|
|
614
|
+
function parseRetryAfter(value) {
|
|
615
|
+
const text2 = value?.trim();
|
|
616
|
+
if (!text2) return void 0;
|
|
617
|
+
if (/^\d+$/.test(text2)) {
|
|
618
|
+
const seconds = Number(text2);
|
|
619
|
+
return Number.isSafeInteger(seconds) ? seconds : void 0;
|
|
620
|
+
}
|
|
621
|
+
const zonedDate = /^(?:[a-z]{3}, \d{2} [a-z]{3} \d{4}|[a-z]+, \d{2}-[a-z]{3}-\d{2}) \d{2}:\d{2}:\d{2} GMT$/i;
|
|
622
|
+
const asctimeDate = /^[a-z]{3} [a-z]{3} (?: \d|\d{2}) \d{2}:\d{2}:\d{2} \d{4}$/i;
|
|
623
|
+
if (!zonedDate.test(text2) && !asctimeDate.test(text2)) return void 0;
|
|
624
|
+
const date = Date.parse(asctimeDate.test(text2) ? `${text2} GMT` : text2);
|
|
625
|
+
return Number.isFinite(date) ? Math.max(0, Math.ceil((date - Date.now()) / 1e3)) : void 0;
|
|
626
|
+
}
|
|
614
627
|
function isOutcomeUnknown(error) {
|
|
615
628
|
if (error instanceof TimeoutError || error instanceof InvalidResponseError) return true;
|
|
616
629
|
return error instanceof ConnectionError && !error.notSent;
|
|
@@ -1063,8 +1076,8 @@ var CloudflareRegistrar = class _CloudflareRegistrar extends BaseRegistrar {
|
|
|
1063
1076
|
message: `${domainName} is not a zone in this account; DNS is managed via the Zones API`
|
|
1064
1077
|
};
|
|
1065
1078
|
}
|
|
1066
|
-
const
|
|
1067
|
-
const list = await this.http.request({ path:
|
|
1079
|
+
const dnsPath2 = `/zones/${encodeURIComponent(zone.id)}/dns_records`;
|
|
1080
|
+
const list = await this.http.request({ path: dnsPath2, ...opts });
|
|
1068
1081
|
if (!list.success) {
|
|
1069
1082
|
return {
|
|
1070
1083
|
success: false,
|
|
@@ -1075,7 +1088,7 @@ var CloudflareRegistrar = class _CloudflareRegistrar extends BaseRegistrar {
|
|
|
1075
1088
|
if (!rec.id) continue;
|
|
1076
1089
|
const del = await this.http.request({
|
|
1077
1090
|
method: "DELETE",
|
|
1078
|
-
path: `${
|
|
1091
|
+
path: `${dnsPath2}/${encodeURIComponent(rec.id)}`,
|
|
1079
1092
|
...opts
|
|
1080
1093
|
});
|
|
1081
1094
|
if (!del.success) {
|
|
@@ -1091,7 +1104,7 @@ var CloudflareRegistrar = class _CloudflareRegistrar extends BaseRegistrar {
|
|
|
1091
1104
|
if (type === "NS" && name === zone.name) continue;
|
|
1092
1105
|
const create = await this.http.request({
|
|
1093
1106
|
method: "POST",
|
|
1094
|
-
path:
|
|
1107
|
+
path: dnsPath2,
|
|
1095
1108
|
body: toCfDnsBody(record, type, name),
|
|
1096
1109
|
...opts
|
|
1097
1110
|
});
|
|
@@ -1760,6 +1773,527 @@ function toContact(c) {
|
|
|
1760
1773
|
return contact;
|
|
1761
1774
|
}
|
|
1762
1775
|
|
|
1776
|
+
// src/registrars/domain101.ts
|
|
1777
|
+
var Domain101HttpClient = class extends HttpClient {
|
|
1778
|
+
async request(req) {
|
|
1779
|
+
try {
|
|
1780
|
+
return await super.request(req);
|
|
1781
|
+
} catch (error) {
|
|
1782
|
+
if (error instanceof AuthorizationError) {
|
|
1783
|
+
const scope = requiredScope(req);
|
|
1784
|
+
if (!scope || error.providerCode !== "INSUFFICIENT_PERMISSIONS") throw error;
|
|
1785
|
+
const scoped = new AuthorizationError(
|
|
1786
|
+
`101domain: this API key does not have the ${scope} scope. Create a key with ${scope} to ${SCOPE_PURPOSE[scope]}.`
|
|
1787
|
+
);
|
|
1788
|
+
scoped.providerCode = error.providerCode;
|
|
1789
|
+
throw scoped;
|
|
1790
|
+
}
|
|
1791
|
+
if (error instanceof OutcomeUnknownError)
|
|
1792
|
+
throw new OutcomeUnknownError(
|
|
1793
|
+
"101domain: the registrar did not confirm this change. Re-read the domain before trying again.",
|
|
1794
|
+
{ feature: error.feature }
|
|
1795
|
+
);
|
|
1796
|
+
if (error instanceof ParsingError) throw new ParsingError("101domain: invalid JSON response");
|
|
1797
|
+
if (error instanceof ConnectionError)
|
|
1798
|
+
throw new ConnectionError("101domain: network request failed", { notSent: error.notSent });
|
|
1799
|
+
throw error;
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
async toStatusError(response, url) {
|
|
1803
|
+
const detail = await errorDetail(response);
|
|
1804
|
+
const error = await super.toStatusError(
|
|
1805
|
+
new Response(null, { status: response.status, headers: response.headers }),
|
|
1806
|
+
url
|
|
1807
|
+
);
|
|
1808
|
+
if (detail) {
|
|
1809
|
+
error.message = `101domain: ${detail.message}`;
|
|
1810
|
+
error.providerCode = detail.code;
|
|
1811
|
+
} else if (response.status === 403) {
|
|
1812
|
+
error.message = "101domain: the request was refused before reaching the API (403 without an API error)";
|
|
1813
|
+
}
|
|
1814
|
+
return error;
|
|
1815
|
+
}
|
|
1816
|
+
};
|
|
1817
|
+
var SCOPE_PURPOSE = {
|
|
1818
|
+
domains_read: "read the domain portfolio",
|
|
1819
|
+
domains_write: "change URL forwarding",
|
|
1820
|
+
dns_read: "read DNS records and nameservers",
|
|
1821
|
+
dns_write: "change DNS records and nameservers"
|
|
1822
|
+
};
|
|
1823
|
+
function requiredScope(req) {
|
|
1824
|
+
const write = !REST_SAFE_METHODS.includes((req.method ?? "GET").toUpperCase());
|
|
1825
|
+
if (req.path.startsWith("/dns/")) return write ? "dns_write" : "dns_read";
|
|
1826
|
+
if (req.path === "/domains" || /^\/domains\/[^/]+(?:\/forwarding)?$/.test(req.path))
|
|
1827
|
+
return write ? "domains_write" : "domains_read";
|
|
1828
|
+
return void 0;
|
|
1829
|
+
}
|
|
1830
|
+
async function errorDetail(response) {
|
|
1831
|
+
try {
|
|
1832
|
+
const body = await response.json();
|
|
1833
|
+
if (typeof body?.code !== "string" || typeof body.message !== "string" || !body.message)
|
|
1834
|
+
return null;
|
|
1835
|
+
return { code: body.code, message: body.message.replace(/\s+/g, " ").slice(0, 200) };
|
|
1836
|
+
} catch {
|
|
1837
|
+
return null;
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
var Domain101Registrar = class extends BaseRegistrar {
|
|
1841
|
+
name = "101domain";
|
|
1842
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
1843
|
+
static displayName = "101domain";
|
|
1844
|
+
static website = "101domain.com";
|
|
1845
|
+
static supportsSandbox = false;
|
|
1846
|
+
static configFields = [
|
|
1847
|
+
{ name: "apiKey", label: "API key", type: "password", required: true }
|
|
1848
|
+
];
|
|
1849
|
+
static helpText = "Create a Bearer API key under My Account > Developer Tools - API & MCP. Use domains_read and dns_read for reads; dns_write for DNS/nameservers and domains_write for forwarding. Only a primary account with 2FA or SSO can create keys. Keys expire after at most one year. Registration, renewal, auto-renew, privacy, lock, contacts and transfers are not available through this API.";
|
|
1850
|
+
static extendedFeatures = [
|
|
1851
|
+
Feature.GetDomainForwarding,
|
|
1852
|
+
Feature.SetDomainForwarding
|
|
1853
|
+
];
|
|
1854
|
+
constructor(credentials, options) {
|
|
1855
|
+
const apiKey = credentials.apiKey?.trim() ?? "";
|
|
1856
|
+
if (/[\r\n]/.test(apiKey)) throw new ConfigurationError("101domain: invalid API key format");
|
|
1857
|
+
const config = {
|
|
1858
|
+
baseUrl: selectBaseUrl("101domain", options?.environment, {
|
|
1859
|
+
production: "https://api.101domain.com/v1"
|
|
1860
|
+
}),
|
|
1861
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
1862
|
+
};
|
|
1863
|
+
super(credentials, config, options);
|
|
1864
|
+
this.http = new Domain101HttpClient({
|
|
1865
|
+
...config,
|
|
1866
|
+
safeMethods: REST_SAFE_METHODS,
|
|
1867
|
+
options: this.options
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1870
|
+
async testConnection(opts) {
|
|
1871
|
+
try {
|
|
1872
|
+
await this.request({
|
|
1873
|
+
path: "/domains",
|
|
1874
|
+
query: { page: 1, per_page: 1 },
|
|
1875
|
+
...opts
|
|
1876
|
+
});
|
|
1877
|
+
return { success: true, message: "Connection successful" };
|
|
1878
|
+
} catch (error) {
|
|
1879
|
+
return { success: false, message: toRegistrarError(error).message };
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
async listDomains(opts) {
|
|
1883
|
+
const { search, detailed: _detailed, ...requestOpts } = opts ?? {};
|
|
1884
|
+
const result = [];
|
|
1885
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1886
|
+
for (let page = 1; ; page++) {
|
|
1887
|
+
const response = await this.request({
|
|
1888
|
+
path: "/domains",
|
|
1889
|
+
query: { page, per_page: 50 },
|
|
1890
|
+
...requestOpts
|
|
1891
|
+
});
|
|
1892
|
+
if (!Array.isArray(response.data)) throw invalid("domain list");
|
|
1893
|
+
const pagination = response.meta?.pagination;
|
|
1894
|
+
if (!pagination || pagination.current_page !== page || !Number.isInteger(pagination.total_pages) || pagination.total_pages < 0 || pagination.total_pages > 1e5 || !Number.isInteger(pagination.total) || pagination.total < 0)
|
|
1895
|
+
throw invalid("pagination");
|
|
1896
|
+
for (const raw of response.data) {
|
|
1897
|
+
const domain = toDomain(raw);
|
|
1898
|
+
if (seen.has(domain.domainName)) throw invalid("duplicate domain across pages");
|
|
1899
|
+
seen.add(domain.domainName);
|
|
1900
|
+
result.push(domain);
|
|
1901
|
+
}
|
|
1902
|
+
if (page >= pagination.total_pages) {
|
|
1903
|
+
if (result.length !== pagination.total) throw invalid("incomplete portfolio");
|
|
1904
|
+
return filterDomains(
|
|
1905
|
+
result.filter((d) => !d.deleted),
|
|
1906
|
+
search
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
if (!response.data.length) throw invalid("empty intermediate page");
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
async getDomain(domainName, opts) {
|
|
1913
|
+
const domain = toDomain(
|
|
1914
|
+
(await this.request({ path: domainPath(domainName), ...opts })).data
|
|
1915
|
+
);
|
|
1916
|
+
if (domain.domainName !== normalizeDomain(domainName)) throw invalid("domain identity");
|
|
1917
|
+
return domain;
|
|
1918
|
+
}
|
|
1919
|
+
async getNameservers(domainName, opts) {
|
|
1920
|
+
const raw = (await this.request({ path: `${dnsPath(domainName)}/nameservers`, ...opts })).data;
|
|
1921
|
+
if (!Array.isArray(raw) || raw.some((n) => typeof n !== "string")) throw invalid("nameservers");
|
|
1922
|
+
return raw.map((n) => n.toLowerCase());
|
|
1923
|
+
}
|
|
1924
|
+
async updateNameservers(domainName, nameservers, opts) {
|
|
1925
|
+
const normalized = nameservers.map((n) => n.trim().toLowerCase());
|
|
1926
|
+
if (normalized.length < 2 || normalized.length > 13 || new Set(normalized).size !== normalized.length || normalized.some((n) => !/^(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9-]+$/.test(n)))
|
|
1927
|
+
throw new ConfigurationError("101domain: provide 2\u201313 distinct nameserver hostnames");
|
|
1928
|
+
try {
|
|
1929
|
+
const response = await this.request({
|
|
1930
|
+
...opts,
|
|
1931
|
+
method: "PUT",
|
|
1932
|
+
path: `${dnsPath(domainName)}/nameservers`,
|
|
1933
|
+
body: { nameservers: normalized }
|
|
1934
|
+
});
|
|
1935
|
+
if (response.data?.change_status === "pending")
|
|
1936
|
+
return {
|
|
1937
|
+
success: true,
|
|
1938
|
+
pending: true,
|
|
1939
|
+
message: "Nameserver change submitted; pending registry processing. Re-read nameservers to confirm completion."
|
|
1940
|
+
};
|
|
1941
|
+
if (response.data?.change_status === "failed")
|
|
1942
|
+
return { success: false, message: "101domain rejected the nameserver change" };
|
|
1943
|
+
if (response.data?.change_status !== "completed")
|
|
1944
|
+
throw new OutcomeUnknownError(
|
|
1945
|
+
"101domain: invalid nameserver change confirmation. Re-read nameservers before trying again."
|
|
1946
|
+
);
|
|
1947
|
+
return { success: true, message: "Nameservers already configured as requested" };
|
|
1948
|
+
} catch (error) {
|
|
1949
|
+
return failed(error);
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
async checkAvailability(domainNames, opts) {
|
|
1953
|
+
const names = [...new Set(domainNames.map(normalizeDomain))];
|
|
1954
|
+
const result = [];
|
|
1955
|
+
for (const domains of chunks(names, 50)) {
|
|
1956
|
+
const response = await this.request({
|
|
1957
|
+
...opts,
|
|
1958
|
+
method: "POST",
|
|
1959
|
+
path: "/domains/bulk-search",
|
|
1960
|
+
body: { domains, pricing_term: 1 }
|
|
1961
|
+
});
|
|
1962
|
+
if (!Array.isArray(response.data) || (response.invalid?.length ?? 0) > 0)
|
|
1963
|
+
throw invalid("availability results");
|
|
1964
|
+
const found = /* @__PURE__ */ new Set();
|
|
1965
|
+
for (const raw of response.data) {
|
|
1966
|
+
if (typeof raw.domain_name !== "string" || typeof raw.available !== "boolean")
|
|
1967
|
+
throw invalid("availability result");
|
|
1968
|
+
const domainName = normalizeDomain(raw.domain_name);
|
|
1969
|
+
if (!domains.includes(domainName) || found.has(domainName))
|
|
1970
|
+
throw invalid("availability identity");
|
|
1971
|
+
found.add(domainName);
|
|
1972
|
+
const price2 = oneYear(raw.pricing);
|
|
1973
|
+
result.push({
|
|
1974
|
+
domainName,
|
|
1975
|
+
available: raw.available,
|
|
1976
|
+
premium: price2?.premium,
|
|
1977
|
+
price: amount(price2?.register),
|
|
1978
|
+
renewalPrice: amount(price2?.renew),
|
|
1979
|
+
currency: price2?.currency,
|
|
1980
|
+
period: 1
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
if (found.size !== domains.length) throw invalid("incomplete availability results");
|
|
1984
|
+
}
|
|
1985
|
+
return result;
|
|
1986
|
+
}
|
|
1987
|
+
async getPricing(tldOrDomain, opts) {
|
|
1988
|
+
const name = normalizeDomain(tldOrDomain);
|
|
1989
|
+
if (name.startsWith(".") || !name.includes(".")) {
|
|
1990
|
+
const tld = name.replace(/^\./, "");
|
|
1991
|
+
const response2 = await this.request({
|
|
1992
|
+
path: `/tlds/${encodeURIComponent("." + tld)}`,
|
|
1993
|
+
query: { pricing_terms: "1" },
|
|
1994
|
+
...opts
|
|
1995
|
+
});
|
|
1996
|
+
const price3 = oneYear(response2.data?.pricing);
|
|
1997
|
+
if (!price3) throw new NotFoundError("101domain: no one-year pricing for this TLD");
|
|
1998
|
+
return {
|
|
1999
|
+
tld,
|
|
2000
|
+
currency: price3.currency,
|
|
2001
|
+
registration: amount(price3.register),
|
|
2002
|
+
renewal: amount(price3.renew),
|
|
2003
|
+
transfer: amount(price3.transfer)
|
|
2004
|
+
};
|
|
2005
|
+
}
|
|
2006
|
+
const response = await this.request({
|
|
2007
|
+
path: "/domains/search",
|
|
2008
|
+
query: { domain_name: name, pricing_terms: "1" },
|
|
2009
|
+
...opts
|
|
2010
|
+
});
|
|
2011
|
+
const raw = response.data;
|
|
2012
|
+
if (!raw || normalizeDomain(raw.domain_name) !== name) throw invalid("pricing identity");
|
|
2013
|
+
const price2 = oneYear(raw.pricing);
|
|
2014
|
+
if (!price2) throw new NotFoundError("101domain: pricing unavailable for this domain");
|
|
2015
|
+
return {
|
|
2016
|
+
tld: name.slice(name.indexOf(".") + 1),
|
|
2017
|
+
currency: price2.currency,
|
|
2018
|
+
registration: amount(price2.register),
|
|
2019
|
+
renewal: amount(price2.renew),
|
|
2020
|
+
transfer: amount(price2.transfer)
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
2023
|
+
async getDnsRecords(domainName, opts) {
|
|
2024
|
+
return (await this.rawRecords(domainName, opts)).map(fromRecord);
|
|
2025
|
+
}
|
|
2026
|
+
// Reconcile by content-derived IDs. Preserve unchanged records, edit by ID, create additions
|
|
2027
|
+
// before removing stale records, and stop on any failed batch. Never retry an
|
|
2028
|
+
// uncertain write. This replaces the custom records, not the apex NS delegation.
|
|
2029
|
+
async setDnsRecords(domainName, records, opts) {
|
|
2030
|
+
const desired = records.map((r) => recordSpec(r, domainName));
|
|
2031
|
+
const unique = desired.filter(
|
|
2032
|
+
(r, i) => desired.findIndex((other) => recordSignature(other) === recordSignature(r)) === i
|
|
2033
|
+
);
|
|
2034
|
+
let changed = false;
|
|
2035
|
+
try {
|
|
2036
|
+
const stale = (await this.rawRecords(domainName, opts)).map((raw) => ({ raw, spec: recordSpec(fromRecord(raw), domainName, false) })).filter(({ spec }) => !(spec.type === "NS" && spec.name === ""));
|
|
2037
|
+
const additions = [];
|
|
2038
|
+
const edits = [];
|
|
2039
|
+
for (const record of unique) {
|
|
2040
|
+
const index = stale.findIndex(
|
|
2041
|
+
({ spec }) => recordSignature(spec) === recordSignature(record)
|
|
2042
|
+
);
|
|
2043
|
+
if (index >= 0) stale.splice(index, 1);
|
|
2044
|
+
else {
|
|
2045
|
+
const priorIndex = stale.findIndex(
|
|
2046
|
+
({ spec }) => spec.type === record.type && spec.name === record.name
|
|
2047
|
+
);
|
|
2048
|
+
const prior = priorIndex >= 0 ? stale.splice(priorIndex, 1)[0].raw : void 0;
|
|
2049
|
+
if (prior?.proxied) record.proxied = true;
|
|
2050
|
+
if (record.ttl === 1 && record.proxied !== true)
|
|
2051
|
+
throw new ConfigurationError(
|
|
2052
|
+
"101domain: automatic TTL requires an existing proxied SWA record"
|
|
2053
|
+
);
|
|
2054
|
+
if (prior) {
|
|
2055
|
+
const edit = { ...record, id: prior.id };
|
|
2056
|
+
delete edit.name;
|
|
2057
|
+
delete edit.type;
|
|
2058
|
+
edits.push(edit);
|
|
2059
|
+
} else additions.push(record);
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
for (const batch of chunks(edits, 25)) {
|
|
2063
|
+
const response = await this.request({
|
|
2064
|
+
...opts,
|
|
2065
|
+
method: "PATCH",
|
|
2066
|
+
path: `${dnsPath(domainName)}/records`,
|
|
2067
|
+
body: { records: batch }
|
|
2068
|
+
});
|
|
2069
|
+
if (!Array.isArray(response.data) || response.data.length !== batch.length || new Set(response.data.map((r) => r?.old_id)).size !== batch.length || response.data.some(
|
|
2070
|
+
(r) => !r || !batch.some((edit) => edit.id === r.old_id) || typeof r.id !== "string" || !r.id
|
|
2071
|
+
))
|
|
2072
|
+
throw new OutcomeUnknownError(
|
|
2073
|
+
"101domain: invalid DNS edit confirmation. Re-read the zone before trying again."
|
|
2074
|
+
);
|
|
2075
|
+
changed = true;
|
|
2076
|
+
}
|
|
2077
|
+
for (const batch of chunks(additions, 25)) {
|
|
2078
|
+
await this.request({
|
|
2079
|
+
...opts,
|
|
2080
|
+
method: "POST",
|
|
2081
|
+
path: `${dnsPath(domainName)}/records`,
|
|
2082
|
+
body: { records: batch }
|
|
2083
|
+
});
|
|
2084
|
+
changed = true;
|
|
2085
|
+
}
|
|
2086
|
+
for (const batch of chunks(stale, 25)) {
|
|
2087
|
+
await this.request({
|
|
2088
|
+
...opts,
|
|
2089
|
+
method: "DELETE",
|
|
2090
|
+
path: `${dnsPath(domainName)}/records`,
|
|
2091
|
+
body: { ids: batch.map(({ raw }) => raw.id) }
|
|
2092
|
+
});
|
|
2093
|
+
changed = true;
|
|
2094
|
+
}
|
|
2095
|
+
return { success: true, message: "DNS records updated successfully" };
|
|
2096
|
+
} catch (error) {
|
|
2097
|
+
const result = failed(error);
|
|
2098
|
+
if (!changed && !result.outcome) return result;
|
|
2099
|
+
return {
|
|
2100
|
+
...result,
|
|
2101
|
+
message: `${result.message}. DNS replacement is not atomic; read the zone before retrying.`
|
|
2102
|
+
};
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
async getDomainForwarding(domainName, opts) {
|
|
2106
|
+
const raw = (await this.request({
|
|
2107
|
+
path: domainPath(domainName),
|
|
2108
|
+
...opts
|
|
2109
|
+
})).data;
|
|
2110
|
+
if (!raw || normalizeDomain(raw.domain_name) !== normalizeDomain(domainName))
|
|
2111
|
+
throw invalid("domain identity");
|
|
2112
|
+
const forward = raw.web_forwarding;
|
|
2113
|
+
if (forward === null || forward?.destination === null && forward.type === null) return [];
|
|
2114
|
+
if (!forward || typeof forward.destination !== "string" || forward.type !== "301" && forward.type !== "cloak")
|
|
2115
|
+
throw invalid("forwarding");
|
|
2116
|
+
return [
|
|
2117
|
+
{
|
|
2118
|
+
host: "@",
|
|
2119
|
+
url: forward.destination,
|
|
2120
|
+
type: forward.type === "301" ? "permanent" : "masked"
|
|
2121
|
+
}
|
|
2122
|
+
];
|
|
2123
|
+
}
|
|
2124
|
+
async setDomainForwarding(domainName, forwards, opts) {
|
|
2125
|
+
if (forwards.length > 1 || forwards.some((f) => f.host !== "@" || f.type !== "permanent"))
|
|
2126
|
+
throw new ConfigurationError(
|
|
2127
|
+
"101domain: only one permanent apex forwarding rule is supported"
|
|
2128
|
+
);
|
|
2129
|
+
if (forwards.length) {
|
|
2130
|
+
let url;
|
|
2131
|
+
try {
|
|
2132
|
+
url = new URL(forwards[0].url);
|
|
2133
|
+
} catch {
|
|
2134
|
+
throw new ConfigurationError("101domain: forwarding needs a valid HTTP(S) URL");
|
|
2135
|
+
}
|
|
2136
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password)
|
|
2137
|
+
throw new ConfigurationError("101domain: forwarding needs a valid HTTP(S) URL");
|
|
2138
|
+
}
|
|
2139
|
+
try {
|
|
2140
|
+
const existing = await this.getDomainForwarding(domainName, opts);
|
|
2141
|
+
const path = `${domainPath(domainName)}/forwarding`;
|
|
2142
|
+
if (!forwards.length) {
|
|
2143
|
+
if (existing.length) await this.request({ ...opts, method: "DELETE", path });
|
|
2144
|
+
} else if (existing[0]?.url !== forwards[0].url || existing[0]?.type !== "permanent") {
|
|
2145
|
+
await this.request({
|
|
2146
|
+
...opts,
|
|
2147
|
+
method: existing.length ? "PATCH" : "POST",
|
|
2148
|
+
path,
|
|
2149
|
+
body: { destination: forwards[0].url, type: "301" }
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2152
|
+
return {
|
|
2153
|
+
success: true,
|
|
2154
|
+
message: forwards.length ? "URL forwarding updated" : "URL forwarding cleared"
|
|
2155
|
+
};
|
|
2156
|
+
} catch (error) {
|
|
2157
|
+
return failed(error);
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
async request(req) {
|
|
2161
|
+
const raw = await this.http.request(req);
|
|
2162
|
+
if (!raw || typeof raw !== "object" || raw.status !== "success" || !("data" in raw)) {
|
|
2163
|
+
if (req.call?.intent === "write" && !REST_SAFE_METHODS.includes(req.method ?? "GET"))
|
|
2164
|
+
throw new OutcomeUnknownError(
|
|
2165
|
+
"101domain: invalid write confirmation. Re-read the domain before trying again."
|
|
2166
|
+
);
|
|
2167
|
+
throw invalid("response envelope");
|
|
2168
|
+
}
|
|
2169
|
+
return raw;
|
|
2170
|
+
}
|
|
2171
|
+
async rawRecords(domainName, opts) {
|
|
2172
|
+
const raw = (await this.request({ path: `${dnsPath(domainName)}/records`, ...opts })).data;
|
|
2173
|
+
if (!Array.isArray(raw) || raw.some(
|
|
2174
|
+
(r) => !r || typeof r.id !== "string" || !r.id || typeof r.name !== "string" || typeof r.value !== "string" || typeof r.type !== "string" || !Number.isInteger(r.ttl)
|
|
2175
|
+
))
|
|
2176
|
+
throw invalid("DNS records");
|
|
2177
|
+
if (new Set(raw.map((r) => r.id)).size !== raw.length) throw invalid("duplicate DNS ids");
|
|
2178
|
+
return raw;
|
|
2179
|
+
}
|
|
2180
|
+
};
|
|
2181
|
+
function invalid(part) {
|
|
2182
|
+
return new InvalidResponseError(`101domain: invalid ${part}`);
|
|
2183
|
+
}
|
|
2184
|
+
function failed(error) {
|
|
2185
|
+
return {
|
|
2186
|
+
success: false,
|
|
2187
|
+
message: toRegistrarError(error).message,
|
|
2188
|
+
...error instanceof OutcomeUnknownError ? { outcome: "unknown" } : {}
|
|
2189
|
+
};
|
|
2190
|
+
}
|
|
2191
|
+
function domainPath(name) {
|
|
2192
|
+
return `/domains/${encodeURIComponent(normalizeDomain(name))}`;
|
|
2193
|
+
}
|
|
2194
|
+
function dnsPath(name) {
|
|
2195
|
+
return `/dns/${encodeURIComponent(normalizeDomain(name))}`;
|
|
2196
|
+
}
|
|
2197
|
+
function chunks(items, size) {
|
|
2198
|
+
const result = [];
|
|
2199
|
+
for (let i = 0; i < items.length; i += size) result.push(items.slice(i, i + size));
|
|
2200
|
+
return result;
|
|
2201
|
+
}
|
|
2202
|
+
function oneYear(pricing) {
|
|
2203
|
+
if (pricing == null) return void 0;
|
|
2204
|
+
if (!Array.isArray(pricing)) throw invalid("pricing");
|
|
2205
|
+
return pricing.find((p) => p?.term_years === 1);
|
|
2206
|
+
}
|
|
2207
|
+
function amount(raw) {
|
|
2208
|
+
if (raw == null) return void 0;
|
|
2209
|
+
if (!/^\d+(?:\.\d+)?$/.test(raw)) throw invalid("price");
|
|
2210
|
+
const value = Number(raw);
|
|
2211
|
+
if (!Number.isFinite(value)) throw invalid("price");
|
|
2212
|
+
return value;
|
|
2213
|
+
}
|
|
2214
|
+
function toDomain(raw) {
|
|
2215
|
+
if (!raw || typeof raw.domain_name !== "string" || !raw.domain_name.trim())
|
|
2216
|
+
throw invalid("domain");
|
|
2217
|
+
return createDomain({
|
|
2218
|
+
domainName: normalizeDomain(raw.domain_name),
|
|
2219
|
+
registrar: "101domain",
|
|
2220
|
+
status: raw.status,
|
|
2221
|
+
createdDate: raw.registered_at,
|
|
2222
|
+
expirationDate: raw.expires_at,
|
|
2223
|
+
autoRenew: raw.auto_renew,
|
|
2224
|
+
locked: raw.registry_statuses?.some((s) => /^clientTransferProhibited$/i.test(s)),
|
|
2225
|
+
nameservers: raw.nameservers,
|
|
2226
|
+
deleted: !isHeld(raw)
|
|
2227
|
+
});
|
|
2228
|
+
}
|
|
2229
|
+
var GONE = /* @__PURE__ */ new Set(["DELETED", "CANCELLED", "DENIED", "XFER_AWAY"]);
|
|
2230
|
+
function isHeld(raw) {
|
|
2231
|
+
const status = raw.status?.toUpperCase() ?? "";
|
|
2232
|
+
return !GONE.has(status) && !status.startsWith("XFER_IN_") && raw.registered_at != null;
|
|
2233
|
+
}
|
|
2234
|
+
function fromRecord(raw) {
|
|
2235
|
+
const common = { name: raw.name || "@", type: raw.type, ttl: raw.ttl };
|
|
2236
|
+
if (raw.type === "MX") {
|
|
2237
|
+
const match = /^(\d+)\s+(.+)$/.exec(raw.value);
|
|
2238
|
+
if (!match) throw invalid("MX record");
|
|
2239
|
+
return { ...common, value: match[2], priority: Number(match[1]) };
|
|
2240
|
+
}
|
|
2241
|
+
if (raw.type === "SRV") {
|
|
2242
|
+
const match = /^(\d+)\s+(\d+)\s+(\d+)\s+(.+)$/.exec(raw.value);
|
|
2243
|
+
if (!match) throw invalid("SRV record");
|
|
2244
|
+
return {
|
|
2245
|
+
...common,
|
|
2246
|
+
value: match[4],
|
|
2247
|
+
priority: Number(match[1]),
|
|
2248
|
+
weight: Number(match[2]),
|
|
2249
|
+
port: Number(match[3])
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
return { ...common, value: raw.value };
|
|
2253
|
+
}
|
|
2254
|
+
function recordSpec(record, domain, strict = true) {
|
|
2255
|
+
const type = record.type.toUpperCase();
|
|
2256
|
+
const zone = normalizeDomain(domain);
|
|
2257
|
+
let name = record.name.trim().toLowerCase().replace(/\.$/, "");
|
|
2258
|
+
if (name === zone || name === "@") name = "";
|
|
2259
|
+
else if (name.endsWith("." + zone)) name = name.slice(0, -zone.length - 1);
|
|
2260
|
+
const reject = (message) => {
|
|
2261
|
+
if (strict) throw new ConfigurationError(`101domain: ${message}`);
|
|
2262
|
+
};
|
|
2263
|
+
if (!["A", "AAAA", "CNAME", "NS", "MX", "TXT", "SRV", "CAA"].includes(type) || type === "NS" && !name)
|
|
2264
|
+
reject("unsupported DNS type or apex NS record");
|
|
2265
|
+
const ttl = record.ttl ?? 3600;
|
|
2266
|
+
if (!Number.isInteger(ttl) || ttl !== 1 && ttl < 300)
|
|
2267
|
+
reject("DNS TTL must be at least 300 seconds");
|
|
2268
|
+
const result = { name, type, ttl };
|
|
2269
|
+
if (type === "MX" || type === "SRV") {
|
|
2270
|
+
if (!Number.isInteger(record.priority) || record.priority < 0 || record.priority > 65535)
|
|
2271
|
+
reject("MX/SRV priority is required");
|
|
2272
|
+
result.priority = record.priority;
|
|
2273
|
+
result.target = record.value;
|
|
2274
|
+
if (type === "SRV") {
|
|
2275
|
+
if (![record.weight, record.port].every((n) => Number.isInteger(n) && n >= 0 && n <= 65535))
|
|
2276
|
+
reject("SRV weight and port are required");
|
|
2277
|
+
result.weight = record.weight;
|
|
2278
|
+
result.port = record.port;
|
|
2279
|
+
}
|
|
2280
|
+
} else if (type === "CAA") {
|
|
2281
|
+
const match = /^(\d+)\s+(\w+)\s+"([\s\S]*)"$/.exec(record.value);
|
|
2282
|
+
if (!match || Number(match[1]) > 255) {
|
|
2283
|
+
reject("CAA needs flags, tag and quoted value");
|
|
2284
|
+
result.value = record.value;
|
|
2285
|
+
} else {
|
|
2286
|
+
result.flag = Number(match[1]);
|
|
2287
|
+
result.tag = match[2];
|
|
2288
|
+
result.value = match[3];
|
|
2289
|
+
}
|
|
2290
|
+
} else result.value = record.value;
|
|
2291
|
+
return result;
|
|
2292
|
+
}
|
|
2293
|
+
function recordSignature(record) {
|
|
2294
|
+
return JSON.stringify(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
|
|
2295
|
+
}
|
|
2296
|
+
|
|
1763
2297
|
// src/registrars/dynadot.ts
|
|
1764
2298
|
var DYNADOT_DEFAULT_NS = ["ns1.dynadot.com", "ns2.dynadot.com"];
|
|
1765
2299
|
var SEARCH_BATCH_SIZE = 100;
|
|
@@ -1798,7 +2332,10 @@ var DynadotRegistrar = class extends BaseRegistrar {
|
|
|
1798
2332
|
production: "https://api.dynadot.com",
|
|
1799
2333
|
sandbox: "https://api-sandbox.dynadot.com"
|
|
1800
2334
|
}),
|
|
1801
|
-
headers: { Authorization: `Bearer ${credentials.apiKey}` }
|
|
2335
|
+
headers: { Authorization: `Bearer ${credentials.apiKey}` },
|
|
2336
|
+
// HTTP 429 can omit Retry-After. Avoid exhausting all attempts inside
|
|
2337
|
+
// Dynadot's regular-tier minute window in that case.
|
|
2338
|
+
rateLimitFallbackSeconds: 60
|
|
1802
2339
|
},
|
|
1803
2340
|
options
|
|
1804
2341
|
);
|
|
@@ -2434,12 +2971,12 @@ function isPrivacyOn(privacy) {
|
|
|
2434
2971
|
}
|
|
2435
2972
|
function oneYearPrice(prices) {
|
|
2436
2973
|
if (!prices?.length) return void 0;
|
|
2437
|
-
const
|
|
2974
|
+
const oneYear2 = prices.find((p) => /\b1\s*year\b/i.test(p.unit ?? "")) ?? prices[0];
|
|
2438
2975
|
return {
|
|
2439
|
-
currency:
|
|
2440
|
-
registration: toNumber(
|
|
2441
|
-
renewal: toNumber(
|
|
2442
|
-
transfer: toNumber(
|
|
2976
|
+
currency: oneYear2.currency,
|
|
2977
|
+
registration: toNumber(oneYear2.registration_price),
|
|
2978
|
+
renewal: toNumber(oneYear2.renewal_price),
|
|
2979
|
+
transfer: toNumber(oneYear2.transfer_price)
|
|
2443
2980
|
};
|
|
2444
2981
|
}
|
|
2445
2982
|
function extractNameservers(glue) {
|
|
@@ -2729,8 +3266,8 @@ var GandiRegistrar = class extends BaseRegistrar {
|
|
|
2729
3266
|
available: status.startsWith("available"),
|
|
2730
3267
|
premium: status.includes("premium") || price2?.type === "premium"
|
|
2731
3268
|
};
|
|
2732
|
-
const
|
|
2733
|
-
if (
|
|
3269
|
+
const amount2 = pickPrice(price2);
|
|
3270
|
+
if (amount2 != null) result.price = amount2;
|
|
2734
3271
|
if (resp.currency) result.currency = resp.currency;
|
|
2735
3272
|
if (price2?.duration_unit === "y" && price2.min_duration != null) {
|
|
2736
3273
|
result.period = price2.min_duration;
|
|
@@ -4739,9 +5276,10 @@ var NamecheapRegistrar = class extends BaseRegistrar {
|
|
|
4739
5276
|
}
|
|
4740
5277
|
/**
|
|
4741
5278
|
* Availability via domains.check (batched at 50 per request, Namecheap's cap).
|
|
4742
|
-
* The check response only carries
|
|
4743
|
-
* (`PremiumRegistrationPrice`); regular
|
|
4744
|
-
* `getPricing`, so `price`
|
|
5279
|
+
* The check response only carries prices for *premium* names
|
|
5280
|
+
* (`PremiumRegistrationPrice`, `PremiumRenewalPrice`); regular pricing comes
|
|
5281
|
+
* from `getPricing`, so `price` and `renewalPrice` are set only for premium
|
|
5282
|
+
* results.
|
|
4745
5283
|
*/
|
|
4746
5284
|
async checkAvailability(domainNames, opts) {
|
|
4747
5285
|
const results = [];
|
|
@@ -4754,12 +5292,16 @@ var NamecheapRegistrar = class extends BaseRegistrar {
|
|
|
4754
5292
|
);
|
|
4755
5293
|
for (const el of ensureArray(cr.DomainCheckResult)) {
|
|
4756
5294
|
const premium = el["@_IsPremiumName"] === "true";
|
|
4757
|
-
const premiumPrice =
|
|
5295
|
+
const premiumPrice = (attr) => {
|
|
5296
|
+
const n = premium ? Number(attr) : NaN;
|
|
5297
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
5298
|
+
};
|
|
4758
5299
|
results.push({
|
|
4759
5300
|
domainName: el["@_Domain"] ?? "",
|
|
4760
5301
|
available: el["@_Available"] === "true",
|
|
4761
5302
|
premium,
|
|
4762
|
-
price:
|
|
5303
|
+
price: premiumPrice(el["@_PremiumRegistrationPrice"]),
|
|
5304
|
+
renewalPrice: premiumPrice(el["@_PremiumRenewalPrice"])
|
|
4763
5305
|
});
|
|
4764
5306
|
}
|
|
4765
5307
|
}
|
|
@@ -5167,12 +5709,11 @@ var NamecomHttpClient = class extends HttpClient {
|
|
|
5167
5709
|
}),
|
|
5168
5710
|
url
|
|
5169
5711
|
);
|
|
5170
|
-
if (error instanceof RateLimitError) {
|
|
5171
|
-
const
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
error.retryAfter = Number.isFinite(seconds) ? Math.max(0, seconds) : Number.isFinite(date) ? Math.max(0, (date - Date.now()) / 1e3) : reset != null && Number.isFinite(Number(reset)) ? Math.max(0, Number(reset) - Date.now() / 1e3) : void 0;
|
|
5712
|
+
if (error instanceof RateLimitError && error.retryAfter === void 0) {
|
|
5713
|
+
const reset = response.headers.get("x-ratelimit-reset")?.trim();
|
|
5714
|
+
if (reset && /^\d+(?:\.\d+)?$/.test(reset)) {
|
|
5715
|
+
error.retryAfter = Math.max(0, Math.ceil(Number(reset) - Date.now() / 1e3));
|
|
5716
|
+
}
|
|
5176
5717
|
}
|
|
5177
5718
|
return error;
|
|
5178
5719
|
}
|
|
@@ -5239,7 +5780,7 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5239
5780
|
}
|
|
5240
5781
|
async getAuthCode(domainName, opts) {
|
|
5241
5782
|
const result = await this.http.request({
|
|
5242
|
-
path: `${
|
|
5783
|
+
path: `${domainPath2(domainName)}:getAuthCode`,
|
|
5243
5784
|
...opts
|
|
5244
5785
|
});
|
|
5245
5786
|
if (!result?.authCode) throw new InvalidResponseError("namecom: missing authorization code");
|
|
@@ -5334,7 +5875,7 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5334
5875
|
validYears(years);
|
|
5335
5876
|
const pricing = await this.domainPricing(domainName, years, opts);
|
|
5336
5877
|
return this.purchase(
|
|
5337
|
-
`${
|
|
5878
|
+
`${domainPath2(domainName)}:renew`,
|
|
5338
5879
|
{
|
|
5339
5880
|
years,
|
|
5340
5881
|
purchasePrice: purchaseQuote(pricing, "renewalPrice")
|
|
@@ -5379,7 +5920,7 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5379
5920
|
}
|
|
5380
5921
|
updateNameservers(domainName, nameservers, opts) {
|
|
5381
5922
|
return this.mutate(
|
|
5382
|
-
{ method: "POST", path: `${
|
|
5923
|
+
{ method: "POST", path: `${domainPath2(domainName)}:setNameservers`, body: { nameservers } },
|
|
5383
5924
|
opts
|
|
5384
5925
|
);
|
|
5385
5926
|
}
|
|
@@ -5410,14 +5951,14 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5410
5951
|
return this.mutate(
|
|
5411
5952
|
{
|
|
5412
5953
|
method: "POST",
|
|
5413
|
-
path: `${
|
|
5954
|
+
path: `${domainPath2(domainName)}:setContacts`,
|
|
5414
5955
|
body: { contacts: toContacts(contacts) }
|
|
5415
5956
|
},
|
|
5416
5957
|
opts
|
|
5417
5958
|
);
|
|
5418
5959
|
}
|
|
5419
5960
|
async getDnsRecords(domainName, opts) {
|
|
5420
|
-
return (await this.pages(`${
|
|
5961
|
+
return (await this.pages(`${domainPath2(domainName)}/records`, "records", opts)).map(fromRecord2);
|
|
5421
5962
|
}
|
|
5422
5963
|
// No bulk replace endpoint. Reconcile by id: preserve identical records, update
|
|
5423
5964
|
// existing type/host pairs, create additions, then delete stale records. This
|
|
@@ -5425,7 +5966,7 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5425
5966
|
async setDnsRecords(domainName, records, opts) {
|
|
5426
5967
|
const desired = records.map(toRecord).filter((record, index, all) => all.findIndex((other) => sameRecord(other, record)) === index);
|
|
5427
5968
|
try {
|
|
5428
|
-
const path = `${
|
|
5969
|
+
const path = `${domainPath2(domainName)}/records`;
|
|
5429
5970
|
const existing = await this.pages(path, "records", opts);
|
|
5430
5971
|
if (existing.some((r) => !Number.isInteger(r.id) || r.id <= 0))
|
|
5431
5972
|
throw new InvalidResponseError("namecom: DNS response missing record ids");
|
|
@@ -5462,14 +6003,14 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5462
6003
|
}
|
|
5463
6004
|
}
|
|
5464
6005
|
patchDomain(domainName, body, opts) {
|
|
5465
|
-
return this.mutate({ method: "PATCH", path:
|
|
6006
|
+
return this.mutate({ method: "PATCH", path: domainPath2(domainName), body }, opts);
|
|
5466
6007
|
}
|
|
5467
6008
|
rawDomain(domainName, opts) {
|
|
5468
|
-
return this.http.request({ path:
|
|
6009
|
+
return this.http.request({ path: domainPath2(domainName), ...opts });
|
|
5469
6010
|
}
|
|
5470
6011
|
domainPricing(domainName, years, opts) {
|
|
5471
6012
|
return this.http.request({
|
|
5472
|
-
path: `${
|
|
6013
|
+
path: `${domainPath2(domainName)}:getPricing`,
|
|
5473
6014
|
query: { years },
|
|
5474
6015
|
...opts
|
|
5475
6016
|
});
|
|
@@ -5585,7 +6126,7 @@ function toContacts(contacts) {
|
|
|
5585
6126
|
throw new ConfigurationError("namecom: at least one contact is required");
|
|
5586
6127
|
return result;
|
|
5587
6128
|
}
|
|
5588
|
-
function
|
|
6129
|
+
function domainPath2(domainName) {
|
|
5589
6130
|
return `/domains/${encodeURIComponent(normalizeDomain(domainName))}`;
|
|
5590
6131
|
}
|
|
5591
6132
|
function validYears(years) {
|
|
@@ -5625,7 +6166,7 @@ function toRecord(r) {
|
|
|
5625
6166
|
...["MX", "SRV"].includes(type) ? { priority: r.priority ?? 0 } : {}
|
|
5626
6167
|
};
|
|
5627
6168
|
}
|
|
5628
|
-
function
|
|
6169
|
+
function fromRecord2(r) {
|
|
5629
6170
|
const type = r.type.toUpperCase();
|
|
5630
6171
|
const record = { type, name: r.host || "@", value: r.answer, ttl: r.ttl };
|
|
5631
6172
|
if (type === "MX" || type === "SRV") record.priority = r.priority ?? 0;
|
|
@@ -7446,22 +7987,23 @@ function toSpaceshipContact(c) {
|
|
|
7446
7987
|
|
|
7447
7988
|
// src/registrars/index.ts
|
|
7448
7989
|
var registrars = {
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7990
|
+
"101domain": Domain101Registrar,
|
|
7991
|
+
"cloudflare": CloudflareRegistrar,
|
|
7992
|
+
"dynadot": DynadotRegistrar,
|
|
7993
|
+
"gandi": GandiRegistrar,
|
|
7994
|
+
"godaddy": GoDaddyRegistrar,
|
|
7995
|
+
"namebright": NameBrightRegistrar,
|
|
7996
|
+
"namecheap": NamecheapRegistrar,
|
|
7997
|
+
"namecom": NamecomRegistrar,
|
|
7998
|
+
"namesilo": NameSiloRegistrar,
|
|
7999
|
+
"porkbun": PorkbunRegistrar,
|
|
8000
|
+
"spaceship": SpaceshipRegistrar
|
|
7459
8001
|
};
|
|
7460
8002
|
function createRegistrar(name, credentials, options) {
|
|
7461
8003
|
const RegistrarClass = registrars[name];
|
|
7462
8004
|
return new RegistrarClass(credentials, options);
|
|
7463
8005
|
}
|
|
7464
8006
|
|
|
7465
|
-
export { ALL_FEATURES, AbortError, AuthenticationError, AuthorizationError, BaseRegistrar, CORE_FEATURES, CloudflareRegistrar, ConfigurationError, ConnectionError, ConsentRequiredError, DEFAULT_OPTIONS, DynadotRegistrar, EXTENDED_FEATURES, FEATURE_CALLS, Feature, GandiRegistrar, GoDaddyRegistrar, HttpClient, InvalidResponseError, MASKED_FORWARD_UNSUPPORTED, NameBrightRegistrar, NameSiloRegistrar, NamecheapRegistrar, NamecomRegistrar, NotFoundError, NotImplementedError, OutcomeUnknownError, ParsingError, PorkbunRegistrar, REST_SAFE_METHODS, RateLimitError, RegistrarClient, RegistrarError, RetryableRegistrarError, SpaceshipRegistrar, TimeoutError, USER_AGENT, asRead, backoffDelay, createDomain, createRegistrar, ensureArray, filterDomains, isCoreFeature, listPortfolio, markNotSent, normalizeDomain, normalizeNameservers, parseDate, parseXml, registrars, requireConsent, selectBaseUrl, settableForwards, sleep, toRegistrarError, wasNotSent };
|
|
8007
|
+
export { ALL_FEATURES, AbortError, AuthenticationError, AuthorizationError, BaseRegistrar, CORE_FEATURES, CloudflareRegistrar, ConfigurationError, ConnectionError, ConsentRequiredError, DEFAULT_OPTIONS, Domain101Registrar, DynadotRegistrar, EXTENDED_FEATURES, FEATURE_CALLS, Feature, GandiRegistrar, GoDaddyRegistrar, HttpClient, InvalidResponseError, MASKED_FORWARD_UNSUPPORTED, NameBrightRegistrar, NameSiloRegistrar, NamecheapRegistrar, NamecomRegistrar, NotFoundError, NotImplementedError, OutcomeUnknownError, ParsingError, PorkbunRegistrar, REST_SAFE_METHODS, RateLimitError, RegistrarClient, RegistrarError, RetryableRegistrarError, SpaceshipRegistrar, TimeoutError, USER_AGENT, asRead, backoffDelay, createDomain, createRegistrar, ensureArray, filterDomains, isCoreFeature, listPortfolio, markNotSent, normalizeDomain, normalizeNameservers, parseDate, parseXml, registrars, requireConsent, selectBaseUrl, settableForwards, sleep, toRegistrarError, wasNotSent };
|
|
7466
8008
|
//# sourceMappingURL=index.js.map
|
|
7467
8009
|
//# sourceMappingURL=index.js.map
|