import { NextResponse } from "next/server"; import { getPaths } from "yt-dlp-transcript-common/lib/paths"; import { isValidChannelSlug } from "yt-dlp-transcript-common/controller/channels"; import { readVideoCues } from "yt-dlp-transcript-common/controller/videoCues"; import { readRoute } from "../_read"; import { opsFail } from "../_lib"; export const dynamic = "force-dynamic"; // GET ?id=[&slug=] // -> { ok, slug, id, source: "cues.json" | "built" | "vtt", // cuesJson: "fresh" | "stale" | "missing", title?, channel?, // uploadDate?, duration?, webpageUrl?, platform?, description?, file?, // cues: [{ start, end, text }] } // // One video's cues off disk, with no index (controller/videoCues.ts): a fresh // transcript.cues.json, else what normalize would write, else the English VTT // alone. Nothing is written. Without `slug` the channel holding data// is // found (two holders → 409, name it). The MCP's get_transcript asks this when // the archive it reads has no such video. export async function GET(request: Request) { return readRoute(request, ["id", "slug"], async (q) => { const id = q.get("id")?.trim() ?? ""; if (!id) return opsFail('"id" is required'); const slug = q.get("slug")?.trim() || undefined; if (slug !== undefined && !isValidChannelSlug(slug)) { return opsFail(`"${slug}" is not a valid channel slug`); } const read = await readVideoCues(getPaths(), { id, ...(slug ? { slug } : {}) }); if ("error" in read) return opsFail(read.error, read.status); return NextResponse.json({ ok: true, ...read }); }); }