{"version":3,"file":"translations.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/menus/[name]/translations.ts"],"sourcesContent":["/**\n * Menu translation endpoints\n *\n * GET  /_emdash/api/menus/:name/translations       — list translations for a menu (uses any locale row)\n * POST /_emdash/api/menus/:name/translations       — create a new locale translation (body: { locale, label })\n */\n\nimport type { APIRoute } from \"astro\";\nimport { z } from \"zod\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleMenuCreate, handleMenuGet, handleMenuTranslations } from \"#api/handlers/menus.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { localeFilterQuery } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nconst createTranslationBody = z\n\t.object({\n\t\tlocale: z.string().min(1),\n\t\tlabel: z.string().min(1).optional(),\n\t})\n\t.meta({ id: \"CreateMenuTranslationBody\" });\n\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst name = params.name!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"menus:read\");\n\tif (denied) return denied;\n\n\tconst localeQ = parseQuery(new URL(request.url), localeFilterQuery);\n\tif (isParseError(localeQ)) return localeQ;\n\n\ttry {\n\t\t// Look up any menu row matching the name so we can get its translation_group.\n\t\tconst anchor = await handleMenuGet(emdash.db, name, { locale: localeQ.locale });\n\t\tif (!anchor.success) return unwrapResult(anchor);\n\t\tconst result = await handleMenuTranslations(emdash.db, anchor.data.id);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch menu translations\", \"MENU_TRANSLATIONS_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst name = params.name!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"menus:manage\");\n\tif (denied) return denied;\n\n\tconst localeQ = parseQuery(new URL(request.url), localeFilterQuery);\n\tif (isParseError(localeQ)) return localeQ;\n\n\ttry {\n\t\tconst body = await parseBody(request, createTranslationBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Resolve the source menu (either by explicit locale in query, or the\n\t\t// first matching row). Its id becomes the `translationOf` for the new row.\n\t\tconst source = await handleMenuGet(emdash.db, name, { locale: localeQ.locale });\n\t\tif (!source.success) return unwrapResult(source);\n\n\t\tconst result = await handleMenuCreate(emdash.db, {\n\t\t\tname,\n\t\t\tlabel: body.label ?? source.data.label,\n\t\t\tlocale: body.locale,\n\t\t\ttranslationOf: source.data.id,\n\t\t});\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create menu translation\", \"MENU_TRANSLATION_CREATE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAa,YAAY;AAEzB,MAAM,wBAAwB,EAC5B,OAAO;CACP,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;CACzB,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;CACnC,CAAC,CACD,KAAK,EAAE,IAAI,6BAA6B,CAAC;AAE3C,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,OAAO,OAAO;CAEpB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,SAAS,YAAY,MAAM,aAAa;AAC9C,KAAI,OAAQ,QAAO;CAEnB,MAAM,UAAU,WAAW,IAAI,IAAI,QAAQ,IAAI,EAAE,kBAAkB;AACnE,KAAI,aAAa,QAAQ,CAAE,QAAO;AAElC,KAAI;EAEH,MAAM,SAAS,MAAM,cAAc,OAAO,IAAI,MAAM,EAAE,QAAQ,QAAQ,QAAQ,CAAC;AAC/E,MAAI,CAAC,OAAO,QAAS,QAAO,aAAa,OAAO;AAEhD,SAAO,aADQ,MAAM,uBAAuB,OAAO,IAAI,OAAO,KAAK,GAAG,CAC3C;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,qCAAqC,0BAA0B;;;AAI3F,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,OAAO,OAAO;CAEpB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;CAEnB,MAAM,UAAU,WAAW,IAAI,IAAI,QAAQ,IAAI,EAAE,kBAAkB;AACnE,KAAI,aAAa,QAAQ,CAAE,QAAO;AAElC,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,sBAAsB;AAC5D,MAAI,aAAa,KAAK,CAAE,QAAO;EAI/B,MAAM,SAAS,MAAM,cAAc,OAAO,IAAI,MAAM,EAAE,QAAQ,QAAQ,QAAQ,CAAC;AAC/E,MAAI,CAAC,OAAO,QAAS,QAAO,aAAa,OAAO;AAQhD,SAAO,aANQ,MAAM,iBAAiB,OAAO,IAAI;GAChD;GACA,OAAO,KAAK,SAAS,OAAO,KAAK;GACjC,QAAQ,KAAK;GACb,eAAe,OAAO,KAAK;GAC3B,CAAC,EAC0B,IAAI;UACxB,OAAO;AACf,SAAO,YAAY,OAAO,qCAAqC,gCAAgC"}