import { nextTick } from "./_next_tick.ts";import { customPromisifyArgs } from "./internal/util.mjs";import { validateBoolean, validateFunction, validateNumber, validateOneOf, validateString,} from "./internal/validators.mjs";import { isIP } from "./internal/net.ts";import { emitInvalidHostnameWarning, getDefaultResolver, getDefaultVerbatim, isFamily, isLookupCallback, isLookupOptions, isResolveCallback, Resolver as CallbackResolver, setDefaultResolver, setDefaultResultOrder, validateHints,} from "./internal/dns/utils.ts";import type { AnyAaaaRecord, AnyARecord, AnyCnameRecord, AnyMxRecord, AnyNaptrRecord, AnyNsRecord, AnyPtrRecord, AnyRecord, AnySoaRecord, AnySrvRecord, AnyTxtRecord, CaaRecord, LookupAddress, LookupAllOptions, LookupOneOptions, LookupOptions, MxRecord, NaptrRecord, Records, RecordWithTtl, ResolveCallback, ResolveOptions, ResolverOptions, ResolveWithTtlOptions, SoaRecord, SrvRecord,} from "./internal/dns/utils.ts";import promisesBase from "./internal/dns/promises.ts";import type { ErrnoException } from "./internal/errors.ts";import { dnsException, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE,} from "./internal/errors.ts";import { AI_ADDRCONFIG as ADDRCONFIG, AI_ALL as ALL, AI_V4MAPPED as V4MAPPED,} from "./internal_binding/ares.ts";import { ChannelWrapQuery, getaddrinfo, GetAddrInfoReqWrap, QueryReqWrap,} from "./internal_binding/cares_wrap.ts";import { toASCII } from "./internal/idna.ts";import { notImplemented } from "./_utils.ts";
function onlookup( this: GetAddrInfoReqWrap, err: number | null, addresses: string[],) { if (err) { return this.callback(dnsException(err, "getaddrinfo", this.hostname)); }
this.callback(null, addresses[0], this.family || isIP(addresses[0]));}
function onlookupall( this: GetAddrInfoReqWrap, err: number | null, addresses: string[],) { if (err) { return this.callback(dnsException(err, "getaddrinfo", this.hostname)); }
const family = this.family; const parsedAddresses = [];
for (let i = 0; i < addresses.length; i++) { const addr = addresses[i]; parsedAddresses[i] = { address: addr, family: family || isIP(addr), }; }
this.callback(null, parsedAddresses);}
type LookupCallback = ( err: ErrnoException | null, addressOrAddresses?: string | LookupAddress[] | null, family?: number,) => void;
const validFamilies = [0, 4, 6];
export function lookup( hostname: string, family: number, callback: ( err: ErrnoException | null, address: string, family: number, ) => void,): GetAddrInfoReqWrap | Record<string, never>;export function lookup( hostname: string, options: LookupOneOptions, callback: ( err: ErrnoException | null, address: string, family: number, ) => void,): GetAddrInfoReqWrap | Record<string, never>;export function lookup( hostname: string, options: LookupAllOptions, callback: (err: ErrnoException | null, addresses: LookupAddress[]) => void,): GetAddrInfoReqWrap | Record<string, never>;export function lookup( hostname: string, options: LookupOptions, callback: ( err: ErrnoException | null, address: string | LookupAddress[], family: number, ) => void,): GetAddrInfoReqWrap | Record<string, never>;export function lookup( hostname: string, callback: ( err: ErrnoException | null, address: string, family: number, ) => void,): GetAddrInfoReqWrap | Record<string, never>;export function lookup( hostname: string, options: unknown, callback?: unknown,): GetAddrInfoReqWrap | Record<string, never> { let hints = 0; let family = 0; let all = false; let verbatim = getDefaultVerbatim();
if (hostname) { validateString(hostname, "hostname"); }
if (isLookupCallback(options)) { callback = options; family = 0; } else if (isFamily(options)) { validateFunction(callback, "callback");
validateOneOf(options, "family", validFamilies); family = options; } else if (!isLookupOptions(options)) { validateFunction(arguments.length === 2 ? options : callback, "callback");
throw new ERR_INVALID_ARG_TYPE("options", ["integer", "object"], options); } else { validateFunction(callback, "callback");
if (options?.hints != null) { validateNumber(options.hints, "options.hints"); hints = options.hints >>> 0; validateHints(hints); }
if (options?.family != null) { validateOneOf(options.family, "options.family", validFamilies); family = options.family; }
if (options?.all != null) { validateBoolean(options.all, "options.all"); all = options.all; }
if (options?.verbatim != null) { validateBoolean(options.verbatim, "options.verbatim"); verbatim = options.verbatim; } }
if (!hostname) { emitInvalidHostnameWarning(hostname);
if (all) { nextTick(callback as LookupCallback, null, []); } else { nextTick(callback as LookupCallback, null, null, family === 6 ? 6 : 4); }
return {}; }
const matchedFamily = isIP(hostname);
if (matchedFamily) { if (all) { nextTick(callback as LookupCallback, null, [ { address: hostname, family: matchedFamily }, ]); } else { nextTick(callback as LookupCallback, null, hostname, matchedFamily); }
return {}; }
const req = new GetAddrInfoReqWrap(); req.callback = callback as LookupCallback; req.family = family; req.hostname = hostname; req.oncomplete = all ? onlookupall : onlookup;
const err = getaddrinfo(req, toASCII(hostname), family, hints, verbatim);
if (err) { nextTick( callback as LookupCallback, dnsException(err, "getaddrinfo", hostname), );
return {}; }
return req;}
Object.defineProperty(lookup, customPromisifyArgs, { value: ["address", "family"], enumerable: false,});
function onresolve( this: QueryReqWrap, err: number, records: Records, ttls?: number[],) { if (err) { this.callback(dnsException(err, this.bindingName, this.hostname));
return; }
const parsedRecords = ttls && this.ttl ? (records as string[]).map((address: string, index: number) => ({ address, ttl: ttls[index], })) : records;
this.callback(null, parsedRecords);}
function resolver(bindingName: keyof ChannelWrapQuery) { function query( this: Resolver, name: string, options: unknown, callback?: unknown, ): QueryReqWrap { if (isResolveCallback(options)) { callback = options; options = {}; }
validateString(name, "name"); validateFunction(callback, "callback");
const req = new QueryReqWrap(); req.bindingName = bindingName; req.callback = callback as ResolveCallback; req.hostname = name; req.oncomplete = onresolve;
if (options && (options as ResolveOptions).ttl) { notImplemented("dns.resolve* with ttl option"); }
req.ttl = !!(options && (options as ResolveOptions).ttl);
const err = this._handle[bindingName](req, toASCII(name));
if (err) { throw dnsException(err, bindingName, name); }
return req; }
Object.defineProperty(query, "name", { value: bindingName });
return query;}
const resolveMap = Object.create(null);
export class Resolver extends CallbackResolver { constructor(options?: ResolverOptions) { super(options); }
[resolveMethod: string]: any;}
Resolver.prototype.resolveAny = resolveMap.ANY = resolver("queryAny");Resolver.prototype.resolve4 = resolveMap.A = resolver("queryA");Resolver.prototype.resolve6 = resolveMap.AAAA = resolver("queryAaaa");Resolver.prototype.resolveCaa = resolveMap.CAA = resolver("queryCaa");Resolver.prototype.resolveCname = resolveMap.CNAME = resolver("queryCname");Resolver.prototype.resolveMx = resolveMap.MX = resolver("queryMx");Resolver.prototype.resolveNs = resolveMap.NS = resolver("queryNs");Resolver.prototype.resolveTxt = resolveMap.TXT = resolver("queryTxt");Resolver.prototype.resolveSrv = resolveMap.SRV = resolver("querySrv");Resolver.prototype.resolvePtr = resolveMap.PTR = resolver("queryPtr");Resolver.prototype.resolveNaptr = resolveMap.NAPTR = resolver("queryNaptr");Resolver.prototype.resolveSoa = resolveMap.SOA = resolver("querySoa");Resolver.prototype.reverse = resolver("getHostByAddr");Resolver.prototype.resolve = _resolve;
function _resolve( this: Resolver, hostname: string, rrtype: unknown, callback?: unknown,): QueryReqWrap { let resolver: Resolver;
if (typeof hostname !== "string") { throw new ERR_INVALID_ARG_TYPE("name", "string", hostname); }
if (typeof rrtype === "string") { resolver = resolveMap[rrtype]; } else if (typeof rrtype === "function") { resolver = resolveMap.A; callback = rrtype; } else { throw new ERR_INVALID_ARG_TYPE("rrtype", "string", rrtype); }
if (typeof resolver === "function") { return Reflect.apply(resolver, this, [hostname, callback]); }
throw new ERR_INVALID_ARG_VALUE("rrtype", rrtype);}
export function setServers(servers: ReadonlyArray<string>) { const resolver = new Resolver();
resolver.setServers(servers); setDefaultResolver(resolver);}
export function getServers(): string[] { return Resolver.prototype.getServers.bind(getDefaultResolver())();}
export function resolveAny( hostname: string, callback: (err: ErrnoException | null, addresses: AnyRecord[]) => void,): QueryReqWrap;export function resolveAny(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveAny.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolve4( hostname: string, callback: (err: ErrnoException | null, addresses: string[]) => void,): void;export function resolve4( hostname: string, options: ResolveWithTtlOptions, callback: (err: ErrnoException | null, addresses: RecordWithTtl[]) => void,): void;export function resolve4( hostname: string, options: ResolveOptions, callback: ( err: ErrnoException | null, addresses: string[] | RecordWithTtl[], ) => void,): void;export function resolve4( hostname: string, options: unknown, callback?: unknown,) { return Resolver.prototype.resolve4.bind(getDefaultResolver() as Resolver)( hostname, options, callback, );}
export function resolve6( hostname: string, callback: (err: ErrnoException | null, addresses: string[]) => void,): void;export function resolve6( hostname: string, options: ResolveWithTtlOptions, callback: (err: ErrnoException | null, addresses: RecordWithTtl[]) => void,): void;export function resolve6( hostname: string, options: ResolveOptions, callback: ( err: ErrnoException | null, addresses: string[] | RecordWithTtl[], ) => void,): void;export function resolve6( hostname: string, options: unknown, callback?: unknown,) { return Resolver.prototype.resolve6.bind(getDefaultResolver() as Resolver)( hostname, options, callback, );}
export function resolveCaa( hostname: string, callback: (err: ErrnoException | null, records: CaaRecord[]) => void,): QueryReqWrap;export function resolveCaa(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveCaa.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolveCname( hostname: string, callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolveCname(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveCname.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolveMx( hostname: string, callback: (err: ErrnoException | null, addresses: MxRecord[]) => void,): QueryReqWrap;export function resolveMx(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveMx.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolveNs( hostname: string, callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolveNs(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveNs.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolveTxt( hostname: string, callback: (err: ErrnoException | null, addresses: string[][]) => void,): QueryReqWrap;export function resolveTxt(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveTxt.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolveSrv( hostname: string, callback: (err: ErrnoException | null, addresses: SrvRecord[]) => void,): QueryReqWrap;export function resolveSrv(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveSrv.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolvePtr( hostname: string, callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolvePtr(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolvePtr.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolveNaptr( hostname: string, callback: (err: ErrnoException | null, addresses: NaptrRecord[]) => void,): QueryReqWrap;export function resolveNaptr(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveNaptr.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolveSoa( hostname: string, callback: (err: ErrnoException | null, address: SoaRecord) => void,): QueryReqWrap;export function resolveSoa(...args: unknown[]): QueryReqWrap { return Resolver.prototype.resolveSoa.bind(getDefaultResolver() as Resolver)( ...args, );}
export function reverse( ip: string, callback: (err: ErrnoException | null, hostnames: string[]) => void,): QueryReqWrap;export function reverse(...args: unknown[]): QueryReqWrap { return Resolver.prototype.reverse.bind(getDefaultResolver() as Resolver)( ...args, );}
export function resolve( hostname: string, callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "A", callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "AAAA", callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "ANY", callback: (err: ErrnoException | null, addresses: AnyRecord[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "CNAME", callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "MX", callback: (err: ErrnoException | null, addresses: MxRecord[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "NAPTR", callback: (err: ErrnoException | null, addresses: NaptrRecord[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "NS", callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "PTR", callback: (err: ErrnoException | null, addresses: string[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "SOA", callback: (err: ErrnoException | null, addresses: SoaRecord) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "SRV", callback: (err: ErrnoException | null, addresses: SrvRecord[]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: "TXT", callback: (err: ErrnoException | null, addresses: string[][]) => void,): QueryReqWrap;export function resolve( hostname: string, rrtype: string, callback: ( err: ErrnoException | null, addresses: | string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[], ) => void,): QueryReqWrap;export function resolve(hostname: string, rrtype: unknown, callback?: unknown) { return Resolver.prototype.resolve.bind(getDefaultResolver() as Resolver)( hostname, rrtype, callback, );}
export const NODATA = "ENODATA";export const FORMERR = "EFORMERR";export const SERVFAIL = "ESERVFAIL";export const NOTFOUND = "ENOTFOUND";export const NOTIMP = "ENOTIMP";export const REFUSED = "EREFUSED";export const BADQUERY = "EBADQUERY";export const BADNAME = "EBADNAME";export const BADFAMILY = "EBADFAMILY";export const BADRESP = "EBADRESP";export const CONNREFUSED = "ECONNREFUSED";export const TIMEOUT = "ETIMEOUT";export const EOF = "EOF";export const FILE = "EFILE";export const NOMEM = "ENOMEM";export const DESTRUCTION = "EDESTRUCTION";export const BADSTR = "EBADSTR";export const BADFLAGS = "EBADFLAGS";export const NONAME = "ENONAME";export const BADHINTS = "EBADHINTS";export const NOTINITIALIZED = "ENOTINITIALIZED";export const LOADIPHLPAPI = "ELOADIPHLPAPI";export const ADDRGETNETWORKPARAMS = "EADDRGETNETWORKPARAMS";export const CANCELLED = "ECANCELLED";
const promises = { ...promisesBase, setDefaultResultOrder, setServers,
NODATA, FORMERR, SERVFAIL, NOTFOUND, NOTIMP, REFUSED, BADQUERY, BADNAME, BADFAMILY, BADRESP, CONNREFUSED, TIMEOUT, EOF, FILE, NOMEM, DESTRUCTION, BADSTR, BADFLAGS, NONAME, BADHINTS, NOTINITIALIZED, LOADIPHLPAPI, ADDRGETNETWORKPARAMS, CANCELLED,};
export { ADDRCONFIG, ALL, promises, setDefaultResultOrder, V4MAPPED };
export type { AnyAaaaRecord, AnyARecord, AnyCnameRecord, AnyMxRecord, AnyNaptrRecord, AnyNsRecord, AnyPtrRecord, AnyRecord, AnySoaRecord, AnySrvRecord, AnyTxtRecord, CaaRecord, LookupAddress, LookupAllOptions, LookupOneOptions, LookupOptions, MxRecord, NaptrRecord, Records, RecordWithTtl, ResolveCallback, ResolveOptions, ResolverOptions, ResolveWithTtlOptions, SoaRecord, SrvRecord,};
export default { ADDRCONFIG, ALL, V4MAPPED, lookup, getServers, resolveAny, resolve4, resolve6, resolveCaa, resolveCname, resolveMx, resolveNs, resolveTxt, resolveSrv, resolvePtr, resolveNaptr, resolveSoa, resolve, Resolver, reverse, setServers, setDefaultResultOrder, promises, NODATA, FORMERR, SERVFAIL, NOTFOUND, NOTIMP, REFUSED, BADQUERY, BADNAME, BADFAMILY, BADRESP, CONNREFUSED, TIMEOUT, EOF, FILE, NOMEM, DESTRUCTION, BADSTR, BADFLAGS, NONAME, BADHINTS, NOTINITIALIZED, LOADIPHLPAPI, ADDRGETNETWORKPARAMS, CANCELLED,};