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
}