domain-alive 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -26,20 +26,16 @@ function getDnsClients(servers) {
26
26
  return servers.map((dns)=>{
27
27
  const protocolIndex = dns.indexOf('://');
28
28
  const protocol = protocolIndex === -1 ? '' : dns.slice(0, protocolIndex);
29
- const rest = dns.slice(protocolIndex + 3);
30
- const [server, _port] = rest.split(':', 2);
29
+ const [server, _port] = dns.slice(protocolIndex + 3).split(':', 2);
31
30
  const port = _port ? Number.parseInt(_port, 10) : 0;
32
31
  let client;
33
32
  switch(protocol){
34
33
  case 'https':
35
34
  {
36
- // TODO: fuck dns2 incorrect DOHClient server parse impl
37
35
  const u = new URL(dns);
38
- if (u.pathname === '/') {
36
+ if (!server.includes('/')) {
39
37
  u.pathname = '/dns-query';
40
38
  }
41
- // u.searchParams.set('dns', '{query}');
42
- u.search = '?dns={query}';
43
39
  client = dns2.DOHClient({
44
40
  dns: u.href
45
41
  });
@@ -1188,7 +1184,7 @@ const whoiserNoWhoisSymbol = Symbol('"whoiser" library returns "No WHOIS data fo
1188
1184
  return whoisErrorCountAsAlive;
1189
1185
  }
1190
1186
  if (whois === whoiserTLDNotSupportedSymbol) {
1191
- // If TLD doesn't support WHOIS/RDAP, we have no choice but to assume it's alive
1187
+ // If TLD doesn't support WHOIS/RDAP, we have no choice but to assume it's registered
1192
1188
  return true;
1193
1189
  }
1194
1190
  if (whois === whoiserNoWhoisSymbol) {
@@ -1225,12 +1221,12 @@ const whoisNotFoundKeywordTest = retrie.createRetrieKeywordFilter([
1225
1221
  // some servers (like TLD whois servers) might have cached/outdated results
1226
1222
  // we can only make sure a domain is alive once all response from all whois servers demonstrate so
1227
1223
  function walkWhois(whois) {
1228
- // eslint-disable-next-line sukka/no-single-return -- mutable
1229
1224
  let whoisIsEmpty = true;
1230
1225
  if ('__raw' in whois && typeof whois.__raw === 'string') {
1231
1226
  const lines = whois.__raw.trim().toLowerCase().replaceAll(/[\t ]+/g, ' ').split(/\r?\n/);
1232
1227
  for (const line of lines){
1233
1228
  if (whoisNotFoundKeywordTest(line)) {
1229
+ log$2('[whois] line %s, %O', line, whois);
1234
1230
  return false;
1235
1231
  }
1236
1232
  }
@@ -1238,7 +1234,6 @@ function walkWhois(whois) {
1238
1234
  // so we can't determine if the domain has been registered or not, that's OK, we can check the referrer/follow/redirected whois output.
1239
1235
  for(const key in whois){
1240
1236
  if (Object.hasOwn(whois, key)) {
1241
- // eslint-disable-next-line sukka/no-single-return -- mutable
1242
1237
  whoisIsEmpty = false;
1243
1238
  if (key === '__raw') {
1244
1239
  continue;
@@ -1253,8 +1248,8 @@ function walkWhois(whois) {
1253
1248
  }
1254
1249
  }
1255
1250
  }
1256
- // eslint-disable-next-line sukka/no-single-return -- mutable
1257
- return whoisIsEmpty;
1251
+ log$2('[whois] %O', whois);
1252
+ return !whoisIsEmpty;
1258
1253
  }
1259
1254
 
1260
1255
  async function cacheApply(cache, key, fn) {
@@ -1284,6 +1279,7 @@ async function cacheApply(cache, key, fn) {
1284
1279
  }
1285
1280
 
1286
1281
  const log$1 = debug__default.default('domain-alive:is-registerable-domain-alive');
1282
+ const deadLog$1 = debug__default.default('domain-alive:dead-domain');
1287
1283
  const getRegisterableDomainTldtsOption = {
1288
1284
  allowIcannDomains: true,
1289
1285
  // we want to extract "github.io" out of "sukkaw.github.io" even though github.io is in the
@@ -1358,7 +1354,6 @@ tencentcloud.com. 86400 IN SOA ns-tel1.qq.com. webmaster.qq.com. 165111089
1358
1354
  let confirmations = 0;
1359
1355
  while(attempts < maxAttempts){
1360
1356
  if (confirmations >= maxConfirmations) {
1361
- log$1('[status] %s %s', registerableDomain, true);
1362
1357
  return {
1363
1358
  registerableDomain,
1364
1359
  alive: true
@@ -1387,13 +1382,14 @@ tencentcloud.com. 86400 IN SOA ns-tel1.qq.com. webmaster.qq.com. 165111089
1387
1382
  try {
1388
1383
  const registered = await domainHasBeenRegistered(registerableDomain, whoisOptions);
1389
1384
  log$1('[whois] %s %s', registerableDomain, registered);
1390
- log$1('[status] %s %s', registerableDomain, registered);
1385
+ if (!registered) {
1386
+ deadLog$1('[dead] %s %s', '(apex)', registerableDomain);
1387
+ }
1391
1388
  return {
1392
1389
  registerableDomain,
1393
1390
  alive: registered
1394
1391
  };
1395
1392
  } catch {
1396
- log$1('[status] %s %s', registerableDomain, whoisOptions.whoisErrorCountAsAlive ?? true);
1397
1393
  return {
1398
1394
  registerableDomain,
1399
1395
  alive: whoisOptions.whoisErrorCountAsAlive ?? true
@@ -1404,6 +1400,7 @@ tencentcloud.com. 86400 IN SOA ns-tel1.qq.com. webmaster.qq.com. 165111089
1404
1400
  }
1405
1401
 
1406
1402
  const log = debug__default.default('domain-alive:is-domain-alive');
1403
+ const deadLog = debug__default.default('domain-alive:dead-domain');
1407
1404
  const sharedNullishResult = Object.freeze({
1408
1405
  registerableDomain: null,
1409
1406
  registerableDomainAlive: false,
@@ -1455,7 +1452,6 @@ function createDomainAliveChecker(options = {}) {
1455
1452
  let confirmations = 0;
1456
1453
  while(attempts < maxAttempts){
1457
1454
  if (confirmations >= maxConfirmations) {
1458
- log('[status] %s %s', domain, true);
1459
1455
  return {
1460
1456
  registerableDomain: registerableDomainAliveResult.registerableDomain,
1461
1457
  registerableDomainAlive: registerableDomainAliveResult.alive,
@@ -1471,6 +1467,11 @@ function createDomainAliveChecker(options = {}) {
1471
1467
  confirmations++;
1472
1468
  }
1473
1469
  } catch (e) {
1470
+ if (typeof e === 'object' && e !== null) {
1471
+ Object.assign(e, {
1472
+ dns: resolve.server
1473
+ });
1474
+ }
1474
1475
  log('[A] %s error %O', domain, e);
1475
1476
  } finally{
1476
1477
  attempts++;
@@ -1484,7 +1485,6 @@ function createDomainAliveChecker(options = {}) {
1484
1485
  let confirmations = 0;
1485
1486
  while(attempts < maxAttempts){
1486
1487
  if (confirmations >= maxConfirmations) {
1487
- log('[status] %s %s', domain, true);
1488
1488
  return {
1489
1489
  registerableDomain: registerableDomainAliveResult.registerableDomain,
1490
1490
  registerableDomainAlive: registerableDomainAliveResult.alive,
@@ -1500,6 +1500,11 @@ function createDomainAliveChecker(options = {}) {
1500
1500
  confirmations++;
1501
1501
  }
1502
1502
  } catch (e) {
1503
+ if (typeof e === 'object' && e !== null) {
1504
+ Object.assign(e, {
1505
+ dns: resolve.server
1506
+ });
1507
+ }
1503
1508
  log('[AAAA] %s error %O', domain, e);
1504
1509
  } finally{
1505
1510
  attempts++;
@@ -1508,7 +1513,7 @@ function createDomainAliveChecker(options = {}) {
1508
1513
  }
1509
1514
  }
1510
1515
  // neither A nor AAAA records found
1511
- log('[status] %s %s', domain, false);
1516
+ deadLog('[dead] %s %s', '(A/AAAA)', domain);
1512
1517
  return {
1513
1518
  registerableDomain: registerableDomainAliveResult.registerableDomain,
1514
1519
  registerableDomainAlive: registerableDomainAliveResult.alive,
package/dist/index.mjs CHANGED
@@ -18,20 +18,16 @@ function getDnsClients(servers) {
18
18
  return servers.map((dns)=>{
19
19
  const protocolIndex = dns.indexOf('://');
20
20
  const protocol = protocolIndex === -1 ? '' : dns.slice(0, protocolIndex);
21
- const rest = dns.slice(protocolIndex + 3);
22
- const [server, _port] = rest.split(':', 2);
21
+ const [server, _port] = dns.slice(protocolIndex + 3).split(':', 2);
23
22
  const port = _port ? Number.parseInt(_port, 10) : 0;
24
23
  let client;
25
24
  switch(protocol){
26
25
  case 'https':
27
26
  {
28
- // TODO: fuck dns2 incorrect DOHClient server parse impl
29
27
  const u = new URL(dns);
30
- if (u.pathname === '/') {
28
+ if (!server.includes('/')) {
31
29
  u.pathname = '/dns-query';
32
30
  }
33
- // u.searchParams.set('dns', '{query}');
34
- u.search = '?dns={query}';
35
31
  client = DOHClient({
36
32
  dns: u.href
37
33
  });
@@ -1180,7 +1176,7 @@ const whoiserNoWhoisSymbol = Symbol('"whoiser" library returns "No WHOIS data fo
1180
1176
  return whoisErrorCountAsAlive;
1181
1177
  }
1182
1178
  if (whois === whoiserTLDNotSupportedSymbol) {
1183
- // If TLD doesn't support WHOIS/RDAP, we have no choice but to assume it's alive
1179
+ // If TLD doesn't support WHOIS/RDAP, we have no choice but to assume it's registered
1184
1180
  return true;
1185
1181
  }
1186
1182
  if (whois === whoiserNoWhoisSymbol) {
@@ -1217,12 +1213,12 @@ const whoisNotFoundKeywordTest = createRetrieKeywordFilter([
1217
1213
  // some servers (like TLD whois servers) might have cached/outdated results
1218
1214
  // we can only make sure a domain is alive once all response from all whois servers demonstrate so
1219
1215
  function walkWhois(whois) {
1220
- // eslint-disable-next-line sukka/no-single-return -- mutable
1221
1216
  let whoisIsEmpty = true;
1222
1217
  if ('__raw' in whois && typeof whois.__raw === 'string') {
1223
1218
  const lines = whois.__raw.trim().toLowerCase().replaceAll(/[\t ]+/g, ' ').split(/\r?\n/);
1224
1219
  for (const line of lines){
1225
1220
  if (whoisNotFoundKeywordTest(line)) {
1221
+ log$2('[whois] line %s, %O', line, whois);
1226
1222
  return false;
1227
1223
  }
1228
1224
  }
@@ -1230,7 +1226,6 @@ function walkWhois(whois) {
1230
1226
  // so we can't determine if the domain has been registered or not, that's OK, we can check the referrer/follow/redirected whois output.
1231
1227
  for(const key in whois){
1232
1228
  if (Object.hasOwn(whois, key)) {
1233
- // eslint-disable-next-line sukka/no-single-return -- mutable
1234
1229
  whoisIsEmpty = false;
1235
1230
  if (key === '__raw') {
1236
1231
  continue;
@@ -1245,8 +1240,8 @@ function walkWhois(whois) {
1245
1240
  }
1246
1241
  }
1247
1242
  }
1248
- // eslint-disable-next-line sukka/no-single-return -- mutable
1249
- return whoisIsEmpty;
1243
+ log$2('[whois] %O', whois);
1244
+ return !whoisIsEmpty;
1250
1245
  }
1251
1246
 
1252
1247
  async function cacheApply(cache, key, fn) {
@@ -1276,6 +1271,7 @@ async function cacheApply(cache, key, fn) {
1276
1271
  }
1277
1272
 
1278
1273
  const log$1 = debug('domain-alive:is-registerable-domain-alive');
1274
+ const deadLog$1 = debug('domain-alive:dead-domain');
1279
1275
  const getRegisterableDomainTldtsOption = {
1280
1276
  allowIcannDomains: true,
1281
1277
  // we want to extract "github.io" out of "sukkaw.github.io" even though github.io is in the
@@ -1350,7 +1346,6 @@ tencentcloud.com. 86400 IN SOA ns-tel1.qq.com. webmaster.qq.com. 165111089
1350
1346
  let confirmations = 0;
1351
1347
  while(attempts < maxAttempts){
1352
1348
  if (confirmations >= maxConfirmations) {
1353
- log$1('[status] %s %s', registerableDomain, true);
1354
1349
  return {
1355
1350
  registerableDomain,
1356
1351
  alive: true
@@ -1379,13 +1374,14 @@ tencentcloud.com. 86400 IN SOA ns-tel1.qq.com. webmaster.qq.com. 165111089
1379
1374
  try {
1380
1375
  const registered = await domainHasBeenRegistered(registerableDomain, whoisOptions);
1381
1376
  log$1('[whois] %s %s', registerableDomain, registered);
1382
- log$1('[status] %s %s', registerableDomain, registered);
1377
+ if (!registered) {
1378
+ deadLog$1('[dead] %s %s', '(apex)', registerableDomain);
1379
+ }
1383
1380
  return {
1384
1381
  registerableDomain,
1385
1382
  alive: registered
1386
1383
  };
1387
1384
  } catch {
1388
- log$1('[status] %s %s', registerableDomain, whoisOptions.whoisErrorCountAsAlive ?? true);
1389
1385
  return {
1390
1386
  registerableDomain,
1391
1387
  alive: whoisOptions.whoisErrorCountAsAlive ?? true
@@ -1396,6 +1392,7 @@ tencentcloud.com. 86400 IN SOA ns-tel1.qq.com. webmaster.qq.com. 165111089
1396
1392
  }
1397
1393
 
1398
1394
  const log = debug('domain-alive:is-domain-alive');
1395
+ const deadLog = debug('domain-alive:dead-domain');
1399
1396
  const sharedNullishResult = Object.freeze({
1400
1397
  registerableDomain: null,
1401
1398
  registerableDomainAlive: false,
@@ -1447,7 +1444,6 @@ function createDomainAliveChecker(options = {}) {
1447
1444
  let confirmations = 0;
1448
1445
  while(attempts < maxAttempts){
1449
1446
  if (confirmations >= maxConfirmations) {
1450
- log('[status] %s %s', domain, true);
1451
1447
  return {
1452
1448
  registerableDomain: registerableDomainAliveResult.registerableDomain,
1453
1449
  registerableDomainAlive: registerableDomainAliveResult.alive,
@@ -1463,6 +1459,11 @@ function createDomainAliveChecker(options = {}) {
1463
1459
  confirmations++;
1464
1460
  }
1465
1461
  } catch (e) {
1462
+ if (typeof e === 'object' && e !== null) {
1463
+ Object.assign(e, {
1464
+ dns: resolve.server
1465
+ });
1466
+ }
1466
1467
  log('[A] %s error %O', domain, e);
1467
1468
  } finally{
1468
1469
  attempts++;
@@ -1476,7 +1477,6 @@ function createDomainAliveChecker(options = {}) {
1476
1477
  let confirmations = 0;
1477
1478
  while(attempts < maxAttempts){
1478
1479
  if (confirmations >= maxConfirmations) {
1479
- log('[status] %s %s', domain, true);
1480
1480
  return {
1481
1481
  registerableDomain: registerableDomainAliveResult.registerableDomain,
1482
1482
  registerableDomainAlive: registerableDomainAliveResult.alive,
@@ -1492,6 +1492,11 @@ function createDomainAliveChecker(options = {}) {
1492
1492
  confirmations++;
1493
1493
  }
1494
1494
  } catch (e) {
1495
+ if (typeof e === 'object' && e !== null) {
1496
+ Object.assign(e, {
1497
+ dns: resolve.server
1498
+ });
1499
+ }
1495
1500
  log('[AAAA] %s error %O', domain, e);
1496
1501
  } finally{
1497
1502
  attempts++;
@@ -1500,7 +1505,7 @@ function createDomainAliveChecker(options = {}) {
1500
1505
  }
1501
1506
  }
1502
1507
  // neither A nor AAAA records found
1503
- log('[status] %s %s', domain, false);
1508
+ deadLog('[dead] %s %s', '(A/AAAA)', domain);
1504
1509
  return {
1505
1510
  registerableDomain: registerableDomainAliveResult.registerableDomain,
1506
1511
  registerableDomainAlive: registerableDomainAliveResult.alive,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domain-alive",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "A Node.js library for checking if an FQDN (Fully Qualified Domain Name) is alive or not, uses a combination techniques of `NS` records, WHOIS/RDAP lookups, `A/AAAA` records",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,13 +32,14 @@
32
32
  "dependencies": {
33
33
  "async-retry": "^1.3.3",
34
34
  "debug": "^4.4.1",
35
- "dns2": "github:lsongdev/node-dns#e4fa035aca0b8eb730bde3431fbf0c60a31a09c9",
35
+ "dns2": "github:lsongdev/node-dns#3adb7e91b3101c0e4f43ebaca3a568269ea04d11",
36
36
  "foxts": "^3.12.0",
37
37
  "punycode": "^2.3.1",
38
38
  "tldts": "^7.0.12"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@eslint-sukka/node": "^6.23.1",
42
+ "@swc-node/register": "^1.11.1",
42
43
  "@types/async-retry": "^1.4.9",
43
44
  "@types/debug": "^4.1.12",
44
45
  "@types/dns2": "^2.0.10",
@@ -46,7 +47,7 @@
46
47
  "@types/punycode": "^2.1.4",
47
48
  "bumpp": "^10.2.3",
48
49
  "bunchee": "^6.6.0",
49
- "eslint": "^9.33.0",
50
+ "eslint": "^9.34.0",
50
51
  "eslint-config-sukka": "^6.23.1",
51
52
  "eslint-formatter-sukka": "^6.23.1",
52
53
  "typescript": "^5.9.2",
@@ -55,6 +56,7 @@
55
56
  "scripts": {
56
57
  "lint": "eslint --format=sukka .",
57
58
  "build": "bunchee --no-sourcemap",
59
+ "node": "node --require=@swc-node/register",
58
60
  "prerelease": "pnpm run lint && pnpm run build",
59
61
  "release": "bumpp -r --all --commit \"release: %s\" --tag \"%s\""
60
62
  }