@hasna/domains 0.0.21 → 0.0.22
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 -3
- package/dist/cli/commands/provider.d.ts.map +1 -1
- package/dist/cli/commands/providers.d.ts.map +1 -1
- package/dist/cli/index.js +584 -112
- package/dist/db/domain-records.d.ts +2 -2
- package/dist/db/domain-records.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +520 -104
- package/dist/lib/brandsight.d.ts +46 -2
- package/dist/lib/brandsight.d.ts.map +1 -1
- package/dist/lib/capability.d.ts +5 -3
- package/dist/lib/capability.d.ts.map +1 -1
- package/dist/lib/cloudflare.d.ts +2 -2
- package/dist/lib/cloudflare.d.ts.map +1 -1
- package/dist/lib/godaddy.d.ts +4 -4
- package/dist/lib/registrar.d.ts +13 -3
- package/dist/lib/registrar.d.ts.map +1 -1
- package/dist/lib/route53.d.ts +2 -0
- package/dist/lib/route53.d.ts.map +1 -1
- package/dist/mcp/index.js +510 -91
- package/package.json +2 -2
package/dist/mcp/index.js
CHANGED
|
@@ -39325,7 +39325,8 @@ function getConfig2() {
|
|
|
39325
39325
|
return {
|
|
39326
39326
|
region: process.env["AWS_REGION"] || "us-east-1",
|
|
39327
39327
|
accessKeyId: process.env["AWS_ACCESS_KEY_ID"],
|
|
39328
|
-
secretAccessKey: process.env["AWS_SECRET_ACCESS_KEY"]
|
|
39328
|
+
secretAccessKey: process.env["AWS_SECRET_ACCESS_KEY"],
|
|
39329
|
+
sessionToken: process.env["AWS_SESSION_TOKEN"]
|
|
39329
39330
|
};
|
|
39330
39331
|
}
|
|
39331
39332
|
function checkCredentials(cfg) {
|
|
@@ -39341,7 +39342,7 @@ function makeClients(config) {
|
|
|
39341
39342
|
const cfg = config ?? getConfig2();
|
|
39342
39343
|
checkCredentials(cfg);
|
|
39343
39344
|
const region = cfg.region || "us-east-1";
|
|
39344
|
-
const credentials = cfg.accessKeyId && cfg.secretAccessKey ? { accessKeyId: cfg.accessKeyId, secretAccessKey: cfg.secretAccessKey } : undefined;
|
|
39345
|
+
const credentials = cfg.accessKeyId && cfg.secretAccessKey ? { accessKeyId: cfg.accessKeyId, secretAccessKey: cfg.secretAccessKey, sessionToken: cfg.sessionToken } : undefined;
|
|
39345
39346
|
return {
|
|
39346
39347
|
route53: new Route53Client({ region, credentials }),
|
|
39347
39348
|
domains: new Route53DomainsClient({ region: "us-east-1", credentials })
|
|
@@ -39481,7 +39482,8 @@ async function listHostedZones(config) {
|
|
|
39481
39482
|
id: cleanZoneId(z2.Id ?? ""),
|
|
39482
39483
|
name: z2.Name ?? "",
|
|
39483
39484
|
record_count: z2.ResourceRecordSetCount ?? 0,
|
|
39484
|
-
comment: z2.Config?.Comment
|
|
39485
|
+
comment: z2.Config?.Comment,
|
|
39486
|
+
private_zone: z2.Config?.PrivateZone
|
|
39485
39487
|
});
|
|
39486
39488
|
}
|
|
39487
39489
|
marker = result.IsTruncated ? result.NextMarker : undefined;
|
|
@@ -39496,7 +39498,8 @@ async function getHostedZone(hostedZoneId, config) {
|
|
|
39496
39498
|
name: result.HostedZone?.Name ?? "",
|
|
39497
39499
|
record_count: result.HostedZone?.ResourceRecordSetCount ?? 0,
|
|
39498
39500
|
comment: result.HostedZone?.Config?.Comment,
|
|
39499
|
-
name_servers: result.DelegationSet?.NameServers ?? []
|
|
39501
|
+
name_servers: result.DelegationSet?.NameServers ?? [],
|
|
39502
|
+
private_zone: result.HostedZone?.Config?.PrivateZone
|
|
39500
39503
|
};
|
|
39501
39504
|
}
|
|
39502
39505
|
async function deleteHostedZone(hostedZoneId, config) {
|
|
@@ -39506,7 +39509,15 @@ async function deleteHostedZone(hostedZoneId, config) {
|
|
|
39506
39509
|
async function findHostedZoneByDomain(domain, config) {
|
|
39507
39510
|
const zones = await listHostedZones(config);
|
|
39508
39511
|
const normalized = domain.endsWith(".") ? domain : `${domain}.`;
|
|
39509
|
-
|
|
39512
|
+
const matches = zones.filter((z2) => z2.name === normalized);
|
|
39513
|
+
if (matches.length === 0)
|
|
39514
|
+
return null;
|
|
39515
|
+
const publicMatches = matches.filter((z2) => !z2.private_zone);
|
|
39516
|
+
const candidates = publicMatches.length > 0 ? publicMatches : matches;
|
|
39517
|
+
if (candidates.length > 1) {
|
|
39518
|
+
throw new Error(`Multiple Route 53 hosted zones found for ${domain}; specify hosted zone id`);
|
|
39519
|
+
}
|
|
39520
|
+
return candidates[0] ?? null;
|
|
39510
39521
|
}
|
|
39511
39522
|
function rrsToRecord(rrs) {
|
|
39512
39523
|
if (rrs.AliasTarget) {
|
|
@@ -39606,19 +39617,53 @@ function createRoute53Provider(config) {
|
|
|
39606
39617
|
const cfg = config ?? getConfig2();
|
|
39607
39618
|
const registerWithRoute53 = registerDomain2;
|
|
39608
39619
|
const updateRoute53Nameservers = updateNameservers2;
|
|
39620
|
+
async function listDomainInventory() {
|
|
39621
|
+
const byDomain = new Map;
|
|
39622
|
+
try {
|
|
39623
|
+
const registered = await listRegisteredDomains(cfg);
|
|
39624
|
+
for (const d3 of registered) {
|
|
39625
|
+
byDomain.set(d3.domain, {
|
|
39626
|
+
domain: d3.domain,
|
|
39627
|
+
registrar: "AWS Route 53",
|
|
39628
|
+
created: "",
|
|
39629
|
+
expires: d3.expiry,
|
|
39630
|
+
nameservers: [],
|
|
39631
|
+
status: "active",
|
|
39632
|
+
auto_renew: d3.auto_renew
|
|
39633
|
+
});
|
|
39634
|
+
}
|
|
39635
|
+
} catch (error) {
|
|
39636
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
39637
|
+
if (!message.includes("route53domains:ListDomains") && !message.includes("AccessDenied")) {
|
|
39638
|
+
throw error;
|
|
39639
|
+
}
|
|
39640
|
+
}
|
|
39641
|
+
const zones = await listHostedZones(cfg);
|
|
39642
|
+
for (const z2 of zones) {
|
|
39643
|
+
const zone = z2.name_servers?.length ? z2 : await getHostedZone(z2.id, cfg).catch(() => z2);
|
|
39644
|
+
const domain = zone.name.replace(/\.$/, "");
|
|
39645
|
+
const nameservers = zone.name_servers ?? [];
|
|
39646
|
+
const existing = byDomain.get(domain);
|
|
39647
|
+
if (existing) {
|
|
39648
|
+
existing.nameservers = nameservers.length > 0 ? nameservers : existing.nameservers;
|
|
39649
|
+
continue;
|
|
39650
|
+
}
|
|
39651
|
+
byDomain.set(domain, {
|
|
39652
|
+
domain,
|
|
39653
|
+
registrar: "AWS Route 53 DNS",
|
|
39654
|
+
created: "",
|
|
39655
|
+
expires: "",
|
|
39656
|
+
nameservers,
|
|
39657
|
+
status: "active",
|
|
39658
|
+
auto_renew: false
|
|
39659
|
+
});
|
|
39660
|
+
}
|
|
39661
|
+
return Array.from(byDomain.values());
|
|
39662
|
+
}
|
|
39609
39663
|
return {
|
|
39610
39664
|
name: "route53",
|
|
39611
39665
|
async listDomains() {
|
|
39612
|
-
|
|
39613
|
-
return domains.map((d3) => ({
|
|
39614
|
-
domain: d3.domain,
|
|
39615
|
-
registrar: "AWS Route 53",
|
|
39616
|
-
created: "",
|
|
39617
|
-
expires: d3.expiry,
|
|
39618
|
-
nameservers: [],
|
|
39619
|
-
status: "active",
|
|
39620
|
-
auto_renew: d3.auto_renew
|
|
39621
|
-
}));
|
|
39666
|
+
return listDomainInventory();
|
|
39622
39667
|
},
|
|
39623
39668
|
async getDomainInfo(domain) {
|
|
39624
39669
|
const detail = await getDomainDetail(domain, cfg);
|
|
@@ -39687,7 +39732,7 @@ function createRoute53Provider(config) {
|
|
|
39687
39732
|
};
|
|
39688
39733
|
},
|
|
39689
39734
|
async syncToLocalDb(dbFns) {
|
|
39690
|
-
const domains = await
|
|
39735
|
+
const domains = await listDomainInventory();
|
|
39691
39736
|
let synced = 0;
|
|
39692
39737
|
let created = 0;
|
|
39693
39738
|
let updated = 0;
|
|
@@ -39696,20 +39741,39 @@ function createRoute53Provider(config) {
|
|
|
39696
39741
|
try {
|
|
39697
39742
|
const existing = dbFns.getDomainByName(d3.domain);
|
|
39698
39743
|
if (existing) {
|
|
39744
|
+
const existingRoute53 = existing.metadata["route53"];
|
|
39745
|
+
const staleDnsOnlyRegistrar = d3.registrar !== "AWS Route 53" && (existing.registrar === "AWS Route 53 DNS" || existing.registrar === "AWS Route 53" && existingRoute53?.source === "route53:hosted_zones");
|
|
39699
39746
|
dbFns.updateDomain(existing.id, {
|
|
39700
|
-
registrar: "AWS Route 53",
|
|
39701
|
-
|
|
39747
|
+
...d3.registrar === "AWS Route 53" ? { registrar: "AWS Route 53" } : {},
|
|
39748
|
+
...staleDnsOnlyRegistrar ? { registrar: null } : {},
|
|
39749
|
+
expires_at: d3.expires || undefined,
|
|
39702
39750
|
auto_renew: d3.auto_renew,
|
|
39751
|
+
nameservers: d3.nameservers.length > 0 ? d3.nameservers : existing.nameservers,
|
|
39752
|
+
metadata: {
|
|
39753
|
+
...existing.metadata,
|
|
39754
|
+
route53: {
|
|
39755
|
+
source: d3.registrar === "AWS Route 53" ? "route53domains+hosted_zones" : "route53:hosted_zones",
|
|
39756
|
+
synced_at: new Date().toISOString()
|
|
39757
|
+
}
|
|
39758
|
+
},
|
|
39703
39759
|
status: "active"
|
|
39704
39760
|
});
|
|
39705
39761
|
updated++;
|
|
39706
39762
|
} else {
|
|
39707
39763
|
dbFns.createDomain({
|
|
39708
39764
|
name: d3.domain,
|
|
39709
|
-
registrar: "AWS Route 53",
|
|
39710
|
-
expires_at: d3.
|
|
39765
|
+
...d3.registrar === "AWS Route 53" ? { registrar: "AWS Route 53" } : {},
|
|
39766
|
+
expires_at: d3.expires || undefined,
|
|
39711
39767
|
auto_renew: d3.auto_renew,
|
|
39712
|
-
|
|
39768
|
+
nameservers: d3.nameservers,
|
|
39769
|
+
status: "active",
|
|
39770
|
+
notes: d3.registrar === "AWS Route 53 DNS" ? "Discovered from Route 53 hosted zones; registrar ownership was not inferred." : undefined,
|
|
39771
|
+
metadata: {
|
|
39772
|
+
route53: {
|
|
39773
|
+
source: d3.registrar === "AWS Route 53" ? "route53domains+hosted_zones" : "route53:hosted_zones",
|
|
39774
|
+
synced_at: new Date().toISOString()
|
|
39775
|
+
}
|
|
39776
|
+
}
|
|
39713
39777
|
});
|
|
39714
39778
|
created++;
|
|
39715
39779
|
}
|
|
@@ -39882,6 +39946,22 @@ async function cfFetch(path, opts = {}) {
|
|
|
39882
39946
|
}
|
|
39883
39947
|
return json.result;
|
|
39884
39948
|
}
|
|
39949
|
+
async function listZones(config) {
|
|
39950
|
+
const zones = [];
|
|
39951
|
+
let page = 1;
|
|
39952
|
+
while (true) {
|
|
39953
|
+
const result = await cfFetch(`/zones?per_page=50&page=${page}`, { config });
|
|
39954
|
+
if (!result || result.length === 0)
|
|
39955
|
+
break;
|
|
39956
|
+
for (const z2 of result) {
|
|
39957
|
+
zones.push({ id: z2.id, name: z2.name, status: z2.status, nameservers: z2.name_servers, original_nameservers: z2.original_name_servers });
|
|
39958
|
+
}
|
|
39959
|
+
if (result.length < 50)
|
|
39960
|
+
break;
|
|
39961
|
+
page++;
|
|
39962
|
+
}
|
|
39963
|
+
return zones;
|
|
39964
|
+
}
|
|
39885
39965
|
async function getZone(domain, config) {
|
|
39886
39966
|
const result = await cfFetch(`/zones?name=${encodeURIComponent(domain)}`, { config });
|
|
39887
39967
|
if (!result || result.length === 0)
|
|
@@ -39923,26 +40003,111 @@ async function listRecords2(zoneId, config) {
|
|
|
39923
40003
|
}
|
|
39924
40004
|
return records;
|
|
39925
40005
|
}
|
|
39926
|
-
async function
|
|
39927
|
-
const
|
|
39928
|
-
|
|
39929
|
-
|
|
39930
|
-
|
|
39931
|
-
|
|
39932
|
-
|
|
39933
|
-
|
|
39934
|
-
|
|
39935
|
-
|
|
39936
|
-
|
|
39937
|
-
|
|
39938
|
-
|
|
39939
|
-
|
|
40006
|
+
async function listRecordsByNameType(zoneId, type, name, config) {
|
|
40007
|
+
const result = await cfFetch(`/zones/${zoneId}/dns_records?type=${encodeURIComponent(type)}&name=${encodeURIComponent(name)}`, { config });
|
|
40008
|
+
return (result ?? []).map((r3) => ({
|
|
40009
|
+
id: r3.id,
|
|
40010
|
+
type: r3.type,
|
|
40011
|
+
name: r3.name,
|
|
40012
|
+
content: r3.content,
|
|
40013
|
+
ttl: r3.ttl,
|
|
40014
|
+
priority: r3.priority,
|
|
40015
|
+
proxied: r3.proxied
|
|
40016
|
+
}));
|
|
40017
|
+
}
|
|
40018
|
+
async function replaceRecordsByNameType(zoneId, records, config) {
|
|
40019
|
+
if (records.length === 0)
|
|
40020
|
+
return;
|
|
40021
|
+
const { type, name } = records[0];
|
|
40022
|
+
const existing = await listRecordsByNameType(zoneId, type, name, config);
|
|
40023
|
+
for (const record of existing) {
|
|
40024
|
+
if (record.id)
|
|
40025
|
+
await deleteRecord2(zoneId, record.id, config);
|
|
40026
|
+
}
|
|
40027
|
+
for (const record of records) {
|
|
40028
|
+
await cfFetch(`/zones/${zoneId}/dns_records`, {
|
|
40029
|
+
method: "POST",
|
|
40030
|
+
body: {
|
|
40031
|
+
type: record.type,
|
|
40032
|
+
name: record.name,
|
|
40033
|
+
content: record.content,
|
|
40034
|
+
ttl: record.ttl ?? 1,
|
|
40035
|
+
priority: record.priority,
|
|
40036
|
+
proxied: record.proxied ?? false
|
|
40037
|
+
},
|
|
40038
|
+
config
|
|
40039
|
+
});
|
|
39940
40040
|
}
|
|
39941
40041
|
}
|
|
40042
|
+
async function deleteRecord2(zoneId, recordId, config) {
|
|
40043
|
+
await cfFetch(`/zones/${zoneId}/dns_records/${recordId}`, { method: "DELETE", config });
|
|
40044
|
+
}
|
|
40045
|
+
function zoneToDomainInfo(zone) {
|
|
40046
|
+
return {
|
|
40047
|
+
domain: zone.name,
|
|
40048
|
+
registrar: "Cloudflare DNS",
|
|
40049
|
+
created: "",
|
|
40050
|
+
expires: "",
|
|
40051
|
+
nameservers: zone.nameservers,
|
|
40052
|
+
status: zone.status === "active" ? "active" : "discovered",
|
|
40053
|
+
auto_renew: false
|
|
40054
|
+
};
|
|
40055
|
+
}
|
|
40056
|
+
function withCloudflareMetadata(existing, zone) {
|
|
40057
|
+
return {
|
|
40058
|
+
...existing,
|
|
40059
|
+
cloudflare: {
|
|
40060
|
+
zone_id: zone.id,
|
|
40061
|
+
zone_status: zone.status,
|
|
40062
|
+
source: "cloudflare:zones",
|
|
40063
|
+
synced_at: new Date().toISOString()
|
|
40064
|
+
}
|
|
40065
|
+
};
|
|
40066
|
+
}
|
|
39942
40067
|
function createCloudflareProvider(config) {
|
|
39943
40068
|
const cfg = config ?? getConfig3();
|
|
39944
40069
|
return {
|
|
39945
40070
|
name: "cloudflare",
|
|
40071
|
+
async listDomains() {
|
|
40072
|
+
const zones = await listZones(cfg);
|
|
40073
|
+
return zones.map(zoneToDomainInfo);
|
|
40074
|
+
},
|
|
40075
|
+
async syncToLocalDb(dbFns) {
|
|
40076
|
+
const zones = await listZones(cfg);
|
|
40077
|
+
let synced = 0;
|
|
40078
|
+
let created = 0;
|
|
40079
|
+
let updated = 0;
|
|
40080
|
+
const errors2 = [];
|
|
40081
|
+
for (const zone of zones) {
|
|
40082
|
+
try {
|
|
40083
|
+
const info = zoneToDomainInfo(zone);
|
|
40084
|
+
const existing = dbFns.getDomainByName(zone.name);
|
|
40085
|
+
if (existing) {
|
|
40086
|
+
dbFns.updateDomain(existing.id, {
|
|
40087
|
+
...existing.registrar === "Cloudflare DNS" ? { registrar: null } : {},
|
|
40088
|
+
status: existing.status === "discovered" && info.status === "active" ? "active" : existing.status,
|
|
40089
|
+
nameservers: zone.nameservers,
|
|
40090
|
+
metadata: withCloudflareMetadata(existing.metadata, zone)
|
|
40091
|
+
});
|
|
40092
|
+
updated++;
|
|
40093
|
+
} else {
|
|
40094
|
+
dbFns.createDomain({
|
|
40095
|
+
name: zone.name,
|
|
40096
|
+
status: info.status === "active" ? "active" : "discovered",
|
|
40097
|
+
auto_renew: false,
|
|
40098
|
+
nameservers: zone.nameservers,
|
|
40099
|
+
notes: "Discovered from Cloudflare zones; registrar ownership was not inferred.",
|
|
40100
|
+
metadata: withCloudflareMetadata({}, zone)
|
|
40101
|
+
});
|
|
40102
|
+
created++;
|
|
40103
|
+
}
|
|
40104
|
+
synced++;
|
|
40105
|
+
} catch (err) {
|
|
40106
|
+
errors2.push(`${zone.name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
40107
|
+
}
|
|
40108
|
+
}
|
|
40109
|
+
return { synced, created, updated, errors: errors2 };
|
|
40110
|
+
},
|
|
39946
40111
|
async getDnsRecords(domain) {
|
|
39947
40112
|
const zone = await getZone(domain, cfg);
|
|
39948
40113
|
if (!zone)
|
|
@@ -39960,8 +40125,15 @@ function createCloudflareProvider(config) {
|
|
|
39960
40125
|
const zone = await getZone(domain, cfg);
|
|
39961
40126
|
if (!zone)
|
|
39962
40127
|
throw new Error(`No Cloudflare zone found for ${domain}`);
|
|
40128
|
+
const grouped = new Map;
|
|
39963
40129
|
for (const r3 of records) {
|
|
39964
|
-
|
|
40130
|
+
const key = `${r3.type}|${r3.name}`;
|
|
40131
|
+
const existing = grouped.get(key) ?? [];
|
|
40132
|
+
existing.push({ type: r3.type, name: r3.name, content: r3.value, ttl: r3.ttl || 1, priority: r3.priority });
|
|
40133
|
+
grouped.set(key, existing);
|
|
40134
|
+
}
|
|
40135
|
+
for (const group of grouped.values()) {
|
|
40136
|
+
await replaceRecordsByNameType(zone.id, group, cfg);
|
|
39965
40137
|
}
|
|
39966
40138
|
return true;
|
|
39967
40139
|
}
|
|
@@ -40006,7 +40178,8 @@ function getConfig4() {
|
|
|
40006
40178
|
return resolveBrandsightConfig();
|
|
40007
40179
|
}
|
|
40008
40180
|
var BRANDSIGHT_BASE = "https://api.brandsight.com/v1";
|
|
40009
|
-
|
|
40181
|
+
var BRANDSIGHT_DOMAIN_BASE = "https://api.godaddy.com/v2";
|
|
40182
|
+
async function apiGet(path, apiKey, baseUrl = BRANDSIGHT_BASE) {
|
|
40010
40183
|
const fetchFn = _fetchFn || globalThis.fetch;
|
|
40011
40184
|
const url = `${baseUrl}${path}`;
|
|
40012
40185
|
const headers = {
|
|
@@ -40017,13 +40190,12 @@ async function apiRequest3(method, path, apiKey, body, baseUrl = BRANDSIGHT_BASE
|
|
|
40017
40190
|
};
|
|
40018
40191
|
try {
|
|
40019
40192
|
const response = await fetchFn(url, {
|
|
40020
|
-
method,
|
|
40193
|
+
method: "GET",
|
|
40021
40194
|
headers,
|
|
40022
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
40023
40195
|
signal: AbortSignal.timeout(15000)
|
|
40024
40196
|
});
|
|
40025
40197
|
if (!response.ok) {
|
|
40026
|
-
throw new BrandsightApiError(`Brandsight API
|
|
40198
|
+
throw new BrandsightApiError(`Brandsight API GET ${path} failed with status ${response.status}`, response.status, await response.text());
|
|
40027
40199
|
}
|
|
40028
40200
|
const data = await response.json();
|
|
40029
40201
|
return { data, stub: false };
|
|
@@ -40033,31 +40205,102 @@ async function apiRequest3(method, path, apiKey, body, baseUrl = BRANDSIGHT_BASE
|
|
|
40033
40205
|
return { data: null, stub: true };
|
|
40034
40206
|
}
|
|
40035
40207
|
}
|
|
40036
|
-
|
|
40037
|
-
const
|
|
40038
|
-
|
|
40039
|
-
|
|
40040
|
-
|
|
40208
|
+
function requireDomainConfig(config) {
|
|
40209
|
+
const cfg = config ?? getConfig4();
|
|
40210
|
+
if (!cfg.apiKey || !cfg.apiSecret || !cfg.customerId) {
|
|
40211
|
+
throw new BrandsightApiError("Brandsight Domain API credentials are not configured. Set BRANDSIGHT_API_KEY, BRANDSIGHT_API_SECRET, and BRANDSIGHT_CUSTOMER_ID (or HASNAXYZ_BRANDSIGHT_LIVE_* aliases).");
|
|
40212
|
+
}
|
|
40213
|
+
return cfg;
|
|
40214
|
+
}
|
|
40215
|
+
function domainBaseUrl(cfg) {
|
|
40216
|
+
return cfg.baseUrl ?? BRANDSIGHT_DOMAIN_BASE;
|
|
40217
|
+
}
|
|
40218
|
+
function domainHeaders(cfg) {
|
|
40219
|
+
return {
|
|
40220
|
+
Authorization: `sso-key ${cfg.apiKey}:${cfg.apiSecret}`,
|
|
40041
40221
|
"Content-Type": "application/json",
|
|
40042
40222
|
Accept: "application/json",
|
|
40043
40223
|
"User-Agent": USER_AGENT
|
|
40044
40224
|
};
|
|
40045
|
-
|
|
40046
|
-
|
|
40047
|
-
|
|
40048
|
-
|
|
40049
|
-
|
|
40050
|
-
|
|
40051
|
-
|
|
40052
|
-
|
|
40053
|
-
|
|
40054
|
-
|
|
40055
|
-
|
|
40056
|
-
|
|
40057
|
-
|
|
40058
|
-
throw error;
|
|
40059
|
-
return { data: null, stub: true };
|
|
40225
|
+
}
|
|
40226
|
+
async function domainApiRequest(method, path, config, body) {
|
|
40227
|
+
const cfg = requireDomainConfig(config);
|
|
40228
|
+
const fetchFn = _fetchFn || globalThis.fetch;
|
|
40229
|
+
const response = await fetchFn(`${domainBaseUrl(cfg)}${path}`, {
|
|
40230
|
+
method,
|
|
40231
|
+
headers: domainHeaders(cfg),
|
|
40232
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
40233
|
+
signal: AbortSignal.timeout(30000)
|
|
40234
|
+
});
|
|
40235
|
+
const text = await response.text();
|
|
40236
|
+
if (!response.ok) {
|
|
40237
|
+
throw new BrandsightApiError(`Brandsight Domain API ${method} ${path} failed with status ${response.status}`, response.status, text);
|
|
40060
40238
|
}
|
|
40239
|
+
if (!text.trim())
|
|
40240
|
+
return {};
|
|
40241
|
+
return JSON.parse(text);
|
|
40242
|
+
}
|
|
40243
|
+
function normalizeBrandsightDomain(raw) {
|
|
40244
|
+
const nameServers = raw.nameServers ?? raw.nameservers ?? [];
|
|
40245
|
+
const expiresAt = raw.expiresAt ?? raw.expires ?? "";
|
|
40246
|
+
const createdAt = raw.createdAt ?? raw.created ?? "";
|
|
40247
|
+
const renewAuto = raw.renewAuto ?? raw.auto_renew ?? false;
|
|
40248
|
+
return {
|
|
40249
|
+
...raw,
|
|
40250
|
+
domain: String(raw.domain ?? ""),
|
|
40251
|
+
status: String(raw.status ?? "UNKNOWN"),
|
|
40252
|
+
created: createdAt,
|
|
40253
|
+
expires: expiresAt,
|
|
40254
|
+
auto_renew: renewAuto,
|
|
40255
|
+
locked: Boolean(raw.locked),
|
|
40256
|
+
nameservers: nameServers,
|
|
40257
|
+
createdAt,
|
|
40258
|
+
expiresAt,
|
|
40259
|
+
nameServers,
|
|
40260
|
+
renewAuto
|
|
40261
|
+
};
|
|
40262
|
+
}
|
|
40263
|
+
function customerPath(cfg, path) {
|
|
40264
|
+
return `/customers/${encodeURIComponent(cfg.customerId)}${path}`;
|
|
40265
|
+
}
|
|
40266
|
+
function domainTld(domain) {
|
|
40267
|
+
const parts = domain.split(".").filter(Boolean);
|
|
40268
|
+
if (parts.length < 2)
|
|
40269
|
+
throw new BrandsightApiError(`Invalid domain name: ${domain}`);
|
|
40270
|
+
return parts.slice(1).join(".");
|
|
40271
|
+
}
|
|
40272
|
+
function brandsightContact(contact) {
|
|
40273
|
+
return {
|
|
40274
|
+
addressMailing: {
|
|
40275
|
+
address1: contact.address_line_1,
|
|
40276
|
+
city: contact.city,
|
|
40277
|
+
country: contact.country_code,
|
|
40278
|
+
postalCode: contact.zip_code,
|
|
40279
|
+
state: contact.state
|
|
40280
|
+
},
|
|
40281
|
+
email: contact.email,
|
|
40282
|
+
encoding: "ASCII",
|
|
40283
|
+
nameFirst: contact.first_name,
|
|
40284
|
+
nameLast: contact.last_name,
|
|
40285
|
+
organization: contact.organization_name,
|
|
40286
|
+
phone: contact.phone
|
|
40287
|
+
};
|
|
40288
|
+
}
|
|
40289
|
+
async function domainAvailability(domain, cfg, type, period = 1) {
|
|
40290
|
+
const params = new URLSearchParams({
|
|
40291
|
+
domain,
|
|
40292
|
+
period: String(period),
|
|
40293
|
+
type,
|
|
40294
|
+
optimizeFor: "ACCURACY"
|
|
40295
|
+
});
|
|
40296
|
+
const result = await domainApiRequest("GET", `/domains/available?${params.toString()}`, cfg);
|
|
40297
|
+
return {
|
|
40298
|
+
domain: result.domain ?? domain,
|
|
40299
|
+
available: Boolean(result.available),
|
|
40300
|
+
price: result.price,
|
|
40301
|
+
currency: result.currency,
|
|
40302
|
+
registryPremiumPricing: result.registryPremiumPricing
|
|
40303
|
+
};
|
|
40061
40304
|
}
|
|
40062
40305
|
function generateStubAlerts(brandName) {
|
|
40063
40306
|
const now = new Date().toISOString();
|
|
@@ -40111,32 +40354,160 @@ async function getThreatAssessment(domain) {
|
|
|
40111
40354
|
return { ...result.data, stub: false };
|
|
40112
40355
|
}
|
|
40113
40356
|
async function listDomains2(config) {
|
|
40114
|
-
const cfg = config
|
|
40115
|
-
const
|
|
40116
|
-
|
|
40117
|
-
|
|
40118
|
-
|
|
40357
|
+
const cfg = requireDomainConfig(config);
|
|
40358
|
+
const domains = [];
|
|
40359
|
+
const seenMarkers = new Set;
|
|
40360
|
+
let marker;
|
|
40361
|
+
while (true) {
|
|
40362
|
+
const params = new URLSearchParams({ limit: "500" });
|
|
40363
|
+
if (marker)
|
|
40364
|
+
params.set("marker", marker);
|
|
40365
|
+
const batch = await domainApiRequest("GET", customerPath(cfg, `/domains?${params.toString()}`), cfg);
|
|
40366
|
+
if (!Array.isArray(batch) || batch.length === 0)
|
|
40367
|
+
break;
|
|
40368
|
+
domains.push(...batch.map(normalizeBrandsightDomain).filter((d3) => d3.domain));
|
|
40369
|
+
if (batch.length < 500)
|
|
40370
|
+
break;
|
|
40371
|
+
const nextMarker = String(batch[batch.length - 1]?.domain ?? "");
|
|
40372
|
+
if (!nextMarker || seenMarkers.has(nextMarker))
|
|
40373
|
+
break;
|
|
40374
|
+
seenMarkers.add(nextMarker);
|
|
40375
|
+
marker = nextMarker;
|
|
40376
|
+
}
|
|
40377
|
+
return domains;
|
|
40119
40378
|
}
|
|
40120
40379
|
async function getDomainInfo3(domain, config) {
|
|
40121
|
-
const cfg = config
|
|
40122
|
-
const result = await
|
|
40123
|
-
|
|
40124
|
-
return null;
|
|
40125
|
-
return result.data;
|
|
40380
|
+
const cfg = requireDomainConfig(config);
|
|
40381
|
+
const result = await domainApiRequest("GET", customerPath(cfg, `/domains/${encodeURIComponent(domain)}`), cfg);
|
|
40382
|
+
return normalizeBrandsightDomain(result);
|
|
40126
40383
|
}
|
|
40127
40384
|
async function checkAvailability4(domain, config) {
|
|
40128
|
-
const cfg = config
|
|
40129
|
-
|
|
40130
|
-
if (result.stub)
|
|
40131
|
-
return { domain, available: false };
|
|
40132
|
-
return result.data;
|
|
40385
|
+
const cfg = requireDomainConfig(config);
|
|
40386
|
+
return domainAvailability(domain, cfg, "REGISTRATION", 1);
|
|
40133
40387
|
}
|
|
40134
40388
|
async function renewDomain3(domain, years = 1, config) {
|
|
40135
|
-
const cfg = config
|
|
40136
|
-
const
|
|
40137
|
-
if (
|
|
40138
|
-
|
|
40139
|
-
|
|
40389
|
+
const cfg = requireDomainConfig(config);
|
|
40390
|
+
const current = await getDomainInfo3(domain, cfg);
|
|
40391
|
+
if (!current?.expires)
|
|
40392
|
+
throw new BrandsightApiError(`Cannot renew ${domain}: current expiry is unavailable`);
|
|
40393
|
+
const quote = await domainAvailability(domain, cfg, "RENEWAL", years);
|
|
40394
|
+
const price = quote.price ?? current.renewal?.price;
|
|
40395
|
+
const currency = quote.currency ?? current.renewal?.currency;
|
|
40396
|
+
if (price == null || !currency) {
|
|
40397
|
+
throw new BrandsightApiError(`Cannot renew ${domain}: renewal quote did not include an exact price and currency`);
|
|
40398
|
+
}
|
|
40399
|
+
const result = await domainApiRequest("POST", customerPath(cfg, `/domains/${encodeURIComponent(domain)}/renew`), cfg, {
|
|
40400
|
+
consent: {
|
|
40401
|
+
agreedAt: new Date().toISOString(),
|
|
40402
|
+
agreedBy: cfg.shopperId ?? "domains-cli",
|
|
40403
|
+
currency,
|
|
40404
|
+
price,
|
|
40405
|
+
registryPremiumPricing: quote.registryPremiumPricing ?? false
|
|
40406
|
+
},
|
|
40407
|
+
expires: current.expires,
|
|
40408
|
+
period: years
|
|
40409
|
+
});
|
|
40410
|
+
return { success: true, orderId: result.orderId ?? result.id };
|
|
40411
|
+
}
|
|
40412
|
+
async function getLegalAgreements(tld, privacy = false, config) {
|
|
40413
|
+
const cfg = requireDomainConfig(config);
|
|
40414
|
+
const params = new URLSearchParams({
|
|
40415
|
+
privacy: String(privacy),
|
|
40416
|
+
tlds: tld
|
|
40417
|
+
});
|
|
40418
|
+
return domainApiRequest("GET", customerPath(cfg, `/domains/agreements?${params.toString()}`), cfg);
|
|
40419
|
+
}
|
|
40420
|
+
async function getRegistrationSchema(tld, config) {
|
|
40421
|
+
const cfg = requireDomainConfig(config);
|
|
40422
|
+
return domainApiRequest("GET", customerPath(cfg, `/domains/register/schema/${encodeURIComponent(tld)}`), cfg);
|
|
40423
|
+
}
|
|
40424
|
+
async function validateRegistrationRequest(payload, config) {
|
|
40425
|
+
const cfg = requireDomainConfig(config);
|
|
40426
|
+
await domainApiRequest("POST", customerPath(cfg, "/domains/register/validate"), cfg, payload);
|
|
40427
|
+
return true;
|
|
40428
|
+
}
|
|
40429
|
+
async function registerBrandsightDomain(domain, contact, options = {}, config) {
|
|
40430
|
+
const cfg = requireDomainConfig(config);
|
|
40431
|
+
const period = options.years ?? 1;
|
|
40432
|
+
const availability = await domainAvailability(domain, cfg, "REGISTRATION", period);
|
|
40433
|
+
if (!availability.available)
|
|
40434
|
+
throw new BrandsightApiError(`${domain} is not available for registration`);
|
|
40435
|
+
const price = options.premiumPrice ?? availability.price;
|
|
40436
|
+
if (price == null || !availability.currency) {
|
|
40437
|
+
throw new BrandsightApiError(`Cannot register ${domain}: availability quote did not include an exact price and currency`);
|
|
40438
|
+
}
|
|
40439
|
+
const tld = domainTld(domain);
|
|
40440
|
+
const schema = await getRegistrationSchema(tld, cfg);
|
|
40441
|
+
const required = Array.isArray(schema["required"]) ? schema["required"] : [];
|
|
40442
|
+
if (required.includes("metadata") && !options.metadata) {
|
|
40443
|
+
throw new BrandsightApiError(`Cannot register ${domain}: ${tld} requires TLD-specific metadata; pass registration metadata before validation`);
|
|
40444
|
+
}
|
|
40445
|
+
const privacy = options.privacy ?? false;
|
|
40446
|
+
const agreements = await getLegalAgreements(tld, privacy, cfg);
|
|
40447
|
+
const agreementKeys = agreements.map((a3) => a3.agreementKey).filter(Boolean);
|
|
40448
|
+
const c3 = brandsightContact(contact);
|
|
40449
|
+
const payload = {
|
|
40450
|
+
consent: {
|
|
40451
|
+
agreedAt: new Date().toISOString(),
|
|
40452
|
+
agreedBy: contact.email || cfg.shopperId || "domains-cli",
|
|
40453
|
+
agreementKeys,
|
|
40454
|
+
currency: availability.currency,
|
|
40455
|
+
price,
|
|
40456
|
+
registryPremiumPricing: availability.registryPremiumPricing ?? !!options.premiumPrice
|
|
40457
|
+
},
|
|
40458
|
+
contacts: {
|
|
40459
|
+
admin: c3,
|
|
40460
|
+
billing: c3,
|
|
40461
|
+
registrant: c3,
|
|
40462
|
+
tech: c3
|
|
40463
|
+
},
|
|
40464
|
+
domain,
|
|
40465
|
+
metadata: options.metadata ?? {},
|
|
40466
|
+
nameServers: options.nameservers ?? [],
|
|
40467
|
+
period,
|
|
40468
|
+
privacy,
|
|
40469
|
+
renewAuto: options.autoRenew ?? true
|
|
40470
|
+
};
|
|
40471
|
+
await validateRegistrationRequest(payload, cfg);
|
|
40472
|
+
const result = await domainApiRequest("POST", customerPath(cfg, "/domains/register"), cfg, payload);
|
|
40473
|
+
return {
|
|
40474
|
+
success: true,
|
|
40475
|
+
orderId: result.orderId ?? result.id,
|
|
40476
|
+
operationId: result.operationId ?? result.id,
|
|
40477
|
+
chargedAmount: String(price)
|
|
40478
|
+
};
|
|
40479
|
+
}
|
|
40480
|
+
async function updateNameservers3(domain, nameservers, config) {
|
|
40481
|
+
const cfg = requireDomainConfig(config);
|
|
40482
|
+
const result = await domainApiRequest("PUT", customerPath(cfg, `/domains/${encodeURIComponent(domain)}/nameServers`), cfg, { nameServers: nameservers });
|
|
40483
|
+
return { success: true, operationId: result.operationId ?? result.id };
|
|
40484
|
+
}
|
|
40485
|
+
async function getDnsRecords3(domain, config) {
|
|
40486
|
+
const cfg = requireDomainConfig(config);
|
|
40487
|
+
const records = [];
|
|
40488
|
+
let offset = 0;
|
|
40489
|
+
const limit = 1000;
|
|
40490
|
+
while (true) {
|
|
40491
|
+
const batch = await domainApiRequest("GET", customerPath(cfg, `/domains/${encodeURIComponent(domain)}/records?offset=${offset}&limit=${limit}`), cfg);
|
|
40492
|
+
if (!Array.isArray(batch) || batch.length === 0)
|
|
40493
|
+
break;
|
|
40494
|
+
records.push(...batch);
|
|
40495
|
+
if (batch.length < limit)
|
|
40496
|
+
break;
|
|
40497
|
+
offset++;
|
|
40498
|
+
}
|
|
40499
|
+
return records;
|
|
40500
|
+
}
|
|
40501
|
+
function normalizeBrandsightDnsRecord(record) {
|
|
40502
|
+
return {
|
|
40503
|
+
...record,
|
|
40504
|
+
ttl: Math.max(record.ttl || 600, 600)
|
|
40505
|
+
};
|
|
40506
|
+
}
|
|
40507
|
+
async function setDnsRecords3(domain, records, config) {
|
|
40508
|
+
const cfg = requireDomainConfig(config);
|
|
40509
|
+
await domainApiRequest("PUT", customerPath(cfg, `/domains/${encodeURIComponent(domain)}/records`), cfg, records.map(normalizeBrandsightDnsRecord));
|
|
40510
|
+
return true;
|
|
40140
40511
|
}
|
|
40141
40512
|
async function syncToLocalDb3(dbFns, config) {
|
|
40142
40513
|
const domains = await listDomains2(config);
|
|
@@ -40181,7 +40552,7 @@ function createBrandsightProvider(config) {
|
|
|
40181
40552
|
return domains.map((d3) => ({
|
|
40182
40553
|
domain: d3.domain,
|
|
40183
40554
|
registrar: "Brandsight",
|
|
40184
|
-
created: "",
|
|
40555
|
+
created: d3.created ?? "",
|
|
40185
40556
|
expires: d3.expires,
|
|
40186
40557
|
nameservers: d3.nameservers,
|
|
40187
40558
|
status: d3.status === "ACTIVE" ? "active" : d3.status.toLowerCase(),
|
|
@@ -40195,7 +40566,7 @@ function createBrandsightProvider(config) {
|
|
|
40195
40566
|
return {
|
|
40196
40567
|
domain: d3.domain,
|
|
40197
40568
|
registrar: "Brandsight",
|
|
40198
|
-
created: "",
|
|
40569
|
+
created: d3.created ?? "",
|
|
40199
40570
|
expires: d3.expires,
|
|
40200
40571
|
nameservers: d3.nameservers,
|
|
40201
40572
|
status: d3.status === "ACTIVE" ? "active" : d3.status.toLowerCase(),
|
|
@@ -40206,12 +40577,47 @@ function createBrandsightProvider(config) {
|
|
|
40206
40577
|
const result = await renewDomain3(domain, years, cfg);
|
|
40207
40578
|
return { domain, success: result.success, orderId: result.orderId };
|
|
40208
40579
|
},
|
|
40580
|
+
async registerDomain(domain, contact, options) {
|
|
40581
|
+
const result = await registerBrandsightDomain(domain, contact, options, cfg);
|
|
40582
|
+
return {
|
|
40583
|
+
domain,
|
|
40584
|
+
success: result.success,
|
|
40585
|
+
orderId: result.orderId,
|
|
40586
|
+
operationId: result.operationId,
|
|
40587
|
+
chargedAmount: result.chargedAmount
|
|
40588
|
+
};
|
|
40589
|
+
},
|
|
40590
|
+
async updateNameservers(domain, nameservers) {
|
|
40591
|
+
const result = await updateNameservers3(domain, nameservers, cfg);
|
|
40592
|
+
return { domain, success: result.success, operationId: result.operationId };
|
|
40593
|
+
},
|
|
40594
|
+
async getDnsRecords(domain) {
|
|
40595
|
+
const records = await getDnsRecords3(domain, cfg);
|
|
40596
|
+
return records.map((r3) => ({
|
|
40597
|
+
type: r3.type,
|
|
40598
|
+
name: r3.name,
|
|
40599
|
+
value: r3.data,
|
|
40600
|
+
ttl: r3.ttl,
|
|
40601
|
+
priority: r3.priority
|
|
40602
|
+
}));
|
|
40603
|
+
},
|
|
40604
|
+
async setDnsRecords(domain, records) {
|
|
40605
|
+
return setDnsRecords3(domain, records.map((r3) => ({
|
|
40606
|
+
type: r3.type,
|
|
40607
|
+
name: r3.name,
|
|
40608
|
+
data: r3.value,
|
|
40609
|
+
ttl: r3.ttl,
|
|
40610
|
+
priority: r3.priority
|
|
40611
|
+
})), cfg);
|
|
40612
|
+
},
|
|
40209
40613
|
async checkAvailability(domain) {
|
|
40210
40614
|
const result = await checkAvailability4(domain, cfg);
|
|
40211
40615
|
return {
|
|
40212
40616
|
domain: result.domain,
|
|
40213
40617
|
available: result.available,
|
|
40214
|
-
|
|
40618
|
+
is_premium: result.registryPremiumPricing,
|
|
40619
|
+
premium_price: result.registryPremiumPricing ? result.price : undefined,
|
|
40620
|
+
standard_price: result.registryPremiumPricing ? undefined : result.price,
|
|
40215
40621
|
currency: result.currency
|
|
40216
40622
|
};
|
|
40217
40623
|
},
|
|
@@ -40409,6 +40815,7 @@ var providerRegistry = new Map([
|
|
|
40409
40815
|
configured: false,
|
|
40410
40816
|
envVars: providerEnvNames("namecheap")
|
|
40411
40817
|
},
|
|
40818
|
+
createInventory: createNamecheapProvider,
|
|
40412
40819
|
createRegistrar: createNamecheapProvider,
|
|
40413
40820
|
createDns: createNamecheapProvider
|
|
40414
40821
|
}],
|
|
@@ -40419,6 +40826,7 @@ var providerRegistry = new Map([
|
|
|
40419
40826
|
configured: false,
|
|
40420
40827
|
envVars: providerEnvNames("godaddy")
|
|
40421
40828
|
},
|
|
40829
|
+
createInventory: createGoDaddyProvider,
|
|
40422
40830
|
createRegistrar: createGoDaddyProvider,
|
|
40423
40831
|
createDns: createGoDaddyProvider
|
|
40424
40832
|
}],
|
|
@@ -40429,6 +40837,7 @@ var providerRegistry = new Map([
|
|
|
40429
40837
|
configured: false,
|
|
40430
40838
|
envVars: providerEnvNames("route53")
|
|
40431
40839
|
},
|
|
40840
|
+
createInventory: () => createRoute53Provider(),
|
|
40432
40841
|
createRegistrar: () => createRoute53Provider(),
|
|
40433
40842
|
createDns: () => createRoute53Provider()
|
|
40434
40843
|
}],
|
|
@@ -40439,16 +40848,19 @@ var providerRegistry = new Map([
|
|
|
40439
40848
|
configured: false,
|
|
40440
40849
|
envVars: providerEnvNames("cloudflare")
|
|
40441
40850
|
},
|
|
40851
|
+
createInventory: () => createCloudflareProvider(),
|
|
40442
40852
|
createDns: createCloudflareProvider
|
|
40443
40853
|
}],
|
|
40444
40854
|
["brandsight", {
|
|
40445
40855
|
info: {
|
|
40446
40856
|
name: "brandsight",
|
|
40447
|
-
type: "
|
|
40857
|
+
type: "full",
|
|
40448
40858
|
configured: false,
|
|
40449
40859
|
envVars: providerEnvNames("brandsight")
|
|
40450
40860
|
},
|
|
40451
|
-
|
|
40861
|
+
createInventory: createBrandsightProvider,
|
|
40862
|
+
createRegistrar: createBrandsightProvider,
|
|
40863
|
+
createDns: createBrandsightProvider
|
|
40452
40864
|
}],
|
|
40453
40865
|
["sedo", {
|
|
40454
40866
|
info: {
|
|
@@ -40465,11 +40877,18 @@ function isConfigured(providerName) {
|
|
|
40465
40877
|
function getAvailableProviders() {
|
|
40466
40878
|
return Array.from(providerRegistry.values()).map((e3) => ({
|
|
40467
40879
|
...e3.info,
|
|
40468
|
-
configured: isConfigured(e3.info.name)
|
|
40880
|
+
configured: isConfigured(e3.info.name),
|
|
40881
|
+
inventory: !!e3.createInventory
|
|
40469
40882
|
}));
|
|
40470
40883
|
}
|
|
40471
|
-
function
|
|
40472
|
-
return !!providerRegistry.get(name.toLowerCase())?.
|
|
40884
|
+
function providerHasInventory(name) {
|
|
40885
|
+
return !!providerRegistry.get(name.toLowerCase())?.createInventory;
|
|
40886
|
+
}
|
|
40887
|
+
function getDomainInventoryProvider(name) {
|
|
40888
|
+
const entry = providerRegistry.get(name.toLowerCase());
|
|
40889
|
+
if (!entry?.createInventory)
|
|
40890
|
+
throw new Error(`No domain inventory provider: ${name}`);
|
|
40891
|
+
return entry.createInventory();
|
|
40473
40892
|
}
|
|
40474
40893
|
function getRegistrarProvider(name) {
|
|
40475
40894
|
const entry = providerRegistry.get(name.toLowerCase());
|
|
@@ -40484,11 +40903,11 @@ function getDnsProvider(name) {
|
|
|
40484
40903
|
return entry.createDns();
|
|
40485
40904
|
}
|
|
40486
40905
|
async function syncAll(dbFns) {
|
|
40487
|
-
const available = getAvailableProviders().filter((p3) => p3.configured &&
|
|
40906
|
+
const available = getAvailableProviders().filter((p3) => p3.configured && providerHasInventory(p3.name));
|
|
40488
40907
|
const result = { providers: [], totalSynced: 0, totalErrors: [] };
|
|
40489
40908
|
for (const info of available) {
|
|
40490
40909
|
try {
|
|
40491
|
-
const provider =
|
|
40910
|
+
const provider = getDomainInventoryProvider(info.name);
|
|
40492
40911
|
const syncResult = await provider.syncToLocalDb(dbFns);
|
|
40493
40912
|
result.providers.push({ name: info.name, result: syncResult });
|
|
40494
40913
|
result.totalSynced += syncResult.synced;
|
|
@@ -41769,7 +42188,7 @@ function buildServer() {
|
|
|
41769
42188
|
});
|
|
41770
42189
|
server.registerTool("sync_all_providers", {
|
|
41771
42190
|
title: "Sync All Providers",
|
|
41772
|
-
description: "Sync domains from all configured
|
|
42191
|
+
description: "Sync domains from all configured domain inventory providers (Route 53, Cloudflare zones, Namecheap, GoDaddy, Brandsight) to local database.",
|
|
41773
42192
|
inputSchema: {}
|
|
41774
42193
|
}, async () => {
|
|
41775
42194
|
try {
|