1+ import * as Fs from 'node:fs'
2+ import * as ESBuild from 'esbuild'
3+ import PackageJson from '@npmcli/package-json'
4+ import { CreateBanner } from './banner/index.js'
5+ import { Build , type BuildOptions } from './build-core.js'
6+
7+ export class GlobalMatchBuild extends Build {
8+ constructor ( FromOrOption : Build | BuildOptions , Option ?: BuildOptions ) {
9+ if ( FromOrOption instanceof Build ) {
10+ super ( Option ! )
11+ this . CopyStateFrom ( FromOrOption )
12+ return
13+ }
14+
15+ super ( FromOrOption )
16+ }
17+
18+ async Build ( ) {
19+ let MatchingDomains : Set < string > = new Set < string > ( this . FetchedDomains . get ( 'Full' ) )
20+ let SubscriptionURL = new URL ( `https://cdn.jsdelivr.net/npm/@filteringdev/tinyshield@${ this . Options ?. Version ?? ( await PackageJson . load ( this . ProjectRoot ) ) . content . version ?? '0.0.0' } /dist/tinyShield-GlobalMatch.user.js` )
21+ const Banner = CreateBanner ( {
22+ Version : this . Options ?. Version ?? ( await PackageJson . load ( this . ProjectRoot ) ) . content . version ?? '0.0.0' ,
23+ BuildType : this . Options ! . BuildType ?? 'production' ,
24+ Domains : new Set < string > ( [ '*' ] ) ,
25+ Name : 'tinyShield GlobalMatch' ,
26+ Namespace : 'https://github.com/FilteringDev/tinyShield' ,
27+ DownloadURL : SubscriptionURL ,
28+ UpdateURL : SubscriptionURL ,
29+ HomepageURL : new URL ( 'https://github.com/FilteringDev/tinyShield' ) ,
30+ SupportURL : new URL ( 'https://github.com/FilteringDev/tinyShield/issues' ) ,
31+ License : 'MPL-2.0' ,
32+ Author : 'PiQuark6046 and contributors' ,
33+ Description : {
34+ en : 'tinyShield allows AdGuard, uBlock Origin, Brave and ABP to resist against Ad-Shield quickly.' ,
35+ ko : 'tinyShield는 AdGuard, uBlock Origin, Brave 와 ABP가 애드쉴드에 빠르게 저항할 수 있도록 합니다.' ,
36+ ja : 'tinyShieldを使うと、AdGuard, uBlock Origin, Brave, およびABPがAd-Shieldに素早く対抗できます。'
37+ }
38+ } )
39+
40+ Fs . copyFileSync ( this . ProjectRoot + '/userscript/source/index.ts' , this . ProjectRoot + '/userscript/source/index-globalmatch.ts' )
41+ const GlobalMatchIndexPath = this . ProjectRoot + '/userscript/source/index-globalmatch.ts'
42+ const SourceText = Fs . readFileSync ( GlobalMatchIndexPath , 'utf8' )
43+ const Anchor = 'export const OriginalRegExpTest = BrowserWindow.RegExp.prototype.test'
44+ const AnchorIndex = SourceText . indexOf ( Anchor )
45+ if ( AnchorIndex === - 1 ) {
46+ throw new Error ( '[globalmatch] Failed to find OriginalRegExpTest anchor in index-globalmatch.ts' )
47+ }
48+
49+ const AnchorLineEndIndex = SourceText . indexOf ( '\n' , AnchorIndex )
50+ if ( AnchorLineEndIndex === - 1 ) {
51+ throw new Error ( '[globalmatch] Failed to determine insertion point in index-globalmatch.ts' )
52+ }
53+
54+ const DomainListElements = Array . from ( MatchingDomains ) . map ( Domain => JSON . stringify ( Domain ) ) . join ( ', ' )
55+ const ExecutionCondition = `(() => {\n const DomainList: string[] = [${ DomainListElements } ]\n const CurrentURL = new URL(BrowserWindow.location.href)\n if (!DomainList.some(Domain => BrowserWindow.location.href.includes(\`://\${Domain}/\`) || CurrentURL.hostname.endsWith(\`.\${Domain}\`))) {\n return\n }\n\n`
56+
57+ const Head = SourceText . slice ( 0 , AnchorLineEndIndex + 1 )
58+ const Tail = SourceText . slice ( AnchorLineEndIndex + 1 )
59+ const TransformedSource = `${ Head } \n${ ExecutionCondition } ${ Tail } \n})()\n`
60+ Fs . writeFileSync ( GlobalMatchIndexPath , TransformedSource )
61+
62+ await ESBuild . build ( {
63+ entryPoints : [ this . ProjectRoot + '/userscript/source/index-globalmatch.ts' ] ,
64+ bundle : true ,
65+ minify : this . Options ! . Minify ,
66+ outfile : `${ this . ProjectRoot } /dist/tinyShield-GlobalMatch${ this . Options ! . BuildType === 'development' ? '.dev' : '' } .user.js` ,
67+ banner : {
68+ js : Banner
69+ } ,
70+ target : [ 'es2024' , 'chrome119' , 'firefox142' , 'safari26' ]
71+ } )
72+
73+ Fs . rmSync ( this . ProjectRoot + '/userscript/source/index-globalmatch.ts' )
74+ }
75+ }
0 commit comments