-
Notifications
You must be signed in to change notification settings - Fork 5
Redesign repo structure and get domains list from multiple sources #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3eb385d
1b9724c
2973ddc
f2bf1af
0173bdb
b7c2fd8
45468db
e4dcb6a
f2532bd
f6f448f
785d139
57f8f26
5d8fdcf
0b7640a
c0bf75c
b253d9b
4be8bd9
5a5ad11
79f1ab5
5dab3b1
b1c9c84
9fb4d9f
33f3ae6
3b37419
4f8b980
efef1c4
b12ec19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| node_modules | ||
| dist | ||
| sources/src/#generated-*.ts | ||
| sources/src/#generated-*.ts | ||
| .buildcache |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "name": "@filteringdev/tinyshield-builder", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "lint": "tsc --noEmit && eslint **/*.ts", | ||
| "build": "tsx source/buildci.ts", | ||
| "debug": "tsx source/debug.ts", | ||
| "clean": "rm -rf dist && rm -rf .buildcache" | ||
| }, | ||
| "dependencies": { | ||
| "@types/node": "^24.10.9" | ||
| }, | ||
| "devDependencies": { | ||
| "@adguard/agtree": "^3.4.3", | ||
| "@npmcli/package-json": "^7.0.4", | ||
| "@types/npmcli__package-json": "^4.0.4", | ||
| "@types/semver": "^7.7.1", | ||
| "@typescriptprime/parsing": "^1.0.4", | ||
| "@typescriptprime/securereq": "^1.1.0", | ||
| "chokidar": "^5.0.0", | ||
| "esbuild": "^0.27.2", | ||
| "eslint": "^9.39.2", | ||
| "semver": "^7.7.3", | ||
| "tldts": "^7.0.19", | ||
| "tsx": "^4.21.0", | ||
| "typescript": "^5.9.3", | ||
| "typescript-eslint": "^8.53.0", | ||
| "zod": "^4.3.5" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,47 @@ | ||||
| export interface BannerOptions { | ||||
| Version: string | ||||
| BuildType: 'production' | 'development' | ||||
| Domains: Set<string> | ||||
| Author: string | ||||
| Name: string | ||||
| Namespace: string | ||||
| HomepageURL: URL | ||||
| SupportURL: URL | ||||
| UpdateURL: URL | ||||
| DownloadURL: URL | ||||
| License: string | ||||
| Description: Record<'en' | 'ko' | 'ja' | string, string> | ||||
| } | ||||
|
|
||||
| export function CreateBanner(Options: BannerOptions): string { | ||||
| let BannerString: string = '// ==UserScript==\n' | ||||
| BannerString += `// @name ${Options.BuildType === 'production' ? Options.Name : Options.Name + ' (Development)'}\n` | ||||
| BannerString += '//\n' | ||||
| BannerString += `// @namespace ${Options.Namespace}\n` | ||||
| BannerString += `// @homepageURL ${Options.HomepageURL.href}\n` | ||||
| BannerString += `// @supportURL ${Options.SupportURL.href}\n` | ||||
| BannerString += `// @updateURL ${Options.UpdateURL.href}\n` | ||||
| BannerString += `// @downloadURL ${Options.DownloadURL.href}\n` | ||||
| BannerString += `// @license ${Options.License}\n` | ||||
| BannerString += '//\n' | ||||
| BannerString += `// @version ${Options.Version}\n` | ||||
| BannerString += `// @author ${Options.Author}\n` | ||||
| BannerString += '//\n' | ||||
| BannerString += '// @grant unsafeWindow\n' | ||||
| BannerString += '// @run-at document-start\n' | ||||
| BannerString += '//\n' | ||||
| BannerString += `// @description ${Options.Description['en']}\n` | ||||
|
|
||||
|
||||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,79 @@ | ||||
| import * as ESBuild from 'esbuild' | ||||
| import * as Zod from 'zod' | ||||
| import * as Process from 'node:process' | ||||
| import * as TLDTS from 'tldts' | ||||
| import PackageJson from '@npmcli/package-json' | ||||
| import { LoadDomainsFromCache } from './cache.js' | ||||
| import { FetchAdShieldDomains } from './references/index.js' | ||||
| import { CustomDefinedMatches } from './references/custom-defined.js' | ||||
| import { ConvertWildcardSuffixToRegexPattern } from './utils/wildcard-suffix-converter.js' | ||||
| import { CreateBanner } from './banner/index.js' | ||||
|
|
||||
| export type BuildOptions = { | ||||
| Minify: boolean | ||||
| UseCache: boolean | ||||
| BuildType: 'production' | 'development', | ||||
| SubscriptionUrl: string, | ||||
| Version?: string | ||||
| } | ||||
|
|
||||
| export async function Build(OptionsParam?: BuildOptions): Promise<void> { | ||||
| const Options = await Zod.strictObject({ | ||||
| Minify: Zod.boolean(), | ||||
| UseCache: Zod.boolean(), | ||||
| BuildType: Zod.enum(['production', 'development']), | ||||
| SubscriptionUrl: Zod.string().transform(Value => new URL(Value)).default(new URL('https://cdn.jsdelivr.net/npm/@filteringdev/tinyshield@latest/dist/tinyShield.user.js')), | ||||
| Version: Zod.string().optional() | ||||
| }).parseAsync(OptionsParam) | ||||
|
|
||||
| let MatchingDomains: Set<string> = new Set<string>() | ||||
| if (Options.UseCache) { | ||||
| MatchingDomains = await LoadDomainsFromCache() | ||||
| } else { | ||||
| MatchingDomains = await FetchAdShieldDomains() | ||||
| } | ||||
| CustomDefinedMatches.forEach(Domain => MatchingDomains.add(Domain)) | ||||
|
|
||||
| MatchingDomains = new Set<string>([...MatchingDomains].map(Domain => TLDTS.parse(Domain).domain ?? Domain).filter((D): D is string => D !== null)) | ||||
| for (const Domain of MatchingDomains) { | ||||
| if (Domain.endsWith('.*')) { | ||||
| MatchingDomains.delete(Domain) | ||||
| ConvertWildcardSuffixToRegexPattern(Domain).forEach(GeneratedPattern => MatchingDomains.add(GeneratedPattern)) | ||||
| } | ||||
| } | ||||
|
|
||||
| let ProjectRoot = Process.cwd() | ||||
| if (Process.cwd().endsWith('/builder')) { | ||||
| ProjectRoot = Process.cwd() + '/..' | ||||
| } | ||||
|
|
||||
|
||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,14 @@ | ||||||||||
| import * as Zod from 'zod' | ||||||||||
| import * as Process from 'node:process' | ||||||||||
| import { PreProcessing, PostProcessing } from '@typescriptprime/parsing' | ||||||||||
| import { Build, BuildOptions } from './build.js' | ||||||||||
|
|
||||||||||
| let ParsedArgv = (await PostProcessing<BuildOptions>(PreProcessing(Process.argv))).Options | ||||||||||
| let Options = await Zod.strictObject({ | ||||||||||
| Minify: Zod.string().pipe(Zod.enum(['true', 'false'])).transform(Value => Value === 'true').default(true), | ||||||||||
| UseCache: Zod.string().pipe(Zod.enum(['true', 'false'])).transform(Value => Value === 'true').default(true), | ||||||||||
|
Comment on lines
+8
to
+9
|
||||||||||
| Minify: Zod.string().pipe(Zod.enum(['true', 'false'])).transform(Value => Value === 'true').default(true), | |
| UseCache: Zod.string().pipe(Zod.enum(['true', 'false'])).transform(Value => Value === 'true').default(true), | |
| Minify: Zod.string().pipe(Zod.enum(['true', 'false'])).transform(Value => Value === 'true').default('true'), | |
| UseCache: Zod.string().pipe(Zod.enum(['true', 'false'])).transform(Value => Value === 'true').default('true'), |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import * as Zod from 'zod' | ||
| import * as Fs from 'node:fs' | ||
| import * as Process from 'node:process' | ||
| import { FetchAdShieldDomains } from './references/index.js' | ||
|
|
||
| const CachePath = Process.cwd() + '/.buildcache' | ||
| const CacheDomainsPath = CachePath + '/domains.json' | ||
|
|
||
| export function CreateCache(Domains: Set<string>) { | ||
| if (!Fs.existsSync(CachePath)) { | ||
| Fs.mkdirSync(CachePath) | ||
| } else if (!Fs.statSync(CachePath).isDirectory()) { | ||
| throw new Error('.buildcache exists and is not a directory!') | ||
| } | ||
| if (Fs.existsSync(CacheDomainsPath)) { | ||
| throw new Error('Cache already exists!') | ||
| } | ||
| Fs.writeFileSync(CacheDomainsPath, JSON.stringify([...Domains], null, 2), { encoding: 'utf-8' }) | ||
| } | ||
|
|
||
| export async function LoadCache(): Promise<Set<string>> { | ||
| if (!Fs.existsSync(CacheDomainsPath)) { | ||
| throw new Error('Cache does not exist!') | ||
| } | ||
| const DomainsRaw = Fs.readFileSync(CacheDomainsPath, { encoding: 'utf-8' }) | ||
| const DomainsArray: string[] = JSON.parse(DomainsRaw) | ||
| await Zod.array(Zod.string().refine((Value) => { | ||
| try { | ||
| new URLPattern(`https://${Value}/`) | ||
| return true | ||
| } catch { | ||
| return false | ||
| } | ||
| })).parseAsync(DomainsArray) | ||
| return new Set(DomainsArray) | ||
| } | ||
|
|
||
| export async function LoadDomainsFromCache(): Promise<Set<string>> { | ||
| if (!Fs.existsSync(CacheDomainsPath)) { | ||
| const Domains = await FetchAdShieldDomains() | ||
| CreateCache(Domains) | ||
| return Domains | ||
| } else { | ||
| return await LoadCache() | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The esbuild version 0.27.2 appears to be outdated. As of January 2025, esbuild was at version 0.24.x or higher. Consider updating to a more recent version.