@hasna/domains 0.0.12 → 0.0.14
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/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/domain.d.ts.map +1 -1
- package/dist/cli/commands/provision.d.ts +3 -0
- package/dist/cli/commands/provision.d.ts.map +1 -0
- package/dist/cli/index.js +478 -255
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +178 -9
- package/dist/lib/brandsight.d.ts +20 -0
- package/dist/lib/brandsight.d.ts.map +1 -1
- package/dist/lib/capability.d.ts +30 -0
- package/dist/lib/capability.d.ts.map +1 -0
- package/dist/lib/cloudflare-auth.d.ts +15 -0
- package/dist/lib/cloudflare-auth.d.ts.map +1 -0
- package/dist/lib/cloudflare.d.ts +13 -4
- package/dist/lib/cloudflare.d.ts.map +1 -1
- package/dist/lib/creds-check.d.ts +13 -0
- package/dist/lib/creds-check.d.ts.map +1 -0
- package/dist/lib/delegate.d.ts +28 -0
- package/dist/lib/delegate.d.ts.map +1 -0
- package/dist/lib/domain-daemon.d.ts +30 -0
- package/dist/lib/domain-daemon.d.ts.map +1 -0
- package/dist/lib/godaddy.d.ts +12 -0
- package/dist/lib/godaddy.d.ts.map +1 -1
- package/dist/lib/ns-drift.d.ts +29 -0
- package/dist/lib/ns-drift.d.ts.map +1 -0
- package/dist/lib/provision-state.d.ts +29 -0
- package/dist/lib/provision-state.d.ts.map +1 -0
- package/dist/lib/registration-poll.d.ts +24 -0
- package/dist/lib/registration-poll.d.ts.map +1 -0
- package/dist/lib/route53.d.ts +17 -0
- package/dist/lib/route53.d.ts.map +1 -1
- package/dist/mcp/index.js +42 -9
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -19207,7 +19207,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
19207
19207
|
|
|
19208
19208
|
// node_modules/@aws-sdk/util-user-agent-node/dist-cjs/index.js
|
|
19209
19209
|
var require_dist_cjs41 = __commonJS((exports) => {
|
|
19210
|
-
var __dirname = "/
|
|
19210
|
+
var __dirname = "/home/hasna/workspace/hasna/opensource/open-domains/node_modules/@aws-sdk/util-user-agent-node/dist-cjs";
|
|
19211
19211
|
var node_os = __require("os");
|
|
19212
19212
|
var node_process = __require("process");
|
|
19213
19213
|
var utilConfigProvider = require_dist_cjs33();
|
|
@@ -25599,6 +25599,322 @@ var init_dist_es9 = __esm(() => {
|
|
|
25599
25599
|
init_fromIni();
|
|
25600
25600
|
});
|
|
25601
25601
|
|
|
25602
|
+
// src/lib/cloudflare-auth.ts
|
|
25603
|
+
function resolveCloudflareConfig(env = process.env) {
|
|
25604
|
+
const accountId = env["CLOUDFLARE_ACCOUNT_ID"] || env["HASNAXYZ_CLOUDFLARE_LIVE_ACCOUNT_ID"] || undefined;
|
|
25605
|
+
if (env["CLOUDFLARE_API_TOKEN"]) {
|
|
25606
|
+
return { apiToken: env["CLOUDFLARE_API_TOKEN"], accountId };
|
|
25607
|
+
}
|
|
25608
|
+
if (env["CLOUDFLARE_API_KEY"] && env["CLOUDFLARE_EMAIL"]) {
|
|
25609
|
+
return { apiKey: env["CLOUDFLARE_API_KEY"], email: env["CLOUDFLARE_EMAIL"], accountId };
|
|
25610
|
+
}
|
|
25611
|
+
if (env["HASNAXYZ_CLOUDFLARE_LIVE_API_KEY"] && env["HASNAXYZ_CLOUDFLARE_LIVE_EMAIL"]) {
|
|
25612
|
+
return {
|
|
25613
|
+
apiKey: env["HASNAXYZ_CLOUDFLARE_LIVE_API_KEY"],
|
|
25614
|
+
email: env["HASNAXYZ_CLOUDFLARE_LIVE_EMAIL"],
|
|
25615
|
+
accountId
|
|
25616
|
+
};
|
|
25617
|
+
}
|
|
25618
|
+
return accountId ? { accountId } : {};
|
|
25619
|
+
}
|
|
25620
|
+
function cloudflareAuthHeaders(cfg) {
|
|
25621
|
+
if (cfg.apiToken)
|
|
25622
|
+
return { Authorization: `Bearer ${cfg.apiToken}` };
|
|
25623
|
+
if (cfg.apiKey && cfg.email)
|
|
25624
|
+
return { "X-Auth-Key": cfg.apiKey, "X-Auth-Email": cfg.email };
|
|
25625
|
+
throw new Error("Cloudflare credentials not configured. Set CLOUDFLARE_API_TOKEN, or CLOUDFLARE_API_KEY + CLOUDFLARE_EMAIL.");
|
|
25626
|
+
}
|
|
25627
|
+
|
|
25628
|
+
// src/lib/brandsight.ts
|
|
25629
|
+
function resolveBrandsightConfig(env = process.env) {
|
|
25630
|
+
return {
|
|
25631
|
+
apiKey: env["BRANDSIGHT_API_KEY"] ?? env["HASNAXYZ_BRANDSIGHT_LIVE_API_KEY"] ?? "",
|
|
25632
|
+
apiSecret: env["BRANDSIGHT_API_SECRET"] ?? env["HASNAXYZ_BRANDSIGHT_LIVE_API_SECRET"],
|
|
25633
|
+
customerId: env["BRANDSIGHT_CUSTOMER_ID"] ?? env["HASNAXYZ_BRANDSIGHT_LIVE_CUSTOMER_ID"],
|
|
25634
|
+
shopperId: env["BRANDSIGHT_SHOPPER_ID"] ?? env["HASNAXYZ_BRANDSIGHT_LIVE_SHOPPER_ID"],
|
|
25635
|
+
accountId: env["BRANDSIGHT_ACCOUNT_ID"] ?? env["HASNAXYZ_BRANDSIGHT_LIVE_CUSTOMER_ID"]
|
|
25636
|
+
};
|
|
25637
|
+
}
|
|
25638
|
+
function getApiKey() {
|
|
25639
|
+
const key = process.env["BRANDSIGHT_API_KEY"];
|
|
25640
|
+
if (!key) {
|
|
25641
|
+
throw new BrandsightApiError("BRANDSIGHT_API_KEY environment variable is not set");
|
|
25642
|
+
}
|
|
25643
|
+
return key;
|
|
25644
|
+
}
|
|
25645
|
+
function getConfig4() {
|
|
25646
|
+
return {
|
|
25647
|
+
apiKey: process.env["BRANDSIGHT_API_KEY"] ?? "",
|
|
25648
|
+
accountId: process.env["BRANDSIGHT_ACCOUNT_ID"]
|
|
25649
|
+
};
|
|
25650
|
+
}
|
|
25651
|
+
async function apiRequest3(method, path, apiKey, body, baseUrl = BRANDSIGHT_BASE) {
|
|
25652
|
+
const fetchFn = _fetchFn || globalThis.fetch;
|
|
25653
|
+
const url = `${baseUrl}${path}`;
|
|
25654
|
+
const headers = {
|
|
25655
|
+
Authorization: `Bearer ${apiKey}`,
|
|
25656
|
+
"Content-Type": "application/json",
|
|
25657
|
+
Accept: "application/json",
|
|
25658
|
+
"User-Agent": USER_AGENT
|
|
25659
|
+
};
|
|
25660
|
+
try {
|
|
25661
|
+
const response = await fetchFn(url, {
|
|
25662
|
+
method,
|
|
25663
|
+
headers,
|
|
25664
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
25665
|
+
signal: AbortSignal.timeout(15000)
|
|
25666
|
+
});
|
|
25667
|
+
if (!response.ok) {
|
|
25668
|
+
throw new BrandsightApiError(`Brandsight API ${method} ${path} failed with status ${response.status}`, response.status, await response.text());
|
|
25669
|
+
}
|
|
25670
|
+
const data = await response.json();
|
|
25671
|
+
return { data, stub: false };
|
|
25672
|
+
} catch (error) {
|
|
25673
|
+
if (error instanceof BrandsightApiError)
|
|
25674
|
+
throw error;
|
|
25675
|
+
return { data: null, stub: true };
|
|
25676
|
+
}
|
|
25677
|
+
}
|
|
25678
|
+
async function apiGet(path, apiKey, baseUrl = BRANDSIGHT_BASE) {
|
|
25679
|
+
const fetchFn = _fetchFn || globalThis.fetch;
|
|
25680
|
+
const url = `${baseUrl}${path}`;
|
|
25681
|
+
const headers = {
|
|
25682
|
+
Authorization: `Bearer ${apiKey}`,
|
|
25683
|
+
"Content-Type": "application/json",
|
|
25684
|
+
Accept: "application/json",
|
|
25685
|
+
"User-Agent": USER_AGENT
|
|
25686
|
+
};
|
|
25687
|
+
try {
|
|
25688
|
+
const response = await fetchFn(url, {
|
|
25689
|
+
method: "GET",
|
|
25690
|
+
headers,
|
|
25691
|
+
signal: AbortSignal.timeout(15000)
|
|
25692
|
+
});
|
|
25693
|
+
if (!response.ok) {
|
|
25694
|
+
throw new BrandsightApiError(`Brandsight API GET ${path} failed with status ${response.status}`, response.status, await response.text());
|
|
25695
|
+
}
|
|
25696
|
+
const data = await response.json();
|
|
25697
|
+
return { data, stub: false };
|
|
25698
|
+
} catch (error) {
|
|
25699
|
+
if (error instanceof BrandsightApiError)
|
|
25700
|
+
throw error;
|
|
25701
|
+
return { data: null, stub: true };
|
|
25702
|
+
}
|
|
25703
|
+
}
|
|
25704
|
+
function generateStubAlerts(brandName) {
|
|
25705
|
+
const now = new Date().toISOString();
|
|
25706
|
+
return [
|
|
25707
|
+
{ domain: `${brandName}-deals.com`, type: "keyword", registered_at: now },
|
|
25708
|
+
{ domain: `${brandName.replace(/a/gi, "4").replace(/e/gi, "3")}.com`, type: "homoglyph", registered_at: now },
|
|
25709
|
+
{ domain: `${brandName}s.com`, type: "typosquat", registered_at: now }
|
|
25710
|
+
];
|
|
25711
|
+
}
|
|
25712
|
+
function generateStubSimilarDomains(domain) {
|
|
25713
|
+
const base = domain.replace(/\.[^.]+$/, "");
|
|
25714
|
+
const tld = domain.slice(base.length);
|
|
25715
|
+
return [
|
|
25716
|
+
`${base}-online${tld}`,
|
|
25717
|
+
`${base}s${tld}`,
|
|
25718
|
+
`${base.replace(/a/gi, "4")}${tld}`,
|
|
25719
|
+
`${base}-app${tld}`,
|
|
25720
|
+
`get${base}${tld}`
|
|
25721
|
+
];
|
|
25722
|
+
}
|
|
25723
|
+
function generateStubThreatAssessment(domain) {
|
|
25724
|
+
return {
|
|
25725
|
+
domain,
|
|
25726
|
+
risk_level: "low",
|
|
25727
|
+
threats: [],
|
|
25728
|
+
recommendation: "No immediate threats detected. Continue routine monitoring."
|
|
25729
|
+
};
|
|
25730
|
+
}
|
|
25731
|
+
async function monitorBrand(brandName) {
|
|
25732
|
+
const apiKey = getApiKey();
|
|
25733
|
+
const result = await apiGet(`/brands/${encodeURIComponent(brandName)}/monitor`, apiKey);
|
|
25734
|
+
if (result.stub) {
|
|
25735
|
+
return { brand: brandName, alerts: generateStubAlerts(brandName), stub: true };
|
|
25736
|
+
}
|
|
25737
|
+
return { brand: brandName, alerts: result.data.alerts, stub: false };
|
|
25738
|
+
}
|
|
25739
|
+
async function getSimilarDomains(domain) {
|
|
25740
|
+
const apiKey = getApiKey();
|
|
25741
|
+
const result = await apiGet(`/domains/${encodeURIComponent(domain)}/similar`, apiKey);
|
|
25742
|
+
if (result.stub) {
|
|
25743
|
+
return { domain, similar: generateStubSimilarDomains(domain), stub: true };
|
|
25744
|
+
}
|
|
25745
|
+
return { domain, similar: result.data.similar, stub: false };
|
|
25746
|
+
}
|
|
25747
|
+
async function getThreatAssessment(domain) {
|
|
25748
|
+
const apiKey = getApiKey();
|
|
25749
|
+
const result = await apiGet(`/domains/${encodeURIComponent(domain)}/threats`, apiKey);
|
|
25750
|
+
if (result.stub) {
|
|
25751
|
+
return { ...generateStubThreatAssessment(domain), stub: true };
|
|
25752
|
+
}
|
|
25753
|
+
return { ...result.data, stub: false };
|
|
25754
|
+
}
|
|
25755
|
+
async function listDomains2(config) {
|
|
25756
|
+
const cfg = config ?? getConfig4();
|
|
25757
|
+
const result = await apiGet("/portfolio/domains", cfg.apiKey);
|
|
25758
|
+
if (result.stub)
|
|
25759
|
+
return [];
|
|
25760
|
+
return result.data.domains ?? [];
|
|
25761
|
+
}
|
|
25762
|
+
async function getDomainInfo3(domain, config) {
|
|
25763
|
+
const cfg = config ?? getConfig4();
|
|
25764
|
+
const result = await apiGet(`/portfolio/domains/${encodeURIComponent(domain)}`, cfg.apiKey);
|
|
25765
|
+
if (result.stub)
|
|
25766
|
+
return null;
|
|
25767
|
+
return result.data;
|
|
25768
|
+
}
|
|
25769
|
+
async function checkAvailability4(domain, config) {
|
|
25770
|
+
const cfg = config ?? getConfig4();
|
|
25771
|
+
const result = await apiGet(`/domains/check?domain=${encodeURIComponent(domain)}`, cfg.apiKey);
|
|
25772
|
+
if (result.stub)
|
|
25773
|
+
return { domain, available: false };
|
|
25774
|
+
return result.data;
|
|
25775
|
+
}
|
|
25776
|
+
async function renewDomain3(domain, years = 1, config) {
|
|
25777
|
+
const cfg = config ?? getConfig4();
|
|
25778
|
+
const result = await apiRequest3("POST", `/portfolio/domains/${encodeURIComponent(domain)}/renew`, cfg.apiKey, { years });
|
|
25779
|
+
if (result.stub)
|
|
25780
|
+
return { success: false };
|
|
25781
|
+
return { success: true, orderId: result.data.orderId };
|
|
25782
|
+
}
|
|
25783
|
+
async function syncToLocalDb3(dbFns, config) {
|
|
25784
|
+
const domains = await listDomains2(config);
|
|
25785
|
+
let synced = 0, created = 0, updated = 0;
|
|
25786
|
+
const errors = [];
|
|
25787
|
+
for (const d3 of domains) {
|
|
25788
|
+
try {
|
|
25789
|
+
const existing = dbFns.getDomainByName(d3.domain);
|
|
25790
|
+
if (existing) {
|
|
25791
|
+
dbFns.updateDomain(existing.id, {
|
|
25792
|
+
registrar: "Brandsight",
|
|
25793
|
+
expires_at: d3.expires || undefined,
|
|
25794
|
+
auto_renew: d3.auto_renew,
|
|
25795
|
+
status: "active",
|
|
25796
|
+
nameservers: d3.nameservers
|
|
25797
|
+
});
|
|
25798
|
+
updated++;
|
|
25799
|
+
} else {
|
|
25800
|
+
dbFns.createDomain({
|
|
25801
|
+
name: d3.domain,
|
|
25802
|
+
registrar: "Brandsight",
|
|
25803
|
+
expires_at: d3.expires || undefined,
|
|
25804
|
+
auto_renew: d3.auto_renew,
|
|
25805
|
+
status: "active",
|
|
25806
|
+
nameservers: d3.nameservers
|
|
25807
|
+
});
|
|
25808
|
+
created++;
|
|
25809
|
+
}
|
|
25810
|
+
synced++;
|
|
25811
|
+
} catch (err) {
|
|
25812
|
+
errors.push(`${d3.domain}: ${err instanceof Error ? err.message : String(err)}`);
|
|
25813
|
+
}
|
|
25814
|
+
}
|
|
25815
|
+
return { synced, created, updated, errors };
|
|
25816
|
+
}
|
|
25817
|
+
function createBrandsightProvider(config) {
|
|
25818
|
+
const cfg = config ?? getConfig4();
|
|
25819
|
+
return {
|
|
25820
|
+
name: "brandsight",
|
|
25821
|
+
async listDomains() {
|
|
25822
|
+
const domains = await listDomains2(cfg);
|
|
25823
|
+
return domains.map((d3) => ({
|
|
25824
|
+
domain: d3.domain,
|
|
25825
|
+
registrar: "Brandsight",
|
|
25826
|
+
created: "",
|
|
25827
|
+
expires: d3.expires,
|
|
25828
|
+
nameservers: d3.nameservers,
|
|
25829
|
+
status: d3.status === "ACTIVE" ? "active" : d3.status.toLowerCase(),
|
|
25830
|
+
auto_renew: d3.auto_renew
|
|
25831
|
+
}));
|
|
25832
|
+
},
|
|
25833
|
+
async getDomainInfo(domain) {
|
|
25834
|
+
const d3 = await getDomainInfo3(domain, cfg);
|
|
25835
|
+
if (!d3)
|
|
25836
|
+
throw new Error(`Domain not found in Brandsight: ${domain}`);
|
|
25837
|
+
return {
|
|
25838
|
+
domain: d3.domain,
|
|
25839
|
+
registrar: "Brandsight",
|
|
25840
|
+
created: "",
|
|
25841
|
+
expires: d3.expires,
|
|
25842
|
+
nameservers: d3.nameservers,
|
|
25843
|
+
status: d3.status === "ACTIVE" ? "active" : d3.status.toLowerCase(),
|
|
25844
|
+
auto_renew: d3.auto_renew
|
|
25845
|
+
};
|
|
25846
|
+
},
|
|
25847
|
+
async renewDomain(domain) {
|
|
25848
|
+
const result = await renewDomain3(domain, 1, cfg);
|
|
25849
|
+
return { domain, success: result.success, orderId: result.orderId };
|
|
25850
|
+
},
|
|
25851
|
+
async checkAvailability(domain) {
|
|
25852
|
+
const result = await checkAvailability4(domain, cfg);
|
|
25853
|
+
return {
|
|
25854
|
+
domain: result.domain,
|
|
25855
|
+
available: result.available,
|
|
25856
|
+
standard_price: result.price,
|
|
25857
|
+
currency: result.currency
|
|
25858
|
+
};
|
|
25859
|
+
},
|
|
25860
|
+
async syncToLocalDb(dbFns) {
|
|
25861
|
+
return syncToLocalDb3(dbFns, cfg);
|
|
25862
|
+
}
|
|
25863
|
+
};
|
|
25864
|
+
}
|
|
25865
|
+
var BrandsightApiError, _fetchFn = null, BRANDSIGHT_BASE = "https://api.brandsight.com/v1";
|
|
25866
|
+
var init_brandsight = __esm(() => {
|
|
25867
|
+
init_version();
|
|
25868
|
+
BrandsightApiError = class BrandsightApiError extends Error {
|
|
25869
|
+
statusCode;
|
|
25870
|
+
responseBody;
|
|
25871
|
+
constructor(message, statusCode, responseBody) {
|
|
25872
|
+
super(message);
|
|
25873
|
+
this.statusCode = statusCode;
|
|
25874
|
+
this.responseBody = responseBody;
|
|
25875
|
+
this.name = "BrandsightApiError";
|
|
25876
|
+
}
|
|
25877
|
+
};
|
|
25878
|
+
});
|
|
25879
|
+
|
|
25880
|
+
// src/lib/creds-check.ts
|
|
25881
|
+
var exports_creds_check = {};
|
|
25882
|
+
__export(exports_creds_check, {
|
|
25883
|
+
checkProvisioningCredentials: () => checkProvisioningCredentials
|
|
25884
|
+
});
|
|
25885
|
+
function checkProvisioningCredentials(env = process.env) {
|
|
25886
|
+
const out = [];
|
|
25887
|
+
const hasAws = !!(env["AWS_ACCESS_KEY_ID"] && env["AWS_SECRET_ACCESS_KEY"]) || !!env["AWS_PROFILE"];
|
|
25888
|
+
out.push({
|
|
25889
|
+
provider: "route53",
|
|
25890
|
+
configured: hasAws,
|
|
25891
|
+
mode: env["AWS_PROFILE"] ? `profile:${env["AWS_PROFILE"]}` : hasAws ? "access-keys" : "none",
|
|
25892
|
+
detail: hasAws ? "AWS credentials present (region us-east-1 for Route53 Domains)" : "Set AWS_PROFILE or AWS_ACCESS_KEY_ID/SECRET"
|
|
25893
|
+
});
|
|
25894
|
+
const cf = resolveCloudflareConfig(env);
|
|
25895
|
+
const cfMode = cf.apiToken ? "token" : cf.apiKey && cf.email ? "global-key" : "none";
|
|
25896
|
+
out.push({
|
|
25897
|
+
provider: "cloudflare",
|
|
25898
|
+
configured: cfMode !== "none",
|
|
25899
|
+
mode: cfMode + (cf.accountId ? "+account" : ""),
|
|
25900
|
+
detail: cfMode === "none" ? "Set CLOUDFLARE_API_TOKEN or CLOUDFLARE_API_KEY+CLOUDFLARE_EMAIL" : cf.accountId ? "ok" : "missing CLOUDFLARE_ACCOUNT_ID (needed to create zones)"
|
|
25901
|
+
});
|
|
25902
|
+
const bs = resolveBrandsightConfig(env);
|
|
25903
|
+
const bsConfigured = !!(bs.apiKey && bs.apiSecret && bs.customerId);
|
|
25904
|
+
out.push({
|
|
25905
|
+
provider: "brandsight",
|
|
25906
|
+
configured: bsConfigured,
|
|
25907
|
+
mode: bsConfigured ? "full-creds" : "none",
|
|
25908
|
+
detail: "enterprise/contract-only (gated) \u2014 not used for automated purchase"
|
|
25909
|
+
});
|
|
25910
|
+
const gd = !!(env["GODADDY_API_KEY"] && env["GODADDY_API_SECRET"]);
|
|
25911
|
+
out.push({ provider: "godaddy", configured: gd, mode: gd ? "key+secret" : "none", detail: "retail API gated for purchase/DNS since 2024" });
|
|
25912
|
+
return out;
|
|
25913
|
+
}
|
|
25914
|
+
var init_creds_check = __esm(() => {
|
|
25915
|
+
init_brandsight();
|
|
25916
|
+
});
|
|
25917
|
+
|
|
25602
25918
|
// src/db/domain-history.ts
|
|
25603
25919
|
function rowToDomainHistory(row) {
|
|
25604
25920
|
return {
|
|
@@ -31990,6 +32306,7 @@ var _Ex = "Expiry";
|
|
|
31990
32306
|
var _F2 = "Fax";
|
|
31991
32307
|
var _FC = "FilterCondition";
|
|
31992
32308
|
var _FCi = "FilterConditions";
|
|
32309
|
+
var _FIAK = "FIAuthKey";
|
|
31993
32310
|
var _FN = "FirstName";
|
|
31994
32311
|
var _Fl2 = "Flags";
|
|
31995
32312
|
var _GDD = "GetDomainDetail";
|
|
@@ -32063,6 +32380,9 @@ var _TTD = "TagsToDelete";
|
|
|
32063
32380
|
var _Tl = "Tld";
|
|
32064
32381
|
var _Ty = "Type";
|
|
32065
32382
|
var _UD = "UpdatedDate";
|
|
32383
|
+
var _UDN = "UpdateDomainNameservers";
|
|
32384
|
+
var _UDNR = "UpdateDomainNameserversRequest";
|
|
32385
|
+
var _UDNRp = "UpdateDomainNameserversResponse";
|
|
32066
32386
|
var _UTLD = "UnsupportedTLD";
|
|
32067
32387
|
var _V2 = "Value";
|
|
32068
32388
|
var _Va = "Values";
|
|
@@ -32153,6 +32473,7 @@ var ContactNumber = [0, n02, _CNo2, 8, 0];
|
|
|
32153
32473
|
var CountryCode = [0, n02, _CC2, 8, 0];
|
|
32154
32474
|
var Email = [0, n02, _E, 8, 0];
|
|
32155
32475
|
var ExtraParamValue = [0, n02, _EPV, 8, 0];
|
|
32476
|
+
var FIAuthKey = [0, n02, _FIAK, 8, 0];
|
|
32156
32477
|
var State = [0, n02, _S2, 8, 0];
|
|
32157
32478
|
var ZipCode = [0, n02, _ZC, 8, 0];
|
|
32158
32479
|
var CheckDomainAvailabilityRequest$ = [
|
|
@@ -32349,8 +32670,25 @@ var SortCondition$ = [
|
|
|
32349
32670
|
[0, 0],
|
|
32350
32671
|
2
|
|
32351
32672
|
];
|
|
32352
|
-
var
|
|
32353
|
-
|
|
32673
|
+
var UpdateDomainNameserversRequest$ = [
|
|
32674
|
+
3,
|
|
32675
|
+
n02,
|
|
32676
|
+
_UDNR,
|
|
32677
|
+
0,
|
|
32678
|
+
[_DN, _Na2, _FIAK],
|
|
32679
|
+
[0, () => NameserverList, [() => FIAuthKey, 0]],
|
|
32680
|
+
2
|
|
32681
|
+
];
|
|
32682
|
+
var UpdateDomainNameserversResponse$ = [
|
|
32683
|
+
3,
|
|
32684
|
+
n02,
|
|
32685
|
+
_UDNRp,
|
|
32686
|
+
0,
|
|
32687
|
+
[_OI],
|
|
32688
|
+
[0]
|
|
32689
|
+
];
|
|
32690
|
+
var DnssecKeyList = [
|
|
32691
|
+
1,
|
|
32354
32692
|
n02,
|
|
32355
32693
|
_DKL,
|
|
32356
32694
|
0,
|
|
@@ -32448,6 +32786,14 @@ var RegisterDomain$ = [
|
|
|
32448
32786
|
() => RegisterDomainRequest$,
|
|
32449
32787
|
() => RegisterDomainResponse$
|
|
32450
32788
|
];
|
|
32789
|
+
var UpdateDomainNameservers$ = [
|
|
32790
|
+
9,
|
|
32791
|
+
n02,
|
|
32792
|
+
_UDN,
|
|
32793
|
+
0,
|
|
32794
|
+
() => UpdateDomainNameserversRequest$,
|
|
32795
|
+
() => UpdateDomainNameserversResponse$
|
|
32796
|
+
];
|
|
32451
32797
|
|
|
32452
32798
|
// node_modules/@aws-sdk/client-route-53-domains/dist-es/runtimeConfig.shared.js
|
|
32453
32799
|
var getRuntimeConfig3 = (config) => {
|
|
@@ -32652,6 +32998,14 @@ class RegisterDomainCommand extends import_smithy_client23.Command.classBuilder(
|
|
|
32652
32998
|
}).s("Route53Domains_v20140515", "RegisterDomain", {}).n("Route53DomainsClient", "RegisterDomainCommand").sc(RegisterDomain$).build() {
|
|
32653
32999
|
}
|
|
32654
33000
|
|
|
33001
|
+
// node_modules/@aws-sdk/client-route-53-domains/dist-es/commands/UpdateDomainNameserversCommand.js
|
|
33002
|
+
var import_middleware_endpoint15 = __toESM(require_dist_cjs39(), 1);
|
|
33003
|
+
var import_smithy_client24 = __toESM(require_dist_cjs27(), 1);
|
|
33004
|
+
class UpdateDomainNameserversCommand extends import_smithy_client24.Command.classBuilder().ep(commonParams2).m(function(Command2, cs, config, o3) {
|
|
33005
|
+
return [import_middleware_endpoint15.getEndpointPlugin(config, Command2.getEndpointParameterInstructions())];
|
|
33006
|
+
}).s("Route53Domains_v20140515", "UpdateDomainNameservers", {}).n("Route53DomainsClient", "UpdateDomainNameserversCommand").sc(UpdateDomainNameservers$).build() {
|
|
33007
|
+
}
|
|
33008
|
+
|
|
32655
33009
|
// src/lib/route53.ts
|
|
32656
33010
|
function getConfig2() {
|
|
32657
33011
|
return {
|
|
@@ -32751,6 +33105,17 @@ async function getDomainDetail(domain, config) {
|
|
|
32751
33105
|
nameservers: (result.Nameservers ?? []).map((ns) => ns.Name ?? "").filter(Boolean)
|
|
32752
33106
|
};
|
|
32753
33107
|
}
|
|
33108
|
+
async function updateNameservers(domain, nameservers, config, client) {
|
|
33109
|
+
if (!nameservers.length) {
|
|
33110
|
+
throw new Error("updateNameservers requires at least one nameserver");
|
|
33111
|
+
}
|
|
33112
|
+
const domains = client ?? makeClients(config).domains;
|
|
33113
|
+
const result = await domains.send(new UpdateDomainNameserversCommand({
|
|
33114
|
+
DomainName: domain,
|
|
33115
|
+
Nameservers: nameservers.map((name) => ({ Name: name }))
|
|
33116
|
+
}));
|
|
33117
|
+
return { operationId: result.OperationId ?? "" };
|
|
33118
|
+
}
|
|
32754
33119
|
async function listRegisteredDomains(config) {
|
|
32755
33120
|
const { domains } = makeClients(config);
|
|
32756
33121
|
const all = [];
|
|
@@ -33036,15 +33401,10 @@ function createRoute53Provider(config) {
|
|
|
33036
33401
|
|
|
33037
33402
|
// src/lib/cloudflare.ts
|
|
33038
33403
|
function getConfig3() {
|
|
33039
|
-
return
|
|
33040
|
-
apiToken: process.env["CLOUDFLARE_API_TOKEN"],
|
|
33041
|
-
accountId: process.env["CLOUDFLARE_ACCOUNT_ID"]
|
|
33042
|
-
};
|
|
33404
|
+
return resolveCloudflareConfig();
|
|
33043
33405
|
}
|
|
33044
33406
|
function checkCredentials2(cfg) {
|
|
33045
|
-
|
|
33046
|
-
throw new Error("Cloudflare credentials not configured. Set CLOUDFLARE_API_TOKEN environment variable.");
|
|
33047
|
-
}
|
|
33407
|
+
cloudflareAuthHeaders(cfg);
|
|
33048
33408
|
}
|
|
33049
33409
|
var CF_BASE = "https://api.cloudflare.com/client/v4";
|
|
33050
33410
|
async function cfFetch(path, opts = {}) {
|
|
@@ -33053,7 +33413,7 @@ async function cfFetch(path, opts = {}) {
|
|
|
33053
33413
|
const res = await fetch(`${CF_BASE}${path}`, {
|
|
33054
33414
|
method: opts.method ?? "GET",
|
|
33055
33415
|
headers: {
|
|
33056
|
-
|
|
33416
|
+
...cloudflareAuthHeaders(cfg),
|
|
33057
33417
|
"Content-Type": "application/json"
|
|
33058
33418
|
},
|
|
33059
33419
|
body: opts.body ? JSON.stringify(opts.body) : undefined
|
|
@@ -33160,250 +33520,8 @@ function createCloudflareProvider(config) {
|
|
|
33160
33520
|
};
|
|
33161
33521
|
}
|
|
33162
33522
|
|
|
33163
|
-
// src/lib/brandsight.ts
|
|
33164
|
-
init_version();
|
|
33165
|
-
|
|
33166
|
-
class BrandsightApiError extends Error {
|
|
33167
|
-
statusCode;
|
|
33168
|
-
responseBody;
|
|
33169
|
-
constructor(message, statusCode, responseBody) {
|
|
33170
|
-
super(message);
|
|
33171
|
-
this.statusCode = statusCode;
|
|
33172
|
-
this.responseBody = responseBody;
|
|
33173
|
-
this.name = "BrandsightApiError";
|
|
33174
|
-
}
|
|
33175
|
-
}
|
|
33176
|
-
var _fetchFn = null;
|
|
33177
|
-
function getApiKey() {
|
|
33178
|
-
const key = process.env["BRANDSIGHT_API_KEY"];
|
|
33179
|
-
if (!key) {
|
|
33180
|
-
throw new BrandsightApiError("BRANDSIGHT_API_KEY environment variable is not set");
|
|
33181
|
-
}
|
|
33182
|
-
return key;
|
|
33183
|
-
}
|
|
33184
|
-
function getConfig4() {
|
|
33185
|
-
return {
|
|
33186
|
-
apiKey: process.env["BRANDSIGHT_API_KEY"] ?? "",
|
|
33187
|
-
accountId: process.env["BRANDSIGHT_ACCOUNT_ID"]
|
|
33188
|
-
};
|
|
33189
|
-
}
|
|
33190
|
-
var BRANDSIGHT_BASE = "https://api.brandsight.com/v1";
|
|
33191
|
-
async function apiRequest3(method, path, apiKey, body, baseUrl = BRANDSIGHT_BASE) {
|
|
33192
|
-
const fetchFn = _fetchFn || globalThis.fetch;
|
|
33193
|
-
const url = `${baseUrl}${path}`;
|
|
33194
|
-
const headers = {
|
|
33195
|
-
Authorization: `Bearer ${apiKey}`,
|
|
33196
|
-
"Content-Type": "application/json",
|
|
33197
|
-
Accept: "application/json",
|
|
33198
|
-
"User-Agent": USER_AGENT
|
|
33199
|
-
};
|
|
33200
|
-
try {
|
|
33201
|
-
const response = await fetchFn(url, {
|
|
33202
|
-
method,
|
|
33203
|
-
headers,
|
|
33204
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
33205
|
-
signal: AbortSignal.timeout(15000)
|
|
33206
|
-
});
|
|
33207
|
-
if (!response.ok) {
|
|
33208
|
-
throw new BrandsightApiError(`Brandsight API ${method} ${path} failed with status ${response.status}`, response.status, await response.text());
|
|
33209
|
-
}
|
|
33210
|
-
const data = await response.json();
|
|
33211
|
-
return { data, stub: false };
|
|
33212
|
-
} catch (error) {
|
|
33213
|
-
if (error instanceof BrandsightApiError)
|
|
33214
|
-
throw error;
|
|
33215
|
-
return { data: null, stub: true };
|
|
33216
|
-
}
|
|
33217
|
-
}
|
|
33218
|
-
async function apiGet(path, apiKey, baseUrl = BRANDSIGHT_BASE) {
|
|
33219
|
-
const fetchFn = _fetchFn || globalThis.fetch;
|
|
33220
|
-
const url = `${baseUrl}${path}`;
|
|
33221
|
-
const headers = {
|
|
33222
|
-
Authorization: `Bearer ${apiKey}`,
|
|
33223
|
-
"Content-Type": "application/json",
|
|
33224
|
-
Accept: "application/json",
|
|
33225
|
-
"User-Agent": USER_AGENT
|
|
33226
|
-
};
|
|
33227
|
-
try {
|
|
33228
|
-
const response = await fetchFn(url, {
|
|
33229
|
-
method: "GET",
|
|
33230
|
-
headers,
|
|
33231
|
-
signal: AbortSignal.timeout(15000)
|
|
33232
|
-
});
|
|
33233
|
-
if (!response.ok) {
|
|
33234
|
-
throw new BrandsightApiError(`Brandsight API GET ${path} failed with status ${response.status}`, response.status, await response.text());
|
|
33235
|
-
}
|
|
33236
|
-
const data = await response.json();
|
|
33237
|
-
return { data, stub: false };
|
|
33238
|
-
} catch (error) {
|
|
33239
|
-
if (error instanceof BrandsightApiError)
|
|
33240
|
-
throw error;
|
|
33241
|
-
return { data: null, stub: true };
|
|
33242
|
-
}
|
|
33243
|
-
}
|
|
33244
|
-
function generateStubAlerts(brandName) {
|
|
33245
|
-
const now = new Date().toISOString();
|
|
33246
|
-
return [
|
|
33247
|
-
{ domain: `${brandName}-deals.com`, type: "keyword", registered_at: now },
|
|
33248
|
-
{ domain: `${brandName.replace(/a/gi, "4").replace(/e/gi, "3")}.com`, type: "homoglyph", registered_at: now },
|
|
33249
|
-
{ domain: `${brandName}s.com`, type: "typosquat", registered_at: now }
|
|
33250
|
-
];
|
|
33251
|
-
}
|
|
33252
|
-
function generateStubSimilarDomains(domain) {
|
|
33253
|
-
const base = domain.replace(/\.[^.]+$/, "");
|
|
33254
|
-
const tld = domain.slice(base.length);
|
|
33255
|
-
return [
|
|
33256
|
-
`${base}-online${tld}`,
|
|
33257
|
-
`${base}s${tld}`,
|
|
33258
|
-
`${base.replace(/a/gi, "4")}${tld}`,
|
|
33259
|
-
`${base}-app${tld}`,
|
|
33260
|
-
`get${base}${tld}`
|
|
33261
|
-
];
|
|
33262
|
-
}
|
|
33263
|
-
function generateStubThreatAssessment(domain) {
|
|
33264
|
-
return {
|
|
33265
|
-
domain,
|
|
33266
|
-
risk_level: "low",
|
|
33267
|
-
threats: [],
|
|
33268
|
-
recommendation: "No immediate threats detected. Continue routine monitoring."
|
|
33269
|
-
};
|
|
33270
|
-
}
|
|
33271
|
-
async function monitorBrand(brandName) {
|
|
33272
|
-
const apiKey = getApiKey();
|
|
33273
|
-
const result = await apiGet(`/brands/${encodeURIComponent(brandName)}/monitor`, apiKey);
|
|
33274
|
-
if (result.stub) {
|
|
33275
|
-
return { brand: brandName, alerts: generateStubAlerts(brandName), stub: true };
|
|
33276
|
-
}
|
|
33277
|
-
return { brand: brandName, alerts: result.data.alerts, stub: false };
|
|
33278
|
-
}
|
|
33279
|
-
async function getSimilarDomains(domain) {
|
|
33280
|
-
const apiKey = getApiKey();
|
|
33281
|
-
const result = await apiGet(`/domains/${encodeURIComponent(domain)}/similar`, apiKey);
|
|
33282
|
-
if (result.stub) {
|
|
33283
|
-
return { domain, similar: generateStubSimilarDomains(domain), stub: true };
|
|
33284
|
-
}
|
|
33285
|
-
return { domain, similar: result.data.similar, stub: false };
|
|
33286
|
-
}
|
|
33287
|
-
async function getThreatAssessment(domain) {
|
|
33288
|
-
const apiKey = getApiKey();
|
|
33289
|
-
const result = await apiGet(`/domains/${encodeURIComponent(domain)}/threats`, apiKey);
|
|
33290
|
-
if (result.stub) {
|
|
33291
|
-
return { ...generateStubThreatAssessment(domain), stub: true };
|
|
33292
|
-
}
|
|
33293
|
-
return { ...result.data, stub: false };
|
|
33294
|
-
}
|
|
33295
|
-
async function listDomains2(config) {
|
|
33296
|
-
const cfg = config ?? getConfig4();
|
|
33297
|
-
const result = await apiGet("/portfolio/domains", cfg.apiKey);
|
|
33298
|
-
if (result.stub)
|
|
33299
|
-
return [];
|
|
33300
|
-
return result.data.domains ?? [];
|
|
33301
|
-
}
|
|
33302
|
-
async function getDomainInfo3(domain, config) {
|
|
33303
|
-
const cfg = config ?? getConfig4();
|
|
33304
|
-
const result = await apiGet(`/portfolio/domains/${encodeURIComponent(domain)}`, cfg.apiKey);
|
|
33305
|
-
if (result.stub)
|
|
33306
|
-
return null;
|
|
33307
|
-
return result.data;
|
|
33308
|
-
}
|
|
33309
|
-
async function checkAvailability4(domain, config) {
|
|
33310
|
-
const cfg = config ?? getConfig4();
|
|
33311
|
-
const result = await apiGet(`/domains/check?domain=${encodeURIComponent(domain)}`, cfg.apiKey);
|
|
33312
|
-
if (result.stub)
|
|
33313
|
-
return { domain, available: false };
|
|
33314
|
-
return result.data;
|
|
33315
|
-
}
|
|
33316
|
-
async function renewDomain3(domain, years = 1, config) {
|
|
33317
|
-
const cfg = config ?? getConfig4();
|
|
33318
|
-
const result = await apiRequest3("POST", `/portfolio/domains/${encodeURIComponent(domain)}/renew`, cfg.apiKey, { years });
|
|
33319
|
-
if (result.stub)
|
|
33320
|
-
return { success: false };
|
|
33321
|
-
return { success: true, orderId: result.data.orderId };
|
|
33322
|
-
}
|
|
33323
|
-
async function syncToLocalDb3(dbFns, config) {
|
|
33324
|
-
const domains = await listDomains2(config);
|
|
33325
|
-
let synced = 0, created = 0, updated = 0;
|
|
33326
|
-
const errors = [];
|
|
33327
|
-
for (const d3 of domains) {
|
|
33328
|
-
try {
|
|
33329
|
-
const existing = dbFns.getDomainByName(d3.domain);
|
|
33330
|
-
if (existing) {
|
|
33331
|
-
dbFns.updateDomain(existing.id, {
|
|
33332
|
-
registrar: "Brandsight",
|
|
33333
|
-
expires_at: d3.expires || undefined,
|
|
33334
|
-
auto_renew: d3.auto_renew,
|
|
33335
|
-
status: "active",
|
|
33336
|
-
nameservers: d3.nameservers
|
|
33337
|
-
});
|
|
33338
|
-
updated++;
|
|
33339
|
-
} else {
|
|
33340
|
-
dbFns.createDomain({
|
|
33341
|
-
name: d3.domain,
|
|
33342
|
-
registrar: "Brandsight",
|
|
33343
|
-
expires_at: d3.expires || undefined,
|
|
33344
|
-
auto_renew: d3.auto_renew,
|
|
33345
|
-
status: "active",
|
|
33346
|
-
nameservers: d3.nameservers
|
|
33347
|
-
});
|
|
33348
|
-
created++;
|
|
33349
|
-
}
|
|
33350
|
-
synced++;
|
|
33351
|
-
} catch (err) {
|
|
33352
|
-
errors.push(`${d3.domain}: ${err instanceof Error ? err.message : String(err)}`);
|
|
33353
|
-
}
|
|
33354
|
-
}
|
|
33355
|
-
return { synced, created, updated, errors };
|
|
33356
|
-
}
|
|
33357
|
-
function createBrandsightProvider(config) {
|
|
33358
|
-
const cfg = config ?? getConfig4();
|
|
33359
|
-
return {
|
|
33360
|
-
name: "brandsight",
|
|
33361
|
-
async listDomains() {
|
|
33362
|
-
const domains = await listDomains2(cfg);
|
|
33363
|
-
return domains.map((d3) => ({
|
|
33364
|
-
domain: d3.domain,
|
|
33365
|
-
registrar: "Brandsight",
|
|
33366
|
-
created: "",
|
|
33367
|
-
expires: d3.expires,
|
|
33368
|
-
nameservers: d3.nameservers,
|
|
33369
|
-
status: d3.status === "ACTIVE" ? "active" : d3.status.toLowerCase(),
|
|
33370
|
-
auto_renew: d3.auto_renew
|
|
33371
|
-
}));
|
|
33372
|
-
},
|
|
33373
|
-
async getDomainInfo(domain) {
|
|
33374
|
-
const d3 = await getDomainInfo3(domain, cfg);
|
|
33375
|
-
if (!d3)
|
|
33376
|
-
throw new Error(`Domain not found in Brandsight: ${domain}`);
|
|
33377
|
-
return {
|
|
33378
|
-
domain: d3.domain,
|
|
33379
|
-
registrar: "Brandsight",
|
|
33380
|
-
created: "",
|
|
33381
|
-
expires: d3.expires,
|
|
33382
|
-
nameservers: d3.nameservers,
|
|
33383
|
-
status: d3.status === "ACTIVE" ? "active" : d3.status.toLowerCase(),
|
|
33384
|
-
auto_renew: d3.auto_renew
|
|
33385
|
-
};
|
|
33386
|
-
},
|
|
33387
|
-
async renewDomain(domain) {
|
|
33388
|
-
const result = await renewDomain3(domain, 1, cfg);
|
|
33389
|
-
return { domain, success: result.success, orderId: result.orderId };
|
|
33390
|
-
},
|
|
33391
|
-
async checkAvailability(domain) {
|
|
33392
|
-
const result = await checkAvailability4(domain, cfg);
|
|
33393
|
-
return {
|
|
33394
|
-
domain: result.domain,
|
|
33395
|
-
available: result.available,
|
|
33396
|
-
standard_price: result.price,
|
|
33397
|
-
currency: result.currency
|
|
33398
|
-
};
|
|
33399
|
-
},
|
|
33400
|
-
async syncToLocalDb(dbFns) {
|
|
33401
|
-
return syncToLocalDb3(dbFns, cfg);
|
|
33402
|
-
}
|
|
33403
|
-
};
|
|
33404
|
-
}
|
|
33405
|
-
|
|
33406
33523
|
// src/lib/registrar.ts
|
|
33524
|
+
init_brandsight();
|
|
33407
33525
|
function createNamecheapProvider() {
|
|
33408
33526
|
return {
|
|
33409
33527
|
name: "namecheap",
|
|
@@ -33732,6 +33850,16 @@ function resolveContact(opts) {
|
|
|
33732
33850
|
return { first_name, last_name, email, phone, address_line_1, city, state, country_code, zip_code, organization_name };
|
|
33733
33851
|
}
|
|
33734
33852
|
|
|
33853
|
+
// src/lib/delegate.ts
|
|
33854
|
+
async function delegateDomainToCloudflare(domain, deps) {
|
|
33855
|
+
const zone = await deps.createCloudflareZone(domain);
|
|
33856
|
+
if (!zone.nameservers || zone.nameservers.length === 0) {
|
|
33857
|
+
throw new Error(`Cloudflare zone for ${domain} returned no nameservers; cannot delegate`);
|
|
33858
|
+
}
|
|
33859
|
+
const { operationId } = await deps.updateNameservers(domain, zone.nameservers);
|
|
33860
|
+
return { zoneId: zone.id, nameservers: zone.nameservers, operationId };
|
|
33861
|
+
}
|
|
33862
|
+
|
|
33735
33863
|
// src/cli/commands/domain.ts
|
|
33736
33864
|
var DOMAIN_STATUS_HELP = DOMAIN_STATUSES.join("/");
|
|
33737
33865
|
var DOMAIN_OFFER_STATUS_HELP = DOMAIN_OFFER_STATUSES.join("/");
|
|
@@ -34155,7 +34283,7 @@ WHOIS for ${result.domain} [${result.source}]:`);
|
|
|
34155
34283
|
process.exit(1);
|
|
34156
34284
|
}
|
|
34157
34285
|
});
|
|
34158
|
-
domain.command("buy <name>").description("Purchase a domain via Route 53 (contact defaults from: domains config set contact.*)").option("--provider <name>", "Registrar provider (default: config default-registrar or route53)").option("--registrar <name>", "Registrar/seller for recorded purchases (alias of --provider)").option("--email <email>", "Registrant email").option("--first-name <n>", "First name").option("--last-name <n>", "Last name").option("--phone <p>", "Phone").option("--address <a>", "Street address").option("--city <c>", "City").option("--state <s>", "State/province").option("--country <c>", "Country code").option("--zip <z>", "ZIP code").option("--org <o>", "Organization").option("--price <amount>", "Record a completed purchase instead of registering via Route 53").option("--expires <date>", "Expiry date for recorded purchases").option("--auto-renew <bool>", "Auto-renew for recorded purchases (true/false)").option("--years <n>", "Years", "1").option("--wait", "Poll until registration completes").action(async (name, opts) => {
|
|
34286
|
+
domain.command("buy <name>").description("Purchase a domain via Route 53 (contact defaults from: domains config set contact.*)").option("--provider <name>", "Registrar provider (default: config default-registrar or route53)").option("--registrar <name>", "Registrar/seller for recorded purchases (alias of --provider)").option("--email <email>", "Registrant email").option("--first-name <n>", "First name").option("--last-name <n>", "Last name").option("--phone <p>", "Phone").option("--address <a>", "Street address").option("--city <c>", "City").option("--state <s>", "State/province").option("--country <c>", "Country code").option("--zip <z>", "ZIP code").option("--org <o>", "Organization").option("--price <amount>", "Record a completed purchase instead of registering via Route 53").option("--expires <date>", "Expiry date for recorded purchases").option("--auto-renew <bool>", "Auto-renew for recorded purchases (true/false)").option("--years <n>", "Years", "1").option("--wait", "Poll until registration completes").option("--dns <provider>", "DNS provider to delegate to after purchase (always cloudflare)", "cloudflare").option("--no-delegate", "Skip delegating DNS to Cloudflare after purchase").action(async (name, opts) => {
|
|
34159
34287
|
const recordedPrice = parseOptionalNumber(opts.price, "--price");
|
|
34160
34288
|
if (recordedPrice !== undefined) {
|
|
34161
34289
|
const registrarName = opts.registrar ?? opts.provider ?? "manual";
|
|
@@ -34238,6 +34366,30 @@ WHOIS for ${result.domain} [${result.source}]:`);
|
|
|
34238
34366
|
});
|
|
34239
34367
|
}
|
|
34240
34368
|
console.log(`\u2713 Added to portfolio`);
|
|
34369
|
+
const dnsProvider = opts.dns ?? "cloudflare";
|
|
34370
|
+
if (opts.delegate !== false && dnsProvider === "cloudflare") {
|
|
34371
|
+
if (!opts.wait) {
|
|
34372
|
+
console.log(` DNS: run 'domains domain buy ${name} --wait' or delegate later \u2014 registration must finish before NS can change.`);
|
|
34373
|
+
} else {
|
|
34374
|
+
try {
|
|
34375
|
+
console.log(`Delegating DNS to Cloudflare...`);
|
|
34376
|
+
const del = await delegateDomainToCloudflare(name, {
|
|
34377
|
+
createCloudflareZone: async (d3) => {
|
|
34378
|
+
const z2 = await createZone(d3);
|
|
34379
|
+
return { id: z2.id, nameservers: z2.nameservers };
|
|
34380
|
+
},
|
|
34381
|
+
updateNameservers: (d3, ns) => updateNameservers(d3, ns)
|
|
34382
|
+
});
|
|
34383
|
+
const existing2 = getDomainByName(name);
|
|
34384
|
+
if (existing2)
|
|
34385
|
+
updateDomain(existing2.id, { nameservers: del.nameservers });
|
|
34386
|
+
console.log(`\u2713 Cloudflare zone ${del.zoneId}; nameservers \u2192 ${del.nameservers.join(", ")} (op ${del.operationId})`);
|
|
34387
|
+
} catch (e3) {
|
|
34388
|
+
console.error(`\u26A0 DNS delegation failed (domain is registered): ${e3 instanceof Error ? e3.message : String(e3)}`);
|
|
34389
|
+
console.error(` Retry: create the Cloudflare zone and point Route53 NS at it.`);
|
|
34390
|
+
}
|
|
34391
|
+
}
|
|
34392
|
+
}
|
|
34241
34393
|
if (!opts.wait)
|
|
34242
34394
|
console.log(` Check: domains r53 status ${reg.operationId}`);
|
|
34243
34395
|
} catch (e3) {
|
|
@@ -34749,6 +34901,7 @@ function registerAlertCommands(program2) {
|
|
|
34749
34901
|
}
|
|
34750
34902
|
|
|
34751
34903
|
// src/cli/commands/monitor.ts
|
|
34904
|
+
init_brandsight();
|
|
34752
34905
|
function registerMonitorCommand(program2) {
|
|
34753
34906
|
const monitor = program2.command("monitor").description("Brand monitoring and threat detection (Brandsight)");
|
|
34754
34907
|
monitor.command("watch <brand>").description("Monitor a brand for new lookalike domain registrations").option("--json", "Output JSON").action(async (brand, opts) => {
|
|
@@ -35193,6 +35346,14 @@ function registerDoctorCommand(program2) {
|
|
|
35193
35346
|
ok("Registrant contact info complete");
|
|
35194
35347
|
else
|
|
35195
35348
|
fail(`Missing contact fields: ${missingContact.join(", ")}`, "domains config set contact.<field> <value>");
|
|
35349
|
+
section("Provisioning Credentials");
|
|
35350
|
+
const { checkProvisioningCredentials: checkProvisioningCredentials2 } = await Promise.resolve().then(() => (init_creds_check(), exports_creds_check));
|
|
35351
|
+
for (const c3 of checkProvisioningCredentials2()) {
|
|
35352
|
+
if (c3.configured)
|
|
35353
|
+
ok(`${c3.provider}: ${c3.mode} \u2014 ${c3.detail}`);
|
|
35354
|
+
else
|
|
35355
|
+
fail(`${c3.provider}: not configured (${c3.detail})`);
|
|
35356
|
+
}
|
|
35196
35357
|
section("Providers");
|
|
35197
35358
|
const providers = getAvailableProviders().filter((p3) => p3.name !== "brandsight");
|
|
35198
35359
|
for (const p3 of providers) {
|
|
@@ -37250,6 +37411,67 @@ function registerWalletCommand(program2) {
|
|
|
37250
37411
|
});
|
|
37251
37412
|
}
|
|
37252
37413
|
|
|
37414
|
+
// src/lib/provision-state.ts
|
|
37415
|
+
var DOMAIN_FLOW = {
|
|
37416
|
+
requested: { action: "register", next: "registered" },
|
|
37417
|
+
registered: { action: "create_cf_zone", next: "cf_zone_ready" },
|
|
37418
|
+
cf_zone_ready: { action: "delegate_ns", next: "ns_delegated" },
|
|
37419
|
+
ns_delegated: { action: "check_ns_propagation", next: "ns_propagated" },
|
|
37420
|
+
ns_propagated: { action: "verify_dns", next: "dns_managed" },
|
|
37421
|
+
dns_managed: { action: "finalize", next: "ready" }
|
|
37422
|
+
};
|
|
37423
|
+
var TERMINAL = new Set(["ready", "failed"]);
|
|
37424
|
+
function domainHappyPath() {
|
|
37425
|
+
return [...Object.keys(DOMAIN_FLOW), "ready"];
|
|
37426
|
+
}
|
|
37427
|
+
function deriveDomainState(sig) {
|
|
37428
|
+
if (!sig.registered)
|
|
37429
|
+
return "requested";
|
|
37430
|
+
if (!sig.zoneExists)
|
|
37431
|
+
return "registered";
|
|
37432
|
+
if (!sig.registrarNsAreCloudflare)
|
|
37433
|
+
return "cf_zone_ready";
|
|
37434
|
+
if (!sig.publicNsAreCloudflare)
|
|
37435
|
+
return "ns_delegated";
|
|
37436
|
+
if (!sig.zoneActive)
|
|
37437
|
+
return "ns_propagated";
|
|
37438
|
+
return "ready";
|
|
37439
|
+
}
|
|
37440
|
+
|
|
37441
|
+
// src/cli/commands/provision.ts
|
|
37442
|
+
var CF_NS_SUFFIX = ".ns.cloudflare.com";
|
|
37443
|
+
function registerProvisionCommand(program2) {
|
|
37444
|
+
const provision = program2.command("provision").description("Domain provisioning lifecycle");
|
|
37445
|
+
provision.command("status <name>").description("Show the provisioning state of a domain (derived from live signals)").action(async (name) => {
|
|
37446
|
+
const signals = {};
|
|
37447
|
+
try {
|
|
37448
|
+
const detail = await getDomainDetail(name).catch(() => null);
|
|
37449
|
+
signals["registered"] = !!detail;
|
|
37450
|
+
const registrarNs = detail?.nameservers ?? [];
|
|
37451
|
+
signals["registrarNsAreCloudflare"] = registrarNs.length > 0 && registrarNs.every((n3) => n3.includes(CF_NS_SUFFIX));
|
|
37452
|
+
const zone = await getZone(name).catch(() => null);
|
|
37453
|
+
signals["zoneExists"] = !!zone;
|
|
37454
|
+
signals["zoneActive"] = zone?.status === "active";
|
|
37455
|
+
try {
|
|
37456
|
+
const resolved = await (await import("dns")).promises.resolveNs(name).catch(() => []);
|
|
37457
|
+
signals["publicNsAreCloudflare"] = resolved.length > 0 && resolved.every((n3) => n3.includes(CF_NS_SUFFIX));
|
|
37458
|
+
} catch {
|
|
37459
|
+
signals["publicNsAreCloudflare"] = false;
|
|
37460
|
+
}
|
|
37461
|
+
} catch (e3) {
|
|
37462
|
+
console.error(`Error gathering signals: ${e3 instanceof Error ? e3.message : String(e3)}`);
|
|
37463
|
+
}
|
|
37464
|
+
const state = deriveDomainState(signals);
|
|
37465
|
+
console.log(`
|
|
37466
|
+
Domain: ${name}`);
|
|
37467
|
+
console.log(`State: ${state}`);
|
|
37468
|
+
console.log(`Signals: ${JSON.stringify(signals)}`);
|
|
37469
|
+
const path = domainHappyPath();
|
|
37470
|
+
const idx = path.indexOf(state);
|
|
37471
|
+
console.log(`Progress: ${idx >= 0 ? idx + 1 : "?"}/${path.length} [${path.join(" \u2192 ")}]`);
|
|
37472
|
+
});
|
|
37473
|
+
}
|
|
37474
|
+
|
|
37253
37475
|
// src/cli/index.ts
|
|
37254
37476
|
init_version();
|
|
37255
37477
|
var program2 = new Command;
|
|
@@ -37273,4 +37495,5 @@ registerResearchCommand(program2);
|
|
|
37273
37495
|
registerOutreachCommand(program2);
|
|
37274
37496
|
registerSedoCommand(program2);
|
|
37275
37497
|
registerWalletCommand(program2);
|
|
37498
|
+
registerProvisionCommand(program2);
|
|
37276
37499
|
program2.parse(process.argv);
|