@hasna/domains 0.0.36 → 0.0.38

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.
Files changed (42) hide show
  1. package/dist/cli/commands/alerts.d.ts.map +1 -1
  2. package/dist/cli/commands/brandsight.d.ts.map +1 -1
  3. package/dist/cli/commands/config.d.ts.map +1 -1
  4. package/dist/cli/commands/db.d.ts.map +1 -1
  5. package/dist/cli/commands/dns.d.ts +4 -1
  6. package/dist/cli/commands/dns.d.ts.map +1 -1
  7. package/dist/cli/commands/doctor.d.ts.map +1 -1
  8. package/dist/cli/commands/domain.d.ts.map +1 -1
  9. package/dist/cli/commands/history.d.ts.map +1 -1
  10. package/dist/cli/commands/interactive.d.ts +7 -1
  11. package/dist/cli/commands/interactive.d.ts.map +1 -1
  12. package/dist/cli/commands/mcp-install.d.ts.map +1 -1
  13. package/dist/cli/commands/monitor.d.ts.map +1 -1
  14. package/dist/cli/commands/outreach.d.ts.map +1 -1
  15. package/dist/cli/commands/owner.d.ts.map +1 -1
  16. package/dist/cli/commands/provider.d.ts.map +1 -1
  17. package/dist/cli/commands/providers.d.ts.map +1 -1
  18. package/dist/cli/commands/provision.d.ts.map +1 -1
  19. package/dist/cli/commands/reconcile-expiry.d.ts.map +1 -1
  20. package/dist/cli/commands/research.d.ts.map +1 -1
  21. package/dist/cli/commands/route53.d.ts.map +1 -1
  22. package/dist/cli/commands/sedo.d.ts.map +1 -1
  23. package/dist/cli/commands/serve.d.ts.map +1 -1
  24. package/dist/cli/commands/ssl.d.ts.map +1 -1
  25. package/dist/cli/commands/wallet.d.ts.map +1 -1
  26. package/dist/cli/commands/zone.d.ts.map +1 -1
  27. package/dist/cli/index.js +906 -749
  28. package/dist/db/dns-tools.d.ts.map +1 -1
  29. package/dist/index.js +74 -16
  30. package/dist/lib/cloudflare.d.ts.map +1 -1
  31. package/dist/lib/cloudflare.js +57 -7
  32. package/dist/lib/dns-plan.d.ts +1 -0
  33. package/dist/lib/dns-plan.d.ts.map +1 -1
  34. package/dist/lib/registrar.d.ts +4 -0
  35. package/dist/lib/registrar.d.ts.map +1 -1
  36. package/dist/lib/registrar.js +58 -7
  37. package/dist/lib/route53.d.ts.map +1 -1
  38. package/dist/lib/route53.js +1 -0
  39. package/dist/lib/stdout.d.ts +54 -0
  40. package/dist/lib/stdout.d.ts.map +1 -0
  41. package/dist/mcp/index.js +74 -16
  42. package/package.json +1 -1
package/dist/mcp/index.js CHANGED
@@ -15752,7 +15752,7 @@ var init_bowser = __esm(() => {
15752
15752
 
15753
15753
  // node_modules/@aws-sdk/core/dist-cjs/submodules/client/index.js
15754
15754
  var require_client2 = __commonJS((exports) => {
15755
- var __dirname = "/home/hasna/.hasna/repos/worktrees/open-domains/282f5cec-baae-438a-beed-bdf090475f02/node_modules/@aws-sdk/core/dist-cjs/submodules/client";
15755
+ var __dirname = "/home/hasna/.hasna/repos/worktrees/domains/0a933b3e-a459-4bcb-b94d-6ab12a2ec235/node_modules/@aws-sdk/core/dist-cjs/submodules/client";
15756
15756
  var retry = require_retry();
15757
15757
  var protocols = require_protocols();
15758
15758
  var lambdaInvokeStore = require_invoke_store();
@@ -42534,6 +42534,9 @@ function normalizeDnsRecordType(value) {
42534
42534
  }
42535
42535
  return recordType4;
42536
42536
  }
42537
+ function getVcardPropertyValue(entry) {
42538
+ return entry.length >= 4 ? entry[3] : entry[2];
42539
+ }
42537
42540
  async function rdapLookup(domainName) {
42538
42541
  const domain = normalizeDomainName(domainName);
42539
42542
  const url = `https://rdap.org/domain/${encodeURIComponent(domain)}`;
@@ -42582,17 +42585,19 @@ function extractRegistrantFromRdap(rdap) {
42582
42585
  for (const entry of vcard) {
42583
42586
  if (!Array.isArray(entry) || entry.length < 3)
42584
42587
  continue;
42585
- const [prop, _params, type] = entry;
42588
+ const [prop] = entry;
42589
+ const value = getVcardPropertyValue(entry);
42586
42590
  if (prop === "fn")
42587
- result.name = type ?? null;
42591
+ result.name = typeof value === "string" ? value : null;
42588
42592
  else if (prop === "email")
42589
- result.email = type ?? null;
42593
+ result.email = typeof value === "string" ? value : null;
42590
42594
  else if (prop === "tel")
42591
- result.phone = type ?? null;
42595
+ result.phone = typeof value === "string" ? value : null;
42592
42596
  else if (prop === "org") {
42593
- result.organization = Array.isArray(type) ? type[0] ?? null : type ?? null;
42597
+ const organization = Array.isArray(value) ? value[0] : value;
42598
+ result.organization = typeof organization === "string" ? organization : null;
42594
42599
  } else if (prop === "n" && !result.name) {
42595
- const parts = Array.isArray(type) ? type.filter(Boolean) : [type];
42600
+ const parts = Array.isArray(value) ? value.filter((part) => typeof part === "string" && part.length > 0) : typeof value === "string" ? [value] : [];
42596
42601
  result.name = parts.reverse().join(" ").trim() || null;
42597
42602
  }
42598
42603
  }
@@ -42609,8 +42614,10 @@ function extractRegistrarFromRdap(rdap) {
42609
42614
  if (entity.vcardArray?.[1]) {
42610
42615
  const vcard = entity.vcardArray[1];
42611
42616
  for (const entry of vcard) {
42612
- if (Array.isArray(entry) && entry[0] === "fn")
42613
- return entry[2] ?? null;
42617
+ if (Array.isArray(entry) && entry[0] === "fn") {
42618
+ const value = getVcardPropertyValue(entry);
42619
+ return typeof value === "string" ? value : null;
42620
+ }
42614
42621
  }
42615
42622
  }
42616
42623
  if (entity.remarks) {
@@ -50608,6 +50615,7 @@ function createRoute53Provider(config2) {
50608
50615
  }
50609
50616
  return {
50610
50617
  name: "route53",
50618
+ dnsWriteScope: "changed-groups",
50611
50619
  async listDomains() {
50612
50620
  return listDomainInventory();
50613
50621
  },
@@ -50964,16 +50972,51 @@ async function listRecordsByNameType(zoneId, type, name, config2) {
50964
50972
  proxied: r4.proxied
50965
50973
  }));
50966
50974
  }
50967
- async function replaceRecordsByNameType(zoneId, records, config2) {
50975
+ function sameRecordIdentity(a4, b4) {
50976
+ return a4.type === b4.type && a4.name === b4.name && a4.content === b4.content && (a4.priority ?? undefined) === (b4.priority ?? undefined);
50977
+ }
50978
+ function resolveDesiredProxied(records, existing) {
50979
+ const omitted = records.filter((record) => record.proxied === undefined);
50980
+ if (omitted.length === 0)
50981
+ return records;
50982
+ const { type, name } = records[0];
50983
+ if (omitted.length === records.length) {
50984
+ const proxyStates = new Set(existing.map((record) => record.proxied));
50985
+ if (proxyStates.size > 1) {
50986
+ throw new Error(`Cannot safely preserve Cloudflare proxied state for ${type} ${name}: ` + "existing records have mixed proxied values while desired records omit proxied; " + "set proxied explicitly on every desired record");
50987
+ }
50988
+ const inherited = existing[0]?.proxied;
50989
+ return inherited === undefined ? records : records.map((record) => ({ ...record, proxied: inherited }));
50990
+ }
50991
+ const existingHasProxyState = existing.some((record) => record.proxied !== undefined);
50992
+ return records.map((record) => {
50993
+ if (record.proxied !== undefined)
50994
+ return record;
50995
+ const matches = existing.filter((candidate) => sameRecordIdentity(candidate, record));
50996
+ if (matches.length === 1 && matches[0].proxied !== undefined) {
50997
+ return { ...record, proxied: matches[0].proxied };
50998
+ }
50999
+ if (!existingHasProxyState)
51000
+ return record;
51001
+ throw new Error(`Cannot safely preserve Cloudflare proxied state for ${type} ${name} record ${record.content}: ` + "omitted proxied does not resolve to exactly one existing value; " + "set proxied explicitly on this desired record");
51002
+ });
51003
+ }
51004
+ async function prepareRecordsByNameType(zoneId, records, config2) {
50968
51005
  if (records.length === 0)
50969
51006
  return;
50970
51007
  const { type, name } = records[0];
50971
51008
  const existing = await listRecordsByNameType(zoneId, type, name, config2);
50972
- for (const record of existing) {
51009
+ if (existing.length === records.length && records.every((record) => existing.some((candidate) => sameRecordIdentity(candidate, record) && candidate.ttl === record.ttl && (record.proxied === undefined || candidate.proxied === record.proxied)))) {
51010
+ return;
51011
+ }
51012
+ return { existing, desired: resolveDesiredProxied(records, existing) };
51013
+ }
51014
+ async function replaceRecordsByNameType(zoneId, replacement, config2) {
51015
+ for (const record of replacement.existing) {
50973
51016
  if (record.id)
50974
51017
  await deleteRecord2(zoneId, record.id, config2);
50975
51018
  }
50976
- for (const record of records) {
51019
+ for (const record of replacement.desired) {
50977
51020
  await cfFetch(`/zones/${zoneId}/dns_records`, {
50978
51021
  method: "POST",
50979
51022
  body: {
@@ -50982,7 +51025,7 @@ async function replaceRecordsByNameType(zoneId, records, config2) {
50982
51025
  content: record.content,
50983
51026
  ttl: record.ttl ?? 1,
50984
51027
  priority: record.priority,
50985
- proxied: record.proxied ?? false
51028
+ ...record.proxied === undefined ? {} : { proxied: record.proxied }
50986
51029
  },
50987
51030
  config: config2
50988
51031
  });
@@ -51017,6 +51060,7 @@ function createCloudflareProvider(config2) {
51017
51060
  const cfg = config2 ?? getConfig3();
51018
51061
  return {
51019
51062
  name: "cloudflare",
51063
+ dnsWriteScope: "changed-groups",
51020
51064
  async listDomains() {
51021
51065
  const zones = await listZones(cfg);
51022
51066
  return zones.map(zoneToDomainInfo);
@@ -51067,7 +51111,8 @@ function createCloudflareProvider(config2) {
51067
51111
  name: r4.name,
51068
51112
  value: r4.content,
51069
51113
  ttl: r4.ttl === 1 ? 0 : r4.ttl,
51070
- priority: r4.priority
51114
+ priority: r4.priority,
51115
+ ...r4.proxied === undefined ? {} : { proxied: r4.proxied }
51071
51116
  }));
51072
51117
  },
51073
51118
  async setDnsRecords(domain, records) {
@@ -51078,11 +51123,24 @@ function createCloudflareProvider(config2) {
51078
51123
  for (const r4 of records) {
51079
51124
  const key = `${r4.type}|${r4.name}`;
51080
51125
  const existing = grouped.get(key) ?? [];
51081
- existing.push({ type: r4.type, name: r4.name, content: r4.value, ttl: r4.ttl || 1, priority: r4.priority });
51126
+ existing.push({
51127
+ type: r4.type,
51128
+ name: r4.name,
51129
+ content: r4.value,
51130
+ ttl: r4.ttl || 1,
51131
+ priority: r4.priority,
51132
+ ...r4.proxied === undefined ? {} : { proxied: r4.proxied }
51133
+ });
51082
51134
  grouped.set(key, existing);
51083
51135
  }
51136
+ const replacements = [];
51084
51137
  for (const group of grouped.values()) {
51085
- await replaceRecordsByNameType(zone.id, group, cfg);
51138
+ const replacement = await prepareRecordsByNameType(zone.id, group, cfg);
51139
+ if (replacement)
51140
+ replacements.push(replacement);
51141
+ }
51142
+ for (const replacement of replacements) {
51143
+ await replaceRecordsByNameType(zone.id, replacement, cfg);
51086
51144
  }
51087
51145
  return true;
51088
51146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/domains",
3
- "version": "0.0.36",
3
+ "version": "0.0.38",
4
4
  "description": "Domain portfolio, registrar, marketplace, and DNS management for AI agents — CLI + MCP + HTTP API + SDK, local SQLite or cloud Postgres",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",