diff --git a/src/scrape/commands/codegen-target-commands.ts b/src/scrape/commands/codegen-target-commands.ts index 825b065..a3c47eb 100644 --- a/src/scrape/commands/codegen-target-commands.ts +++ b/src/scrape/commands/codegen-target-commands.ts @@ -3,15 +3,16 @@ import { Command } from "commander"; import { configureTargetCommand } from "../services/command-builder.js"; import { snakeToKebab } from "../services/naming.js"; import { createTargetAction } from "../services/run-target-scrape.js"; +import { resolveTargetGroup } from "../services/target-group.js"; export function createCodegenTargetCommands(schema: DecodoSchema): Command[] { const commands: Command[] = []; for (const target of schema.listTargets()) { const commandName = snakeToKebab(target); - const meta = schema.getTargetMeta(target); + const group = resolveTargetGroup(schema, target); const command = new Command(commandName).description( - meta?.group ? `${meta.group} scrape target` : `${target} scrape target` + group ? `${group} scrape target` : "Scrape target" ); configureTargetCommand(command, target, schema); diff --git a/src/scrape/commands/list-targets.ts b/src/scrape/commands/list-targets.ts index 0893e0c..e98aaf6 100644 --- a/src/scrape/commands/list-targets.ts +++ b/src/scrape/commands/list-targets.ts @@ -1,6 +1,7 @@ import type { DecodoSchema } from "@decodo/sdk-ts"; import { Command } from "commander"; import { snakeToKebab } from "../services/naming.js"; +import { resolveTargetGroup } from "../services/target-group.js"; export function createListTargetsCommand(schema: DecodoSchema): Command { return new Command("targets") @@ -9,7 +10,7 @@ export function createListTargetsCommand(schema: DecodoSchema): Command { const grouped = new Map(); for (const target of schema.listTargets()) { - const group = schema.getTargetMeta(target)?.group ?? "Other"; + const group = resolveTargetGroup(schema, target) ?? "Other"; const names = grouped.get(group) ?? []; names.push(snakeToKebab(target)); grouped.set(group, names); diff --git a/src/scrape/services/target-group.ts b/src/scrape/services/target-group.ts new file mode 100644 index 0000000..612ec53 --- /dev/null +++ b/src/scrape/services/target-group.ts @@ -0,0 +1,14 @@ +import type { DecodoSchema } from "@decodo/sdk-ts"; + +const NO_GROUP = "None"; + +export function resolveTargetGroup( + schema: DecodoSchema, + target: string +): string | undefined { + const group = schema.getTargetMeta(target)?.group; + if (!group || group === NO_GROUP) { + return; + } + return group; +} diff --git a/tests/scrape/commands/codegen-target-commands.test.ts b/tests/scrape/commands/codegen-target-commands.test.ts index 5d1d320..4ffbe73 100644 --- a/tests/scrape/commands/codegen-target-commands.test.ts +++ b/tests/scrape/commands/codegen-target-commands.test.ts @@ -20,4 +20,15 @@ describe("createCodegenTargetCommands", () => { true ); }); + + it("uses a generic description for targets without a real group", () => { + const schema = BundledSchema.shared; + const commands = createCodegenTargetCommands(schema); + + const ungrouped = commands.find((cmd) => cmd.name() === "youtube-video"); + expect(ungrouped?.description()).toBe("Scrape target"); + + const grouped = commands.find((cmd) => cmd.name() === "amazon-product"); + expect(grouped?.description()).toBe("Amazon scrape target"); + }); }); diff --git a/tests/scrape/services/target-group.test.ts b/tests/scrape/services/target-group.test.ts new file mode 100644 index 0000000..d613446 --- /dev/null +++ b/tests/scrape/services/target-group.test.ts @@ -0,0 +1,27 @@ +import type { DecodoSchema } from "@decodo/sdk-ts"; +import { describe, expect, it } from "vitest"; +import { resolveTargetGroup } from "../../../src/scrape/services/target-group.js"; + +function schemaWithGroup(group: string | undefined): DecodoSchema { + return { + getTargetMeta: () => (group === undefined ? undefined : { group }), + } as unknown as DecodoSchema; +} + +describe("resolveTargetGroup", () => { + it("returns the group when it is a real value", () => { + expect( + resolveTargetGroup(schemaWithGroup("Amazon"), "amazon_product") + ).toBe("Amazon"); + }); + + it.each([ + "None", + "", + undefined, + ])("returns undefined for the %p sentinel group", (group) => { + expect( + resolveTargetGroup(schemaWithGroup(group), "youtube_video") + ).toBeUndefined(); + }); +});