@aoxborrow/registrar-client 0.1.0 → 0.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/README.md +4 -2
- package/dist/index.cjs +27 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +27 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/client.ts +4 -2
- package/src/registrar.ts +6 -0
- package/src/registrars/cloudflare.ts +1 -0
- package/src/registrars/dynadot.ts +5 -0
- package/src/registrars/gandi.ts +1 -0
- package/src/registrars/godaddy.ts +5 -0
- package/src/registrars/namebright.ts +1 -0
- package/src/registrars/namecheap.ts +1 -0
- package/src/registrars/namesilo.ts +5 -0
- package/src/registrars/porkbun.ts +1 -0
- package/src/registrars/spaceship.ts +5 -0
- package/src/types.ts +11 -2
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://nodejs.org)
|
|
6
6
|
[](https://www.typescriptlang.org)
|
|
7
|
+
[](https://github.com/sponsors/aoxborrow)
|
|
7
8
|
|
|
8
9
|
> One consistent, fully-typed TypeScript interface to many domain registrar APIs.
|
|
9
10
|
|
|
@@ -55,8 +56,9 @@ npm install @aoxborrow/registrar-client
|
|
|
55
56
|
| `spaceship` | Spaceship | key + secret | — | |
|
|
56
57
|
|
|
57
58
|
Each provider class exposes static discovery metadata — `displayName`,
|
|
58
|
-
`
|
|
59
|
-
them) — so you can build a
|
|
59
|
+
`website` (its public domain, e.g. `gandi.net`), `configFields` (the credential
|
|
60
|
+
fields it needs), and `helpText` (where to get them) — so you can build a
|
|
61
|
+
credential UI generically.
|
|
60
62
|
|
|
61
63
|
Research notes for additional registrars live in
|
|
62
64
|
[`docs/registrars/`](docs/registrars). Three are documented but **not**
|
package/dist/index.cjs
CHANGED
|
@@ -258,7 +258,7 @@ var RegistrarClient = class {
|
|
|
258
258
|
try {
|
|
259
259
|
const detail = await this.provider.getDomain(name, opts);
|
|
260
260
|
let merged = { ...domains[index], ...detail };
|
|
261
|
-
if (merged.nameservers.length === 0) {
|
|
261
|
+
if (merged.nameservers.length === 0 && this.provider.requiresNameserversFetch) {
|
|
262
262
|
try {
|
|
263
263
|
const nameservers = normalizeNameservers(
|
|
264
264
|
await this.provider.getNameservers(name, opts)
|
|
@@ -646,6 +646,11 @@ var BaseRegistrar = class {
|
|
|
646
646
|
supports(feature) {
|
|
647
647
|
return this.features.includes(feature);
|
|
648
648
|
}
|
|
649
|
+
// See Registrar.requiresNameserversFetch. Defaults true, so a provider
|
|
650
|
+
// whose getNameservers hits a real endpoint keeps the enrichment fallback
|
|
651
|
+
// without opting in; the providers whose getNameservers just re-reads getDomain
|
|
652
|
+
// override this to false to drop the redundant call.
|
|
653
|
+
requiresNameserversFetch = true;
|
|
649
654
|
constructor(credentials, httpConfig, options) {
|
|
650
655
|
const { environment = "production", ...clientOptions } = options ?? {};
|
|
651
656
|
this.credentials = credentials;
|
|
@@ -743,6 +748,7 @@ var BaseRegistrar = class {
|
|
|
743
748
|
var CloudflareRegistrar = class _CloudflareRegistrar extends BaseRegistrar {
|
|
744
749
|
name = "cloudflare";
|
|
745
750
|
static displayName = "Cloudflare";
|
|
751
|
+
static website = "cloudflare.com";
|
|
746
752
|
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.';
|
|
747
753
|
static configFields = [
|
|
748
754
|
{ name: "apiToken", label: "API Token", type: "password", required: true },
|
|
@@ -1599,6 +1605,7 @@ var SUPPORTED_DNS_TYPES = /* @__PURE__ */ new Set(["A", "AAAA", "CNAME", "MX", "
|
|
|
1599
1605
|
var DynadotRegistrar = class extends BaseRegistrar {
|
|
1600
1606
|
name = "dynadot";
|
|
1601
1607
|
static displayName = "Dynadot";
|
|
1608
|
+
static website = "dynadot.com";
|
|
1602
1609
|
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.";
|
|
1603
1610
|
static configFields = [
|
|
1604
1611
|
{ name: "apiKey", label: "API Key", type: "password", required: true },
|
|
@@ -1714,6 +1721,9 @@ ${bodyStr}`;
|
|
|
1714
1721
|
if (!data.domain_info) throw new NotFoundError(`Dynadot: domain '${domainName}' not found`);
|
|
1715
1722
|
return data.domain_info;
|
|
1716
1723
|
}
|
|
1724
|
+
// getNameservers re-reads getDomain (domain_info carries NS inline; no separate
|
|
1725
|
+
// endpoint), so listing enrichment gains nothing from the fallback — skip it.
|
|
1726
|
+
requiresNameserversFetch = false;
|
|
1717
1727
|
async getNameservers(domainName, opts) {
|
|
1718
1728
|
const domain = await this.getDomain(domainName, opts);
|
|
1719
1729
|
return domain.nameservers;
|
|
@@ -2346,6 +2356,7 @@ var GANDI_TYPE_TO_FORWARD = {
|
|
|
2346
2356
|
var GandiRegistrar = class extends BaseRegistrar {
|
|
2347
2357
|
name = "gandi";
|
|
2348
2358
|
static displayName = "Gandi.net";
|
|
2359
|
+
static website = "gandi.net";
|
|
2349
2360
|
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.)";
|
|
2350
2361
|
static configFields = [
|
|
2351
2362
|
{ name: "apiKey", label: "Personal Access Token", type: "password", required: true }
|
|
@@ -3032,6 +3043,7 @@ var PRICE_MICRO_UNITS = 1e6;
|
|
|
3032
3043
|
var GoDaddyRegistrar = class _GoDaddyRegistrar extends BaseRegistrar {
|
|
3033
3044
|
name = "godaddy";
|
|
3034
3045
|
static displayName = "GoDaddy";
|
|
3046
|
+
static website = "godaddy.com";
|
|
3035
3047
|
static helpText = 'Authenticate one of two ways. For production, create a Personal Access Token (PAT) at https://developer.godaddy.com and pass it as `apiToken` \u2014 this enables the modern v3 API. For sandbox testing, create OTE (test environment) keys and pass `apiKey` + `apiSecret` with { environment: "sandbox" }; OTE only exposes the legacy v1 API. The sso-key (API Key/Secret) scheme is deprecated by GoDaddy in 2026. Domain forwarding uses the v2 customer-scoped API \u2014 set `customerId` to your GoDaddy customer UUID, or to your numeric shopper/account ID (which the client resolves to the UUID via an sso-key-authenticated lookup).';
|
|
3036
3048
|
static configFields = [
|
|
3037
3049
|
{ name: "apiToken", label: "API Token (PAT)", type: "password", required: false },
|
|
@@ -3155,6 +3167,9 @@ var GoDaddyRegistrar = class _GoDaddyRegistrar extends BaseRegistrar {
|
|
|
3155
3167
|
});
|
|
3156
3168
|
return this.toDomain(d);
|
|
3157
3169
|
}
|
|
3170
|
+
// getNameservers re-reads getDomain (GoDaddy has no dedicated NS endpoint), so
|
|
3171
|
+
// listing enrichment gains nothing from the fallback — skip it.
|
|
3172
|
+
requiresNameserversFetch = false;
|
|
3158
3173
|
async getNameservers(domainName, opts) {
|
|
3159
3174
|
const domain = await this.getDomain(domainName, opts);
|
|
3160
3175
|
return domain.nameservers;
|
|
@@ -3896,6 +3911,7 @@ var TOKEN_URL = "https://api.namebright.com/auth/token";
|
|
|
3896
3911
|
var NameBrightRegistrar = class extends BaseRegistrar {
|
|
3897
3912
|
name = "namebright";
|
|
3898
3913
|
static displayName = "NameBright";
|
|
3914
|
+
static website = "namebright.com";
|
|
3899
3915
|
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.';
|
|
3900
3916
|
static configFields = [
|
|
3901
3917
|
{ name: "clientId", label: "Client ID", type: "text", required: true },
|
|
@@ -4386,6 +4402,7 @@ var NC_CONTACT_ROLES = [
|
|
|
4386
4402
|
var NamecheapRegistrar = class extends BaseRegistrar {
|
|
4387
4403
|
name = "namecheap";
|
|
4388
4404
|
static displayName = "Namecheap";
|
|
4405
|
+
static website = "namecheap.com";
|
|
4389
4406
|
static helpText = "Enable API access in your Namecheap account under Profile > Tools > API Access, generate an API key, and whitelist your request IP(s) in the API settings. Provide the whitelisted IP as the Client IP field.";
|
|
4390
4407
|
static configFields = [
|
|
4391
4408
|
{ name: "username", label: "Username", type: "text", required: true },
|
|
@@ -4943,6 +4960,7 @@ function toNcContactParams(prefix, c) {
|
|
|
4943
4960
|
var NameSiloRegistrar = class extends BaseRegistrar {
|
|
4944
4961
|
name = "namesilo";
|
|
4945
4962
|
static displayName = "NameSilo";
|
|
4963
|
+
static website = "namesilo.com";
|
|
4946
4964
|
static helpText = 'Generate an API key in your NameSilo account under Account Options > API Manager. You can optionally restrict the key to specific IP addresses there. For sandbox testing, use { environment: "sandbox" } (OTE host ote.namesilo.com) \u2014 OTE credentials are not self-service; you must contact NameSilo support to be issued them.';
|
|
4947
4965
|
static configFields = [
|
|
4948
4966
|
{ name: "apiKey", label: "API Key", type: "password", required: true }
|
|
@@ -5053,6 +5071,9 @@ var NameSiloRegistrar = class extends BaseRegistrar {
|
|
|
5053
5071
|
nameservers: extractNsHosts(r.nameservers)
|
|
5054
5072
|
});
|
|
5055
5073
|
}
|
|
5074
|
+
// getNameservers re-reads getDomain (getDomainInfo carries NS; no separate
|
|
5075
|
+
// endpoint), so listing enrichment gains nothing from the fallback — skip it.
|
|
5076
|
+
requiresNameserversFetch = false;
|
|
5056
5077
|
async getNameservers(domainName, opts) {
|
|
5057
5078
|
const domain = await this.getDomain(domainName, opts);
|
|
5058
5079
|
return domain.nameservers;
|
|
@@ -5624,6 +5645,7 @@ var PB_TYPE_TO_FORWARD = {
|
|
|
5624
5645
|
var PorkbunRegistrar = class extends BaseRegistrar {
|
|
5625
5646
|
name = "porkbun";
|
|
5626
5647
|
static displayName = "Porkbun";
|
|
5648
|
+
static website = "porkbun.com";
|
|
5627
5649
|
static helpText = 'Create an API key and secret in your Porkbun account under Account > API Access, then enable "API Access" on each domain you want to manage (per-domain toggle in the domain details). For testing, use a sandbox key (prefixed "pk1_sb_") with { environment: "sandbox" } \u2014 it hits the same base URL but an isolated test environment with $1,000 of fake credit and no real charges (top up or reset via POST /sandbox/topup and POST /sandbox/reset).';
|
|
5628
5650
|
static configFields = [
|
|
5629
5651
|
{ name: "apiKey", label: "API Key", type: "password", required: true },
|
|
@@ -6230,6 +6252,7 @@ var WRITABLE_DNS_TYPES = /* @__PURE__ */ new Set(["A", "AAAA", "CNAME", "NS", "T
|
|
|
6230
6252
|
var SpaceshipRegistrar = class extends BaseRegistrar {
|
|
6231
6253
|
name = "spaceship";
|
|
6232
6254
|
static displayName = "Spaceship";
|
|
6255
|
+
static website = "spaceship.com";
|
|
6233
6256
|
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.';
|
|
6234
6257
|
static configFields = [
|
|
6235
6258
|
{ name: "apiKey", label: "API Key", type: "password", required: true },
|
|
@@ -6292,6 +6315,9 @@ var SpaceshipRegistrar = class extends BaseRegistrar {
|
|
|
6292
6315
|
async getDomain(domainName, opts) {
|
|
6293
6316
|
return this.toDomain(await this.getRaw(domainName, opts));
|
|
6294
6317
|
}
|
|
6318
|
+
// getNameservers reads the same getRaw payload as getDomain (no dedicated NS
|
|
6319
|
+
// endpoint), so listing enrichment gains nothing from the fallback — skip it.
|
|
6320
|
+
requiresNameserversFetch = false;
|
|
6295
6321
|
async getNameservers(domainName, opts) {
|
|
6296
6322
|
const d = await this.getRaw(domainName, opts);
|
|
6297
6323
|
return d.nameservers?.hosts ?? [];
|