Surge_by_SukkaW/Dist/Build/lib/is-domain-alive.cjs
SukkaW d354c5e988
Some checks are pending
Build / Build (push) Waiting to run
Build / Diff output (push) Blocked by required conditions
Build / Deploy to Cloudflare Pages (push) Blocked by required conditions
Build / Deploy to GitHub and GitLab (push) Blocked by required conditions
Chore: maintainance
2025-02-07 17:52:36 +08:00

396 lines
13 KiB
JavaScript

'use strict';Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});const isDomainAlive=require('../../_virtual/is-domain-alive.cjs'),require$$5=require('tldts-experimental'),looseTldtsOpt=require('../constants/loose-tldts-opt.cjs'),require$$0=require('picocolors'),require$$3$1=require('dns2'),require$$4=require('async-retry'),require$$5$1=require('whoiser'),require$$3=require('foxts/retrie'),require$$1=require('node:process');var hasRequiredIsDomainAlive;
function requireIsDomainAlive () {
if (hasRequiredIsDomainAlive) return isDomainAlive.__exports;
hasRequiredIsDomainAlive = 1;
(function (exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
isDomainAlive: function() {
return isDomainAlive;
},
keyedAsyncMutexWithQueue: function() {
return keyedAsyncMutexWithQueue;
},
noWhois: function() {
return noWhois;
}
});
const _tldtsexperimental = /*#__PURE__*/ _interop_require_default(require$$5);
const _loosetldtsopt = /*@__PURE__*/ looseTldtsOpt.__require();
const _picocolors = /*#__PURE__*/ _interop_require_default(require$$0);
const _dns2 = /*#__PURE__*/ _interop_require_default(require$$3$1);
const _asyncretry = /*#__PURE__*/ _interop_require_default(require$$4);
const _whoiser = /*#__PURE__*/ _interop_require_wildcard(require$$5$1);
const _retrie = require$$3;
const _nodeprocess = /*#__PURE__*/ _interop_require_default(require$$1);
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const mutex = new Map();
function keyedAsyncMutexWithQueue(key, fn) {
if (mutex.has(key)) {
return mutex.get(key);
}
const promise = fn();
mutex.set(key, promise);
return promise;
}
class DnsError extends Error {
message;
server;
name;
constructor(message, server){
super(message), this.message = message, this.server = server, this.name = 'DnsError';
}
}
const dohServers = [
'8.8.8.8',
'8.8.4.4',
'1.0.0.1',
'1.1.1.1',
'162.159.36.1',
'162.159.46.1',
'101.101.101.101',
'185.222.222.222',
'45.11.45.11',
'dns10.quad9.net',
'doh.sandbox.opendns.com',
'unfiltered.adguard-dns.com',
// '0ms.dev', // Proxy Cloudflare
// '76.76.2.0', // ControlD unfiltered, path not /dns-query
// '76.76.10.0', // ControlD unfiltered, path not /dns-query
// 'dns.bebasid.com', // BebasID, path not /dns-query but /unfiltered
// '193.110.81.0', // dns0.eu
// '185.253.5.0', // dns0.eu
// 'zero.dns0.eu',
'dns.nextdns.io',
'anycast.dns.nextdns.io',
'wikimedia-dns.org',
// 'ordns.he.net',
// 'dns.mullvad.net',
'basic.rethinkdns.com',
'198.54.117.10' // NameCheap DNS, supports DoT, DoH, UDP53
].map((dns)=>[
dns,
_dns2.default.DOHClient({
dns,
http: false
})
]);
const domesticDohServers = [
'223.5.5.5',
'223.6.6.6',
'120.53.53.53',
'1.12.12.12'
].map((dns)=>[
dns,
_dns2.default.DOHClient({
dns,
http: false
})
]);
function createResolve(server) {
return async (...args)=>{
try {
return await (0, _asyncretry.default)(async ()=>{
const [dohServer, dohClient] = server[Math.floor(Math.random() * server.length)];
try {
return {
...await dohClient(...args),
dns: dohServer
};
} catch (e) {
// console.error(e);
throw new DnsError(e.message, dohServer);
}
}, {
retries: 5
});
} catch (e) {
console.log('[doh error]', ...args, e);
throw e;
}
};
}
const resolve = createResolve(dohServers);
const domesticResolve = createResolve(domesticDohServers);
async function getWhois(domain) {
return (0, _asyncretry.default)(()=>_whoiser.domain(domain, {
raw: true
}), {
retries: 5
});
}
const domainAliveMap = new Map();
function onDomainAlive(domain) {
domainAliveMap.set(domain, true);
return [
domain,
true
];
}
function onDomainDead(domain) {
domainAliveMap.set(domain, false);
return [
domain,
false
];
}
async function isDomainAlive(domain, isSuffix) {
if (domainAliveMap.has(domain)) {
return [
domain,
domainAliveMap.get(domain)
];
}
const apexDomain = _tldtsexperimental.default.getDomain(domain, _loosetldtsopt.looseTldtsOpt);
if (!apexDomain) {
console.log(_picocolors.default.gray('[domain invalid]'), _picocolors.default.gray('no apex domain'), {
domain
});
return onDomainAlive(domain);
}
const apexDomainAlive = await keyedAsyncMutexWithQueue(apexDomain, ()=>isApexDomainAlive(apexDomain));
if (isSuffix) {
return apexDomainAlive;
}
if (!apexDomainAlive[1]) {
return apexDomainAlive;
}
const $domain = domain[0] === '.' ? domain.slice(1) : domain;
const aDns = [];
const aaaaDns = [];
// test 2 times before make sure record is empty
for(let i = 0; i < 2; i++){
// eslint-disable-next-line no-await-in-loop -- sequential
const aRecords = await resolve($domain, 'A');
if (aRecords.answers.length > 0) {
return onDomainAlive(domain);
}
aDns.push(aRecords.dns);
}
for(let i = 0; i < 2; i++){
// eslint-disable-next-line no-await-in-loop -- sequential
const aaaaRecords = await resolve($domain, 'AAAA');
if (aaaaRecords.answers.length > 0) {
return onDomainAlive(domain);
}
aaaaDns.push(aaaaRecords.dns);
}
// only then, let's test once with domesticDohServers
const aRecords = await domesticResolve($domain, 'A');
if (aRecords.answers.length > 0) {
return onDomainAlive(domain);
}
aDns.push(aRecords.dns);
const aaaaRecords = await domesticResolve($domain, 'AAAA');
if (aaaaRecords.answers.length > 0) {
return onDomainAlive(domain);
}
aaaaDns.push(aaaaRecords.dns);
console.log(_picocolors.default.red('[domain dead]'), 'no A/AAAA records', {
domain,
a: aDns,
aaaa: aaaaDns
});
return onDomainDead($domain);
}
const apexDomainNsResolvePromiseMap = new Map();
async function isApexDomainAlive(apexDomain) {
if (domainAliveMap.has(apexDomain)) {
return [
apexDomain,
domainAliveMap.get(apexDomain)
];
}
let resp;
if (apexDomainNsResolvePromiseMap.has(apexDomain)) {
resp = await apexDomainNsResolvePromiseMap.get(apexDomain);
} else {
const promise = resolve(apexDomain, 'NS');
apexDomainNsResolvePromiseMap.set(apexDomain, promise);
resp = await promise;
}
if (resp.answers.length > 0) {
return onDomainAlive(apexDomain);
}
let whois;
try {
whois = await getWhois(apexDomain);
} catch (e) {
console.log(_picocolors.default.red('[whois error]'), {
domain: apexDomain
}, e);
return onDomainAlive(apexDomain);
}
if (_nodeprocess.default.env.DEBUG) {
console.log(JSON.stringify(whois, null, 2));
}
const whoisError = noWhois(whois);
if (!whoisError) {
console.log(_picocolors.default.gray('[domain alive]'), _picocolors.default.gray('whois found'), {
domain: apexDomain
});
return onDomainAlive(apexDomain);
}
console.log(_picocolors.default.red('[domain dead]'), 'whois not found', {
domain: apexDomain,
err: whoisError
});
return onDomainDead(apexDomain);
}
// TODO: this is a workaround for https://github.com/LayeredStudio/whoiser/issues/117
const whoisNotFoundKeywordTest = (0, _retrie.createRetrieKeywordFilter)([
'no match for',
'does not exist',
'not found',
'no found',
'no entries',
'no data found',
'is available for registration',
'currently available for application',
'no matching record',
'no information available about domain name',
'not been registered',
'no match!!',
'status: available',
' is free',
'no object found',
'nothing found',
'status: free',
'pendingdelete',
' has been blocked by '
]);
function noWhois(whois) {
let empty = true;
for(const key in whois){
if (Object.hasOwn(whois, key)) {
empty = false;
// if (key === 'error') {
// // if (
// // (typeof whois.error === 'string' && whois.error)
// // || (Array.isArray(whois.error) && whois.error.length > 0)
// // ) {
// // console.error(whois);
// // return true;
// // }
// continue;
// }
// if (key === 'text') {
// if (Array.isArray(whois.text)) {
// for (const value of whois.text) {
// if (whoisNotFoundKeywordTest(value.toLowerCase())) {
// return value;
// }
// }
// }
// continue;
// }
// if (key === 'Name Server') {
// // if (Array.isArray(whois[key]) && whois[key].length === 0) {
// // return false;
// // }
// continue;
// }
// if (key === 'Domain Status') {
// if (Array.isArray(whois[key])) {
// for (const status of whois[key]) {
// if (status === 'free' || status === 'AVAILABLE') {
// return key + ': ' + status;
// }
// if (whoisNotFoundKeywordTest(status.toLowerCase())) {
// return key + ': ' + status;
// }
// }
// }
// continue;
// }
// if (typeof whois[key] === 'string' && whois[key]) {
// if (whoisNotFoundKeywordTest(whois[key].toLowerCase())) {
// return key + ': ' + whois[key];
// }
// continue;
// }
if (key === '__raw' && typeof whois.__raw === 'string') {
const lines = whois.__raw.trim().toLowerCase().replaceAll(/[\t ]+/g, ' ').split(/\r?\n/);
if (_nodeprocess.default.env.DEBUG) {
console.log({
lines
});
}
for (const line of lines){
if (whoisNotFoundKeywordTest(line)) {
return line;
}
}
continue;
}
if (typeof whois[key] === 'object' && !Array.isArray(whois[key])) {
const tmp = noWhois(whois[key]);
if (tmp) {
return tmp;
}
continue;
}
}
}
if (empty) {
return 'whois is empty';
}
return null;
}
} (isDomainAlive.__exports));
return isDomainAlive.__exports;
}exports.__require=requireIsDomainAlive;