import { NextResponse } from "next/server"; import { cutReleases, dateProblem, describeCutFailure, RELEASE_TARGETS, versionSpecProblem, } from "yt-dlp-transcript-common/controller/cutRelease"; import { revalidateAfterReleaseCut } from "../../../sites/lib/revalidateAfterReleaseCut"; import { OpsInputError, oneOf, ops, opsFail, optBool, optString, reqString, } from "../_lib"; export const dynamic = "force-dynamic"; // POST { workspace: "editor" | "export" | "all", // version: "X.Y.Z" | "next" | "next-minor", // commit?: boolean (default false), // date?: "YYYY-MM-DD" (default today, server local time) } // // SYNCHRONOUS: a cut is one heading edit per changelog and at most two // path-limited commits, not a job. The writer is the one the Cut release form // and `archilyzer release cut` call (common/controller/cutRelease.ts), so every // refusal is its sentence. `all` cuts editor then export with ONE version and a // commit each — or neither: every check runs before either file is written. // // 200 { ok: true, version, results } when every changelog was cut. A refusal // is a 400 { ok: false, error, version, results, notAttempted, untouched }. // `untouched` is always there (release 11 slice O3): true means no changelog // was written — every refusal, `all`'s preflight included; false means a cut // stopped half-way (a write or a commit failed after something was written), // and then `error` names what was already cut as well as what failed, and a // result with `written: true` is a changelog cut whose commit failed. export async function POST(request: Request) { return ops(request, ["workspace", "version", "commit", "date"], async (body) => { const workspace = oneOf(body, "workspace", RELEASE_TARGETS); const version = reqString(body, "version"); const versionProblem = versionSpecProblem(version); if (versionProblem) throw new OpsInputError(versionProblem); const date = optString(body, "date"); const badDate = date === undefined ? null : dateProblem(date); if (badDate) throw new OpsInputError(badDate); const commit = optBool(body, "commit") ?? false; const outcome = await cutReleases({ workspace, version, commit, date }); // Whenever a changelog changed on disk — a cut whose commit then failed // included (review L3: it used to revalidate nothing). if (outcome.untouched !== true) revalidateAfterReleaseCut(); if (outcome.ok) { return NextResponse.json({ ok: true, version: outcome.version, results: outcome.results, }); } return opsFail(describeCutFailure(outcome, workspace), 400, { version: outcome.version, results: outcome.results, notAttempted: outcome.notAttempted, untouched: outcome.untouched === true, }); }); }