diff --git a/Build/build-public.ts b/Build/build-public.ts index 82168534..7f410752 100644 --- a/Build/build-public.ts +++ b/Build/build-public.ts @@ -129,7 +129,7 @@ function treeHtml(tree: TreeTypeArray, level = 0, closedFolderList: string[] = [ `; - } else if (/* entry.type === 'file' && */ !entry.name.endsWith('.html') && !entry.name.startsWith('_')) { + } else if (/* entry.type === 'file' && */ !entry.name.endsWith('.html') && entry.name[0] !== '_') { result += html`
  • ${entry.name}
  • `; diff --git a/Build/build-sgmodule-redirect.ts b/Build/build-sgmodule-redirect.ts index f5a739ee..e6a41be3 100644 --- a/Build/build-sgmodule-redirect.ts +++ b/Build/build-sgmodule-redirect.ts @@ -251,7 +251,8 @@ function uBOUriTransformGenerator(acc: string[], [from, to, canUboUriTransform]: } // unlike Surge, which processes rules form top to bottom, uBO treats later rules with higher priority (overriden-like behavior), - // so when doing uBO we need to prepend. Given the the rules count is small, the performance impact is negligible. + // so when doing uBO we need to prepend. + // eslint-disable-next-line sukka/unicorn/no-array-front-mutation -- Given the the rules count is small, the performance impact is negligible. acc.unshift( '||' + from @@ -280,7 +281,7 @@ function uBOUriTransformGeneratorForFakeWebsites(acc: string[], [from, to]: [fro // https://www.formysql.com/en/products/navicat-for-mysql // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // https://www.navicat.com.cn - + String.raw`\/.*` + escapeRegexp(from).replaceAll('/', String.raw`\/`) + String.raw`.*` + + String.raw`\/.*` + escapeRegexp(from).replaceAll('/', String.raw`\/`) + '.*' + '/' + to.replace('https://', '').replaceAll('/', String.raw`\/`) + '/' diff --git a/Build/build-telegram-cidr.ts b/Build/build-telegram-cidr.ts index c8642041..96e9d189 100644 --- a/Build/build-telegram-cidr.ts +++ b/Build/build-telegram-cidr.ts @@ -9,6 +9,7 @@ import dns from 'node:dns/promises'; import { createReadlineInterfaceFromResponse } from './lib/fetch-text-by-line'; import { fastIpVersion } from 'foxts/fast-ip-version'; import { fastStringArrayJoin } from 'foxts/fast-string-array-join'; +import { appendArrayInPlace } from 'foxts/append-array-in-place'; export const buildTelegramCIDR = task(require.main === module, __filename)(async (span) => { const { timestamp, ipcidr, ipcidr6 } = await span.traceChildAsync('get telegram cidr', async () => { @@ -129,7 +130,7 @@ export const buildTelegramCIDR = task(require.main === module, __filename)(async console.log('[telegram backup ip]', `Found ${backupIPs.size} backup IPs:`, backupIPs); - ipcidr.push(...Array.from(backupIPs).map(i => i + '/32')); + appendArrayInPlace(ipcidr, Array.from(backupIPs).map(i => i + '/32')); return { timestamp: date.getTime(), ipcidr, ipcidr6 }; }); diff --git a/Build/build-telegram-cidr.worker.ts b/Build/build-telegram-cidr.worker.ts index f17e824c..a1521e0a 100644 --- a/Build/build-telegram-cidr.worker.ts +++ b/Build/build-telegram-cidr.worker.ts @@ -9,6 +9,7 @@ import dns from 'node:dns/promises'; import { createReadlineInterfaceFromResponse } from './lib/fetch-text-by-line'; import { fastIpVersion } from 'foxts/fast-ip-version'; import { fastStringArrayJoin } from 'foxts/fast-string-array-join'; +import { appendArrayInPlace } from 'foxts/append-array-in-place'; export const buildTelegramCIDR = task(require.main === module, __filename)(async (span) => { const { timestamp, ipcidr, ipcidr6 } = await span.traceChildAsync('get telegram cidr', async () => { @@ -129,7 +130,7 @@ export const buildTelegramCIDR = task(require.main === module, __filename)(async console.log('[telegram backup ip]', `Found ${backupIPs.size} backup IPs:`, backupIPs); - ipcidr.push(...Array.from(backupIPs).map(i => i + '/32')); + appendArrayInPlace(ipcidr, Array.from(backupIPs).map(i => i + '/32')); return { timestamp: date.getTime(), ipcidr, ipcidr6 }; }); diff --git a/Build/lib/create-file.ts b/Build/lib/create-file.ts index 0b388efb..d2bf3280 100644 --- a/Build/lib/create-file.ts +++ b/Build/lib/create-file.ts @@ -41,9 +41,8 @@ export async function compareAndWriteFile(span: Span, linesA: string[], filePath } const writeStream = fs.createWriteStream(filePath); - let p; for (let i = 0; i < linesALen; i++) { - p = asyncWriteToStream(writeStream, linesA[i] + '\n'); + const p = asyncWriteToStream(writeStream, linesA[i] + '\n'); // eslint-disable-next-line no-await-in-loop -- stream high water mark if (p) await p; } diff --git a/Build/lib/fetch-retry.ts b/Build/lib/fetch-retry.ts index 402e9793..2bc7ceaf 100644 --- a/Build/lib/fetch-retry.ts +++ b/Build/lib/fetch-retry.ts @@ -21,6 +21,7 @@ import path from 'node:path'; import fs from 'node:fs'; import { CACHE_DIR } from '../constants/dir'; import { isAbortErrorLike } from 'foxts/abort-error'; +import { isErrorLikeObject } from 'foxts/extract-error-message'; if (!fs.existsSync(CACHE_DIR)) { fs.mkdirSync(CACHE_DIR, { recursive: true }); @@ -58,6 +59,7 @@ const agent = new Agent({ if ( errorCode === 'ERR_UNESCAPED_CHARACTERS' || errorCode === 'UND_ERR_DESTROYED' + // eslint-disable-next-line sukka/prefer-foxts-error-util -- we already know this is Error type || err.message === 'Request path contains unescaped characters' || err.name === 'AbortError' ) { @@ -277,7 +279,7 @@ export async function requestWithLog(url: string, opt?: Parameters) { - let d: string | null; for (let i = 0, len = domains.length; i < len; i++) { - d = domains[i]; + const d = domains[i]; if (d !== null) { this.domainTrie.add(d, false, null, 0); } diff --git a/Build/lib/tree-dir.ts b/Build/lib/tree-dir.ts index 848cc41a..397de054 100644 --- a/Build/lib/tree-dir.ts +++ b/Build/lib/tree-dir.ts @@ -57,7 +57,6 @@ export async function treeDir(rootPath: string): Promise { path: childRelativeToRoot }; node.push(newNode); - continue; } } }; diff --git a/Build/lib/trie.ts b/Build/lib/trie.ts index 42328146..6fc281f1 100644 --- a/Build/lib/trie.ts +++ b/Build/lib/trie.ts @@ -285,10 +285,9 @@ abstract class Triebase { const suffixStack: string[][] = [initialSuffix]; let node: TrieNode = initialNode; - let r; do { - r = dfsImpl(nodeStack, suffixStack); + const r = dfsImpl(nodeStack, suffixStack); node = r[0]!; const suffix = r[1]; @@ -588,20 +587,20 @@ export class HostnameSmolTrie extends Triebase { } function cleanUpEmptyTrailNode(node: TrieNode) { - if ( + let current = node; + while ( // the current node is not an "end node", a.k.a. not the start of a domain - missingBit(node[0], START) + missingBit(current[0], START) // also no leading "." (no subdomain) - && missingBit(node[0], INCLUDE_ALL_SUBDOMAIN) + && missingBit(current[0], INCLUDE_ALL_SUBDOMAIN) // child is empty - && node[2].size === 0 - // has parent: we need to detele the cureent node from the parent - // we also need to recursively clean up the parent node - && node[1] + && current[2].size === 0 + // has parent: we need to delete the current node from the parent + // we also need to clean up the parent node + && current[1] ) { - node[1][2].delete(node[3]); - // finish of the current stack - return cleanUpEmptyTrailNode(node[1]); + current[1][2].delete(current[3]); + current = current[1]; } } diff --git a/Build/lib/writing-strategy/clash.ts b/Build/lib/writing-strategy/clash.ts index 56a5b99c..bd5ed7d2 100644 --- a/Build/lib/writing-strategy/clash.ts +++ b/Build/lib/writing-strategy/clash.ts @@ -162,7 +162,6 @@ export class ClashClassicRuleSet extends BaseWriteStrategy { } if (v === 6) { this.result.push(`SRC-IP-CIDR6,${value}/128`); - continue; } } } diff --git a/Build/validate-gfwlist.ts b/Build/validate-gfwlist.ts index 9a6dd69a..11825357 100644 --- a/Build/validate-gfwlist.ts +++ b/Build/validate-gfwlist.ts @@ -92,11 +92,11 @@ export async function parseGfwList() { gfwListTrie.add('.' + line.slice(2)); continue; } - if (line.startsWith('|')) { + if (line[0] === '|') { gfwListTrie.add(line.slice(1)); continue; } - if (line.startsWith('.')) { + if (line[0] === '.') { gfwListTrie.add(line); continue; } @@ -104,7 +104,6 @@ export async function parseGfwList() { if (d) { totalGfwSize++; gfwListTrie.add(d); - continue; } } for await (const l of await fetchRemoteTextByLine('https://raw.githubusercontent.com/Loyalsoldier/cn-blocked-domain/release/domains.txt', true)) { diff --git a/Build/validate-global-tld.ts b/Build/validate-global-tld.ts index a33e3adf..3eb0f649 100644 --- a/Build/validate-global-tld.ts +++ b/Build/validate-global-tld.ts @@ -21,8 +21,8 @@ import { MARKER_DOMAIN } from './constants/description'; } }, 'ruleset'); - await runAgainstSourceFile(path.join(OUTPUT_SURGE_DIR, 'non_ip', 'global.conf'), (domain, includeAllSubDomain) => { - trie.add(domain, includeAllSubDomain); + await runAgainstSourceFile(path.join(OUTPUT_SURGE_DIR, 'non_ip', 'global.conf'), (domain, includeAllSubdomain) => { + trie.add(domain, includeAllSubdomain); }, 'ruleset'); ICP_TLD.forEach(tld => trie.whitelist(tld, true)); diff --git a/Build/validate-hash-collision-test.ts b/Build/validate-hash-collision-test.ts index fbadb1de..fd2e1daa 100644 --- a/Build/validate-hash-collision-test.ts +++ b/Build/validate-hash-collision-test.ts @@ -28,7 +28,7 @@ import { xxhash3 } from 'hash-wasm'; if (file.startsWith('domainset' + path.sep)) { await runHash((await readFileIntoProcessedArray(fullpath)).map(i => (i[0] === '.' ? i.slice(1) : i))); } else if (file.startsWith('non_ip' + path.sep)) { - await runHash((await readFileIntoProcessedArray(fullpath)).map(i => i.split(',')[1])); + await runHash((await readFileIntoProcessedArray(fullpath)).map(i => i.split(',', 2)[1])); } } diff --git a/Mock/www-google-analytics-com_inpage_linkid.js b/Mock/www-google-analytics-com_inpage_linkid.js index d0724575..42e0788e 100644 --- a/Mock/www-google-analytics-com_inpage_linkid.js +++ b/Mock/www-google-analytics-com_inpage_linkid.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - window._gaq = window._gaq || { + window._gaq ||= { push() { // noop }