From ed1273f6e9c50e91bf3b5737b50dba9f20440dd4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 05:06:26 +0000 Subject: [PATCH 1/2] Initial plan From 5472bb00dec2acc3c058e7318c51da963e0dfef5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 05:11:45 +0000 Subject: [PATCH 2/2] Fix validation schema to match upstream @jk-com/adblock-compiler - Remove support for 'content' field and 'inline' type (not in upstream ISource) - Make 'source' field required (per upstream schema) - Update valid types to only 'adblock' or 'hosts' (per upstream SourceType enum) - Create user-rules.txt file to replace inline content - Update compiler-config.json to use file-based source - Update tests to reflect schema changes Co-authored-by: jaypatrick <1800595+jaypatrick@users.noreply.github.com> --- data/input/user-rules.txt | 5 +++ .../compiler-config.json | 10 +---- .../src/validation.test.ts | 2 +- .../src/validation.ts | 41 +++++-------------- 4 files changed, 18 insertions(+), 40 deletions(-) create mode 100644 data/input/user-rules.txt diff --git a/data/input/user-rules.txt b/data/input/user-rules.txt new file mode 100644 index 00000000..3c63553f --- /dev/null +++ b/data/input/user-rules.txt @@ -0,0 +1,5 @@ +! Title: Custom User Rules +! Description: Personal ad-blocking rules +! Last modified: 2024-01-01 +||example-ads.com^ +||tracking.example.net^ diff --git a/src/rules-compiler-typescript/compiler-config.json b/src/rules-compiler-typescript/compiler-config.json index 49f51639..14346981 100644 --- a/src/rules-compiler-typescript/compiler-config.json +++ b/src/rules-compiler-typescript/compiler-config.json @@ -16,14 +16,8 @@ "sources": [ { "name": "User Rules", - "type": "inline", - "content": [ - "! Title: Custom User Rules", - "! Description: Personal ad-blocking rules", - "! Last modified: 2024-01-01", - "||example-ads.com^", - "||tracking.example.net^" - ] + "source": "data/input/user-rules.txt", + "type": "adblock" } ], "transformations": [ diff --git a/src/rules-compiler-typescript/src/validation.test.ts b/src/rules-compiler-typescript/src/validation.test.ts index 99410e67..00cf9afe 100644 --- a/src/rules-compiler-typescript/src/validation.test.ts +++ b/src/rules-compiler-typescript/src/validation.test.ts @@ -99,7 +99,7 @@ Deno.test('validateConfiguration - validates source objects', () => { const result = validateConfiguration(config); assertEquals(result.valid, false); - assertEquals(result.errors.some((e) => e.includes('sources[0]') && (e.includes('source') || e.includes('content'))), true); + assertEquals(result.errors.some((e) => e.includes('sources[0]') && e.includes('source')), true); }); Deno.test('validateConfiguration - validates source type values', () => { diff --git a/src/rules-compiler-typescript/src/validation.ts b/src/rules-compiler-typescript/src/validation.ts index 87f2894b..5103254a 100644 --- a/src/rules-compiler-typescript/src/validation.ts +++ b/src/rules-compiler-typescript/src/validation.ts @@ -63,42 +63,21 @@ function validateSource(source: unknown, index: number): string[] { const sourceObj = source as Record; - // Either 'source' or 'content' field is required - const hasSource = sourceObj['source'] && typeof sourceObj['source'] === 'string'; - const hasContent = sourceObj['content'] && Array.isArray(sourceObj['content']); - - if (!hasSource && !hasContent) { - errors.push(`${prefix}: must have either 'source' (URL/path) or 'content' (inline rules) field`); - } - - // Validate source field if present - if (sourceObj['source'] !== undefined) { - if (typeof sourceObj['source'] !== 'string') { - errors.push(`${prefix}.source: must be a string`); - } else if (sourceObj['source'].trim() === '') { - errors.push(`${prefix}.source: cannot be empty`); - } - } - - // Validate content field if present - if (sourceObj['content'] !== undefined) { - if (!Array.isArray(sourceObj['content'])) { - errors.push(`${prefix}.content: must be an array`); - } else { - for (let i = 0; i < sourceObj['content'].length; i++) { - if (typeof sourceObj['content'][i] !== 'string') { - errors.push(`${prefix}.content[${i}]: must be a string`); - } - } - } + // Required field: 'source' (path or URL) + if (!sourceObj['source']) { + errors.push(`${prefix}: must have 'source' field (URL or file path)`); + } else if (typeof sourceObj['source'] !== 'string') { + errors.push(`${prefix}.source: must be a string`); + } else if (sourceObj['source'].trim() === '') { + errors.push(`${prefix}.source: cannot be empty`); } - // type validation if present + // type validation if present - only 'adblock' or 'hosts' allowed per upstream schema if (sourceObj['type'] !== undefined) { if (typeof sourceObj['type'] !== 'string') { errors.push(`${prefix}.type: must be a string`); - } else if (!['adblock', 'hosts', 'inline'].includes(sourceObj['type'])) { - errors.push(`${prefix}.type: must be 'adblock', 'hosts', or 'inline'`); + } else if (!['adblock', 'hosts'].includes(sourceObj['type'])) { + errors.push(`${prefix}.type: must be 'adblock' or 'hosts'`); } }