{"version":3,"file":"translations.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/admin/bylines/[id]/translations.ts"],"sourcesContent":["/**\n * Byline translation endpoints\n *\n * GET  /_emdash/api/admin/bylines/:id/translations  — list every translation\n *                                                     of a byline (siblings\n *                                                     in the same\n *                                                     translation_group)\n * POST /_emdash/api/admin/bylines/:id/translations  — create a new locale\n *                                                     variant joining the\n *                                                     source's\n *                                                     translation_group\n *                                                     (body: { locale, ... })\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineCreate, handleBylineTranslations } from \"#api/handlers/bylines.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineTranslationCreateBody } from \"#api/schemas.js\";\nimport { invalidateBylineCache } from \"#bylines/index.js\";\nimport { BylineRepository } from \"#db/repositories/byline.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst id = params.id!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"bylines:read\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst result = await handleBylineTranslations(emdash.db, id);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch byline translations\", \"BYLINE_TRANSLATIONS_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst id = params.id!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, bylineTranslationCreateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Look up the source byline so we can:\n\t\t//  (a) emit a clean 404 when it doesn't exist (route layer);\n\t\t//  (b) fall back to its slug + display_name + avatar/website when\n\t\t//      the body omits them. Editors creating a translation often\n\t\t//      want to keep the slug stable and only enter the localized\n\t\t//      bio/displayName — defaulting saves clicks.\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst source = await repo.findById(id);\n\t\tif (!source) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Byline not found\", 404);\n\t\t}\n\n\t\tconst result = await handleBylineCreate(emdash.db, {\n\t\t\tslug: body.slug ?? source.slug,\n\t\t\tdisplayName: body.displayName ?? source.displayName,\n\t\t\tbio: body.bio ?? null,\n\t\t\tavatarMediaId: body.avatarMediaId ?? source.avatarMediaId,\n\t\t\twebsiteUrl: body.websiteUrl ?? source.websiteUrl,\n\t\t\t// Translations don't inherit the source's user_id or guest flag —\n\t\t\t// the partial unique on (user_id, locale) means a single user can\n\t\t\t// own one byline per locale, but the editor must opt into linking\n\t\t\t// the new row by editing it after creation.\n\t\t\tuserId: null,\n\t\t\tisGuest: source.isGuest,\n\t\t\tlocale: body.locale,\n\t\t\ttranslationOf: id,\n\t\t});\n\n\t\tif (result.success) invalidateBylineCache();\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(\n\t\t\terror,\n\t\t\t\"Failed to create byline translation\",\n\t\t\t\"BYLINE_TRANSLATION_CREATE_ERROR\",\n\t\t);\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,KAAK,OAAO;CAElB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AAEnB,KAAI;AAEH,SAAO,aADQ,MAAM,yBAAyB,OAAO,IAAI,GAAG,CACjC;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,uCAAuC,4BAA4B;;;AAI/F,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,KAAK,OAAO;CAElB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,4BAA4B;AAClE,MAAI,aAAa,KAAK,CAAE,QAAO;EAS/B,MAAM,SAAS,MADF,IAAI,iBAAiB,OAAO,GAAG,CAClB,SAAS,GAAG;AACtC,MAAI,CAAC,OACJ,QAAO,SAAS,aAAa,oBAAoB,IAAI;EAGtD,MAAM,SAAS,MAAM,mBAAmB,OAAO,IAAI;GAClD,MAAM,KAAK,QAAQ,OAAO;GAC1B,aAAa,KAAK,eAAe,OAAO;GACxC,KAAK,KAAK,OAAO;GACjB,eAAe,KAAK,iBAAiB,OAAO;GAC5C,YAAY,KAAK,cAAc,OAAO;GAKtC,QAAQ;GACR,SAAS,OAAO;GAChB,QAAQ,KAAK;GACb,eAAe;GACf,CAAC;AAEF,MAAI,OAAO,QAAS,wCAAuB;AAC3C,SAAO,aAAa,QAAQ,IAAI;UACxB,OAAO;AACf,SAAO,YACN,OACA,uCACA,kCACA"}