@url-sanitize/adguard 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@url-sanitize/adguard",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "AdGuard URL Tracking Protection catalog adapter for @url-sanitize/core.",
5
5
  "license": "LGPL-3.0-only",
6
6
  "type": "module",
@@ -31,7 +31,7 @@
31
31
  "NOTICE"
32
32
  ],
33
33
  "dependencies": {
34
- "@url-sanitize/core": "2.0.4"
34
+ "@url-sanitize/core": "2.0.5"
35
35
  },
36
36
  "keywords": [
37
37
  "adguard",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "sideEffects": false,
52
52
  "scripts": {
53
- "build": "tsup src/index.ts src/raw.ts src/adapter.ts src/types.ts --format esm --dts --clean",
54
- "dev": "tsup src/index.ts src/raw.ts src/adapter.ts src/types.ts --format esm --dts --watch"
53
+ "build": "vp pack",
54
+ "dev": "vp pack --watch"
55
55
  }
56
56
  }
@@ -1,192 +0,0 @@
1
- // src/adapter.ts
2
- function adguardToCatalog(data, meta) {
3
- const rules = [];
4
- const lines = preprocessConditionals(data.text);
5
- let index = 0;
6
- for (const line of lines) {
7
- const parsed = parseLine(line, index);
8
- if (!parsed) continue;
9
- index++;
10
- const rule = {
11
- kind: "strip-param",
12
- source: "adguard",
13
- provider: parsed.provider,
14
- paramPattern: parsed.paramPattern,
15
- exceptions: parsed.exceptions
16
- };
17
- if (parsed.urlPattern) rule.urlPattern = parsed.urlPattern;
18
- if (parsed.valuePattern) rule.valuePattern = parsed.valuePattern;
19
- rules.push(rule);
20
- }
21
- return {
22
- version: meta.version,
23
- generatedAt: meta.fetchedAt,
24
- sources: [
25
- {
26
- name: "adguard",
27
- version: meta.version,
28
- hash: meta.hash,
29
- license: meta.license,
30
- upstream: meta.upstream
31
- }
32
- ],
33
- rules
34
- };
35
- }
36
- function preprocessConditionals(text) {
37
- const activeStack = [true];
38
- const out = [];
39
- for (const rawLine of text.split(/\r?\n/)) {
40
- const line = rawLine.trim();
41
- if (!line) continue;
42
- if (line.startsWith("!#if")) {
43
- const condition = line.slice("!#if".length).trim();
44
- activeStack.push(activeStack.at(-1) === true && evalCondition(condition));
45
- continue;
46
- }
47
- if (line.startsWith("!#else")) {
48
- if (activeStack.length > 1) {
49
- const parentActive = activeStack.at(-2) === true;
50
- const branchWasActive = activeStack.at(-1) === true;
51
- activeStack[activeStack.length - 1] = parentActive && !branchWasActive;
52
- }
53
- continue;
54
- }
55
- if (line.startsWith("!#endif")) {
56
- if (activeStack.length > 1) activeStack.pop();
57
- continue;
58
- }
59
- if (line.startsWith("!")) continue;
60
- if (activeStack.at(-1) !== true) continue;
61
- out.push(line);
62
- }
63
- return out;
64
- }
65
- function evalCondition(condition) {
66
- return condition.replace(/\badguard_ext_chromium_mv3\b/g, "false").replace(/\bext_ublock\b/g, "false").split("||").some(
67
- (orPart) => orPart.split("&&").every((andPart) => {
68
- const part = andPart.trim().replace(/^\(|\)$/g, "");
69
- if (part.startsWith("!")) return !booleanToken(part.slice(1));
70
- return booleanToken(part);
71
- })
72
- );
73
- }
74
- function booleanToken(token) {
75
- return token.trim() === "true";
76
- }
77
- function parseLine(line, index) {
78
- const modifierIndex = modifierStart(line);
79
- if (modifierIndex === -1) return null;
80
- const prefix = line.slice(0, modifierIndex);
81
- const modifiers = parseModifiers(line.slice(modifierIndex + 1));
82
- const removeParam = modifiers.get("removeparam") ?? deriveParamFromPrefix(prefix);
83
- if (!removeParam) return null;
84
- const pattern = parseRemoveParam(removeParam);
85
- if (!pattern) return null;
86
- const domainModifier = modifiers.get("domain");
87
- const denyallow = modifiers.get("denyallow");
88
- const positives = domainModifier ? domainModifier.split("|").filter((domain) => domain.length > 0 && !domain.startsWith("~")) : [];
89
- const negatives = [
90
- ...domainModifier ? domainModifier.split("|").filter((domain) => domain.startsWith("~")).map((domain) => domain.slice(1)) : [],
91
- ...denyallow ? denyallow.split("|").filter(Boolean) : []
92
- ];
93
- const urlPattern = positives.length > 0 ? domainsPattern(positives) : prefixPattern(prefix);
94
- const parsed = {
95
- provider: `adguard-${index}`,
96
- paramPattern: pattern.paramPattern,
97
- exceptions: negatives.map(domainPattern)
98
- };
99
- if (urlPattern) parsed.urlPattern = urlPattern;
100
- if (pattern.valuePattern) parsed.valuePattern = pattern.valuePattern;
101
- return parsed;
102
- }
103
- function modifierStart(line) {
104
- const candidates = ["$removeparam", "$denyallow"];
105
- const indexes = candidates.map((candidate) => line.indexOf(candidate)).filter((i) => i >= 0);
106
- return indexes.length === 0 ? -1 : Math.min(...indexes);
107
- }
108
- function parseModifiers(raw) {
109
- const out = /* @__PURE__ */ new Map();
110
- for (const part of splitModifiers(raw)) {
111
- const eq = part.indexOf("=");
112
- if (eq === -1) {
113
- out.set(part.toLowerCase(), "");
114
- } else {
115
- out.set(part.slice(0, eq).toLowerCase(), part.slice(eq + 1).replace(/\\,/g, ","));
116
- }
117
- }
118
- return out;
119
- }
120
- function splitModifiers(raw) {
121
- const out = [];
122
- let current = "";
123
- let inRegex = false;
124
- let escaped = false;
125
- for (const char of raw) {
126
- if (escaped) {
127
- current += char;
128
- escaped = false;
129
- continue;
130
- }
131
- if (char === "\\") {
132
- current += char;
133
- escaped = true;
134
- continue;
135
- }
136
- if (char === "/") inRegex = !inRegex;
137
- if (char === "," && !inRegex) {
138
- out.push(current);
139
- current = "";
140
- continue;
141
- }
142
- current += char;
143
- }
144
- if (current) out.push(current);
145
- return out.filter(Boolean);
146
- }
147
- function parseRemoveParam(value) {
148
- if (value.startsWith("/") && value.lastIndexOf("/") > 0) {
149
- const body = value.slice(1, value.lastIndexOf("/")).replace(/\\,/g, ",");
150
- const eq = body.indexOf("=");
151
- if (eq > 0) {
152
- return {
153
- paramPattern: stripAnchors(body.slice(0, eq)),
154
- valuePattern: body.slice(eq + 1)
155
- };
156
- }
157
- return { paramPattern: body };
158
- }
159
- return { paramPattern: escapeRegExp(value) };
160
- }
161
- function stripAnchors(value) {
162
- return value.replace(/^\^/, "").replace(/\$$/, "");
163
- }
164
- function deriveParamFromPrefix(prefix) {
165
- const match = /[?&;/]([^?&;/*=]+)=?\*?$/.exec(prefix);
166
- return match?.[1] ? escapeRegExp(match[1]) : null;
167
- }
168
- function prefixPattern(prefix) {
169
- if (!prefix) return void 0;
170
- if (prefix.startsWith("||")) {
171
- const domain = prefix.slice(2).replace(/\^.*$/, "");
172
- return domainPattern(domain);
173
- }
174
- return globPattern(prefix.replace(/\^/g, "*"));
175
- }
176
- function domainsPattern(domains) {
177
- return domains.map(domainPattern).join("|");
178
- }
179
- function domainPattern(domain) {
180
- const escaped = escapeRegExp(domain.replace(/^\|\|/, "").replace(/\^$/, ""));
181
- return `^https?:\\/\\/([^/?#]+\\.)?${escaped}(?::[0-9]+)?(?:[/?#]|$)`;
182
- }
183
- function globPattern(glob) {
184
- return escapeRegExp(glob).replace(/\\\*/g, ".*");
185
- }
186
- function escapeRegExp(value) {
187
- return value.replace(/[|\\{}()[\]^$+?.*]/g, "\\$&");
188
- }
189
-
190
- export {
191
- adguardToCatalog
192
- };