diff --git a/data/input/user-rules.txt b/data/input/user-rules.txt new file mode 100644 index 0000000..3c63553 --- /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 49f5163..1434698 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 99410e6..00cf9af 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 87f2894..5103254 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'`); } }