validate-domestic.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import path from 'node:path';
  2. import { SOURCE_DIR } from './constants/dir';
  3. import { parseFelixDnsmasqFromResp } from './lib/parse-dnsmasq';
  4. import { $$fetch } from './lib/fetch-retry';
  5. import runAgainstSourceFile from './lib/run-against-source-file';
  6. import { getTopOneMillionDomains } from './validate-gfwlist';
  7. import { HostnameSmolTrie } from 'hntrie/smol';
  8. import { domainToASCII } from 'node:url';
  9. import tldts from 'tldts-experimental';
  10. import { DOMESTICS } from '../Source/non_ip/domestic';
  11. export async function parseDomesticList() {
  12. const allChinaDomains = new Set<string>(await parseFelixDnsmasqFromResp(await $$fetch('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf')));
  13. const topDomainTrie = await getTopOneMillionDomains();
  14. const resultTrie = new HostnameSmolTrie();
  15. topDomainTrie.dump((domain) => {
  16. const apexDomain = tldts.getDomain(domain);
  17. if (apexDomain && allChinaDomains.has(apexDomain)) {
  18. resultTrie.add(apexDomain);
  19. }
  20. });
  21. const callback = (domain: string, includeAllSubdomain: boolean) => resultTrie.whitelist(includeAllSubdomain ? '.' + domain : domain);
  22. // await Promise.all([
  23. await runAgainstSourceFile(
  24. path.resolve(SOURCE_DIR, 'non_ip/domestic.conf'),
  25. callback
  26. );
  27. await runAgainstSourceFile(
  28. path.resolve(SOURCE_DIR, 'domainset/reject.conf'),
  29. callback
  30. );
  31. Object.values(DOMESTICS).forEach(domestic => {
  32. domestic.domains.forEach(domain => {
  33. switch (domain[0]) {
  34. case '+':
  35. case '$': {
  36. resultTrie.whitelist('.' + domain.slice(1));
  37. break;
  38. }
  39. default: {
  40. resultTrie.whitelist('.' + domain);
  41. break;
  42. }
  43. }
  44. });
  45. });
  46. // noop, DOMAIN-KEYWORD handing
  47. // for (const d of top5000) {
  48. // if (d.includes(domain)) {
  49. // notIncludedDomestic.delete(d);
  50. // }
  51. // }
  52. // ]);
  53. const dump: string[] = [];
  54. resultTrie.dump((rawDomain, includeSubdomain) => {
  55. const domain = domainToASCII(rawDomain);
  56. if (domain) dump.push(includeSubdomain ? '.' + domain : domain);
  57. });
  58. dump.sort((a, b) => (a.length - b.length) || (a < b ? -1 : a > b ? 1 : 0));
  59. console.log(dump.join('\n') + '\n');
  60. console.log(`# Total: ${dump.length}`);
  61. }
  62. if (require.main === module) {
  63. parseDomesticList().catch(console.error);
  64. }