adguardhome.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { escapeStringRegexp } from 'foxts/escape-string-regexp';
  2. import { BaseWriteStrategy } from './base';
  3. import { noop } from 'foxts/noop';
  4. import { notSupported } from '../misc';
  5. export class AdGuardHome extends BaseWriteStrategy {
  6. public readonly name = 'adguardhome';
  7. // readonly type = 'domainset';
  8. readonly fileExtension = 'txt';
  9. readonly type = '';
  10. protected result: string[] = [];
  11. // eslint-disable-next-line @typescript-eslint/class-methods-use-this -- abstract method
  12. withPadding(title: string, description: string[] | readonly string[], date: Date, content: string[]): string[] {
  13. return [
  14. `! Title: ${title}`,
  15. '! Last modified: ' + date.toUTCString(),
  16. '! Expires: 6 hours',
  17. '! License: https://github.com/SukkaW/Surge/blob/master/LICENSE',
  18. '! Homepage: https://github.com/SukkaW/Surge',
  19. `! Description: ${description.join(' ')}`,
  20. '!',
  21. ...content,
  22. '! EOF'
  23. ];
  24. }
  25. writeDomain(domain: string): void {
  26. this.result.push(`|${domain}^`);
  27. }
  28. // const whitelistArray = sortDomains(Array.from(whitelist));
  29. // for (let i = 0, len = whitelistArray.length; i < len; i++) {
  30. // const domain = whitelistArray[i];
  31. // if (domain[0] === '.') {
  32. // results.push(`@@||${domain.slice(1)}^`);
  33. // } else {
  34. // results.push(`@@|${domain}^`);
  35. // }
  36. // }
  37. writeDomainSuffix(domain: string): void {
  38. this.result.push(`||${domain}^`);
  39. }
  40. writeDomainKeywords(keywords: Set<string>): void {
  41. for (const keyword of keywords) {
  42. // Use regex to match keyword
  43. this.result.push(`/${escapeStringRegexp(keyword, false)}/`);
  44. }
  45. }
  46. writeDomainWildcard(wildcard: string): void {
  47. const processed = wildcard.replaceAll('?', '*');
  48. if (processed.startsWith('*.')) {
  49. this.result.push(`||${processed.slice(2)}^`);
  50. } else {
  51. this.result.push(`|${processed}^`);
  52. }
  53. }
  54. writeUserAgents = noop;
  55. writeProcessNames = noop;
  56. writeProcessPaths = noop;
  57. writeUrlRegexes = noop;
  58. writeIpCidrs(ipGroup: string[], noResolve: boolean): void {
  59. if (noResolve) {
  60. // When IP is provided to AdGuardHome, any domain resolve to those IP will be blocked
  61. // So we can't do noResolve
  62. return;
  63. }
  64. for (const ipcidr of ipGroup) {
  65. if (ipcidr.endsWith('/32')) {
  66. this.result.push(`||${ipcidr.slice(0, -3)}`);
  67. /* else if (ipcidr.endsWith('.0/24')) {
  68. results.push(`||${ipcidr.slice(0, -6)}.*`);
  69. } */
  70. } else {
  71. this.result.push(`||${ipcidr}^`);
  72. }
  73. }
  74. }
  75. writeIpCidr6s(ipGroup: string[], noResolve: boolean): void {
  76. if (noResolve) {
  77. // When IP is provided to AdGuardHome, any domain resolve to those IP will be blocked
  78. // So we can't do noResolve
  79. return;
  80. }
  81. for (const ipcidr of ipGroup) {
  82. if (ipcidr.endsWith('/128')) {
  83. this.result.push(`||${ipcidr.slice(0, -4)}`);
  84. } else {
  85. this.result.push(`||${ipcidr}`);
  86. }
  87. }
  88. };
  89. writeGeoip = notSupported('writeGeoip');
  90. writeIpAsns = notSupported('writeIpAsns');
  91. writeSourceIpCidrs = notSupported('writeSourceIpCidrs');
  92. writeSourcePorts = notSupported('writeSourcePorts');
  93. writeDestinationPorts = noop;
  94. writeProtocols = noop;
  95. writeOtherRules = noop;
  96. }