Refactor: adjust write strategy usage

This commit is contained in:
SukkaW
2025-01-29 21:24:00 +08:00
parent 956d98d7dc
commit f9163db26c
9 changed files with 365 additions and 209 deletions

View File

@@ -12,7 +12,7 @@ import * as yaml from 'yaml';
import { appendArrayInPlace } from './lib/append-array-in-place';
import { OUTPUT_INTERNAL_DIR, OUTPUT_MODULES_DIR, OUTPUT_MODULES_RULES_DIR, SOURCE_DIR } from './constants/dir';
import { RulesetOutput } from './lib/create-file';
import { SurgeRuleSet } from './lib/writing-strategy/surge';
import { SurgeOnlyRulesetOutput } from './lib/rules/ruleset';
export function createGetDnsMappingRule(allowWildcard: boolean) {
const hasWildcard = (domain: string) => {
@@ -115,16 +115,13 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as
return;
}
const output = new RulesetOutput(span, name.toLowerCase(), 'sukka_local_dns_mapping')
const output = new SurgeOnlyRulesetOutput(span, name.toLowerCase(), 'sukka_local_dns_mapping', OUTPUT_MODULES_RULES_DIR)
.withTitle(`Sukka's Ruleset - Local DNS Mapping (${name})`)
.withDescription([
...SHARED_DESCRIPTION,
'',
'This is an internal rule that is only referenced by sukka_local_dns_mapping.sgmodule',
'Do not use this file in your Rule section, all rules are included in non_ip/domestic.conf already.'
])
.replaceStrategies([
new SurgeRuleSet('sukka_local_dns_mapping', OUTPUT_MODULES_RULES_DIR)
]);
domains.forEach((domain) => {

View File

@@ -19,8 +19,7 @@ import { addArrayElementsToSet } from 'foxts/add-array-elements-to-set';
import { OUTPUT_INTERNAL_DIR, SOURCE_DIR } from './constants/dir';
import { DomainsetOutput } from './lib/create-file';
import { foundDebugDomain } from './lib/parse-filter/shared';
import { AdGuardHome } from './lib/writing-strategy/adguardhome';
import { FileOutput } from './lib/rules/base';
import { AdGuardHomeOutput } from './lib/rules/domainset';
const readLocalRejectDomainsetPromise = readFileIntoProcessedArray(path.join(SOURCE_DIR, 'domainset/reject_sukka.conf'));
const readLocalRejectExtraDomainsetPromise = readFileIntoProcessedArray(path.join(SOURCE_DIR, 'domainset/reject_sukka_extra.conf'));
@@ -151,12 +150,11 @@ export const buildRejectDomainSet = task(require.main === module, __filename)(as
// we are going to re-use rejectOutput's domainTrie and mutate it
// so we must wait until we write rejectOutput to disk after we can mutate its trie
const rejectOutputAdGuardHome = new FileOutput(span, 'reject-adguardhome')
const rejectOutputAdGuardHome = new AdGuardHomeOutput(span, 'reject-adguardhome', OUTPUT_INTERNAL_DIR)
.withTitle('Sukka\'s Ruleset - Blocklist for AdGuardHome')
.withDescription([
'The domainset supports AD blocking, tracking protection, privacy protection, anti-phishing, anti-mining'
])
.replaceStrategies([new AdGuardHome(OUTPUT_INTERNAL_DIR)]);
]);
rejectOutputAdGuardHome.domainTrie = rejectOutput.domainTrie;

View File

@@ -1,6 +1,6 @@
import path from 'node:path';
import { task } from './trace';
import { compareAndWriteFile, DomainsetOutput } from './lib/create-file';
import { compareAndWriteFile } from './lib/create-file';
import { DIRECTS, LAN } from '../Source/non_ip/direct';
import type { DNSMapping } from '../Source/non_ip/direct';
import { DOMESTICS, DOH_BOOTSTRAP } from '../Source/non_ip/domestic';
@@ -10,6 +10,7 @@ import { appendArrayInPlace } from './lib/append-array-in-place';
import { SHARED_DESCRIPTION } from './constants/description';
import { createGetDnsMappingRule } from './build-domestic-direct-lan-ruleset-dns-mapping-module';
import { ClashDomainSet } from './lib/writing-strategy/clash';
import { FileOutput } from './lib/rules/base';
const HOSTNAMES = [
// Network Detection, Captive Portal
@@ -39,14 +40,14 @@ const HOSTNAMES = [
export const buildAlwaysRealIPModule = task(require.main === module, __filename)(async (span) => {
const surge: string[] = [];
const clashFakeIpFilter = new DomainsetOutput(span, 'clash_fake_ip_filter')
const clashFakeIpFilter = new FileOutput(span, 'clash_fake_ip_filter')
.withTitle('Sukka\'s Ruleset - Always Real IP Plus')
.withDescription([
...SHARED_DESCRIPTION,
'',
'Clash.Meta fake-ip-filter as ruleset'
])
.replaceStrategies([
.withStrategies([
new ClashDomainSet('domainset')
]);

View File

@@ -7,12 +7,12 @@ import path from 'node:path';
import { ALL as AllStreamServices } from '../Source/stream';
import { getChnCidrPromise } from './build-chn-cidr';
import { getTelegramCIDRPromise } from './build-telegram-cidr';
import { compareAndWriteFile, RulesetOutput } from './lib/create-file';
import { compareAndWriteFile } from './lib/create-file';
import { getMicrosoftCdnRulesetPromise } from './build-microsoft-cdn';
import { isTruthy, nullthrow } from 'foxts/guard';
import { appendArrayInPlace } from './lib/append-array-in-place';
import { OUTPUT_INTERNAL_DIR, OUTPUT_SURGE_DIR, SOURCE_DIR } from './constants/dir';
import { ClashClassicRuleSet } from './lib/writing-strategy/clash';
import { ClashOnlyRulesetOutput } from './lib/rules/ruleset';
const POLICY_GROUPS: Array<[name: string, insertProxy: boolean, insertDirect: boolean]> = [
['Default Proxy', true, false],
@@ -79,8 +79,7 @@ export const buildSSPanelUIMAppProfile = task(require.main === module, __filenam
readFileIntoProcessedArray(path.join(OUTPUT_SURGE_DIR, 'ip/lan.conf'))
] as const);
const domestic = new RulesetOutput(span, '_', 'non_ip')
.replaceStrategies([new ClashClassicRuleSet('non_ip')])
const domestic = new ClashOnlyRulesetOutput(span, '_', 'non_ip')
.addFromRuleset(domesticRules)
.bulkAddDomainSuffix(appleCdnDomains)
.bulkAddDomain(microsoftCdnDomains)
@@ -88,61 +87,52 @@ export const buildSSPanelUIMAppProfile = task(require.main === module, __filenam
.addFromRuleset(appleCnRules)
.addFromRuleset(neteaseMusicRules);
const microsoftApple = new RulesetOutput(span, '_', 'non_ip')
.replaceStrategies([new ClashClassicRuleSet('non_ip')])
const microsoftApple = new ClashOnlyRulesetOutput(span, '_', 'non_ip')
.addFromRuleset(microsoftRules)
.addFromRuleset(appleRules);
const stream = new RulesetOutput(span, '_', 'non_ip')
.replaceStrategies([new ClashClassicRuleSet('non_ip')])
const stream = new ClashOnlyRulesetOutput(span, '_', 'non_ip')
.addFromRuleset(streamRules);
const steam = new RulesetOutput(span, '_', 'non_ip')
.replaceStrategies([new ClashClassicRuleSet('non_ip')])
const steam = new ClashOnlyRulesetOutput(span, '_', 'non_ip')
.addFromDomainset(steamDomainset);
const global = new RulesetOutput(span, '_', 'non_ip')
.replaceStrategies([new ClashClassicRuleSet('non_ip')])
const global = new ClashOnlyRulesetOutput(span, '_', 'non_ip')
.addFromRuleset(globalRules)
.addFromRuleset(telegramRules);
const direct = new RulesetOutput(span, '_', 'non_ip')
.replaceStrategies([new ClashClassicRuleSet('non_ip')])
const direct = new ClashOnlyRulesetOutput(span, '_', 'non_ip')
.addFromRuleset(directRules)
.addFromRuleset(lanRules);
const domesticCidr = new RulesetOutput(span, '_', 'ip')
.replaceStrategies([new ClashClassicRuleSet('ip')])
const domesticCidr = new ClashOnlyRulesetOutput(span, '_', 'ip')
.bulkAddCIDR4(domesticCidrs4)
.bulkAddCIDR6(domesticCidrs6);
const streamCidr = new RulesetOutput(span, '_', 'ip')
.replaceStrategies([new ClashClassicRuleSet('ip')])
const streamCidr = new ClashOnlyRulesetOutput(span, '_', 'ip')
.bulkAddCIDR4(streamCidrs4)
.bulkAddCIDR6(streamCidrs6);
const telegramCidr = new RulesetOutput(span, '_', 'ip')
.replaceStrategies([new ClashClassicRuleSet('ip')])
const telegramCidr = new ClashOnlyRulesetOutput(span, '_', 'ip')
.bulkAddCIDR4(telegramCidrs4)
.bulkAddCIDR6(telegramCidrs6);
const lanCidrs = new RulesetOutput(span, '_', 'ip')
.replaceStrategies([new ClashClassicRuleSet('ip')])
const lanCidrs = new ClashOnlyRulesetOutput(span, '_', 'ip')
.addFromRuleset(rawLanCidrs);
const output = generateAppProfile(
...(
(await Promise.all([
domestic.output(),
microsoftApple.output(),
stream.output(),
steam.output(),
global.output(),
direct.output(),
domesticCidr.output(),
streamCidr.output(),
telegramCidr.output(),
lanCidrs.output()
domestic.compile(),
microsoftApple.compile(),
stream.compile(),
steam.compile(),
global.compile(),
direct.compile(),
domesticCidr.compile(),
streamCidr.compile(),
telegramCidr.compile(),
lanCidrs.compile()
])).map(output => nullthrow(output[0]))
) as [
string[], string[], string[], string[], string[],

View File

@@ -57,7 +57,7 @@ export class FileOutput {
return this;
}
replaceStrategies(strategies: Array<BaseWriteStrategy | false>) {
public withStrategies(strategies: Array<BaseWriteStrategy | false>) {
this.strategies = strategies;
return this;
}
@@ -444,7 +444,7 @@ export class FileOutput {
});
}
async output(): Promise<Array<string[] | null>> {
async compile(): Promise<Array<string[] | null>> {
await this.writeToStrategies();
return this.strategies.reduce<Array<string[] | null>>((acc, strategy) => {

View File

@@ -1,3 +1,5 @@
import type { Span } from '../../trace';
import { AdGuardHome } from '../writing-strategy/adguardhome';
import type { BaseWriteStrategy } from '../writing-strategy/base';
import { ClashDomainSet } from '../writing-strategy/clash';
import { SingboxSource } from '../writing-strategy/singbox';
@@ -13,3 +15,19 @@ export class DomainsetOutput extends FileOutput {
new SingboxSource(this.type)
];
}
export class AdGuardHomeOutput extends FileOutput {
strategies: Array<false | BaseWriteStrategy>;
constructor(
span: Span,
id: string,
outputDir: string
) {
super(span, id);
this.strategies = [
new AdGuardHome(outputDir)
];
}
}

View File

@@ -15,3 +15,32 @@ export class RulesetOutput extends FileOutput {
];
}
}
export class SurgeOnlyRulesetOutput extends FileOutput {
constructor(
span: Span,
id: string,
protected type: 'non_ip' | 'ip' | (string & {}),
overrideOutputDir?: string
) {
super(span, id);
this.strategies = [
new SurgeRuleSet(this.type, overrideOutputDir)
];
}
}
export class ClashOnlyRulesetOutput extends FileOutput {
constructor(
span: Span,
id: string,
protected type: 'non_ip' | 'ip' | (string & {})
) {
super(span, id);
this.strategies = [
new ClashClassicRuleSet(this.type)
];
}
}