@multiformats/dns
Version:
Resolve DNS queries with browser fallback
73 lines • 2.68 kB
JavaScript
import { CustomProgressEvent } from 'progress-events';
import { defaultResolver } from './resolvers/default.js';
import { cache } from './utils/cache.js';
import { getTypes } from './utils/get-types.js';
const DEFAULT_ANSWER_CACHE_SIZE = 1000;
export class DNS {
resolvers;
cache;
constructor(init) {
this.resolvers = {};
this.cache = cache(init.cacheSize ?? DEFAULT_ANSWER_CACHE_SIZE);
Object.entries(init.resolvers ?? {}).forEach(([tld, resolver]) => {
if (!Array.isArray(resolver)) {
resolver = [resolver];
}
// convert `com` -> `com.`
if (!tld.endsWith('.')) {
tld = `${tld}.`;
}
this.resolvers[tld] = resolver;
});
// configure default resolver if none specified
if (this.resolvers['.'] == null) {
this.resolvers['.'] = defaultResolver();
}
}
/**
* Queries DNS resolvers for the passed record types for the passed domain.
*
* If cached records exist for all desired types they will be returned
* instead.
*
* Any new responses will be added to the cache for subsequent requests.
*/
async query(domain, options = {}) {
const types = getTypes(options.types);
const cached = options.cached !== false ? this.cache.get(domain, types) : undefined;
if (cached != null) {
options.onProgress?.(new CustomProgressEvent('dns:cache', { detail: cached }));
return cached;
}
const tld = `${domain.split('.').pop()}.`;
const resolvers = (this.resolvers[tld] ?? this.resolvers['.']).sort(() => {
return (Math.random() > 0.5) ? -1 : 1;
});
const errors = [];
for (const resolver of resolvers) {
// skip further resolutions if the user aborted the signal
if (options.signal?.aborted === true) {
break;
}
try {
const result = await resolver(domain, {
...options,
types
});
for (const answer of result.Answer) {
this.cache.add(domain, answer);
}
return result;
}
catch (err) {
errors.push(err);
options.onProgress?.(new CustomProgressEvent('dns:error', { detail: err }));
}
}
if (errors.length === 1) {
throw errors[0];
}
throw new AggregateError(errors, `DNS lookup of ${domain} ${types} failed`);
}
}
//# sourceMappingURL=dns.js.map