@aoxborrow/registrar-client 0.6.0 → 0.7.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 +64 -5
- package/dist/index.cjs +207 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -3
- package/dist/index.d.ts +46 -3
- package/dist/index.js +202 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/errors.ts +69 -1
- package/src/features.ts +42 -0
- package/src/http.ts +76 -5
- package/src/index.ts +9 -2
- package/src/registrar.ts +47 -2
- package/src/registrars/cloudflare.ts +3 -0
- package/src/registrars/dynadot.ts +3 -0
- package/src/registrars/gandi.ts +3 -0
- package/src/registrars/godaddy.ts +3 -0
- package/src/registrars/namebright.ts +6 -2
- package/src/registrars/namecheap.ts +6 -1
- package/src/registrars/namecom.ts +10 -6
- package/src/registrars/namesilo.ts +4 -4
- package/src/registrars/porkbun.ts +3 -3
- package/src/registrars/spaceship.ts +3 -0
- package/src/types.ts +30 -1
- package/src/utils.ts +16 -1
package/dist/index.js
CHANGED
|
@@ -55,11 +55,61 @@ var TimeoutError = class extends RetryableRegistrarError {
|
|
|
55
55
|
var ConnectionError = class extends RetryableRegistrarError {
|
|
56
56
|
status = 503;
|
|
57
57
|
// Service Unavailable
|
|
58
|
-
|
|
58
|
+
// true when the failure is known to have happened before the request left:
|
|
59
|
+
// DNS, connection refused, TLS handshake, or a proxy that never opened its
|
|
60
|
+
// tunnel. The registrar cannot have acted on it, so it is safe to re-send
|
|
61
|
+
// even for a write.
|
|
62
|
+
notSent;
|
|
63
|
+
constructor(message, details = {}) {
|
|
59
64
|
super(message);
|
|
60
65
|
this.name = "ConnectionError";
|
|
66
|
+
this.notSent = details.notSent ?? false;
|
|
61
67
|
}
|
|
62
68
|
};
|
|
69
|
+
var OutcomeUnknownError = class extends RegistrarError {
|
|
70
|
+
status = 504;
|
|
71
|
+
// Gateway Timeout
|
|
72
|
+
feature;
|
|
73
|
+
cause;
|
|
74
|
+
constructor(message, details = {}) {
|
|
75
|
+
super(message);
|
|
76
|
+
this.name = "OutcomeUnknownError";
|
|
77
|
+
this.feature = details.feature;
|
|
78
|
+
this.cause = details.cause;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var NOT_SENT = /* @__PURE__ */ Symbol.for("registrar-client.notSent");
|
|
82
|
+
function markNotSent(error) {
|
|
83
|
+
if (typeof error === "object" && error !== null) {
|
|
84
|
+
Object.defineProperty(error, NOT_SENT, { value: true, enumerable: false });
|
|
85
|
+
}
|
|
86
|
+
return error;
|
|
87
|
+
}
|
|
88
|
+
var PRE_SEND_CODES = /* @__PURE__ */ new Set([
|
|
89
|
+
"ENOTFOUND",
|
|
90
|
+
"EAI_AGAIN",
|
|
91
|
+
"ECONNREFUSED",
|
|
92
|
+
"EHOSTUNREACH",
|
|
93
|
+
"ENETUNREACH",
|
|
94
|
+
"EADDRNOTAVAIL",
|
|
95
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
96
|
+
"CERT_HAS_EXPIRED",
|
|
97
|
+
"CERT_NOT_YET_VALID",
|
|
98
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
99
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
100
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
101
|
+
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
|
|
102
|
+
"ERR_TLS_CERT_ALTNAME_INVALID"
|
|
103
|
+
]);
|
|
104
|
+
function wasNotSent(error) {
|
|
105
|
+
for (let e = error, depth = 0; e && typeof e === "object" && depth < 5; depth++) {
|
|
106
|
+
if (e[NOT_SENT] === true) return true;
|
|
107
|
+
const code = e.code;
|
|
108
|
+
if (typeof code === "string" && PRE_SEND_CODES.has(code)) return true;
|
|
109
|
+
e = e.cause;
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
63
113
|
var AuthenticationError = class extends RegistrarError {
|
|
64
114
|
status = 401;
|
|
65
115
|
// Unauthorized
|
|
@@ -226,6 +276,9 @@ function createDomain(data = {}) {
|
|
|
226
276
|
deleted: data.deleted ?? false
|
|
227
277
|
};
|
|
228
278
|
}
|
|
279
|
+
function asRead(opts) {
|
|
280
|
+
return { ...opts, call: { ...opts?.call, intent: "read" } };
|
|
281
|
+
}
|
|
229
282
|
|
|
230
283
|
// src/client.ts
|
|
231
284
|
var RegistrarClient = class {
|
|
@@ -376,6 +429,7 @@ var DEFAULT_OPTIONS = {
|
|
|
376
429
|
var USER_AGENT = "@aoxborrow/registrar-client";
|
|
377
430
|
|
|
378
431
|
// src/http.ts
|
|
432
|
+
var REST_SAFE_METHODS = ["GET", "HEAD"];
|
|
379
433
|
var HttpClient = class {
|
|
380
434
|
constructor(config) {
|
|
381
435
|
this.config = config;
|
|
@@ -399,7 +453,20 @@ var HttpClient = class {
|
|
|
399
453
|
async requestText(req) {
|
|
400
454
|
return this.withRetries(req, () => this.send(req));
|
|
401
455
|
}
|
|
402
|
-
//
|
|
456
|
+
// Shared retry-with-backoff wrapper around a single-attempt operation.
|
|
457
|
+
//
|
|
458
|
+
// What may be re-sent depends on where the failure happened and on whether
|
|
459
|
+
// the call reads or writes:
|
|
460
|
+
//
|
|
461
|
+
// failure read write
|
|
462
|
+
// never sent (DNS, refused, TLS, proxy stage) retry retry
|
|
463
|
+
// 429 retry retry
|
|
464
|
+
// unknown (timeout, dropped mid-response, 5xx) retry OutcomeUnknownError
|
|
465
|
+
// any other response fail fail
|
|
466
|
+
//
|
|
467
|
+
// A write whose outcome is unknown may have been applied, so it is never
|
|
468
|
+
// re-sent: a second renewal charges twice, a second record-create leaves a
|
|
469
|
+
// duplicate. The caller re-reads the domain instead.
|
|
403
470
|
async withRetries(req, attemptFn) {
|
|
404
471
|
const retries = req.retries ?? this.config.options.retries;
|
|
405
472
|
const backoff = req.backoff ?? this.config.options.backoff;
|
|
@@ -409,6 +476,14 @@ var HttpClient = class {
|
|
|
409
476
|
return await attemptFn();
|
|
410
477
|
} catch (error) {
|
|
411
478
|
lastError = toRegistrarError(error);
|
|
479
|
+
if (this.intentOf(req) === "write" && isOutcomeUnknown(lastError)) {
|
|
480
|
+
const unknown = new OutcomeUnknownError(
|
|
481
|
+
`The registrar did not confirm this change, so it may or may not have been applied. Check the domain before trying again. (${lastError.message})`,
|
|
482
|
+
{ feature: req.call?.feature, cause: lastError }
|
|
483
|
+
);
|
|
484
|
+
if (req.call) req.call.outcomeUnknown = unknown;
|
|
485
|
+
throw unknown;
|
|
486
|
+
}
|
|
412
487
|
if (attempt >= retries || !lastError.shouldRetry()) {
|
|
413
488
|
throw lastError;
|
|
414
489
|
}
|
|
@@ -418,6 +493,14 @@ var HttpClient = class {
|
|
|
418
493
|
}
|
|
419
494
|
throw lastError ?? new RegistrarError("Request failed");
|
|
420
495
|
}
|
|
496
|
+
// Whether a request only reads. A method the API reserves for reads wins;
|
|
497
|
+
// otherwise it is whatever the feature being served is, and a request that
|
|
498
|
+
// says nothing is assumed to write.
|
|
499
|
+
intentOf(req) {
|
|
500
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
501
|
+
if (this.config.safeMethods?.includes(method)) return "read";
|
|
502
|
+
return req.call?.intent ?? "write";
|
|
503
|
+
}
|
|
421
504
|
// build the full URL for a request, applying query parameters
|
|
422
505
|
buildUrl(req) {
|
|
423
506
|
let base;
|
|
@@ -460,7 +543,8 @@ var HttpClient = class {
|
|
|
460
543
|
try {
|
|
461
544
|
let response;
|
|
462
545
|
try {
|
|
463
|
-
|
|
546
|
+
const doFetch = req.fetch ?? this.config.options.fetch ?? fetch;
|
|
547
|
+
response = await doFetch(url, {
|
|
464
548
|
method: req.method ?? "GET",
|
|
465
549
|
headers,
|
|
466
550
|
body: req.body !== void 0 ? JSON.stringify(req.body) : void 0,
|
|
@@ -471,7 +555,9 @@ var HttpClient = class {
|
|
|
471
555
|
if (externalSignal?.aborted) throw new AbortError("Request was aborted");
|
|
472
556
|
throw new TimeoutError(`Request to '${url}' timed out after ${timeout}ms`);
|
|
473
557
|
}
|
|
474
|
-
throw new ConnectionError(`Failed to reach '${url}': ${errorMessage(error)}
|
|
558
|
+
throw new ConnectionError(`Failed to reach '${url}': ${errorMessage(error)}`, {
|
|
559
|
+
notSent: wasNotSent(error)
|
|
560
|
+
});
|
|
475
561
|
}
|
|
476
562
|
if (!response.ok) {
|
|
477
563
|
throw await this.toStatusError(response, url);
|
|
@@ -479,7 +565,17 @@ var HttpClient = class {
|
|
|
479
565
|
if (response.status === 204) {
|
|
480
566
|
return "";
|
|
481
567
|
}
|
|
482
|
-
|
|
568
|
+
try {
|
|
569
|
+
return await response.text();
|
|
570
|
+
} catch (error) {
|
|
571
|
+
if (isAbortError(error)) {
|
|
572
|
+
if (externalSignal?.aborted) throw new AbortError("Request was aborted");
|
|
573
|
+
throw new TimeoutError(`Response from '${url}' timed out after ${timeout}ms`);
|
|
574
|
+
}
|
|
575
|
+
throw new ConnectionError(
|
|
576
|
+
`Connection to '${url}' was lost while reading the response: ${errorMessage(error)}`
|
|
577
|
+
);
|
|
578
|
+
}
|
|
483
579
|
} finally {
|
|
484
580
|
clearTimeout(timeoutId);
|
|
485
581
|
externalSignal?.removeEventListener("abort", onAbort);
|
|
@@ -515,6 +611,10 @@ var HttpClient = class {
|
|
|
515
611
|
}
|
|
516
612
|
}
|
|
517
613
|
};
|
|
614
|
+
function isOutcomeUnknown(error) {
|
|
615
|
+
if (error instanceof TimeoutError || error instanceof InvalidResponseError) return true;
|
|
616
|
+
return error instanceof ConnectionError && !error.notSent;
|
|
617
|
+
}
|
|
518
618
|
function isAbortError(error) {
|
|
519
619
|
return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
|
|
520
620
|
}
|
|
@@ -611,6 +711,33 @@ var CORE_FEATURE_SET = new Set(CORE_FEATURES);
|
|
|
611
711
|
function isCoreFeature(feature) {
|
|
612
712
|
return CORE_FEATURE_SET.has(feature);
|
|
613
713
|
}
|
|
714
|
+
var FEATURE_CALLS = {
|
|
715
|
+
testConnection: { intent: "read", optsIndex: 0 },
|
|
716
|
+
listDomains: { intent: "read", optsIndex: 0 },
|
|
717
|
+
getDomain: { intent: "read", optsIndex: 1 },
|
|
718
|
+
checkAvailability: { intent: "read", optsIndex: 1 },
|
|
719
|
+
getPricing: { intent: "read", optsIndex: 1 },
|
|
720
|
+
registerDomain: { intent: "write", optsIndex: 2 },
|
|
721
|
+
renewDomain: { intent: "write", optsIndex: 2 },
|
|
722
|
+
setAutoRenew: { intent: "write", optsIndex: 2 },
|
|
723
|
+
transferIn: { intent: "write", optsIndex: 2 },
|
|
724
|
+
updateNameservers: { intent: "write", optsIndex: 2 },
|
|
725
|
+
getNameservers: { intent: "read", optsIndex: 1 },
|
|
726
|
+
lockDomain: { intent: "write", optsIndex: 1 },
|
|
727
|
+
unlockDomain: { intent: "write", optsIndex: 1 },
|
|
728
|
+
setPrivacy: { intent: "write", optsIndex: 2 },
|
|
729
|
+
getContacts: { intent: "read", optsIndex: 1 },
|
|
730
|
+
updateContacts: { intent: "write", optsIndex: 2 },
|
|
731
|
+
getDnsRecords: { intent: "read", optsIndex: 1 },
|
|
732
|
+
setDnsRecords: { intent: "write", optsIndex: 2 },
|
|
733
|
+
getAuthCode: { intent: "write", optsIndex: 1 },
|
|
734
|
+
getDnssec: { intent: "read", optsIndex: 1 },
|
|
735
|
+
disableDnssec: { intent: "write", optsIndex: 1 },
|
|
736
|
+
getEmailForwarding: { intent: "read", optsIndex: 1 },
|
|
737
|
+
setEmailForwarding: { intent: "write", optsIndex: 2 },
|
|
738
|
+
getDomainForwarding: { intent: "read", optsIndex: 1 },
|
|
739
|
+
setDomainForwarding: { intent: "write", optsIndex: 2 }
|
|
740
|
+
};
|
|
614
741
|
|
|
615
742
|
// src/registrar.ts
|
|
616
743
|
function selectBaseUrl(registrar, environment, urls) {
|
|
@@ -636,6 +763,9 @@ var BaseRegistrar = class {
|
|
|
636
763
|
static get features() {
|
|
637
764
|
return [...CORE_FEATURES, ...this.extendedFeatures];
|
|
638
765
|
}
|
|
766
|
+
// HTTP methods this provider's API reserves for reads; see
|
|
767
|
+
// `HttpClientConfig.safeMethods`. REST providers set `REST_SAFE_METHODS`.
|
|
768
|
+
static safeMethods = [];
|
|
639
769
|
// instance mirror of the static `features`
|
|
640
770
|
get features() {
|
|
641
771
|
return this.constructor.features;
|
|
@@ -654,7 +784,39 @@ var BaseRegistrar = class {
|
|
|
654
784
|
this.credentials = credentials;
|
|
655
785
|
this.environment = environment;
|
|
656
786
|
this.options = { ...DEFAULT_OPTIONS, ...clientOptions };
|
|
657
|
-
this.http = new HttpClient({
|
|
787
|
+
this.http = new HttpClient({
|
|
788
|
+
safeMethods: this.constructor.safeMethods,
|
|
789
|
+
...httpConfig,
|
|
790
|
+
options: this.options
|
|
791
|
+
});
|
|
792
|
+
this.threadFeatureCalls();
|
|
793
|
+
}
|
|
794
|
+
// Wrap each feature method so its `RequestOptions` carry a `FeatureCall`:
|
|
795
|
+
// the read/write intent the HTTP layer needs to decide what may be re-sent,
|
|
796
|
+
// and a slot where it reports a write whose outcome is unknown. Providers
|
|
797
|
+
// already forward their options into every request, so nothing else changes.
|
|
798
|
+
//
|
|
799
|
+
// A feature calling another feature (a write re-reading the domain, say)
|
|
800
|
+
// goes through that feature's own wrapper, so the inner read is still a read.
|
|
801
|
+
// Providers fold most failures into an `OperationResult`; the unknown outcome
|
|
802
|
+
// is copied onto that result so it is not lost along with the error.
|
|
803
|
+
threadFeatureCalls() {
|
|
804
|
+
const self = this;
|
|
805
|
+
for (const [feature, { intent, optsIndex }] of Object.entries(FEATURE_CALLS)) {
|
|
806
|
+
const original = self[feature];
|
|
807
|
+
if (typeof original !== "function") continue;
|
|
808
|
+
self[feature] = (...args) => {
|
|
809
|
+
const call = { intent, feature };
|
|
810
|
+
const next = [...args];
|
|
811
|
+
while (next.length <= optsIndex) next.push(void 0);
|
|
812
|
+
next[optsIndex] = { ...next[optsIndex], call };
|
|
813
|
+
const result = original.apply(this, next);
|
|
814
|
+
if (!(result instanceof Promise)) return result;
|
|
815
|
+
return result.then(
|
|
816
|
+
(value) => call.outcomeUnknown && value !== null && typeof value === "object" && value.success === false ? { ...value, outcome: "unknown" } : value
|
|
817
|
+
);
|
|
818
|
+
};
|
|
819
|
+
}
|
|
658
820
|
}
|
|
659
821
|
testConnection(_opts) {
|
|
660
822
|
return Promise.reject(
|
|
@@ -745,6 +907,8 @@ var BaseRegistrar = class {
|
|
|
745
907
|
// src/registrars/cloudflare.ts
|
|
746
908
|
var CloudflareRegistrar = class _CloudflareRegistrar extends BaseRegistrar {
|
|
747
909
|
name = "cloudflare";
|
|
910
|
+
// a REST API: GET and HEAD never change state
|
|
911
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
748
912
|
static displayName = "Cloudflare";
|
|
749
913
|
static website = "cloudflare.com";
|
|
750
914
|
static helpText = 'Create an API token in your Cloudflare dashboard under My Profile > API Tokens. The token needs "Account.Registrar" read/write permissions. Find your Account ID in the URL or on the Overview page of any zone.';
|
|
@@ -1602,6 +1766,8 @@ var SEARCH_BATCH_SIZE = 100;
|
|
|
1602
1766
|
var SUPPORTED_DNS_TYPES = /* @__PURE__ */ new Set(["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SRV", "CAA"]);
|
|
1603
1767
|
var DynadotRegistrar = class extends BaseRegistrar {
|
|
1604
1768
|
name = "dynadot";
|
|
1769
|
+
// a REST API: GET and HEAD never change state
|
|
1770
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
1605
1771
|
static displayName = "Dynadot";
|
|
1606
1772
|
static website = "dynadot.com";
|
|
1607
1773
|
static helpText = "Under Tools > API in your Dynadot account, generate an API Key and API Secret. The account must be unlocked with API access enabled. The key identifies you; the secret signs requests (X-Signature) and is never sent directly.";
|
|
@@ -2353,6 +2519,8 @@ var GANDI_TYPE_TO_FORWARD = {
|
|
|
2353
2519
|
};
|
|
2354
2520
|
var GandiRegistrar = class extends BaseRegistrar {
|
|
2355
2521
|
name = "gandi";
|
|
2522
|
+
// a REST API: GET and HEAD never change state
|
|
2523
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
2356
2524
|
static displayName = "Gandi.net";
|
|
2357
2525
|
static website = "gandi.net";
|
|
2358
2526
|
static helpText = "Generate a Personal Access Token (PAT) in your Gandi account under Account Settings > Security. The token needs permission to manage domains. (Gandi has deprecated the legacy API Key; use a PAT.)";
|
|
@@ -3040,6 +3208,8 @@ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
|
3040
3208
|
var PRICE_MICRO_UNITS = 1e6;
|
|
3041
3209
|
var GoDaddyRegistrar = class _GoDaddyRegistrar extends BaseRegistrar {
|
|
3042
3210
|
name = "godaddy";
|
|
3211
|
+
// a REST API: GET and HEAD never change state
|
|
3212
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
3043
3213
|
static displayName = "GoDaddy";
|
|
3044
3214
|
static website = "godaddy.com";
|
|
3045
3215
|
static helpText = "Create a Personal Access Token (PAT) at https://developer.godaddy.com and paste it here. The PAT is GoDaddy's modern credential: it unlocks the v3 API (discovery, registration, DNS, nameservers) and also authenticates the legacy v1 API for management operations (renew, transfer, auto-renew, lock, privacy, contacts) \u2014 one token covers everything.";
|
|
@@ -3920,6 +4090,8 @@ function dnsFieldsDiffer(a, b) {
|
|
|
3920
4090
|
var TOKEN_URL = "https://api.namebright.com/auth/token";
|
|
3921
4091
|
var NameBrightRegistrar = class extends BaseRegistrar {
|
|
3922
4092
|
name = "namebright";
|
|
4093
|
+
// a REST API: GET and HEAD never change state
|
|
4094
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
3923
4095
|
static displayName = "NameBright";
|
|
3924
4096
|
static website = "namebright.com";
|
|
3925
4097
|
static helpText = 'API access is not enabled by default \u2014 you must request it from NameBright (contact support / your account manager) before the API Management page is available. Once enabled, create an API Application under my.namebright.com > My Account > API Management. The Client ID is "<accountName>:<applicationName>"; NameBright issues the Client Secret. Note the application also enforces an IP whitelist.';
|
|
@@ -3958,7 +4130,8 @@ var NameBrightRegistrar = class extends BaseRegistrar {
|
|
|
3958
4130
|
client_id: this.credentials.clientId,
|
|
3959
4131
|
client_secret: this.credentials.clientSecret
|
|
3960
4132
|
},
|
|
3961
|
-
|
|
4133
|
+
// issuing a token changes nothing on the account, whatever it precedes
|
|
4134
|
+
...asRead(opts)
|
|
3962
4135
|
});
|
|
3963
4136
|
if (!res.access_token) {
|
|
3964
4137
|
throw new AuthenticationError("NameBright: token endpoint returned no access_token");
|
|
@@ -4737,7 +4910,11 @@ var NamecheapRegistrar = class extends BaseRegistrar {
|
|
|
4737
4910
|
* has no WhoisGuard allotted (e.g. TLDs that don't offer it).
|
|
4738
4911
|
*/
|
|
4739
4912
|
async setPrivacy(domainName, enabled, opts) {
|
|
4740
|
-
const cr = await this.command(
|
|
4913
|
+
const cr = await this.command(
|
|
4914
|
+
"namecheap.domains.getInfo",
|
|
4915
|
+
{ DomainName: domainName },
|
|
4916
|
+
asRead(opts)
|
|
4917
|
+
);
|
|
4741
4918
|
const id = cr.DomainGetInfoResult?.Whoisguard?.ID;
|
|
4742
4919
|
if (id == null || String(id) === "0") {
|
|
4743
4920
|
throw new Error(`${this.name}: ${domainName} has no WhoisGuard subscription to toggle`);
|
|
@@ -4977,7 +5154,7 @@ var NamecomHttpClient = class extends HttpClient {
|
|
|
4977
5154
|
} catch (error) {
|
|
4978
5155
|
if (error instanceof ParsingError) throw new ParsingError("namecom: invalid JSON response");
|
|
4979
5156
|
if (error instanceof ConnectionError)
|
|
4980
|
-
throw new ConnectionError("namecom: network request failed");
|
|
5157
|
+
throw new ConnectionError("namecom: network request failed", { notSent: error.notSent });
|
|
4981
5158
|
throw error;
|
|
4982
5159
|
}
|
|
4983
5160
|
}
|
|
@@ -5002,6 +5179,8 @@ var NamecomHttpClient = class extends HttpClient {
|
|
|
5002
5179
|
};
|
|
5003
5180
|
var NamecomRegistrar = class extends BaseRegistrar {
|
|
5004
5181
|
name = "namecom";
|
|
5182
|
+
// a REST API: GET and HEAD never change state
|
|
5183
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
5005
5184
|
static displayName = "Name.com";
|
|
5006
5185
|
static website = "name.com";
|
|
5007
5186
|
static supportsSandbox = true;
|
|
@@ -5030,7 +5209,11 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5030
5209
|
headers: { Authorization: `Basic ${auth}` }
|
|
5031
5210
|
};
|
|
5032
5211
|
super(credentials, config, options);
|
|
5033
|
-
this.http = new NamecomHttpClient({
|
|
5212
|
+
this.http = new NamecomHttpClient({
|
|
5213
|
+
...config,
|
|
5214
|
+
safeMethods: REST_SAFE_METHODS,
|
|
5215
|
+
options: this.options
|
|
5216
|
+
});
|
|
5034
5217
|
}
|
|
5035
5218
|
async testConnection(opts) {
|
|
5036
5219
|
try {
|
|
@@ -5258,7 +5441,6 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5258
5441
|
const old = index >= 0 ? remaining.splice(index, 1)[0] : void 0;
|
|
5259
5442
|
await this.http.request({
|
|
5260
5443
|
...opts,
|
|
5261
|
-
retries: 0,
|
|
5262
5444
|
method: old ? "PUT" : "POST",
|
|
5263
5445
|
path: old ? `${path}/${old.id}` : path,
|
|
5264
5446
|
body: record
|
|
@@ -5267,7 +5449,6 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5267
5449
|
for (const old of remaining) {
|
|
5268
5450
|
await this.http.request({
|
|
5269
5451
|
...opts,
|
|
5270
|
-
retries: 0,
|
|
5271
5452
|
method: "DELETE",
|
|
5272
5453
|
path: `${path}/${old.id}`
|
|
5273
5454
|
});
|
|
@@ -5331,7 +5512,7 @@ var NamecomRegistrar = class extends BaseRegistrar {
|
|
|
5331
5512
|
}
|
|
5332
5513
|
async mutate(req, opts) {
|
|
5333
5514
|
try {
|
|
5334
|
-
await this.http.request({ ...req, ...opts
|
|
5515
|
+
await this.http.request({ ...req, ...opts });
|
|
5335
5516
|
return { success: true, message: "Domain updated successfully" };
|
|
5336
5517
|
} catch (error) {
|
|
5337
5518
|
return { success: false, message: toRegistrarError(error).message };
|
|
@@ -5744,7 +5925,7 @@ var NameSiloRegistrar = class extends BaseRegistrar {
|
|
|
5744
5925
|
*/
|
|
5745
5926
|
async disableDnssec(domainName, opts) {
|
|
5746
5927
|
try {
|
|
5747
|
-
const res = await this.call("dnsSecListRecords", { domain: domainName }, opts);
|
|
5928
|
+
const res = await this.call("dnsSecListRecords", { domain: domainName }, asRead(opts));
|
|
5748
5929
|
if (!replyOk(res)) return statusResult2(res);
|
|
5749
5930
|
for (const d of ensureArray(res.reply?.ds_record)) {
|
|
5750
5931
|
const del = await this.call(
|
|
@@ -5817,7 +5998,7 @@ var NameSiloRegistrar = class extends BaseRegistrar {
|
|
|
5817
5998
|
desired.set(f.alias, list);
|
|
5818
5999
|
}
|
|
5819
6000
|
const currentAliases = new Set(
|
|
5820
|
-
(await this.listEmailForwards(domainName, opts)).map((r) => r.alias).filter(Boolean)
|
|
6001
|
+
(await this.listEmailForwards(domainName, asRead(opts))).map((r) => r.alias).filter(Boolean)
|
|
5821
6002
|
);
|
|
5822
6003
|
for (const alias of currentAliases) {
|
|
5823
6004
|
if (!desired.has(alias)) {
|
|
@@ -5908,7 +6089,7 @@ var NameSiloRegistrar = class extends BaseRegistrar {
|
|
|
5908
6089
|
* delegation nameservers aren't part of this list (see `updateNameservers`).
|
|
5909
6090
|
*/
|
|
5910
6091
|
async setDnsRecords(domainName, records, opts) {
|
|
5911
|
-
const listRes = await this.call("dnsListRecords", { domain: domainName }, opts);
|
|
6092
|
+
const listRes = await this.call("dnsListRecords", { domain: domainName }, asRead(opts));
|
|
5912
6093
|
if (!replyOk(listRes)) return { success: false, message: replyDetail(listRes) };
|
|
5913
6094
|
const existing = ensureArray(listRes.reply?.resource_record);
|
|
5914
6095
|
const existingByKey = /* @__PURE__ */ new Map();
|
|
@@ -6435,7 +6616,7 @@ var PorkbunRegistrar = class extends BaseRegistrar {
|
|
|
6435
6616
|
* renewals aren't supported via the API.
|
|
6436
6617
|
*/
|
|
6437
6618
|
async renewDomain(domainName, _years = 1, opts) {
|
|
6438
|
-
const pricing = await this.tldPricing(extractTld(domainName), opts);
|
|
6619
|
+
const pricing = await this.tldPricing(extractTld(domainName), asRead(opts));
|
|
6439
6620
|
if (pricing.renewal == null) {
|
|
6440
6621
|
throw new Error(`${this.name}: could not determine the renewal price for ${domainName}`);
|
|
6441
6622
|
}
|
|
@@ -6466,7 +6647,7 @@ var PorkbunRegistrar = class extends BaseRegistrar {
|
|
|
6466
6647
|
* aren't supported via the API.
|
|
6467
6648
|
*/
|
|
6468
6649
|
async transferIn(domainName, input, opts) {
|
|
6469
|
-
const pricing = await this.tldPricing(extractTld(domainName), opts);
|
|
6650
|
+
const pricing = await this.tldPricing(extractTld(domainName), asRead(opts));
|
|
6470
6651
|
if (pricing.transfer == null) {
|
|
6471
6652
|
throw new Error(`${this.name}: could not determine the transfer price for ${domainName}`);
|
|
6472
6653
|
}
|
|
@@ -6759,6 +6940,8 @@ function toDnsRecord3(r, domainName) {
|
|
|
6759
6940
|
var WRITABLE_DNS_TYPES = /* @__PURE__ */ new Set(["A", "AAAA", "CNAME", "NS", "TXT", "MX"]);
|
|
6760
6941
|
var SpaceshipRegistrar = class extends BaseRegistrar {
|
|
6761
6942
|
name = "spaceship";
|
|
6943
|
+
// a REST API: GET and HEAD never change state
|
|
6944
|
+
static safeMethods = REST_SAFE_METHODS;
|
|
6762
6945
|
static displayName = "Spaceship";
|
|
6763
6946
|
static website = "spaceship.com";
|
|
6764
6947
|
static helpText = 'Generate your API key and secret in the API Manager at Spaceship using the "New API key" button. The API requires both X-API-Key and X-API-Secret headers.';
|
|
@@ -7279,6 +7462,6 @@ function createRegistrar(name, credentials, options) {
|
|
|
7279
7462
|
return new RegistrarClass(credentials, options);
|
|
7280
7463
|
}
|
|
7281
7464
|
|
|
7282
|
-
export { ALL_FEATURES, AbortError, AuthenticationError, AuthorizationError, BaseRegistrar, CORE_FEATURES, CloudflareRegistrar, ConfigurationError, ConnectionError, ConsentRequiredError, DEFAULT_OPTIONS, DynadotRegistrar, EXTENDED_FEATURES, Feature, GandiRegistrar, GoDaddyRegistrar, HttpClient, InvalidResponseError, MASKED_FORWARD_UNSUPPORTED, NameBrightRegistrar, NameSiloRegistrar, NamecheapRegistrar, NamecomRegistrar, NotFoundError, NotImplementedError, ParsingError, PorkbunRegistrar, RateLimitError, RegistrarClient, RegistrarError, RetryableRegistrarError, SpaceshipRegistrar, TimeoutError, USER_AGENT, backoffDelay, createDomain, createRegistrar, ensureArray, filterDomains, isCoreFeature, listPortfolio, normalizeDomain, normalizeNameservers, parseDate, parseXml, registrars, requireConsent, selectBaseUrl, settableForwards, sleep, toRegistrarError };
|
|
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 };
|
|
7283
7466
|
//# sourceMappingURL=index.js.map
|
|
7284
7467
|
//# sourceMappingURL=index.js.map
|