UNPKG

@nasriya/atomix

Version:

Composable helper functions for building reliable systems

248 lines (247 loc) 8.46 kB
import dns from "dns"; import stringsGuard from "../../data-types/string/strings-guard.js"; import runtime from "../../runtime/runtime.js"; import arraysUtils from "../../data-types/array/arrays-utils.js"; /** * Network Utilities module providing methods for local system network info, * remote network info, DNS operations, and network inspections. * * Supports Node.js and Bun runtimes, Deno support untested. * * @since v1.0.0 */ class NetworkDNS { async resolve(hostname, rrtype) { if (!stringsGuard.isString(hostname)) { throw new Error(`The hostname should be string, instead got ${typeof hostname}`); } if (rrtype === undefined) { rrtype = 'A'; } try { const result = await dns.promises.resolve(hostname, rrtype); switch (rrtype) { case 'A': { if (runtime.isBun()) { return [result.address]; } return result; } case 'AAAA': { if (runtime.isBun()) { return [result.address]; } return result; } case 'TXT': { return arraysUtils.deepFlatten(result); } default: { return result; } } } catch (error) { if (error instanceof Error) { const err = error; if (['ENOTFOUND', 'ENOTIMP', 'ENODATA'].includes(err.code)) { return []; } if (['ETIMEOUT', 'ECONNREFUSED'].includes(err.code)) { err.message = `Unable to resolve ${hostname}: ${err.message}`; } } throw error; } } /** * Resolves the given hostname to an array of its IP addresses. * * This is a convenience method for resolving hostnames to their IP addresses. * It is equivalent to calling `resolve(hostname, 'A')`. * * @param hostname - The hostname to resolve (e.g., "example.com"). * * @returns A Promise resolving to an array of IP addresses for the given hostname. * An empty array is returned if the hostname is not resolvable. * * @throws {Error} If the hostname is not a string. * * @example * // Resolve the IP addresses for "example.com" * const ips = await lookup("example.com"); */ async lookup(hostname) { return this.resolve(hostname); } /** * Resolves the given IP address to an array of hostnames. * * This is a convenience method for reversing IP addresses to their hostnames. * It is equivalent to calling `resolve(address, 'PTR')`. * * @param address - The IP address to reverse (e.g., "192.0.2.1"). * * @returns A Promise resolving to an array of hostnames for the given IP address. * An empty array is returned if the IP address is not resolvable. * * @throws {Error} If the address is not a string. * * @example * // Reverse the hostname for "192.0.2.1" * const names = await reverseLookup("192.0.2.1"); */ async reverseLookup(address) { try { const result = await dns.promises.reverse(address); return result; } catch (error) { if (error instanceof Error) { const err = error; if (['ENOTFOUND', 'ENOTIMP', 'ENODATA'].includes(err.code)) { return []; } if (['ETIMEOUT', 'ECONNREFUSED'].includes(err.code)) { err.message = `Unable to reverse lookup ${address}: ${err.message}`; } } throw error; } } /** * Resolves the given hostname to an array of MX records. * * This method calls the underlying DNS resolver to resolve the given hostname * to an array of MX records. The returned array is sorted by priority. * * @param hostname - The hostname to resolve MX records for (e.g., "example.com"). * * @returns A Promise resolving to an array of MX records for the given hostname. * An empty array is returned if the hostname is not resolvable. * * @throws {Error} If the hostname is not a string. * * @example * // Resolve the MX records for "example.com" * const mxRecords = await resolveMx("example.com"); * @since v1.0.0 */ async resolveMx(hostname) { try { const result = await dns.promises.resolveMx(hostname); return result; } catch (error) { if (error instanceof Error) { error.message = `Unable to resolve MX records for host ${hostname}: ${error.message}`; } throw error; } } /** * Resolves the given hostname to an array of NS records. * * This method calls the underlying DNS resolver to resolve the given hostname * to an array of NS records. * * @param hostname - The hostname to resolve NS records for (e.g., "example.com"). * * @returns A Promise resolving to an array of NS records for the given hostname. * An empty array is returned if the hostname is not resolvable. * * @throws {Error} If the hostname is not a string. * * @example * // Resolve the NS records for "example.com" * const nsRecords = await resolveNs("example.com"); * @since v1.0.0 */ async resolveNs(hostname) { try { const result = await dns.promises.resolveNs(hostname); return result; } catch (error) { if (error instanceof Error) { error.message = `Unable to resolve NS records for host ${hostname}: ${error.message}`; } throw error; } } /** * Resolves the given hostname to an array of TXT records. * * This method calls the underlying DNS resolver to resolve the given hostname * to an array of TXT records. * * @param hostname - The hostname to resolve TXT records for (e.g., "example.com"). * * @returns A Promise resolving to an array of TXT records for the given hostname. * An empty array is returned if the hostname is not resolvable. * * @throws {Error} If the hostname is not a string. * * @example * // Resolve the TXT records for "example.com" * const txtRecords = await resolveTxt("example.com"); * @since v1.0.0 */ async resolveTxt(hostname) { try { const result = await dns.promises.resolveTxt(hostname); return result; } catch (error) { if (error instanceof Error) { error.message = `Unable to resolve TXT records for host ${hostname}: ${error.message}`; } throw error; } } /** * Retrieves the list of configured DNS servers. * * @returns {string[]} An array of DNS server IP addresses or hostnames. * * @throws {Error} If unable to get the DNS servers. * @since v1.0.0 */ getDNSServers() { try { const result = dns.promises.getServers(); return result; } catch (error) { if (error instanceof Error) { error.message = `Unable to get DNS servers: ${error.message}`; } throw error; } } /** * Checks if a domain is resolvable to an IP address. * * This method performs a DNS lookup for the given domain and returns true if * the domain can be resolved, false otherwise. * * @param domain - The domain name to check. * * @returns A Promise resolving to true if the domain is resolvable, false otherwise. * * @example * const isResolvable = await networkDNS.isDNSResolvable('example.com'); * @since v1.0.0 */ async isDNSResolvable(domain) { try { await this.resolve(domain); return true; } catch (error) { return false; } } } const networkDNS = new NetworkDNS(); export default networkDNS;