@hasna/domains
Version:
Domain portfolio, registrar, marketplace, and DNS management for AI agents — CLI + MCP + HTTP API + SDK, shared account API and PostgreSQL
219 lines • 12.7 kB
TypeScript
import type { CredentialChainOptions, CredentialTier, HasnaStorageClient } from "../lib/client-types.js";
import type { CreateDomainInput, Domain, DomainDetails, DomainEmailLink, DomainOffer, DomainStats, ListDomainsOptions, RecordDomainPurchaseInput, UpdateDomainInput, CreateDomainOfferInput, CreateDomainEmailLinkInput, DomainStatus } from "./domain-records.js";
import type { DnsRecord, CreateDnsRecordInput, UpdateDnsRecordInput } from "./dns-records.js";
import type { Alert, CreateAlertInput } from "./alerts.js";
import type { DomainOwner, CreateDomainOwnerInput, DomainOwnerSource, DomainWithOwner } from "./domain-owners.js";
import type { DomainHistory, CreateHistoryEntryInput, DomainHistoryType } from "./domain-history.js";
import type { DomainReputation, CreateReputationInput } from "./domain-reputation.js";
export interface DomainsStore {
/** Which transport backs this store (for banners/diagnostics only). */
readonly transport: "local" | "http";
createDomain(input: CreateDomainInput): Promise<Domain>;
getDomain(id: string): Promise<Domain | null>;
getDomainByName(name: string): Promise<Domain | null>;
getDomainByIdentifier(identifier: string): Promise<Domain | null>;
getDomainDetails(identifier: string): Promise<DomainDetails | null>;
listDomains(options?: ListDomainsOptions): Promise<Domain[]>;
updateDomain(id: string, input: UpdateDomainInput): Promise<Domain | null>;
deleteDomain(id: string): Promise<boolean>;
countDomains(): Promise<number>;
searchDomains(query: string): Promise<Domain[]>;
getByRegistrar(registrar: string): Promise<Domain[]>;
/**
* Two-sided by default: already-lapsed names PLUS those due within `days`.
* Pass `includeLapsed: false` for the forward-only window.
*/
listExpiring(days: number, options?: {
includeLapsed?: boolean;
}): Promise<Domain[]>;
listSslExpiring(days: number, options?: {
includeLapsed?: boolean;
}): Promise<Domain[]>;
/** Past recorded expiry while still status=active. */
listPastExpiry(): Promise<Domain[]>;
listSslPastExpiry(): Promise<Domain[]>;
getDomainStats(): Promise<DomainStats>;
markDomainPremium(identifier: string, premiumPrice: number, standardPrice?: number): Promise<Domain | null>;
updateDomainLifecycleStatus(identifier: string, status: DomainStatus, notes?: string): Promise<Domain | null>;
recordDomainPurchase(identifier: string, input: RecordDomainPurchaseInput): Promise<Domain | null>;
createDomainOffer(input: CreateDomainOfferInput): Promise<DomainOffer>;
getDomainOffer(id: string): Promise<DomainOffer | null>;
listDomainOffers(domainId: string): Promise<DomainOffer[]>;
linkDomainEmail(input: CreateDomainEmailLinkInput): Promise<DomainEmailLink>;
getDomainEmailLink(id: string): Promise<DomainEmailLink | null>;
listDomainEmailLinks(domainId: string): Promise<DomainEmailLink[]>;
createDnsRecord(input: CreateDnsRecordInput): Promise<DnsRecord>;
getDnsRecord(id: string): Promise<DnsRecord | null>;
listDnsRecords(domainId: string, type?: DnsRecord["type"]): Promise<DnsRecord[]>;
updateDnsRecord(id: string, input: UpdateDnsRecordInput): Promise<DnsRecord | null>;
deleteDnsRecord(id: string): Promise<boolean>;
createAlert(input: CreateAlertInput): Promise<Alert>;
getAlert(id: string): Promise<Alert | null>;
listAlerts(domainId: string): Promise<Alert[]>;
deleteAlert(id: string): Promise<boolean>;
createDomainOwner(input: CreateDomainOwnerInput): Promise<DomainOwner>;
getDomainOwner(id: string): Promise<DomainOwner | null>;
getDomainOwnerByDomain(domainId: string): Promise<DomainOwner | null>;
getDomainOwnerByDomainName(domainName: string): Promise<DomainOwner | null>;
listDomainOwners(options?: {
search?: string;
source?: DomainOwnerSource;
verified?: boolean;
}): Promise<DomainOwner[]>;
updateDomainOwner(id: string, input: Partial<CreateDomainOwnerInput>): Promise<DomainOwner | null>;
deleteDomainOwner(id: string): Promise<boolean>;
listDomainsWithOwners(): Promise<DomainWithOwner[]>;
createHistoryEntry(input: CreateHistoryEntryInput): Promise<DomainHistory>;
getHistoryEntry(id: string): Promise<DomainHistory | null>;
getHistoryByDomain(domainId: string, options?: {
type?: DomainHistoryType;
limit?: number;
}): Promise<DomainHistory[]>;
getLatestSnapshot(domainId: string, type: DomainHistoryType): Promise<DomainHistory | null>;
getHistoryByDateRange(startDate: string, endDate: string, domainId?: string): Promise<DomainHistory[]>;
listDomainsWithHistoryChanges(): Promise<Array<{
domain_id: string;
domain_name: string;
latest_snapshot_type: string;
latest_snapshot_at: string;
snapshot_count: number;
}>>;
deleteHistoryEntry(id: string): Promise<boolean>;
deleteHistoryByDomain(domainId: string): Promise<boolean>;
upsertDomainReputation(input: CreateReputationInput): Promise<DomainReputation>;
getDomainReputation(domainId: string): Promise<DomainReputation | null>;
getDomainReputationByName(domainName: string): Promise<DomainReputation | null>;
updateDomainReputation(id: string, input: Partial<CreateReputationInput>): Promise<DomainReputation | null>;
listBlacklistedDomains(): Promise<DomainReputation[]>;
listHighThreatDomains(threshold?: number): Promise<DomainReputation[]>;
deleteDomainReputation(id: string): Promise<boolean>;
}
export declare class ApiStore implements DomainsStore {
private readonly client;
readonly transport: "http";
constructor(client: HasnaStorageClient);
private get http();
createDomain(input: CreateDomainInput): Promise<Domain>;
getDomain(id: string): Promise<Domain | null>;
getDomainByName(name: string): Promise<Domain | null>;
getDomainByIdentifier(identifier: string): Promise<Domain | null>;
getDomainDetails(identifier: string): Promise<DomainDetails | null>;
listDomains(options?: ListDomainsOptions): Promise<Domain[]>;
/**
* Page through `/v1/domains` until the full result set for the given
* server-side query (search/status only) is retrieved. The server orders by
* name ASC and caps each page at {@link DOMAINS_PAGE_SIZE}; a short page means
* the end has been reached. This is what makes cloud parity match LocalStore's
* unbounded reads at >100-domain scale.
*/
private listAllDomains;
updateDomain(id: string, input: UpdateDomainInput): Promise<Domain | null>;
deleteDomain(id: string): Promise<boolean>;
countDomains(): Promise<number>;
searchDomains(query: string): Promise<Domain[]>;
getByRegistrar(registrar: string): Promise<Domain[]>;
listExpiring(days: number, options?: {
includeLapsed?: boolean;
}): Promise<Domain[]>;
listSslExpiring(days: number, options?: {
includeLapsed?: boolean;
}): Promise<Domain[]>;
listPastExpiry(): Promise<Domain[]>;
listSslPastExpiry(): Promise<Domain[]>;
getDomainStats(): Promise<DomainStats>;
markDomainPremium(identifier: string, premiumPrice: number, standardPrice?: number): Promise<Domain | null>;
updateDomainLifecycleStatus(identifier: string, status: DomainStatus, notes?: string): Promise<Domain | null>;
recordDomainPurchase(identifier: string, input: RecordDomainPurchaseInput): Promise<Domain | null>;
createDomainOffer(input: CreateDomainOfferInput): Promise<DomainOffer>;
getDomainOffer(id: string): Promise<DomainOffer | null>;
listDomainOffers(domainId: string): Promise<DomainOffer[]>;
linkDomainEmail(input: CreateDomainEmailLinkInput): Promise<DomainEmailLink>;
getDomainEmailLink(id: string): Promise<DomainEmailLink | null>;
listDomainEmailLinks(domainId: string): Promise<DomainEmailLink[]>;
createDnsRecord(input: CreateDnsRecordInput): Promise<DnsRecord>;
getDnsRecord(id: string): Promise<DnsRecord | null>;
listDnsRecords(domainId: string, type?: DnsRecord["type"]): Promise<DnsRecord[]>;
updateDnsRecord(id: string, input: UpdateDnsRecordInput): Promise<DnsRecord | null>;
deleteDnsRecord(id: string): Promise<boolean>;
createAlert(input: CreateAlertInput): Promise<Alert>;
getAlert(id: string): Promise<Alert | null>;
listAlerts(domainId: string): Promise<Alert[]>;
deleteAlert(id: string): Promise<boolean>;
createDomainOwner(input: CreateDomainOwnerInput): Promise<DomainOwner>;
getDomainOwner(id: string): Promise<DomainOwner | null>;
getDomainOwnerByDomain(domainId: string): Promise<DomainOwner | null>;
getDomainOwnerByDomainName(domainName: string): Promise<DomainOwner | null>;
listDomainOwners(options?: {
search?: string;
source?: DomainOwnerSource;
verified?: boolean;
}): Promise<DomainOwner[]>;
updateDomainOwner(id: string, input: Partial<CreateDomainOwnerInput>): Promise<DomainOwner | null>;
deleteDomainOwner(id: string): Promise<boolean>;
listDomainsWithOwners(): Promise<DomainWithOwner[]>;
createHistoryEntry(input: CreateHistoryEntryInput): Promise<DomainHistory>;
getHistoryEntry(id: string): Promise<DomainHistory | null>;
getHistoryByDomain(domainId: string, options?: {
type?: DomainHistoryType;
limit?: number;
}): Promise<DomainHistory[]>;
getLatestSnapshot(domainId: string, type: DomainHistoryType): Promise<DomainHistory | null>;
getHistoryByDateRange(startDate: string, endDate: string, domainId?: string): Promise<DomainHistory[]>;
listDomainsWithHistoryChanges(): Promise<Array<{
domain_id: string;
domain_name: string;
latest_snapshot_type: string;
latest_snapshot_at: string;
snapshot_count: number;
}>>;
deleteHistoryEntry(id: string): Promise<boolean>;
deleteHistoryByDomain(domainId: string): Promise<boolean>;
upsertDomainReputation(input: CreateReputationInput): Promise<DomainReputation>;
getDomainReputation(domainId: string): Promise<DomainReputation | null>;
getDomainReputationByName(domainName: string): Promise<DomainReputation | null>;
updateDomainReputation(id: string, input: Partial<CreateReputationInput>): Promise<DomainReputation | null>;
listBlacklistedDomains(): Promise<DomainReputation[]>;
listHighThreatDomains(threshold?: number): Promise<DomainReputation[]>;
deleteDomainReputation(id: string): Promise<boolean>;
}
export { LOCAL_PATH_VARS, explicitLocalPathVar } from "../lib/client-storage-policy.js";
/**
* A resolved store, with the sources that decided it — never a key value, and
* never a URL for the local transport.
*/
export interface DomainsStoreResolution {
/** Which transport backs the store. */
transport: "http";
/** The local-path var that opted into LocalStore, or null for http. */
localPathVar: null;
/** For http: the `<origin>/v1` base URL the resolver produced. */
baseUrl: string | null;
/** WHERE the API URL came from: env key NAME, Keychain reference, file PATH, or `"default"`. */
apiUrlSource: string | null;
/** WHERE the API key came from: env key NAME, Keychain reference, or file PATH. Never a value. */
apiKeySource: string | null;
/** Which tier of the credential chain supplied the key, or null for local. */
apiKeyTier: CredentialTier | null;
}
/** Options forwarded to the shared resolver (credential tier-1 inputs, Keychain seam). */
export interface StoreResolutionOptions {
credentials?: CredentialChainOptions;
}
/** Resolve the shared API store; a local path can never select SQLite. */
export declare function getStore(env?: Record<string, string | undefined>, options?: StoreResolutionOptions): DomainsStore;
/**
* Resolve the store WITHOUT constructing it — the same decision {@link
* getStore} makes, returned as a report a diagnostic (`domains doctor`) or a
* caller can show. Mirrors {@link getStore} exactly: an env that would make
* {@link getStore} throw throws here too.
*/
export declare function getStoreResolution(env?: Record<string, string | undefined>, options?: StoreResolutionOptions): DomainsStoreResolution;
/**
* True when the resolved store is the hosted HTTP transport. Mirrors
* {@link getStore} exactly: an env that would make {@link getStore} throw
* (no resolvable credential) throws here too — a
* bare `false` must never be read as a licence to open the default local
* database.
*/
export declare function isCloudStore(env?: Record<string, string | undefined>, options?: StoreResolutionOptions): boolean;
//# sourceMappingURL=store.d.ts.map