import chalk from "chalk"; import { define } from "gunshi"; import { openDb } from "@/db"; import * as authorsQ from "@/db/queries/authors"; import type { AuthorRow } from "@/interfaces"; import { formatIso } from "@/utils/dates"; import { ExitCodes, exitWith, wrap } from "../envelope"; import { enterJsonMode, isJsonMode, printHuman, printJson } from "../output"; const commonDbArg = { db: { type: "string", description: "SQLite DB path (default: ~/.fc2cma/db.sqlite or $FC2CMA_DB)" } } as const; const commonJsonArg = { json: { type: "boolean", description: "Emit machine-readable JSON envelope on stdout" } } as const; const subscribeAddCommand = define({ name: "add", description: "Subscribe to an FC2 author", args: { author: { type: "positional", description: "FC2 author slug" }, note: { type: "string", description: "Optional note for this author" }, ...commonDbArg, ...commonJsonArg }, run(ctx) { const v = ctx.values; enterJsonMode(Boolean(v.json)); const db = openDb(v.db); const { inserted, row } = authorsQ.addAuthor(db, v.author, v.note); const payload = { inserted, author: row }; if (isJsonMode()) { printJson(wrap("subscribe.add", payload)); } else { if (inserted) printHuman(chalk.green(`Added ${row.name}`)); else printHuman(chalk.yellow(`Already subscribed to ${row.name}`)); } db.close(); } }); const subscribeRemoveCommand = define({ name: "remove", description: "Unsubscribe from an FC2 author", args: { author: { type: "positional", description: "FC2 author slug" }, purge: { type: "boolean", description: "Also delete works/price_history/magnets for this author" }, ...commonDbArg, ...commonJsonArg }, run(ctx) { const v = ctx.values; enterJsonMode(Boolean(v.json)); const db = openDb(v.db); const { removed, purgedWorks } = authorsQ.removeAuthor(db, v.author, { purge: Boolean(v.purge) }); const payload = { removed, purgedWorks, author: v.author }; if (isJsonMode()) { printJson(wrap("subscribe.remove", payload)); } else { if (!removed) { printHuman(chalk.yellow(`Not subscribed to ${v.author}`)); } else if (v.purge) { printHuman(chalk.red(`Removed ${v.author} and purged ${purgedWorks} works`)); } else { printHuman(chalk.green(`Unsubscribed ${v.author} (history kept)`)); } } db.close(); } }); const subscribeListCommand = define({ name: "list", description: "List subscribed authors", args: { ...commonDbArg, ...commonJsonArg }, run(ctx) { const v = ctx.values; enterJsonMode(Boolean(v.json)); const db = openDb(v.db); const authors = authorsQ.listAuthors(db); const payload: { authors: AuthorRow[] } = { authors }; if (isJsonMode()) { printJson(wrap("subscribe.list", payload)); } else { if (authors.length === 0) { printHuman(chalk.dim("(no authors subscribed)")); } else { for (const a of authors) { const synced = a.lastSyncedAt ? formatIso(a.lastSyncedAt) : "never"; printHuman( `${chalk.cyan(a.name)} last_synced=${chalk.dim(synced)}${a.note ? ` note=${a.note}` : ""}` ); } } } db.close(); } }); export const subscribeCommand = define({ name: "subscribe", description: "Manage the author subscription list", subCommands: { add: subscribeAddCommand, remove: subscribeRemoveCommand, list: subscribeListCommand }, run() { exitWith(ExitCodes.USAGE, "subscribe: subcommand required (add | remove | list)"); } });