build-internal-cdn-rules.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // @ts-check
  2. const fse = require('fs-extra');
  3. const path = require('path');
  4. const tldts = require('tldts');
  5. const { processLine } = require('./lib/process-line');
  6. const { readFileByLine } = require('./lib/fetch-remote-text-by-line');
  7. const { createDomainSorter } = require('./lib/stable-sort-domain');
  8. const { task } = require('./lib/trace-runner');
  9. const { compareAndWriteFile } = require('./lib/create-file');
  10. const { getGorhillPublicSuffixPromise } = require('./lib/get-gorhill-publicsuffix');
  11. const { createCachedGorhillGetDomain } = require('./lib/cached-tld-parse');
  12. /**
  13. * @param {string} string
  14. */
  15. const escapeRegExp = (string) => {
  16. return string.replaceAll(/[$()*+.?[\\\]^{|}]/g, '\\$&');
  17. };
  18. const buildInternalCDNDomains = task(__filename, async () => {
  19. const set = new Set();
  20. const keywords = new Set();
  21. const gorhill = await getGorhillPublicSuffixPromise();
  22. const getDomain = createCachedGorhillGetDomain(gorhill);
  23. const domainSorter = createDomainSorter(gorhill);
  24. /**
  25. * @param {string} input
  26. */
  27. const addApexDomain = (input) => {
  28. const d = getDomain(input);
  29. if (d) {
  30. set.add(d);
  31. }
  32. };
  33. /**
  34. * @param {string} domainSetPath
  35. */
  36. const processLocalDomainSet = async (domainSetPath) => {
  37. for await (const line of readFileByLine(domainSetPath)) {
  38. const parsed = tldts.parse(line, { allowPrivateDomains: true });
  39. if (parsed.isIp) continue;
  40. if (parsed.isIcann || parsed.isPrivate) {
  41. if (parsed.domain) {
  42. set.add(parsed.domain);
  43. }
  44. continue;
  45. }
  46. if (processLine(line)) {
  47. console.warn('[drop line from domainset]', line);
  48. }
  49. }
  50. };
  51. /**
  52. * @param {string} ruleSetPath
  53. */
  54. const processLocalRuleSet = async (ruleSetPath) => {
  55. for await (const line of readFileByLine(ruleSetPath)) {
  56. if (line.startsWith('DOMAIN-SUFFIX,')) {
  57. addApexDomain(line.replace('DOMAIN-SUFFIX,', ''));
  58. } else if (line.startsWith('DOMAIN,')) {
  59. addApexDomain(line.replace('DOMAIN,', ''));
  60. } else if (line.startsWith('DOMAIN-KEYWORD')) {
  61. keywords.add(escapeRegExp(line.replace('DOMAIN-KEYWORD,', '')));
  62. } else if (line.startsWith('USER-AGENT,') || line.startsWith('PROCESS-NAME,')) {
  63. // do nothing
  64. } else if (processLine(line)) {
  65. console.warn('[drop line from ruleset]', line);
  66. }
  67. }
  68. };
  69. await Promise.all([
  70. processLocalRuleSet(path.resolve(__dirname, '../List/non_ip/cdn.conf')),
  71. processLocalRuleSet(path.resolve(__dirname, '../List/non_ip/global.conf')),
  72. processLocalRuleSet(path.resolve(__dirname, '../List/non_ip/global_plus.conf')),
  73. processLocalRuleSet(path.resolve(__dirname, '../List/non_ip/my_proxy.conf')),
  74. processLocalRuleSet(path.resolve(__dirname, '../List/non_ip/stream.conf')),
  75. processLocalRuleSet(path.resolve(__dirname, '../List/non_ip/telegram.conf')),
  76. processLocalDomainSet(path.resolve(__dirname, '../List/domainset/cdn.conf')),
  77. processLocalDomainSet(path.resolve(__dirname, '../List/domainset/download.conf')),
  78. fse.ensureDir(path.resolve(__dirname, '../List/internal'))
  79. ]);
  80. return compareAndWriteFile(
  81. [
  82. ...Array.from(set).sort(domainSorter).map(i => `SUFFIX,${i}`),
  83. ...Array.from(keywords).sort().map(i => `REGEX,${i}`)
  84. ],
  85. path.resolve(__dirname, '../List/internal/cdn.txt')
  86. );
  87. });
  88. module.exports.buildInternalCDNDomains = buildInternalCDNDomains;
  89. if (require.main === module) {
  90. buildInternalCDNDomains();
  91. }