diff --git a/packages/scanner/src/__tests__/scan-files.test.ts b/packages/scanner/src/__tests__/scan-files.test.ts index 7f85987..e32c8ca 100644 --- a/packages/scanner/src/__tests__/scan-files.test.ts +++ b/packages/scanner/src/__tests__/scan-files.test.ts @@ -103,4 +103,16 @@ describe("scanFiles()", () => { const after = readFileRecord(projectId, "src/x.ts")!; expect(after.candidates.length).toBe(candCountBefore); }); + + it("throws on unknown matcher slugs", async () => { + const { root, projectId } = makeProject({ "a.ts": "x\n" }); + await expect( + scanFiles({ + projectId, + root, + filePaths: ["a.ts"], + matcherSlugs: ["xss", "does-not-exist", "also-fake"], + }), + ).rejects.toThrow(/Unknown matcher slugs: does-not-exist, also-fake/); + }); }); diff --git a/packages/scanner/src/index.ts b/packages/scanner/src/index.ts index d953f08..16f6ce0 100644 --- a/packages/scanner/src/index.ts +++ b/packages/scanner/src/index.ts @@ -367,6 +367,17 @@ export async function scan(params: { languageStats: LanguageStats[]; }> { const registry = buildMergedRegistry(); + + if (params.matcherSlugs) { + const unknown = registry.unknownSlugs(params.matcherSlugs); + if (unknown.length > 0) { + throw new Error( + `Unknown matcher slug${unknown.length > 1 ? "s" : ""}: ${unknown.join(", ")}.\n` + + ` Available matchers: ${registry.slugs().sort().join(", ")}`, + ); + } + } + const allSelected = params.matcherSlugs ? registry.getBySlugs(params.matcherSlugs) : registry.getAll(); @@ -550,6 +561,17 @@ export async function scanFiles(params: { skippedMatchers: string[]; }> { const registry = buildMergedRegistry(); + + if (params.matcherSlugs) { + const unknown = registry.unknownSlugs(params.matcherSlugs); + if (unknown.length > 0) { + throw new Error( + `Unknown matcher slug${unknown.length > 1 ? "s" : ""}: ${unknown.join(", ")}.\n` + + ` Available matchers: ${registry.slugs().sort().join(", ")}`, + ); + } + } + const allSelected = params.matcherSlugs ? registry.getBySlugs(params.matcherSlugs) : registry.getAll(); diff --git a/packages/scanner/src/matcher-registry.ts b/packages/scanner/src/matcher-registry.ts index 60350c7..b232b6e 100644 --- a/packages/scanner/src/matcher-registry.ts +++ b/packages/scanner/src/matcher-registry.ts @@ -21,6 +21,11 @@ export class MatcherRegistry { .filter((m): m is MatcherPlugin => m !== undefined); } + /** Returns slug strings from `requested` that don't exist in the registry. */ + unknownSlugs(requested: string[]): string[] { + return requested.filter((s) => !this.matchers.has(s)); + } + slugs(): string[] { return Array.from(this.matchers.keys()); }