@walkinissue/angy 0.2.17 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/lib/server/route.ts", "../src/lib/server/commit.ts", "../src/lib/server/catalog.ts", "../src/lib/server/config.ts", "../src/lib/server/context.ts", "../src/lib/server/suggestions.ts"],
4
- "sourcesContent": ["import { json, type RequestHandler } from \"@sveltejs/kit\";\nimport { handleCommit, handleCommitBatch, handleRotateCatalogs } from \"./commit.ts\";\nimport {\n\tconfigureTranslationHelper,\n\tloadAngyConfigFromRoot,\n\tnormalizeTranslationHelperConfig,\n\ttype TranslationHelperConfig\n} from \"./config.ts\";\nimport { handleContext } from \"./context.ts\";\nimport { handleSuggestions } from \"./suggestions.ts\";\n\nexport async function handleTranslationRequest(\n\trequest: Request,\n\turl: URL,\n\toptions?: { devOnly?: boolean; config?: Partial<TranslationHelperConfig>; dev?: boolean }\n) {\n\tconst devOnly = options?.devOnly ?? true;\n\tconst runtimeDev =\n\t\ttypeof import.meta !== \"undefined\" &&\n\t\ttypeof import.meta.env !== \"undefined\" &&\n\t\timport.meta.env.DEV === true;\n\tconst isDev = options?.dev ?? runtimeDev;\n\n\tif (devOnly && !isDev) {\n\t\treturn json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Disabled outside dev\"\n\t\t\t},\n\t\t\t{ status: 404 }\n\t\t);\n\t}\n\n\tif (options?.config) {\n\t\tconfigureTranslationHelper(normalizeTranslationHelperConfig(process.cwd(), options.config));\n\t} else {\n\t\tawait loadAngyConfigFromRoot(process.cwd());\n\t}\n\n\tconst intent = url.searchParams.get(\"intent\") ?? \"commit\";\n\n\tif (intent === \"commit-batch\") {\n\t\treturn handleCommitBatch(request);\n\t}\n\n\tif (intent === \"context\") {\n\t\treturn handleContext(request);\n\t}\n\n\tif (intent === \"suggestions\") {\n\t\treturn handleSuggestions(request);\n\t}\n\n\tif (intent === \"rotate-catalogs\") {\n\t\treturn handleRotateCatalogs();\n\t}\n\n\treturn handleCommit(request);\n}\n\nfunction createAngyHandler(\n\toptions?: { devOnly?: boolean; config?: Partial<TranslationHelperConfig> }\n): RequestHandler {\n\treturn async ({ request, url }) => handleTranslationRequest(request, url, options);\n}\n\nexport const handler = createAngyHandler();\n\nexport {\n\tdefineAngyConfig,\n\ttype AngyConfigInput,\n\ttype SuggestionProvider,\n\ttype SuggestionProviderInput,\n\ttype SuggestionRequestItem,\n\ttype SuggestionResponseItem\n} from \"./config.ts\";\n", "import { json } from \"@sveltejs/kit\";\nimport {\n\tensureWorkingCatalog,\n\treadParsedCatalog,\n\tremoveFuzzyFlag,\n\trotateCatalogs,\n\truntimeTranslations,\n\twriteWorkingCatalog\n} from \"./catalog.ts\";\nimport type { CommitBatchItem, PoTranslationEntry } from \"./types.ts\";\n\r\nfunction runtimeKey(msgid: string, msgctxt: string | null) {\r\n\treturn `${msgctxt ?? \"\"}::${msgid}`;\r\n}\r\n\r\nexport async function writeTranslationToWorkingCatalog(\r\n\tresolvedMsgid: string,\r\n\tresolvedMsgctxt: string | null,\r\n\ttranslationValue: string\r\n) {\r\n\tawait ensureWorkingCatalog();\r\n\r\n\tconst [baseParsed, workingParsed] = await Promise.all([\r\n\t\treadParsedCatalog(\"base\"),\r\n\t\treadParsedCatalog(\"working\")\r\n\t]);\r\n\r\n\tif (!baseParsed || !workingParsed) {\r\n\t\treturn { ok: false as const, error: \"Unable to load catalogs\" };\r\n\t}\r\n\r\n\tconst baseTranslations = baseParsed.translations ?? {};\r\n\tconst workingTranslations = workingParsed.translations ?? {};\r\n\r\n\tconst ctxKey = resolvedMsgctxt ?? \"\";\r\n\tconst baseGroup = baseTranslations[ctxKey];\r\n\tif (!baseGroup) {\r\n\t\treturn { ok: false as const, error: \"Context group not found in base catalog\" };\r\n\t}\r\n\r\n\tconst baseEntry = baseGroup[resolvedMsgid] as PoTranslationEntry | undefined;\r\n\tif (!baseEntry) {\r\n\t\treturn { ok: false as const, error: \"Target msgid not found in base catalog\" };\r\n\t}\r\n\r\n\tconst workingGroup = (workingTranslations[ctxKey] ??= {});\r\n\tconst entry = ((workingGroup[resolvedMsgid] as PoTranslationEntry | undefined) ??=\r\n\t\tcloneEntryForWorking(baseEntry, resolvedMsgid, resolvedMsgctxt));\r\n\r\n\tentry.msgstr = [translationValue];\r\n\tentry.comments ??= {};\r\n\tentry.comments.flag = removeFuzzyFlag(entry.comments.flag);\r\n\r\n\tawait writeWorkingCatalog(workingParsed);\r\n\r\n\truntimeTranslations.set(runtimeKey(resolvedMsgid, resolvedMsgctxt), translationValue);\r\n\r\n\treturn {\r\n\t\tok: true as const,\r\n\t\tmsgid: resolvedMsgid,\r\n\t\tmsgctxt: resolvedMsgctxt,\r\n\t\tworkingCatalog: \"en-working.po\"\r\n\t};\r\n}\r\n\r\nfunction cloneEntryForWorking(\r\n\tbaseEntry: PoTranslationEntry,\r\n\tmsgid: string,\r\n\tmsgctxt: string | null\r\n): PoTranslationEntry {\r\n\treturn {\r\n\t\tmsgid,\r\n\t\tmsgctxt: msgctxt ?? undefined,\r\n\t\tmsgid_plural: baseEntry.msgid_plural,\r\n\t\tmsgstr: Array.isArray(baseEntry.msgstr) ? [...baseEntry.msgstr] : [\"\"],\r\n\t\tobsolete: Boolean(baseEntry.obsolete),\r\n\t\tcomments: baseEntry.comments\r\n\t\t\t? {\r\n\t\t\t\t\treference: baseEntry.comments.reference,\r\n\t\t\t\t\textracted: baseEntry.comments.extracted,\r\n\t\t\t\t\tflag: baseEntry.comments.flag,\r\n\t\t\t\t\tprevious: baseEntry.comments.previous\r\n\t\t\t\t}\r\n\t\t\t: undefined\r\n\t};\r\n}\r\n\r\nexport async function handleCommitBatch(request: Request) {\r\n\tconst data = await request.json().catch(() => null);\r\n\tconst items = Array.isArray(data?.items) ? (data.items as CommitBatchItem[]) : [];\r\n\r\n\tif (!items.length) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"No items to commit\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\r\n\t\t);\r\n\t}\r\n\r\n\tconst results: Array<{ msgid: string; msgctxt: string | null; ok: boolean; error?: string }> = [];\r\n\r\n\tfor (const item of items) {\r\n\t\tconst resolvedMsgid = item.resolvedMsgid?.trim();\r\n\t\tconst resolvedMsgctxt =\r\n\t\t\titem.resolvedMsgctxt && item.resolvedMsgctxt.trim().length > 0\r\n\t\t\t\t? item.resolvedMsgctxt.trim()\r\n\t\t\t\t: null;\r\n\t\tconst translationValue = item.translationValue?.trim();\r\n\r\n\t\tif (!resolvedMsgid || !translationValue) {\r\n\t\t\tresults.push({\r\n\t\t\t\tmsgid: resolvedMsgid ?? \"\",\r\n\t\t\t\tmsgctxt: resolvedMsgctxt,\r\n\t\t\t\tok: false,\r\n\t\t\t\terror: \"resolvedMsgid and translationValue are required\"\r\n\t\t\t});\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tconst result = await writeTranslationToWorkingCatalog(\r\n\t\t\tresolvedMsgid,\r\n\t\t\tresolvedMsgctxt,\r\n\t\t\ttranslationValue\r\n\t\t);\r\n\r\n\t\tif (!result.ok) {\r\n\t\t\tresults.push({\r\n\t\t\t\tmsgid: resolvedMsgid,\r\n\t\t\t\tmsgctxt: resolvedMsgctxt,\r\n\t\t\t\tok: false,\r\n\t\t\t\terror: result.error\r\n\t\t\t});\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tresults.push({\r\n\t\t\tmsgid: resolvedMsgid,\r\n\t\t\tmsgctxt: resolvedMsgctxt,\r\n\t\t\tok: true\r\n\t\t});\r\n\t}\r\n\r\n\tconst failed = results.filter((item) => !item.ok);\r\n\tif (failed.length) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"Some translations failed to commit\",\r\n\t\t\t\tresults\r\n\t\t\t},\r\n\t\t\t{ status: 207 }\r\n\t\t);\r\n\t}\r\n\r\n\treturn json({\r\n\t\tsuccess: true,\r\n\t\tmessage: `Committed ${results.length} translations to en-working.po`,\r\n\t\tresults\r\n\t});\r\n}\r\n\r\nexport async function handleCommit(request: Request) {\n\tconst data = await request.formData();\r\n\tconst resolvedMsgid = data.get(\"resolvedMsgid\")?.toString().trim();\r\n\tconst resolvedMsgctxtRaw = data.get(\"resolvedMsgctxt\")?.toString();\r\n\tconst translationValue = data.get(\"translationValue\")?.toString().trim();\r\n\tconst resolvedMsgctxt =\r\n\t\tresolvedMsgctxtRaw && resolvedMsgctxtRaw.trim().length > 0\r\n\t\t\t? resolvedMsgctxtRaw.trim()\r\n\t\t\t: null;\r\n\r\n\tif (!resolvedMsgid || !translationValue) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"resolvedMsgid and translationValue are required\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\r\n\t\t);\r\n\t}\r\n\r\n\tconst result = await writeTranslationToWorkingCatalog(\r\n\t\tresolvedMsgid,\r\n\t\tresolvedMsgctxt,\r\n\t\ttranslationValue\r\n\t);\r\n\r\n\tif (!result.ok) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: result.error\r\n\t\t\t},\r\n\t\t\t{ status: 404 }\r\n\t\t);\r\n\t}\r\n\r\n\treturn json({\n\t\tsuccess: true,\n\t\tmessage: \"Translation written to en-working.po\",\n\t\tmsgid: result.msgid,\n\t\tmsgctxt: result.msgctxt,\n\t\tworkingCatalog: result.workingCatalog\n\t});\n}\n\nexport async function handleRotateCatalogs() {\n\tconst result = await rotateCatalogs();\n\n\tif (!result.ok) {\n\t\treturn json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: result.error\n\t\t\t},\n\t\t\t{ status: 400 }\n\t\t);\n\t}\n\n\treturn json({\n\t\tsuccess: true,\n\t\tmessage: \"Catalogs rotated\",\n\t\tbasePoPath: result.basePoPath,\n\t\tworkingPoPath: result.workingPoPath,\n\t\tbaseBackupPath: result.baseBackupPath,\n\t\tworkingBackupPath: result.workingBackupPath\n\t});\n}\n", "import { constants as fsConstants } from \"node:fs\";\nimport { access, copyFile, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, extname, join, basename } from \"node:path\";\nimport gettextParser from \"gettext-parser\";\nimport Fuse from \"fuse.js\";\nimport type { NormalizedEntry, PoTranslationEntry, TranslationOrigin } from \"./types.ts\";\nimport { getTranslationHelperConfig, suspendWorkingCatalogWatch } from \"./config.ts\";\n\r\nexport const runtimeTranslations = new Map<string, string>();\r\n\r\nexport function catalogEntryKey(msgid: string, msgctxt: string | null) {\r\n\treturn `${msgctxt ?? \"\"}::${msgid}`;\r\n}\r\n\r\nexport function normalizeWhitespace(value: string): string {\r\n\treturn value.replace(/\\s+/g, \" \").trim();\r\n}\r\n\r\nexport function normalizeForLookup(value: string): string {\r\n\treturn normalizeWhitespace(value)\r\n\t\t.replace(/<\\/?[a-z][^>]*>/gi, \"<x>\")\r\n\t\t.replace(/<\\/?\\d+>/g, \"<x>\")\r\n\t\t.replace(/\\{\\{?\\s*[^}]+\\s*\\}?\\}/g, \"{0}\")\r\n\t\t.replace(/\\{\\d+\\}/g, \"{0}\")\r\n\t\t.replace(/[\"\"'`\u00C2\u00B4]/g, \"'\")\r\n\t\t.toLowerCase();\r\n}\r\n\r\nexport function tokenizeForLookup(value: string): string[] {\r\n\treturn normalizeForLookup(value)\r\n\t\t.split(/[\\s,.;:!?()[\\]{}]+/)\r\n\t\t.map((token) => token.trim())\r\n\t\t.filter(Boolean);\r\n}\r\n\r\nexport function buildLookupVariants(raw: string): string[] {\r\n\tconst normalized = normalizeForLookup(raw);\r\n\tconst variants = new Set<string>([normalized]);\r\n\r\n\tvariants.add(normalized.replace(/<x>/g, \"<0>\"));\r\n\tvariants.add(normalized.replace(/<x>/g, \"\").replace(/\\s+/g, \" \").trim());\r\n\tvariants.add(normalized.replace(/\\{0\\}/g, \"\").replace(/\\s+/g, \" \").trim());\r\n\r\n\treturn [...variants].filter(Boolean);\r\n}\r\n\r\nexport function flattenPoEntries(parsed: any, translationOrigin: TranslationOrigin): NormalizedEntry[] {\r\n\tconst entries: NormalizedEntry[] = [];\r\n\tconst translations = parsed?.translations ?? {};\r\n\r\n\tfor (const [ctxKey, group] of Object.entries(translations)) {\r\n\t\tfor (const [msgidKey, raw] of Object.entries(group as Record<string, unknown>)) {\r\n\t\t\tif (!msgidKey) continue;\r\n\r\n\t\t\tconst entry = raw as PoTranslationEntry;\r\n\t\t\tconst msgid = entry.msgid ?? msgidKey;\r\n\t\t\tconst msgctxt = entry.msgctxt ?? (ctxKey === \"\" ? null : ctxKey);\r\n\t\t\tconst msgidPlural = entry.msgid_plural ?? null;\r\n\t\t\tconst msgstr = Array.isArray(entry.msgstr) ? entry.msgstr.filter(Boolean) : [];\r\n\t\t\tconst references = entry.comments?.reference\r\n\t\t\t\t? entry.comments.reference.split(\"\\n\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst extractedComments = entry.comments?.extracted\r\n\t\t\t\t? entry.comments.extracted.split(\"\\n\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst flags = entry.comments?.flag\r\n\t\t\t\t? entry.comments.flag.split(\",\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst previous = entry.comments?.previous\r\n\t\t\t\t? entry.comments.previous.split(\"\\n\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst translated = entry.msgstr?.some((item) => item.trim().length > 0) ?? false;\r\n\t\t\tconst fuzzy = entry.comments?.flag?.includes(\"fuzzy\");\r\n\r\n\t\t\tentries.push({\r\n\t\t\t\tmsgid,\r\n\t\t\t\tmsgctxt,\r\n\t\t\t\tmsgidPlural,\r\n\t\t\t\tmsgstr,\r\n\t\t\t\treferences,\r\n\t\t\t\textractedComments,\r\n\t\t\t\tflags,\r\n\t\t\t\tprevious,\r\n\t\t\t\tobsolete: Boolean(entry.obsolete),\r\n\t\t\t\tsearchText: normalizeForLookup(msgid),\r\n\t\t\t\tsearchTokens: tokenizeForLookup(msgid),\r\n\t\t\t\tisFuzzy: fuzzy,\r\n\t\t\t\thasTranslation: translated,\r\n\t\t\t\ttranslationOrigin\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\treturn entries;\r\n}\r\n\r\nexport function createFuse(entries: NormalizedEntry[]) {\r\n\treturn new Fuse(entries, {\r\n\t\tincludeScore: true,\r\n\t\tignoreLocation: true,\r\n\t\tthreshold: 0.34,\r\n\t\tminMatchCharLength: 2,\r\n\t\tkeys: [\r\n\t\t\t{ name: \"msgid\", weight: 0.7 },\r\n\t\t\t{ name: \"searchText\", weight: 0.2 },\r\n\t\t\t{ name: \"references\", weight: 0.1 }\r\n\t\t]\r\n\t});\r\n}\r\n\r\nexport function buildEntryMap(entries: NormalizedEntry[]) {\r\n\treturn new Map(entries.map((entry) => [catalogEntryKey(entry.msgid, entry.msgctxt), entry]));\r\n}\r\n\r\nexport function applyWorkingState(\r\n\tbaseEntry: NormalizedEntry,\r\n\tworkingEntry?: NormalizedEntry\r\n): NormalizedEntry {\r\n\tif (!workingEntry) {\r\n\t\treturn baseEntry;\r\n\t}\r\n\r\n\treturn {\r\n\t\t...baseEntry,\r\n\t\tmsgstr: workingEntry.msgstr,\r\n\t\tflags: workingEntry.flags,\r\n\t\tprevious: workingEntry.previous,\r\n\t\tobsolete: workingEntry.obsolete,\r\n\t\thasTranslation: workingEntry.hasTranslation,\r\n\t\tisFuzzy: workingEntry.isFuzzy,\r\n\t\ttranslationOrigin: workingEntry.translationOrigin\r\n\t};\r\n}\r\n\r\nexport async function fileExists(path: string) {\r\n\ttry {\r\n\t\tawait access(path, fsConstants.F_OK);\r\n\t\treturn true;\r\n\t} catch {\r\n\t\treturn false;\r\n\t}\r\n}\r\n\r\nexport async function readCatIndex(catalog: TranslationOrigin) {\n\tconst { basePoPath, workingPoPath } = getTranslationHelperConfig();\n\tlet path = \"\";\n\n\tif (catalog === \"base\") {\n\t\tpath = basePoPath;\n\t} else {\n\t\tconst exists = await fileExists(workingPoPath);\n\t\tif (!exists) return null;\n\t\tpath = workingPoPath;\n\t}\n\r\n\tconst raw = await readFile(path);\r\n\tconst parsed = gettextParser.po.parse(raw);\r\n\tconst entries = flattenPoEntries(parsed, catalog);\r\n\r\n\treturn {\r\n\t\tentries,\r\n\t\tfuse: createFuse(entries)\r\n\t};\r\n}\r\n\r\nexport async function readParsedCatalog(catalog: TranslationOrigin) {\n\tconst { basePoPath, workingPoPath } = getTranslationHelperConfig();\n\tconst path = catalog === \"base\" ? basePoPath : workingPoPath;\n\r\n\tif (catalog === \"working\") {\r\n\t\tconst exists = await fileExists(path);\r\n\t\tif (!exists) return null;\r\n\t}\r\n\r\n\tconst raw = await readFile(path);\r\n\treturn gettextParser.po.parse(raw);\r\n}\r\n\r\nexport async function ensureWorkingCatalog() {\n\tconst { basePoPath, workingPoPath } = getTranslationHelperConfig();\n\tconst exists = await fileExists(workingPoPath);\n\tif (!exists) {\n\t\tawait copyFile(basePoPath, workingPoPath);\n\t}\n}\n\r\nexport function removeFuzzyFlag(flagString?: string) {\r\n\tif (!flagString) return \"\";\r\n\r\n\treturn flagString\r\n\t\t.split(\",\")\r\n\t\t.map((item) => item.trim())\r\n\t\t.filter(Boolean)\r\n\t\t.filter((item) => item !== \"fuzzy\")\r\n\t\t.join(\", \");\r\n}\r\n\r\nexport async function writeWorkingCatalog(parsed: any) {\n\tconst { workingPoPath } = getTranslationHelperConfig();\n\tsuspendWorkingCatalogWatch(workingPoPath);\n\tconst compiled = gettextParser.po.compile(parsed);\n\tawait writeFile(workingPoPath, compiled);\n}\n\nfunction timestampForBackup() {\n\treturn new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nfunction buildBackupPath(path: string, label: string) {\n\tconst directory = dirname(path);\n\tconst extension = extname(path);\n\tconst stem = basename(path, extension);\n\treturn join(directory, `${stem}.${label}.${timestampForBackup()}${extension}`);\n}\n\nexport async function rotateCatalogs() {\n\tconst { basePoPath, workingPoPath } = getTranslationHelperConfig();\n\tconst workingExists = await fileExists(workingPoPath);\n\n\tif (!workingExists) {\n\t\treturn { ok: false as const, error: \"Working catalog does not exist\" };\n\t}\n\n\tconst baseBackupPath = buildBackupPath(basePoPath, \"base-backup\");\n\tconst workingBackupPath = buildBackupPath(workingPoPath, \"working-backup\");\n\n\tawait copyFile(basePoPath, baseBackupPath);\n\tawait copyFile(workingPoPath, workingBackupPath);\n\tawait copyFile(workingPoPath, basePoPath);\n\tawait copyFile(basePoPath, workingPoPath);\n\n\treturn {\n\t\tok: true as const,\n\t\tbasePoPath,\n\t\tworkingPoPath,\n\t\tbaseBackupPath,\n\t\tworkingBackupPath\n\t};\n}\n", "import { readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, extname, isAbsolute, normalize, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { pathToFileURL } from \"node:url\";\nimport { transform } from \"esbuild\";\nimport type { TranslationContextResult } from \"../client/toggleQA.shared\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst CONFIG_FILENAMES = [\n\t\"angy.config.ts\",\n\t\"angy.config.js\",\n\t\"angy.config.mjs\",\n\t\"angy.config.cjs\"\n];\n\nexport type TranslationHelperConfig = {\n\tbasePoPath: string;\n\tworkingPoPath: string;\n\tsourceLocale: string;\n\ttargetLocale: string;\n\troutePath: string;\n\tapiKey: string;\n\tsystemMessage: string;\n\tsuggestionModel: string;\n\twatchIgnore: string[];\n\tsuggestionProvider?: SuggestionProvider;\n};\n\nexport type SuggestionRequestItem = {\n\tmsgid: string;\n\tmsgctxt: string | null;\n};\n\nexport type SuggestionResponseItem = {\n\tmsgid: string;\n\tmsgctxt: string | null;\n\tsuggestion: string;\n};\n\nexport type SuggestionProviderInput = {\n\tcontext: TranslationContextResult;\n\titems: SuggestionRequestItem[];\n\tsourceLocale: string;\n\ttargetLocale: string;\n\tsystemMessage: string;\n\tmodel: string;\n\tapiKey: string;\n};\n\nexport type SuggestionProvider = (\n\tinput: SuggestionProviderInput\n) => Promise<SuggestionResponseItem[]>;\n\nexport type TranslationHelperUserConfig = Partial<TranslationHelperConfig>;\n\nexport type AngyConfigInput = {\n\tbasePoPath: string;\n\tworkingPoPath: string;\n\tsourceLocale: string;\n\ttargetLocale: string;\n\troutePath?: string;\n\tapiKey: string;\n\tsystemMessage?: string;\n\tsuggestionModel?: string;\n\twatchIgnore?: string[];\n\tsuggestionProvider?: SuggestionProvider;\n};\n\nexport function buildDefaultSystemMessage(sourceLocale: string, targetLocale: string) {\n\treturn `You are an expert product localization assistant translating ${sourceLocale} UI copy into polished ${targetLocale}. Keep already-${targetLocale} text unchanged. Preserve placeholders like {0}, {1}, ICU fragments, HTML-like markers such as <0/> and <strong>, line breaks, punctuation, capitalization, and button-like brevity. Prefer terminology and syntax that stay close to the translated examples so the product voice remains cohesive. Do not invent extra context, do not expand abbreviations unless the examples already do, and avoid semantic drift. Return only high-confidence translation suggestions for the provided untranslated strings.`;\n}\n\nfunction assertNonEmptyString(value: unknown, key: string) {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`[angy] ${key} is required and must be a non-empty string.`);\n\t}\n}\n\nfunction validateRoutePath(routePath: unknown) {\n\tif (routePath == null || routePath === \"\") return;\n\tif (typeof routePath !== \"string\" || !routePath.startsWith(\"/\")) {\n\t\tthrow new Error(`[angy] routePath must be an absolute path starting with \"/\".`);\n\t}\n}\n\nfunction validateWatchIgnore(watchIgnore: unknown) {\n\tif (watchIgnore == null) return;\n\tif (!Array.isArray(watchIgnore) || watchIgnore.some((item) => typeof item !== \"string\")) {\n\t\tthrow new Error(`[angy] watchIgnore must be an array of strings.`);\n\t}\n}\n\nfunction validateSuggestionProvider(suggestionProvider: unknown) {\n\tif (suggestionProvider == null) return;\n\tif (typeof suggestionProvider !== \"function\") {\n\t\tthrow new Error(`[angy] suggestionProvider must be a function.`);\n\t}\n}\n\nconst config: TranslationHelperConfig = {\n\tbasePoPath: resolve(__dirname, \"../../locales/en.po\"),\n\tworkingPoPath: resolve(__dirname, \"../../locales/en-working.po\"),\n\tsourceLocale: \"sv\",\n\ttargetLocale: \"en\",\n\troutePath: \"/api/translations\",\n\tapiKey: \"\",\n\tsystemMessage: buildDefaultSystemMessage(\"sv\", \"en\"),\n\tsuggestionModel: \"gpt-4.1-mini\",\n\twatchIgnore: [\"**/en-working.po\"]\n};\n\nlet loadedConfigRoot: string | null = null;\nconst workingCatalogWatchControllers = new Set<(path: string, delayMs?: number) => void>();\n\nexport function configureTranslationHelper(next: Partial<TranslationHelperConfig>) {\n\tObject.assign(config, next);\n}\n\nexport function getTranslationHelperConfig() {\n\treturn config;\n}\n\nfunction normalizeFsPath(path: string) {\n\treturn normalize(path).replace(/\\\\/g, \"/\");\n}\n\nexport function inferLocaleFromCatalogPath(path: string) {\n\tconst fileName = basename(path);\n\tif (!fileName) return null;\n\treturn fileName.slice(0, fileName.length - extname(fileName).length) || null;\n}\n\nfunction resolveLocaleAlias(\n\tvalue: string,\n\tpaths: { basePoPath: string; workingPoPath: string }\n) {\n\tif (value === \"working\") {\n\t\tconst locale = inferLocaleFromCatalogPath(paths.workingPoPath);\n\t\tif (!locale) {\n\t\t\tthrow new Error(\"[angy] Unable to infer locale from workingPoPath.\");\n\t\t}\n\t\treturn locale;\n\t}\n\n\tif (value === \"base\") {\n\t\tconst locale = inferLocaleFromCatalogPath(paths.basePoPath);\n\t\tif (!locale) {\n\t\t\tthrow new Error(\"[angy] Unable to infer locale from basePoPath.\");\n\t\t}\n\t\treturn locale;\n\t}\n\n\treturn value;\n}\n\nfunction validateLocaleAliasUsage(sourceLocale: string, targetLocale: string) {\n\tif (sourceLocale === \"working\") {\n\t\tthrow new Error('[angy] sourceLocale cannot be \"working\". Use an explicit source locale.');\n\t}\n\n\tif (targetLocale === \"base\") {\n\t\tthrow new Error('[angy] targetLocale cannot be \"base\". Use an explicit target locale or \"working\".');\n\t}\n}\n\nexport function registerWorkingCatalogWatchController(\n\tcontroller: (path: string, delayMs?: number) => void\n) {\n\tworkingCatalogWatchControllers.add(controller);\n\treturn () => {\n\t\tworkingCatalogWatchControllers.delete(controller);\n\t};\n}\n\nexport function suspendWorkingCatalogWatch(path: string, delayMs = 800) {\n\tconst normalizedPath = normalizeFsPath(path);\n\tfor (const controller of workingCatalogWatchControllers) {\n\t\tcontroller(normalizedPath, delayMs);\n\t}\n}\n\nexport function normalizeTranslationHelperConfig(\n\troot: string,\n\tnext: TranslationHelperUserConfig\n): TranslationHelperUserConfig {\n\tconst normalized = { ...next };\n\n\tif (normalized.basePoPath && !isAbsolute(normalized.basePoPath)) {\n\t\tnormalized.basePoPath = resolve(root, normalized.basePoPath);\n\t}\n\n\tif (normalized.workingPoPath && !isAbsolute(normalized.workingPoPath)) {\n\t\tnormalized.workingPoPath = resolve(root, normalized.workingPoPath);\n\t}\n\n\treturn normalized;\n}\n\nexport function resolveConfiguredLocaleAliases(\n\tnext: TranslationHelperConfig\n): TranslationHelperConfig {\n\tconst rawSourceLocale = next.sourceLocale;\n\tconst rawTargetLocale = next.targetLocale;\n\tconst resolvedSourceLocale = resolveLocaleAlias(rawSourceLocale, next);\n\tconst resolvedTargetLocale = resolveLocaleAlias(rawTargetLocale, next);\n\tconst usesDefaultSystemMessage =\n\t\tnext.systemMessage === buildDefaultSystemMessage(rawSourceLocale, rawTargetLocale);\n\n\treturn {\n\t\t...next,\n\t\tsourceLocale: resolvedSourceLocale,\n\t\ttargetLocale: resolvedTargetLocale,\n\t\tsystemMessage: usesDefaultSystemMessage\n\t\t\t? buildDefaultSystemMessage(resolvedSourceLocale, resolvedTargetLocale)\n\t\t\t: next.systemMessage\n\t};\n}\n\nexport function completeAngyConfig(input: AngyConfigInput): TranslationHelperConfig {\n\tassertNonEmptyString(input.basePoPath, \"basePoPath\");\n\tassertNonEmptyString(input.workingPoPath, \"workingPoPath\");\n\tassertNonEmptyString(input.sourceLocale, \"sourceLocale\");\n\tassertNonEmptyString(input.targetLocale, \"targetLocale\");\n\tvalidateLocaleAliasUsage(input.sourceLocale, input.targetLocale);\n\tif (typeof input.apiKey !== \"string\") {\n\t\tthrow new Error(`[angy] apiKey is required and must be a string. Use an empty string to disable suggestions.`);\n\t}\n\tvalidateRoutePath(input.routePath);\n\tvalidateWatchIgnore(input.watchIgnore);\n\tvalidateSuggestionProvider(input.suggestionProvider);\n\n\treturn {\n\t\tbasePoPath: input.basePoPath,\n\t\tworkingPoPath: input.workingPoPath,\n\t\tsourceLocale: input.sourceLocale,\n\t\ttargetLocale: input.targetLocale,\n\t\troutePath: input.routePath ?? \"/api/translations\",\n\t\tapiKey: input.apiKey,\n\t\tsystemMessage:\n\t\t\tinput.systemMessage ??\n\t\t\tbuildDefaultSystemMessage(input.sourceLocale, input.targetLocale),\n\t\tsuggestionModel: input.suggestionModel ?? \"gpt-4.1-mini\",\n\t\twatchIgnore: input.watchIgnore ?? [\"**/en-working.po\"],\n\t\tsuggestionProvider: input.suggestionProvider\n\t};\n}\n\nexport function defineAngyConfig(config: AngyConfigInput) {\n\treturn completeAngyConfig(config);\n}\n\nasync function fileExists(path: string) {\n\ttry {\n\t\tawait readFile(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function loadTsConfigModule(path: string) {\n\tconst source = await readFile(path, \"utf8\");\n\tconst transformed = await transform(source, {\n\t\tloader: \"ts\",\n\t\tformat: \"esm\",\n\t\ttarget: \"es2022\"\n\t});\n\tconst tempPath = `${path}.angy.tmp.mjs`;\n\tawait writeFile(tempPath, transformed.code, \"utf8\");\n\n\ttry {\n\t\treturn await import(`${pathToFileURL(tempPath).href}?t=${Date.now()}`);\n\t} finally {\n\t\tawait unlink(tempPath).catch(() => undefined);\n\t}\n}\n\nasync function loadJsConfigModule(path: string) {\n\treturn import(pathToFileURL(path).href);\n}\n\nexport async function loadAngyConfigFromRoot(root: string) {\n\tif (loadedConfigRoot === root) {\n\t\treturn config;\n\t}\n\n\tfor (const filename of CONFIG_FILENAMES) {\n\t\tconst fullPath = `${root}/${filename}`.replace(/\\\\/g, \"/\");\n\t\tif (!(await fileExists(fullPath))) continue;\n\n\t\tconst module =\n\t\t\tfilename.endsWith(\".ts\")\n\t\t\t\t? await loadTsConfigModule(fullPath)\n\t\t\t\t: await loadJsConfigModule(fullPath);\n\t\tconst raw = (module.default ?? module.config ?? {}) as TranslationHelperUserConfig;\n\t\tconst next = resolveConfiguredLocaleAliases(\n\t\t\tnormalizeTranslationHelperConfig(root, completeAngyConfig(raw as AngyConfigInput))\n\t\t);\n\t\tconfigureTranslationHelper(next);\n\t\tloadedConfigRoot = root;\n\t\treturn config;\n\t}\n\n\tloadedConfigRoot = root;\n\treturn config;\n}\n", "import { json } from \"@sveltejs/kit\";\r\nimport {\n\tapplyWorkingState,\n\tbuildEntryMap,\n\tbuildLookupVariants,\n\tcatalogEntryKey,\n\tcreateFuse,\n\treadCatIndex\n} from \"./catalog.ts\";\nimport type { NormalizedEntry } from \"./types.ts\";\n\r\nconst DIRECT_MATCH_LIMIT = 5;\nconst MAX_ALTERNATIVES = 300;\nconst TRANSLATED_TARGET = Math.floor(MAX_ALTERNATIVES * 0.2);\nconst UNTRANSLATED_TARGET = MAX_ALTERNATIVES - TRANSLATED_TARGET;\nconst UNTRANSLATED_RANK_BONUS = 0.03;\n\r\ntype Candidate = {\r\n\tentry: NormalizedEntry;\r\n\tscore: number;\r\n\tvariant: string;\r\n};\r\n\r\ntype ScoredEntry = {\r\n\tentry: NormalizedEntry;\r\n\tscore: number;\r\n\tvariant: string;\r\n};\r\n\r\nexport function entryKey(msgid: string, msgctxt: string | null) {\r\n\treturn catalogEntryKey(msgid, msgctxt);\r\n}\r\n\r\nfunction normalizeCurrentPath(currentPath: string) {\r\n\ttry {\r\n\t\treturn new URL(currentPath, \"http://localhost\").pathname;\r\n\t} catch {\r\n\t\treturn currentPath;\r\n\t}\r\n}\r\n\r\nfunction inferPageReference(currentPath: string) {\r\n\tconst normalizedPath = normalizeCurrentPath(currentPath);\r\n\tif (normalizedPath === \"/\") {\r\n\t\treturn \"src/routes/+page.svelte\";\r\n\t}\r\n\r\n\tconst trimmedPath = normalizedPath.replace(/\\/+$/, \"\");\r\n\treturn `src/routes${trimmedPath}/+page.svelte`;\r\n}\r\n\r\nfunction routeLooksRelevant(routeReference: string, refs: string[], extractedComments: string[]) {\r\n\tif (!routeReference) return false;\r\n\r\n\tconst haystack = [...refs, ...extractedComments].join(\" \").toLowerCase();\r\n\treturn haystack.includes(routeReference.toLowerCase());\r\n}\r\n\r\nfunction dedupeCandidates(candidates: Candidate[]) {\r\n\tconst deduped = new Map<string, Candidate>();\r\n\r\n\tfor (const item of candidates) {\r\n\t\tconst id = entryKey(item.entry.msgid, item.entry.msgctxt);\r\n\t\tconst existing = deduped.get(id);\r\n\t\tif (!existing || item.score < existing.score) {\r\n\t\t\tdeduped.set(id, item);\r\n\t\t}\r\n\t}\r\n\r\n\treturn [...deduped.values()];\r\n}\r\n\r\nfunction rankDirectMatches(candidates: Candidate[], routeReference: string) {\n\treturn [...candidates].sort((left, right) => {\n\t\tconst leftRoute = routeLooksRelevant(\n\t\t\trouteReference,\n\t\t\tleft.entry.references,\r\n\t\t\tleft.entry.extractedComments\r\n\t\t)\r\n\t\t\t? -0.08\r\n\t\t\t: 0;\r\n\t\tconst rightRoute = routeLooksRelevant(\n\t\t\trouteReference,\n\t\t\tright.entry.references,\n\t\t\tright.entry.extractedComments\n\t\t)\n\t\t\t? -0.08\n\t\t\t: 0;\n\t\tconst leftUntranslated = !left.entry.hasTranslation ? -UNTRANSLATED_RANK_BONUS : 0;\n\t\tconst rightUntranslated = !right.entry.hasTranslation ? -UNTRANSLATED_RANK_BONUS : 0;\n\n\t\treturn left.score + leftRoute + leftUntranslated - (right.score + rightRoute + rightUntranslated);\n\t});\n}\n\r\nfunction getReferenceTokens(reference: string) {\r\n\treturn reference\r\n\t\t.toLowerCase()\r\n\t\t.split(/[\\/\\[\\].:_-]+/)\r\n\t\t.map((token) => token.trim())\r\n\t\t.filter(Boolean);\r\n}\r\n\r\nfunction getReferenceSimilarity(reference: string, routeReference: string) {\r\n\tconst referenceTokens = new Set(getReferenceTokens(reference));\r\n\tconst routeTokens = getReferenceTokens(routeReference);\r\n\r\n\tif (!routeTokens.length || !referenceTokens.size) return 0;\r\n\r\n\tlet matches = 0;\r\n\tfor (const token of routeTokens) {\r\n\t\tif (referenceTokens.has(token)) {\r\n\t\t\tmatches += 1;\r\n\t\t}\r\n\t}\r\n\r\n\treturn matches / routeTokens.length;\r\n}\r\n\r\nfunction collectSharedReferenceAlternatives(\n\tentries: NormalizedEntry[],\n\tbestEntry: NormalizedEntry,\n\trouteReference: string,\n\texcludedKeys: Set<string>\n) {\r\n\tconst sharedReferences = new Set(bestEntry.references.map((reference) => reference.toLowerCase()));\r\n\r\n\treturn entries\r\n\t\t.filter((entry) => !excludedKeys.has(entryKey(entry.msgid, entry.msgctxt)))\r\n\t\t.map((entry) => {\r\n\t\t\tconst referenceMatches = entry.references.filter((reference) =>\r\n\t\t\t\tsharedReferences.has(reference.toLowerCase())\r\n\t\t\t);\r\n\t\t\tconst routeMatch = entry.references.some((reference) =>\r\n\t\t\t\treference.toLowerCase().includes(routeReference.toLowerCase())\r\n\t\t\t);\r\n\r\n\t\t\tif (!referenceMatches.length && !routeMatch) {\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\tconst referenceSimilarity = Math.max(\n\t\t\t\t0,\n\t\t\t\t...entry.references.map((reference) => getReferenceSimilarity(reference, routeReference))\n\t\t\t);\n\t\t\tconst untranslatedBonus = !entry.hasTranslation ? 0.35 : 0;\n\n\t\t\treturn {\n\t\t\t\tentry,\n\t\t\t\tscore:\n\t\t\t\t\treferenceMatches.length * 100 +\n\t\t\t\t\t(routeMatch ? 25 : 0) +\n\t\t\t\t\treferenceSimilarity +\n\t\t\t\t\tuntranslatedBonus,\n\t\t\t\tvariant: \"shared-reference\"\n\t\t\t};\n\t\t})\n\t\t.filter((item): item is ScoredEntry => Boolean(item))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction collectRouteFillAlternatives(\n\tentries: NormalizedEntry[],\n\trouteReference: string,\n\texcludedKeys: Set<string>\n) {\n\treturn entries\r\n\t\t.filter((entry) => !excludedKeys.has(entryKey(entry.msgid, entry.msgctxt)))\r\n\t\t.map((entry) => {\r\n\t\t\tconst referenceSimilarity = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\t...entry.references.map((reference) => getReferenceSimilarity(reference, routeReference))\r\n\t\t\t);\r\n\r\n\t\t\tif (referenceSimilarity <= 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst untranslatedBonus = !entry.hasTranslation ? 0.2 : 0;\n\n\t\t\treturn {\n\t\t\t\tentry,\n\t\t\t\tscore: referenceSimilarity + untranslatedBonus,\n\t\t\t\tvariant: \"route-reference\"\n\t\t\t};\n\t\t})\n\t\t.filter((item): item is ScoredEntry => Boolean(item))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction collectTranslatedCohesionAlternatives(\r\n\tdirectMatches: Candidate[],\r\n\texcludedKeys: Set<string>\r\n) {\r\n\treturn directMatches\r\n\t\t.filter((item) => item.entry.hasTranslation)\r\n\t\t.filter((item) => !excludedKeys.has(entryKey(item.entry.msgid, item.entry.msgctxt)))\r\n\t\t.map((item) => ({\r\n\t\t\tentry: item.entry,\r\n\t\t\tscore: 1 - item.score,\r\n\t\t\tvariant: \"translated-cohesion\"\r\n\t\t}))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction collectUntranslatedSimilarityAlternatives(\r\n\tdirectMatches: Candidate[],\r\n\texcludedKeys: Set<string>\r\n) {\r\n\treturn directMatches\r\n\t\t.filter((item) => !item.entry.hasTranslation)\r\n\t\t.filter((item) => !excludedKeys.has(entryKey(item.entry.msgid, item.entry.msgctxt)))\r\n\t\t.map((item) => ({\r\n\t\t\tentry: item.entry,\r\n\t\t\tscore: 1 - item.score,\r\n\t\t\tvariant: \"untranslated-similarity\"\r\n\t\t}))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction buildAlternativePool(\r\n\ttopDirectAlternatives: Candidate[],\r\n\tsharedReferenceAlternatives: ScoredEntry[],\r\n\trouteFillAlternatives: ScoredEntry[],\r\n\ttranslatedCohesionAlternatives: ScoredEntry[],\r\n\tuntranslatedSimilarityAlternatives: ScoredEntry[]\r\n) {\r\n\tconst alternatives: ScoredEntry[] = [...topDirectAlternatives];\r\n\tconst selectedKeys = new Set<string>(\r\n\t\ttopDirectAlternatives.map((item) => entryKey(item.entry.msgid, item.entry.msgctxt))\r\n\t);\r\n\r\n\tlet translatedCount = topDirectAlternatives.filter((item) => item.entry.hasTranslation).length;\r\n\tlet untranslatedCount = topDirectAlternatives.length - translatedCount;\r\n\r\n\tconst tryAdd = (item: ScoredEntry, honorQuota = true) => {\r\n\t\tif (alternatives.length >= MAX_ALTERNATIVES) return false;\r\n\r\n\t\tconst id = entryKey(item.entry.msgid, item.entry.msgctxt);\r\n\t\tif (selectedKeys.has(id)) return false;\r\n\r\n\t\tif (honorQuota) {\r\n\t\t\tif (item.entry.hasTranslation && translatedCount >= TRANSLATED_TARGET) return false;\r\n\t\t\tif (!item.entry.hasTranslation && untranslatedCount >= UNTRANSLATED_TARGET) return false;\r\n\t\t}\r\n\r\n\t\tselectedKeys.add(id);\r\n\t\talternatives.push(item);\r\n\r\n\t\tif (item.entry.hasTranslation) {\r\n\t\t\ttranslatedCount += 1;\r\n\t\t} else {\r\n\t\t\tuntranslatedCount += 1;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t};\r\n\r\n\tconst prioritizedSources = [\r\n\t\tsharedReferenceAlternatives,\r\n\t\trouteFillAlternatives,\r\n\t\tuntranslatedSimilarityAlternatives,\r\n\t\ttranslatedCohesionAlternatives\r\n\t];\r\n\r\n\tfor (const source of prioritizedSources) {\r\n\t\tfor (const item of source) {\r\n\t\t\ttryAdd(item, true);\r\n\t\t}\r\n\t}\r\n\r\n\tif (alternatives.length < MAX_ALTERNATIVES) {\r\n\t\tfor (const source of prioritizedSources) {\r\n\t\t\tfor (const item of source) {\r\n\t\t\t\ttryAdd(item, false);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn alternatives.slice(0, MAX_ALTERNATIVES);\r\n}\r\n\r\nexport async function findTranslationContext(\r\n\tkey: string,\r\n\tcurrentPath: string\r\n) {\r\n\tconst baseIndex = await readCatIndex(\"base\");\r\n\tif (!baseIndex) return null;\r\n\r\n\tconst workingIndex = await readCatIndex(\"working\");\r\n\tconst workingMap = workingIndex\r\n\t\t? buildEntryMap(workingIndex.entries)\r\n\t\t: new Map<string, NormalizedEntry>();\r\n\tconst effectiveEntries = baseIndex.entries.map((entry) =>\n\t\tapplyWorkingState(entry, workingMap.get(entryKey(entry.msgid, entry.msgctxt)))\n\t);\n\tconst effectiveIndex = {\n\t\tentries: effectiveEntries,\n\t\tfuse: createFuse(effectiveEntries)\n\t};\n\n\tconst routeReference = inferPageReference(currentPath);\n\tconst directMatches = rankDirectMatches(\n\t\tdedupeCandidates(\n\t\t\tbuildLookupVariants(key).flatMap((variant) =>\n\t\t\t\teffectiveIndex.fuse.search(variant, { limit: 180 }).map((hit) => ({\n\t\t\t\t\tentry: hit.item,\n\t\t\t\t\tscore: hit.score ?? 1,\n\t\t\t\t\tvariant\n\t\t\t\t}))\n\t\t\t)\n\t\t),\r\n\t\trouteReference\r\n\t);\r\n\r\n\tconst best = directMatches[0];\r\n\tif (!best || best.score > 0.42) {\n\t\treturn null;\n\t}\n\n\tconst effectiveDirectMatches = directMatches;\n\tconst bestEffective = effectiveDirectMatches[0];\n\tconst topDirectAlternatives = effectiveDirectMatches.slice(1, DIRECT_MATCH_LIMIT);\n\tconst excludedKeys = new Set<string>([\r\n\t\tentryKey(best.entry.msgid, best.entry.msgctxt),\r\n\t\t...topDirectAlternatives.map((item) => entryKey(item.entry.msgid, item.entry.msgctxt))\r\n\t]);\r\n\r\n\tconst sharedReferenceAlternatives = collectSharedReferenceAlternatives(\r\n\t\teffectiveEntries,\r\n\t\tbestEffective.entry,\r\n\t\trouteReference,\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\tconst routeFillAlternatives = collectRouteFillAlternatives(\r\n\t\teffectiveEntries,\r\n\t\trouteReference,\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\tconst translatedCohesionAlternatives = collectTranslatedCohesionAlternatives(\r\n\t\teffectiveDirectMatches.slice(DIRECT_MATCH_LIMIT),\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\tconst untranslatedSimilarityAlternatives = collectUntranslatedSimilarityAlternatives(\r\n\t\teffectiveDirectMatches.slice(DIRECT_MATCH_LIMIT),\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\treturn {\r\n\t\tbest,\r\n\t\talternatives: buildAlternativePool(\r\n\t\t\ttopDirectAlternatives,\r\n\t\t\tsharedReferenceAlternatives,\r\n\t\t\trouteFillAlternatives,\r\n\t\t\ttranslatedCohesionAlternatives,\r\n\t\t\tuntranslatedSimilarityAlternatives\r\n\t\t),\r\n\t\trouteReference,\r\n\t\tworkingMap\r\n\t};\r\n}\r\n\r\nexport function toPublicEntry(entry: NormalizedEntry, workingEntry?: NormalizedEntry) {\n\tconst effective = workingEntry ?? entry;\n\tconst baseValue = entry.msgstr[0] ?? \"\";\n\tconst workingValue = workingEntry?.msgstr[0] ?? \"\";\n\tconst workingDiffersFromBase =\n\t\tBoolean(workingEntry?.hasTranslation) && workingValue !== baseValue;\n\n\treturn {\n\t\tmsgid: entry.msgid,\n\t\tmsgctxt: entry.msgctxt,\r\n\t\tmsgidPlural: entry.msgidPlural,\r\n\t\tmsgstr: effective.msgstr,\r\n\t\treferences: entry.references,\r\n\t\textractedComments: entry.extractedComments,\r\n\t\tflags: effective.flags,\r\n\t\tprevious: effective.previous,\r\n\t\tobsolete: effective.obsolete,\n\t\thasTranslation: effective.hasTranslation,\n\t\tisFuzzy: effective.isFuzzy,\n\t\tisCommittedToWorking: workingDiffersFromBase,\n\t\tmatchesTargetTranslation:\n\t\t\tBoolean(effective.hasTranslation) && (!workingEntry?.hasTranslation || workingValue === baseValue),\n\t\ttranslationOrigin: workingDiffersFromBase ? \"working\" : \"base\"\n\t};\n}\n\r\nexport function toPublicAlternative(\r\n\tentry: NormalizedEntry,\r\n\tscore: number,\r\n\tworkingEntry?: NormalizedEntry\r\n) {\n\tconst effective = workingEntry ?? entry;\n\tconst baseValue = entry.msgstr[0] ?? \"\";\n\tconst workingValue = workingEntry?.msgstr[0] ?? \"\";\n\tconst workingDiffersFromBase =\n\t\tBoolean(workingEntry?.hasTranslation) && workingValue !== baseValue;\n\n\treturn {\n\t\tmsgid: entry.msgid,\n\t\tmsgctxt: entry.msgctxt,\r\n\t\tscore,\r\n\t\treferences: entry.references,\r\n\t\tmsgstr: effective.msgstr,\n\t\thasTranslation: effective.hasTranslation,\n\t\tisFuzzy: effective.isFuzzy,\n\t\tisCommittedToWorking: workingDiffersFromBase,\n\t\tmatchesTargetTranslation:\n\t\t\tBoolean(effective.hasTranslation) && (!workingEntry?.hasTranslation || workingValue === baseValue),\n\t\ttranslationOrigin: workingDiffersFromBase ? \"working\" : \"base\"\n\t};\n}\n\r\nexport async function handleContext(request: Request) {\r\n\tconst data = await request.formData();\r\n\tconst key = data.get(\"translationKey\")?.toString().trim();\r\n\tconst currentPath = data.get(\"currentPath\")?.toString().trim();\r\n\r\n\tif (!key || !currentPath) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"translationKey and currentPath are required\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\r\n\t\t);\r\n\t}\r\n\r\n\tconst baseFound = await findTranslationContext(key, currentPath);\r\n\tif (!baseFound) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"Translation key context not found\"\r\n\t\t\t},\r\n\t\t\t{ status: 404 }\r\n\t\t);\r\n\t}\r\n\r\n\tconst bestBase = baseFound.best.entry;\r\n\tconst bestWorking = baseFound.workingMap.get(entryKey(bestBase.msgid, bestBase.msgctxt));\r\n\r\n\treturn json({\r\n\t\tsuccess: true,\r\n\t\tmatch: {\r\n\t\t\tscore: baseFound.best.score,\r\n\t\t\tvia: baseFound.best.variant\r\n\t\t},\r\n\t\tentry: toPublicEntry(bestBase, bestWorking),\r\n\t\talternatives: baseFound.alternatives.map((item) => {\r\n\t\t\tconst workingAlt = baseFound.workingMap.get(entryKey(item.entry.msgid, item.entry.msgctxt));\r\n\t\t\treturn toPublicAlternative(item.entry, item.score, workingAlt);\r\n\t\t})\r\n\t});\r\n}\r\n", "import { json } from \"@sveltejs/kit\";\nimport type { TranslationContextResult } from \"../client/toggleQA.shared\";\nimport type { SuggestionRequestItem, SuggestionResponseItem } from \"./config.ts\";\nimport { getTranslationHelperConfig } from \"./config.ts\";\n\r\nfunction getEntriesForSuggestions(contextResult: TranslationContextResult) {\r\n\treturn [contextResult.entry, ...contextResult.alternatives];\r\n}\r\n\r\nfunction getTranslatedExamples(contextResult: TranslationContextResult) {\r\n\treturn getEntriesForSuggestions(contextResult)\r\n\t\t.filter((entry) => entry.hasTranslation && entry.msgstr?.[0])\r\n\t\t.slice(0, 30)\r\n\t\t.map((entry) => ({\r\n\t\t\tmsgid: entry.msgid,\r\n\t\t\tmsgctxt: entry.msgctxt,\r\n\t\t\ttranslation: entry.msgstr[0]\r\n\t\t}));\r\n}\r\n\r\nfunction buildUserMessage(\r\n\tcontextResult: TranslationContextResult,\r\n\titems: SuggestionRequestItem[]\r\n) {\r\n\treturn JSON.stringify(\r\n\t\t{\r\n\t\t\ttask: \"Return translation suggestions for the untranslated UI strings.\",\r\n\t\t\toutput_format: {\r\n\t\t\t\titems: [\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tmsgid: \"source string\",\r\n\t\t\t\t\t\tmsgctxt: \"optional context or null\",\r\n\t\t\t\t\t\tsuggestion: \"translated suggestion\"\r\n\t\t\t\t\t}\r\n\t\t\t\t]\r\n\t\t\t},\r\n\t\t\ttranslated_examples: getTranslatedExamples(contextResult),\r\n\t\t\tuntranslated_items: items\r\n\t\t},\r\n\t\tnull,\r\n\t\t2\r\n\t);\r\n}\r\n\r\nfunction parseSuggestions(responseText: string): SuggestionResponseItem[] {\r\n\ttry {\r\n\t\tconst parsed = JSON.parse(responseText);\r\n\t\tconst items = Array.isArray(parsed?.items) ? parsed.items : [];\r\n\t\treturn items.filter(\r\n\t\t\t(item): item is SuggestionResponseItem =>\r\n\t\t\t\ttypeof item?.msgid === \"string\" &&\r\n\t\t\t\t(item.msgctxt === null || typeof item.msgctxt === \"string\") &&\r\n\t\t\t\ttypeof item?.suggestion === \"string\"\r\n\t\t);\r\n\t} catch {\r\n\t\treturn [];\r\n\t}\r\n}\r\n\r\nexport async function handleSuggestions(request: Request) {\n\tconst {\n\t\tapiKey,\n\t\tsuggestionModel,\n\t\tsystemMessage,\n\t\tsourceLocale,\n\t\ttargetLocale,\n\t\tsuggestionProvider\n\t} = getTranslationHelperConfig();\n\n\tconst data = await request.json().catch(() => null);\n\tconst context = data?.context as TranslationContextResult | undefined;\n\tconst items = Array.isArray(data?.items) ? (data.items as SuggestionRequestItem[]) : [];\n\r\n\tif (!context || !items.length) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"context and items are required\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\n\t\t);\n\t}\n\n\tif (suggestionProvider) {\n\t\tconst providedItems = await suggestionProvider({\n\t\t\tcontext,\n\t\t\titems,\n\t\t\tsourceLocale,\n\t\t\ttargetLocale,\n\t\t\tsystemMessage,\n\t\t\tmodel: suggestionModel,\n\t\t\tapiKey\n\t\t});\n\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\titems: providedItems\n\t\t});\n\t}\n\n\tif (!apiKey.trim()) {\n\t\tconsole.warn(\"[angy] Suggestions disabled because apiKey is empty.\");\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\tdisabled: true,\n\t\t\titems: []\n\t\t});\n\t}\n\n\ttry {\n\t\tconsole.info(\"[angy] Suggestion request starting.\", {\n\t\t\tmodel: suggestionModel,\n\t\t\tsourceLocale,\n\t\t\ttargetLocale,\n\t\t\titemCount: items.length,\n\t\t\thasApiKey: Boolean(apiKey.trim())\n\t\t});\n\n\t\tconst response = await fetch(\"https://api.openai.com/v1/responses\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t\t\"content-type\": \"application/json\"\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tmodel: suggestionModel,\n\t\t\t\treasoning: {\n\t\t\t\t\teffort: \"medium\"\n\t\t\t\t},\n\t\t\t\tinput: [\n\t\t\t\t\t{\n\t\t\t\t\t\trole: \"system\",\n\t\t\t\t\t\tcontent: [{ type: \"input_text\", text: systemMessage }]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"input_text\", text: buildUserMessage(context, items) }]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\ttext: {\n\t\t\t\t\tformat: {\n\t\t\t\t\t\ttype: \"json_schema\",\n\t\t\t\t\t\tname: \"translation_suggestions\",\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tmsgid: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\t\tmsgctxt: { type: [\"string\", \"null\"] },\n\t\t\t\t\t\t\t\t\t\t\tsuggestion: { type: \"string\" }\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\trequired: [\"msgid\", \"msgctxt\", \"suggestion\"]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\trequired: [\"items\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorBody = await response.text().catch(() => \"\");\n\t\t\tconsole.error(\"[angy] Suggestion request failed.\", {\n\t\t\t\tstatus: response.status,\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\tbody: errorBody\n\t\t\t});\n\n\t\t\treturn json(\n\t\t\t\t{\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: `Suggestion request failed: ${response.status}`\n\t\t\t\t},\n\t\t\t\t{ status: 502 }\n\t\t\t);\n\t\t}\n\n\t\tconst responseJson = await response.json();\n\tconst responseText =\n\t\tresponseJson?.output_text ??\n\t\tresponseJson?.output\n\t\t\t?.flatMap((item: any) => item?.content ?? [])\n\t\t\t.find((part: any) => part?.text)?.text ??\n\t\t\"\";\n\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\titems: parseSuggestions(responseText)\n\t\t});\n\t} catch (error) {\n\t\tconsole.error(\"[angy] Suggestion request threw.\", error);\n\t\treturn json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Suggestion request failed before reaching the model\"\n\t\t\t},\n\t\t\t{ status: 502 }\n\t\t);\n\t}\n}\n"],
5
- "mappings": "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",
6
- "names": ["json", "readFile", "writeFile", "dirname", "extname", "basename", "config", "fileExists", "readFile", "writeFile", "dirname", "extname", "basename", "json", "json", "json", "json", "json"]
4
+ "sourcesContent": ["import { json, type RequestHandler } from \"@sveltejs/kit\";\nimport {\n\thandleCommit,\n\thandleCommitBatch,\n\thandlePromoteWorkingPreview,\n\thandleRotateCatalogs,\n\thandleRotatePreflight\n} from \"./commit.ts\";\nimport {\n\tconfigureTranslationHelper,\n\tloadAngyConfigFromRoot,\n\tnormalizeTranslationHelperConfig,\n\ttype TranslationHelperConfig\n} from \"./config.ts\";\nimport { handleContext } from \"./context.ts\";\nimport { handleSuggestions } from \"./suggestions.ts\";\n\nexport async function handleTranslationRequest(\n\trequest: Request,\n\turl: URL,\n\toptions?: { devOnly?: boolean; config?: Partial<TranslationHelperConfig>; dev?: boolean }\n) {\n\tconst devOnly = options?.devOnly ?? true;\n\tconst runtimeDev =\n\t\ttypeof import.meta !== \"undefined\" &&\n\t\ttypeof import.meta.env !== \"undefined\" &&\n\t\timport.meta.env.DEV === true;\n\tconst isDev = options?.dev ?? runtimeDev;\n\n\tif (devOnly && !isDev) {\n\t\treturn json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Disabled outside dev\"\n\t\t\t},\n\t\t\t{ status: 404 }\n\t\t);\n\t}\n\n\tif (options?.config) {\n\t\tconfigureTranslationHelper(normalizeTranslationHelperConfig(process.cwd(), options.config));\n\t} else {\n\t\tawait loadAngyConfigFromRoot(process.cwd());\n\t}\n\n\tconst intent = url.searchParams.get(\"intent\") ?? \"commit\";\n\n\tif (intent === \"commit-batch\") {\n\t\treturn handleCommitBatch(request);\n\t}\n\n\tif (intent === \"context\") {\n\t\treturn handleContext(request);\n\t}\n\n\tif (intent === \"suggestions\") {\n\t\treturn handleSuggestions(request);\n\t}\n\n\tif (intent === \"rotate-catalogs\") {\n\t\treturn handleRotateCatalogs(request);\n\t}\n\n\tif (intent === \"rotate-preflight\") {\n\t\treturn handleRotatePreflight();\n\t}\n\n\tif (intent === \"promote-working-preview\") {\n\t\treturn handlePromoteWorkingPreview();\n\t}\n\n\treturn handleCommit(request);\n}\n\nfunction createAngyHandler(\n\toptions?: { devOnly?: boolean; config?: Partial<TranslationHelperConfig> }\n): RequestHandler {\n\treturn async ({ request, url }) => handleTranslationRequest(request, url, options);\n}\n\nexport const handler = createAngyHandler();\n\nexport {\n\tdefineAngyConfig,\n\ttype AngyConfigInput,\n\ttype SuggestionProvider,\n\ttype SuggestionProviderInput,\n\ttype SuggestionRequestItem,\n\ttype SuggestionResponseItem\n} from \"./config.ts\";\nexport {\n\tCatalogIntegrityError,\n\tcollectCatalogIntegrityIssues,\n\tcollectRotationImpact,\n\tgetRotationPreflight,\n\treadCatalogPair,\n\tresolveTranslationState\n} from \"./catalog.ts\";\n", "import { json } from \"@sveltejs/kit\";\nimport { basename } from \"node:path\";\nimport {\n\tCatalogIntegrityError,\n\tgetRotationPreflight,\n\tensureWorkingCatalog,\n\tpromoteWorkingDraftToRuntime,\n\treadCatalogPair,\n\treadParsedCatalog,\n\tremoveFuzzyFlag,\n\trotateCatalogs,\n\truntimeTranslations,\n\twriteWorkingCatalog\n} from \"./catalog.ts\";\nimport type { CommitBatchItem, PoTranslationEntry } from \"./types.ts\";\nimport { getTranslationHelperConfig, inferLocaleFromCatalogPath } from \"./config.ts\";\n\r\nfunction runtimeKey(msgid: string, msgctxt: string | null) {\r\n\treturn `${msgctxt ?? \"\"}::${msgid}`;\r\n}\r\n\r\nexport async function writeTranslationToWorkingCatalog(\n\tresolvedMsgid: string,\n\tresolvedMsgctxt: string | null,\n\ttranslationValue: string\n) {\n\tawait ensureWorkingCatalog();\n\n\tawait readCatalogPair({ ensureWorking: true });\n\n\tconst [baseParsed, workingParsed] = await Promise.all([readParsedCatalog(\"base\"), readParsedCatalog(\"working\")]);\n\n\tif (!baseParsed || !workingParsed) {\n\t\treturn { ok: false as const, error: \"Unable to load catalogs\" };\n\t}\n\r\n\tconst baseTranslations = baseParsed.translations ?? {};\r\n\tconst workingTranslations = workingParsed.translations ?? {};\r\n\r\n\tconst ctxKey = resolvedMsgctxt ?? \"\";\r\n\tconst baseGroup = baseTranslations[ctxKey];\r\n\tif (!baseGroup) {\r\n\t\treturn { ok: false as const, error: \"Context group not found in base catalog\" };\r\n\t}\r\n\r\n\tconst baseEntry = baseGroup[resolvedMsgid] as PoTranslationEntry | undefined;\r\n\tif (!baseEntry) {\r\n\t\treturn { ok: false as const, error: \"Target msgid not found in base catalog\" };\r\n\t}\r\n\r\n\tconst workingGroup = (workingTranslations[ctxKey] ??= {});\r\n\tconst entry = ((workingGroup[resolvedMsgid] as PoTranslationEntry | undefined) ??=\r\n\t\tcloneEntryForWorking(baseEntry, resolvedMsgid, resolvedMsgctxt));\r\n\r\n\tentry.msgstr = [translationValue];\r\n\tentry.comments ??= {};\r\n\tentry.comments.flag = removeFuzzyFlag(entry.comments.flag);\r\n\r\n\tawait writeWorkingCatalog(workingParsed);\r\n\r\n\truntimeTranslations.set(runtimeKey(resolvedMsgid, resolvedMsgctxt), translationValue);\n\n\tconst workingCatalogName = inferLocaleFromCatalogPath(getTranslationHelperConfig().workingPoPath) ?? \"working\";\n\n\treturn {\n\t\tok: true as const,\n\t\tmsgid: resolvedMsgid,\n\t\tmsgctxt: resolvedMsgctxt,\n\t\tworkingCatalog: workingCatalogName\n\t};\n}\n\r\nfunction cloneEntryForWorking(\r\n\tbaseEntry: PoTranslationEntry,\r\n\tmsgid: string,\r\n\tmsgctxt: string | null\r\n): PoTranslationEntry {\r\n\treturn {\r\n\t\tmsgid,\r\n\t\tmsgctxt: msgctxt ?? undefined,\r\n\t\tmsgid_plural: baseEntry.msgid_plural,\r\n\t\tmsgstr: Array.isArray(baseEntry.msgstr) ? [...baseEntry.msgstr] : [\"\"],\r\n\t\tobsolete: Boolean(baseEntry.obsolete),\r\n\t\tcomments: baseEntry.comments\r\n\t\t\t? {\r\n\t\t\t\t\treference: baseEntry.comments.reference,\r\n\t\t\t\t\textracted: baseEntry.comments.extracted,\r\n\t\t\t\t\tflag: baseEntry.comments.flag,\r\n\t\t\t\t\tprevious: baseEntry.comments.previous\r\n\t\t\t\t}\r\n\t\t\t: undefined\r\n\t};\r\n}\r\n\r\nexport async function handleCommitBatch(request: Request) {\n\tconst data = await request.json().catch(() => null);\n\tconst items = Array.isArray(data?.items) ? (data.items as CommitBatchItem[]) : [];\n\r\n\tif (!items.length) {\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"No items to commit\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\r\n\t\t);\r\n\t}\n\n\ttry {\n\t\tawait readCatalogPair({ ensureWorking: true });\n\t} catch (error) {\n\t\tif (error instanceof CatalogIntegrityError) {\n\t\t\treturn json(\n\t\t\t\t{\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: error.message,\n\t\t\t\t\tcode: \"catalog_integrity_error\",\n\t\t\t\t\tissues: error.issues\n\t\t\t\t},\n\t\t\t\t{ status: 409 }\n\t\t\t);\n\t\t}\n\n\t\tthrow error;\n\t}\n\n\tconst results: Array<{ msgid: string; msgctxt: string | null; ok: boolean; error?: string }> = [];\n\r\n\tfor (const item of items) {\r\n\t\tconst resolvedMsgid = item.resolvedMsgid?.trim();\r\n\t\tconst resolvedMsgctxt =\r\n\t\t\titem.resolvedMsgctxt && item.resolvedMsgctxt.trim().length > 0\r\n\t\t\t\t? item.resolvedMsgctxt.trim()\r\n\t\t\t\t: null;\r\n\t\tconst translationValue = item.translationValue?.trim();\r\n\r\n\t\tif (!resolvedMsgid || !translationValue) {\r\n\t\t\tresults.push({\r\n\t\t\t\tmsgid: resolvedMsgid ?? \"\",\r\n\t\t\t\tmsgctxt: resolvedMsgctxt,\r\n\t\t\t\tok: false,\r\n\t\t\t\terror: \"resolvedMsgid and translationValue are required\"\r\n\t\t\t});\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tconst result = await writeTranslationToWorkingCatalog(\r\n\t\t\tresolvedMsgid,\r\n\t\t\tresolvedMsgctxt,\r\n\t\t\ttranslationValue\r\n\t\t);\r\n\r\n\t\tif (!result.ok) {\r\n\t\t\tresults.push({\r\n\t\t\t\tmsgid: resolvedMsgid,\r\n\t\t\t\tmsgctxt: resolvedMsgctxt,\r\n\t\t\t\tok: false,\r\n\t\t\t\terror: result.error\r\n\t\t\t});\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tresults.push({\r\n\t\t\tmsgid: resolvedMsgid,\r\n\t\t\tmsgctxt: resolvedMsgctxt,\r\n\t\t\tok: true\r\n\t\t});\r\n\t}\r\n\r\n\tconst failed = results.filter((item) => !item.ok);\r\n\tif (failed.length) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"Some translations failed to commit\",\r\n\t\t\t\tresults\r\n\t\t\t},\r\n\t\t\t{ status: 207 }\r\n\t\t);\r\n\t}\r\n\r\n\treturn json({\n\t\tsuccess: true,\n\t\tmessage: `Committed ${results.length} translations to Angy draft working catalog`,\n\t\tresults\n\t});\n}\n\r\nexport async function handleCommit(request: Request) {\n\tconst data = await request.formData();\r\n\tconst resolvedMsgid = data.get(\"resolvedMsgid\")?.toString().trim();\r\n\tconst resolvedMsgctxtRaw = data.get(\"resolvedMsgctxt\")?.toString();\r\n\tconst translationValue = data.get(\"translationValue\")?.toString().trim();\r\n\tconst resolvedMsgctxt =\r\n\t\tresolvedMsgctxtRaw && resolvedMsgctxtRaw.trim().length > 0\r\n\t\t\t? resolvedMsgctxtRaw.trim()\r\n\t\t\t: null;\r\n\r\n\tif (!resolvedMsgid || !translationValue) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"resolvedMsgid and translationValue are required\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\r\n\t\t);\r\n\t}\r\n\r\n\tconst result = await writeTranslationToWorkingCatalog(\n\t\tresolvedMsgid,\n\t\tresolvedMsgctxt,\n\t\ttranslationValue\n\t);\n\r\n\tif (!result.ok) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: result.error\r\n\t\t\t},\r\n\t\t\t{ status: 404 }\r\n\t\t);\r\n\t}\r\n\r\n\treturn json({\n\t\tsuccess: true,\n\t\tmessage: \"Translation written to Angy draft working catalog\",\n\t\tmsgid: result.msgid,\n\t\tmsgctxt: result.msgctxt,\n\t\tworkingCatalog: result.workingCatalog\n\t});\n}\n\nexport async function handlePromoteWorkingPreview() {\n\ttry {\n\t\tawait readCatalogPair({ ensureWorking: true });\n\t\tawait promoteWorkingDraftToRuntime();\n\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\tmessage: `Promoted Angy draft into ${basename(getTranslationHelperConfig().workingPoPath)}`\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof CatalogIntegrityError) {\n\t\t\treturn json(\n\t\t\t\t{\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: error.message,\n\t\t\t\t\tcode: \"catalog_integrity_error\",\n\t\t\t\t\tissues: error.issues\n\t\t\t\t},\n\t\t\t\t{ status: 409 }\n\t\t\t);\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\nexport async function handleRotatePreflight() {\n\ttry {\n\t\tconst preflight = await getRotationPreflight();\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\tsafe: preflight.safe,\n\t\t\tstatus: preflight.status,\n\t\t\taffected: preflight.affected\n\t\t});\n\t} catch (error) {\n\t\tif (error instanceof CatalogIntegrityError) {\n\t\t\treturn json(\n\t\t\t\t{\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: error.message,\n\t\t\t\t\tcode: \"catalog_integrity_error\",\n\t\t\t\t\tissues: error.issues\n\t\t\t\t},\n\t\t\t\t{ status: 409 }\n\t\t\t);\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\nexport async function handleRotateCatalogs(request: Request) {\n\tconst data = await request.json().catch(() => null);\n\tconst confirmDestructive = data?.confirmDestructive === true;\n\tconst preflight = await getRotationPreflight();\n\n\tif (!preflight.safe && !confirmDestructive) {\n\t\treturn json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Catalog rotation would overwrite working-only translations. Confirm rotation explicitly to continue.\",\n\t\t\t\tcode: \"rotation_confirmation_required\",\n\t\t\t\tstatus: preflight.status,\n\t\t\t\taffected: preflight.affected\n\t\t\t},\n\t\t\t{ status: 409 }\n\t\t);\n\t}\n\n\tconst result = await rotateCatalogs({ allowOutOfSync: confirmDestructive });\n\n\tif (!result.ok) {\n\t\treturn json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: result.error,\n\t\t\t\tstatus: \"status\" in result ? result.status : undefined,\n\t\t\t\taffected: \"affected\" in result ? result.affected : undefined\n\t\t\t},\n\t\t\t{ status: \"status\" in result && result.status === \"out_of_sync\" ? 409 : 400 }\n\t\t);\n\t}\n\n\treturn json({\n\t\tsuccess: true,\n\t\tmessage: \"Catalogs rotated\",\n\t\tbasePoPath: result.basePoPath,\n\t\tworkingPoPath: result.workingPoPath,\n\t\tbaseBackupPath: result.baseBackupPath,\n\t\tworkingBackupPath: result.workingBackupPath\n\t});\n}\n", "import { constants as fsConstants } from \"node:fs\";\nimport { access, copyFile, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, extname, join, basename } from \"node:path\";\nimport gettextParser from \"gettext-parser\";\nimport Fuse from \"fuse.js\";\nimport type {\n\tCatalogIntegrityIssue,\n\tNormalizedEntry,\n\tPoTranslationEntry,\n\tRotationImpactItem,\n\tTranslationOrigin,\n\tTranslationStatus\n} from \"./types.ts\";\nimport { getTranslationHelperConfig, suspendWorkingCatalogWatch } from \"./config.ts\";\n\nexport const runtimeTranslations = new Map<string, string>();\n\nexport class CatalogIntegrityError extends Error {\n\tissues: CatalogIntegrityIssue[];\n\n\tconstructor(message: string, issues: CatalogIntegrityIssue[]) {\n\t\tsuper(message);\n\t\tthis.name = \"CatalogIntegrityError\";\n\t\tthis.issues = issues;\n\t}\n}\n\ntype CatalogPair = {\n\tbaseEntries: NormalizedEntry[];\n\tworkingEntries: NormalizedEntry[];\n\tbaseMap: Map<string, NormalizedEntry>;\n\tworkingMap: Map<string, NormalizedEntry>;\n\trotationImpact: RotationImpactItem[];\n};\n\nexport function catalogEntryKey(msgid: string, msgctxt: string | null) {\n\treturn `${msgctxt ?? \"\"}::${msgid}`;\n}\n\r\nexport function normalizeWhitespace(value: string): string {\r\n\treturn value.replace(/\\s+/g, \" \").trim();\r\n}\r\n\r\nexport function normalizeForLookup(value: string): string {\r\n\treturn normalizeWhitespace(value)\r\n\t\t.replace(/<\\/?[a-z][^>]*>/gi, \"<x>\")\r\n\t\t.replace(/<\\/?\\d+>/g, \"<x>\")\r\n\t\t.replace(/\\{\\{?\\s*[^}]+\\s*\\}?\\}/g, \"{0}\")\r\n\t\t.replace(/\\{\\d+\\}/g, \"{0}\")\r\n\t\t.replace(/[\"\"'`\u00C2\u00B4]/g, \"'\")\r\n\t\t.toLowerCase();\r\n}\r\n\r\nexport function tokenizeForLookup(value: string): string[] {\r\n\treturn normalizeForLookup(value)\r\n\t\t.split(/[\\s,.;:!?()[\\]{}]+/)\r\n\t\t.map((token) => token.trim())\r\n\t\t.filter(Boolean);\r\n}\r\n\r\nexport function buildLookupVariants(raw: string): string[] {\r\n\tconst normalized = normalizeForLookup(raw);\r\n\tconst variants = new Set<string>([normalized]);\r\n\r\n\tvariants.add(normalized.replace(/<x>/g, \"<0>\"));\r\n\tvariants.add(normalized.replace(/<x>/g, \"\").replace(/\\s+/g, \" \").trim());\r\n\tvariants.add(normalized.replace(/\\{0\\}/g, \"\").replace(/\\s+/g, \" \").trim());\r\n\r\n\treturn [...variants].filter(Boolean);\r\n}\r\n\r\nexport function flattenPoEntries(parsed: any, translationOrigin: TranslationOrigin): NormalizedEntry[] {\r\n\tconst entries: NormalizedEntry[] = [];\r\n\tconst translations = parsed?.translations ?? {};\r\n\r\n\tfor (const [ctxKey, group] of Object.entries(translations)) {\r\n\t\tfor (const [msgidKey, raw] of Object.entries(group as Record<string, unknown>)) {\r\n\t\t\tif (!msgidKey) continue;\r\n\r\n\t\t\tconst entry = raw as PoTranslationEntry;\r\n\t\t\tconst msgid = entry.msgid ?? msgidKey;\r\n\t\t\tconst msgctxt = entry.msgctxt ?? (ctxKey === \"\" ? null : ctxKey);\r\n\t\t\tconst msgidPlural = entry.msgid_plural ?? null;\r\n\t\t\tconst msgstr = Array.isArray(entry.msgstr) ? entry.msgstr.filter(Boolean) : [];\r\n\t\t\tconst references = entry.comments?.reference\r\n\t\t\t\t? entry.comments.reference.split(\"\\n\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst extractedComments = entry.comments?.extracted\r\n\t\t\t\t? entry.comments.extracted.split(\"\\n\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst flags = entry.comments?.flag\r\n\t\t\t\t? entry.comments.flag.split(\",\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst previous = entry.comments?.previous\r\n\t\t\t\t? entry.comments.previous.split(\"\\n\").map((item) => item.trim()).filter(Boolean)\r\n\t\t\t\t: [];\r\n\t\t\tconst translated = entry.msgstr?.some((item) => item.trim().length > 0) ?? false;\r\n\t\t\tconst fuzzy = entry.comments?.flag?.includes(\"fuzzy\");\r\n\r\n\t\t\tentries.push({\r\n\t\t\t\tmsgid,\r\n\t\t\t\tmsgctxt,\r\n\t\t\t\tmsgidPlural,\r\n\t\t\t\tmsgstr,\r\n\t\t\t\treferences,\r\n\t\t\t\textractedComments,\r\n\t\t\t\tflags,\r\n\t\t\t\tprevious,\r\n\t\t\t\tobsolete: Boolean(entry.obsolete),\r\n\t\t\t\tsearchText: normalizeForLookup(msgid),\r\n\t\t\t\tsearchTokens: tokenizeForLookup(msgid),\r\n\t\t\t\tisFuzzy: fuzzy,\r\n\t\t\t\thasTranslation: translated,\r\n\t\t\t\ttranslationOrigin\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\treturn entries;\r\n}\r\n\r\nexport function createFuse(entries: NormalizedEntry[]) {\r\n\treturn new Fuse(entries, {\r\n\t\tincludeScore: true,\r\n\t\tignoreLocation: true,\r\n\t\tthreshold: 0.34,\r\n\t\tminMatchCharLength: 2,\r\n\t\tkeys: [\r\n\t\t\t{ name: \"msgid\", weight: 0.7 },\r\n\t\t\t{ name: \"searchText\", weight: 0.2 },\r\n\t\t\t{ name: \"references\", weight: 0.1 }\r\n\t\t]\r\n\t});\r\n}\r\n\r\nexport function buildEntryMap(entries: NormalizedEntry[]) {\n\treturn new Map(entries.map((entry) => [catalogEntryKey(entry.msgid, entry.msgctxt), entry]));\n}\n\nexport function getEntryValue(entry?: Pick<NormalizedEntry, \"msgstr\"> | null) {\n\tif (!entry?.msgstr?.length) return \"\";\n\treturn entry.msgstr.find((item) => item.trim().length > 0)?.trim() ?? \"\";\n}\n\nexport function applyWorkingState(\n\tbaseEntry: NormalizedEntry,\n\tworkingEntry?: NormalizedEntry\n): NormalizedEntry {\n\tif (!workingEntry) {\r\n\t\treturn baseEntry;\r\n\t}\r\n\r\n\treturn {\r\n\t\t...baseEntry,\r\n\t\tmsgstr: workingEntry.msgstr,\r\n\t\tflags: workingEntry.flags,\r\n\t\tprevious: workingEntry.previous,\r\n\t\tobsolete: workingEntry.obsolete,\r\n\t\thasTranslation: workingEntry.hasTranslation,\r\n\t\tisFuzzy: workingEntry.isFuzzy,\r\n\t\ttranslationOrigin: workingEntry.translationOrigin\r\n\t};\r\n}\r\n\r\nexport async function fileExists(path: string) {\r\n\ttry {\r\n\t\tawait access(path, fsConstants.F_OK);\r\n\t\treturn true;\r\n\t} catch {\r\n\t\treturn false;\r\n\t}\r\n}\r\n\r\nexport async function readCatIndex(catalog: TranslationOrigin) {\n\tconst { basePoPath } = getTranslationHelperConfig();\n\tlet path = \"\";\n\n\tif (catalog === \"base\") {\n\t\tpath = basePoPath;\n\t} else {\n\t\tpath = await getEffectiveWorkingPoPath();\n\t\tconst exists = await fileExists(path);\n\t\tif (!exists) return null;\n\t}\n\r\n\tconst raw = await readFile(path);\r\n\tconst parsed = gettextParser.po.parse(raw);\r\n\tconst entries = flattenPoEntries(parsed, catalog);\r\n\r\n\treturn {\r\n\t\tentries,\r\n\t\tfuse: createFuse(entries)\r\n\t};\r\n}\r\n\r\nexport async function readParsedCatalog(catalog: TranslationOrigin) {\n\tconst { basePoPath } = getTranslationHelperConfig();\n\tconst path = catalog === \"base\" ? basePoPath : await getEffectiveWorkingPoPath();\n\r\n\tif (catalog === \"working\") {\r\n\t\tconst exists = await fileExists(path);\r\n\t\tif (!exists) return null;\r\n\t}\r\n\r\n\tconst raw = await readFile(path);\r\n\treturn gettextParser.po.parse(raw);\r\n}\r\n\r\nexport async function ensureWorkingCatalog() {\n\tconst { basePoPath, workingPoPath } = getTranslationHelperConfig();\n\tconst exists = await fileExists(workingPoPath);\n\tif (!exists) {\n\t\tawait copyFile(basePoPath, workingPoPath);\n\t}\n}\n\nexport function getWorkingDraftPoPath() {\n\tconst { workingPoPath } = getTranslationHelperConfig();\n\tconst extension = extname(workingPoPath);\n\tconst stem = workingPoPath.slice(0, workingPoPath.length - extension.length);\n\treturn `${stem}.angy-draft${extension}`;\n}\n\nasync function getEffectiveWorkingPoPath() {\n\tconst draftPoPath = getWorkingDraftPoPath();\n\tif (await fileExists(draftPoPath)) {\n\t\treturn draftPoPath;\n\t}\n\n\treturn getTranslationHelperConfig().workingPoPath;\n}\n\nexport async function ensureWorkingDraftCatalog() {\n\tawait ensureWorkingCatalog();\n\n\tconst { workingPoPath } = getTranslationHelperConfig();\n\tconst draftPoPath = getWorkingDraftPoPath();\n\tconst exists = await fileExists(draftPoPath);\n\tif (!exists) {\n\t\tawait copyFile(workingPoPath, draftPoPath);\n\t}\n}\n\r\nexport function removeFuzzyFlag(flagString?: string) {\r\n\tif (!flagString) return \"\";\r\n\r\n\treturn flagString\r\n\t\t.split(\",\")\r\n\t\t.map((item) => item.trim())\r\n\t\t.filter(Boolean)\r\n\t\t.filter((item) => item !== \"fuzzy\")\r\n\t\t.join(\", \");\r\n}\r\n\r\nexport async function writeWorkingCatalog(parsed: any) {\n\tawait ensureWorkingDraftCatalog();\n\tconst draftPoPath = getWorkingDraftPoPath();\n\tconst compiled = gettextParser.po.compile(parsed);\n\tawait writeFile(draftPoPath, compiled);\n}\n\nexport async function promoteWorkingDraftToRuntime() {\n\tawait ensureWorkingDraftCatalog();\n\n\tconst { workingPoPath } = getTranslationHelperConfig();\n\tconst draftPoPath = getWorkingDraftPoPath();\n\tconst publishPath = `${workingPoPath}.angy-publish`;\n\tconst compiled = await readFile(draftPoPath);\n\n\tsuspendWorkingCatalogWatch(workingPoPath);\n\tawait writeFile(publishPath, compiled);\n\tawait rm(workingPoPath, { force: true });\n\tawait rename(publishPath, workingPoPath);\n}\n\nexport function collectCatalogIntegrityIssues(\n\tbaseEntries: NormalizedEntry[],\n\tworkingEntries: NormalizedEntry[]\n) {\n\tconst issues: CatalogIntegrityIssue[] = [];\n\tconst baseMap = buildEntryMap(baseEntries);\n\tconst workingMap = buildEntryMap(workingEntries);\n\n\tfor (const baseEntry of baseEntries) {\n\t\tconst key = catalogEntryKey(baseEntry.msgid, baseEntry.msgctxt);\n\t\tconst workingEntry = workingMap.get(key);\n\t\tif (!workingEntry) {\n\t\t\tissues.push({\n\t\t\t\ttype: \"key_mismatch\",\n\t\t\t\tmsgid: baseEntry.msgid,\n\t\t\t\tmsgctxt: baseEntry.msgctxt,\n\t\t\t\treason: \"missing_in_working\"\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst baseValue = getEntryValue(baseEntry);\n\t\tconst workingValue = getEntryValue(workingEntry);\n\t\tif (baseValue && !workingValue) {\n\t\t\tissues.push({\n\t\t\t\ttype: \"missing_working_translation\",\n\t\t\t\tmsgid: baseEntry.msgid,\n\t\t\t\tmsgctxt: baseEntry.msgctxt,\n\t\t\t\tbaseValue\n\t\t\t});\n\t\t}\n\t}\n\n\tfor (const workingEntry of workingEntries) {\n\t\tconst key = catalogEntryKey(workingEntry.msgid, workingEntry.msgctxt);\n\t\tif (!baseMap.has(key)) {\n\t\t\tissues.push({\n\t\t\t\ttype: \"key_mismatch\",\n\t\t\t\tmsgid: workingEntry.msgid,\n\t\t\t\tmsgctxt: workingEntry.msgctxt,\n\t\t\t\treason: \"missing_in_base\"\n\t\t\t});\n\t\t}\n\t}\n\n\treturn issues;\n}\n\nexport function assertCatalogIntegrity(baseEntries: NormalizedEntry[], workingEntries: NormalizedEntry[]) {\n\tconst issues = collectCatalogIntegrityIssues(baseEntries, workingEntries);\n\tif (issues.length) {\n\t\tthrow new CatalogIntegrityError(\n\t\t\t\"Working catalog is out of sync with the base catalog. Regenerate or replace the working catalog before using Angy.\",\n\t\t\tissues\n\t\t);\n\t}\n}\n\nexport function collectRotationImpact(\n\tbaseEntries: NormalizedEntry[],\n\tworkingMap: Map<string, NormalizedEntry>\n) {\n\tconst impacted: RotationImpactItem[] = [];\n\n\tfor (const baseEntry of baseEntries) {\n\t\tconst workingEntry = workingMap.get(catalogEntryKey(baseEntry.msgid, baseEntry.msgctxt));\n\t\tif (!workingEntry) continue;\n\n\t\tconst baseValue = getEntryValue(baseEntry);\n\t\tconst workingValue = getEntryValue(workingEntry);\n\t\tif (!workingValue) continue;\n\t\tif (baseValue === workingValue) continue;\n\n\t\timpacted.push({\n\t\t\tmsgid: baseEntry.msgid,\n\t\t\tmsgctxt: baseEntry.msgctxt,\n\t\t\tbaseValue,\n\t\t\tworkingValue\n\t\t});\n\t}\n\n\treturn impacted;\n}\n\nexport function resolveTranslationState(\n\tbaseEntry: NormalizedEntry,\n\tworkingEntry?: NormalizedEntry\n) {\n\tconst baseValue = getEntryValue(baseEntry);\n\tconst workingValue = getEntryValue(workingEntry);\n\tconst activeEntry = workingEntry && workingValue ? workingEntry : baseEntry;\n\tconst fuzzy = Boolean(activeEntry.isFuzzy);\n\tlet translationOrigin: TranslationOrigin = \"base\";\n\tlet translationStatus: TranslationStatus = \"none\";\n\tlet effectiveEntry = baseEntry;\n\n\tif (workingEntry && workingValue) {\n\t\teffectiveEntry = workingEntry;\n\t\tif (!baseValue || workingValue !== baseValue) {\n\t\t\ttranslationOrigin = \"working\";\n\t\t\ttranslationStatus = \"working\";\n\t\t} else {\n\t\t\ttranslationOrigin = \"base\";\n\t\t\ttranslationStatus = \"base\";\n\t\t}\n\t} else if (baseValue) {\n\t\teffectiveEntry = baseEntry;\n\t\ttranslationOrigin = \"base\";\n\t\ttranslationStatus = \"base\";\n\t}\n\n\tif (fuzzy) {\n\t\ttranslationStatus = \"fuzzy\";\n\t}\n\n\treturn {\n\t\teffectiveEntry,\n\t\tbaseValue,\n\t\tworkingValue,\n\t\ttranslationOrigin,\n\t\ttranslationStatus,\n\t\thasTranslation: Boolean(getEntryValue(effectiveEntry)),\n\t\tisFuzzy: fuzzy\n\t};\n}\n\nexport async function readCatalogPair(options?: { ensureWorking?: boolean }): Promise<CatalogPair> {\n\tif (options?.ensureWorking) {\n\t\tawait ensureWorkingCatalog();\n\t}\n\n\tconst [baseParsed, workingParsed] = await Promise.all([\n\t\treadParsedCatalog(\"base\"),\n\t\treadParsedCatalog(\"working\")\n\t]);\n\n\tif (!baseParsed || !workingParsed) {\n\t\tthrow new Error(\"Unable to load base and working catalogs.\");\n\t}\n\n\tconst baseEntries = flattenPoEntries(baseParsed, \"base\");\n\tconst workingEntries = flattenPoEntries(workingParsed, \"working\");\n\tassertCatalogIntegrity(baseEntries, workingEntries);\n\n\tconst baseMap = buildEntryMap(baseEntries);\n\tconst workingMap = buildEntryMap(workingEntries);\n\tconst rotationImpact = collectRotationImpact(baseEntries, workingMap);\n\n\treturn {\n\t\tbaseEntries,\n\t\tworkingEntries,\n\t\tbaseMap,\n\t\tworkingMap,\n\t\trotationImpact\n\t};\n}\n\nexport async function getRotationPreflight() {\n\tconst { rotationImpact } = await readCatalogPair({ ensureWorking: true });\n\n\treturn {\n\t\tsafe: true as const,\n\t\tstatus: \"ok\" as const,\n\t\taffected: rotationImpact\n\t};\n}\n\nfunction timestampForBackup() {\n\treturn new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nfunction buildBackupPath(path: string, label: string) {\n\tconst directory = dirname(path);\n\tconst extension = extname(path);\n\tconst stem = basename(path, extension);\n\treturn join(directory, `${stem}.${label}.${timestampForBackup()}${extension}`);\n}\n\nexport async function rotateCatalogs(options?: { allowOutOfSync?: boolean }) {\n\tconst { basePoPath, workingPoPath } = getTranslationHelperConfig();\n\tconst draftPoPath = getWorkingDraftPoPath();\n\tconst effectiveWorkingPoPath = await getEffectiveWorkingPoPath();\n\tconst workingExists = await fileExists(effectiveWorkingPoPath);\n\n\tif (!workingExists) {\n\t\treturn { ok: false as const, error: \"Working catalog does not exist\" };\n\t}\n\n\tconst baseBackupPath = buildBackupPath(basePoPath, \"base-backup\");\n\tconst workingBackupPath = buildBackupPath(workingPoPath, \"working-backup\");\n\n\tawait copyFile(basePoPath, baseBackupPath);\n\tawait copyFile(effectiveWorkingPoPath, workingBackupPath);\n\tawait copyFile(effectiveWorkingPoPath, basePoPath);\n\tawait copyFile(basePoPath, workingPoPath);\n\tawait copyFile(workingPoPath, draftPoPath);\n\n\treturn {\n\t\tok: true as const,\n\t\tbasePoPath,\n\t\tworkingPoPath,\n\t\tbaseBackupPath,\n\t\tworkingBackupPath\n\t};\n}\n", "import { readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, extname, isAbsolute, normalize, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { pathToFileURL } from \"node:url\";\nimport { transform } from \"esbuild\";\nimport type { TranslationContextResult } from \"../client/toggleQA.shared\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst CONFIG_FILENAMES = [\n\t\"angy.config.ts\",\n\t\"angy.config.js\",\n\t\"angy.config.mjs\",\n\t\"angy.config.cjs\"\n];\n\nexport type TranslationHelperConfig = {\n\tbasePoPath: string;\n\tworkingPoPath: string;\n\tsourceLocale: string;\n\ttargetLocale: string;\n\troutePath: string;\n\tapiKey: string;\n\tsystemMessage: string;\n\tsuggestionModel: string;\n\twatchIgnore: string[];\n\tsuggestionProvider?: SuggestionProvider;\n};\n\nexport type SuggestionRequestItem = {\n\tmsgid: string;\n\tmsgctxt: string | null;\n};\n\nexport type SuggestionResponseItem = {\n\tmsgid: string;\n\tmsgctxt: string | null;\n\tsuggestion: string;\n};\n\nexport type SuggestionProviderInput = {\n\tcontext: TranslationContextResult;\n\titems: SuggestionRequestItem[];\n\tsourceLocale: string;\n\ttargetLocale: string;\n\tsystemMessage: string;\n\tmodel: string;\n\tapiKey: string | undefined;\n};\n\nexport type SuggestionProvider = (\n\tinput: SuggestionProviderInput\n) => Promise<SuggestionResponseItem[]>;\n\nexport type TranslationHelperUserConfig = Partial<TranslationHelperConfig>;\n\nexport type AngyConfigInput = {\n\tbasePoPath: string;\n\tworkingPoPath: string;\n\tsourceLocale: string;\n\ttargetLocale: string;\n\troutePath?: string;\n\tapiKey?: string;\n\tsystemMessage?: string;\n\tsuggestionModel?: string;\n\twatchIgnore?: string[];\n\tsuggestionProvider?: SuggestionProvider;\n};\n\nexport function buildDefaultSystemMessage(sourceLocale: string, targetLocale: string) {\n\treturn `You are an expert product localization assistant translating ${sourceLocale} UI copy into polished ${targetLocale}. Keep already-${targetLocale} text unchanged. Preserve placeholders like {0}, {1}, ICU fragments, HTML-like markers such as <0/> and <strong>, line breaks, punctuation, capitalization, and button-like brevity. Prefer terminology and syntax that stay close to the translated examples so the product voice remains cohesive. Do not invent extra context, do not expand abbreviations unless the examples already do, and avoid semantic drift. Return only high-confidence translation suggestions for the provided untranslated strings.`;\n}\n\nfunction assertNonEmptyString(value: unknown, key: string) {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`[angy] ${key} is required and must be a non-empty string.`);\n\t}\n}\n\nfunction validateRoutePath(routePath: unknown) {\n\tif (routePath == null || routePath === \"\") return;\n\tif (typeof routePath !== \"string\" || !routePath.startsWith(\"/\")) {\n\t\tthrow new Error(`[angy] routePath must be an absolute path starting with \"/\".`);\n\t}\n}\n\nfunction validateWatchIgnore(watchIgnore: unknown) {\n\tif (watchIgnore == null) return;\n\tif (!Array.isArray(watchIgnore) || watchIgnore.some((item) => typeof item !== \"string\")) {\n\t\tthrow new Error(`[angy] watchIgnore must be an array of strings.`);\n\t}\n}\n\nfunction validateSuggestionProvider(suggestionProvider: unknown) {\n\tif (suggestionProvider == null) return;\n\tif (typeof suggestionProvider !== \"function\") {\n\t\tthrow new Error(`[angy] suggestionProvider must be a function.`);\n\t}\n}\n\nconst config: TranslationHelperConfig = {\n\tbasePoPath: resolve(__dirname, \"../../locales/en.po\"),\n\tworkingPoPath: resolve(__dirname, \"../../locales/en-working.po\"),\n\tsourceLocale: \"sv\",\n\ttargetLocale: \"en\",\n\troutePath: \"/api/translations\",\n\tapiKey: \"\",\n\tsystemMessage: buildDefaultSystemMessage(\"sv\", \"en\"),\n\tsuggestionModel: \"gpt-4.1-mini\",\n\twatchIgnore: [\"**/en-working.po\"]\n};\n\nlet loadedConfigRoot: string | null = null;\nconst workingCatalogWatchControllers = new Set<(path: string, delayMs?: number) => void>();\n\nexport function configureTranslationHelper(next: Partial<TranslationHelperConfig>) {\n\tObject.assign(config, next);\n}\n\nexport function getTranslationHelperConfig() {\n\treturn config;\n}\n\nfunction normalizeFsPath(path: string) {\n\treturn normalize(path).replace(/\\\\/g, \"/\");\n}\n\nexport function inferLocaleFromCatalogPath(path: string) {\n\tconst fileName = basename(path);\n\tif (!fileName) return null;\n\treturn fileName.slice(0, fileName.length - extname(fileName).length) || null;\n}\n\nfunction resolveLocaleAlias(\n\tvalue: string,\n\tpaths: { basePoPath: string; workingPoPath: string }\n) {\n\tif (value === \"working\") {\n\t\tconst locale = inferLocaleFromCatalogPath(paths.workingPoPath);\n\t\tif (!locale) {\n\t\t\tthrow new Error(\"[angy] Unable to infer locale from workingPoPath.\");\n\t\t}\n\t\treturn locale;\n\t}\n\n\tif (value === \"base\") {\n\t\tconst locale = inferLocaleFromCatalogPath(paths.basePoPath);\n\t\tif (!locale) {\n\t\t\tthrow new Error(\"[angy] Unable to infer locale from basePoPath.\");\n\t\t}\n\t\treturn locale;\n\t}\n\n\treturn value;\n}\n\nfunction validateLocaleAliasUsage(sourceLocale: string, targetLocale: string) {\n\tif (sourceLocale === \"working\") {\n\t\tthrow new Error('[angy] sourceLocale cannot be \"working\". Use an explicit source locale.');\n\t}\n\n\tif (targetLocale === \"base\") {\n\t\tthrow new Error('[angy] targetLocale cannot be \"base\". Use an explicit target locale or \"working\".');\n\t}\n}\n\nfunction validateCatalogPathSemantics(next: TranslationHelperConfig) {\n\tconst baseLocale = inferLocaleFromCatalogPath(next.basePoPath);\n\tconst workingLocale = inferLocaleFromCatalogPath(next.workingPoPath);\n\tconst expectedWorkingLocale = `${next.targetLocale}-working`;\n\n\tif (baseLocale !== next.targetLocale) {\n\t\tthrow new Error(\n\t\t\t`[angy] basePoPath must point to the ${next.targetLocale}.po catalog. Received \"${baseLocale ?? \"unknown\"}\".`\n\t\t);\n\t}\n\n\tif (workingLocale !== expectedWorkingLocale) {\n\t\tthrow new Error(\n\t\t\t`[angy] workingPoPath must point to the ${expectedWorkingLocale}.po catalog. Received \"${workingLocale ?? \"unknown\"}\".`\n\t\t);\n\t}\n}\n\nexport function registerWorkingCatalogWatchController(\n\tcontroller: (path: string, delayMs?: number) => void\n) {\n\tworkingCatalogWatchControllers.add(controller);\n\treturn () => {\n\t\tworkingCatalogWatchControllers.delete(controller);\n\t};\n}\n\nexport function suspendWorkingCatalogWatch(path: string, delayMs = 800) {\n\tconst normalizedPath = normalizeFsPath(path);\n\tfor (const controller of workingCatalogWatchControllers) {\n\t\tcontroller(normalizedPath, delayMs);\n\t}\n}\n\nexport function normalizeTranslationHelperConfig(\n\troot: string,\n\tnext: TranslationHelperUserConfig\n): TranslationHelperUserConfig {\n\tconst normalized = { ...next };\n\n\tif (normalized.basePoPath && !isAbsolute(normalized.basePoPath)) {\n\t\tnormalized.basePoPath = resolve(root, normalized.basePoPath);\n\t}\n\n\tif (normalized.workingPoPath && !isAbsolute(normalized.workingPoPath)) {\n\t\tnormalized.workingPoPath = resolve(root, normalized.workingPoPath);\n\t}\n\n\treturn normalized;\n}\n\nexport function resolveConfiguredLocaleAliases(\n\tnext: TranslationHelperConfig\n): TranslationHelperConfig {\n\tconst rawSourceLocale = next.sourceLocale;\n\tconst rawTargetLocale = next.targetLocale;\n\tconst resolvedSourceLocale = resolveLocaleAlias(rawSourceLocale, next);\n\tconst resolvedTargetLocale = resolveLocaleAlias(rawTargetLocale, next);\n\tconst usesDefaultSystemMessage =\n\t\tnext.systemMessage === buildDefaultSystemMessage(rawSourceLocale, rawTargetLocale);\n\n\tconst resolved = {\n\t\t...next,\n\t\tsourceLocale: resolvedSourceLocale,\n\t\ttargetLocale: resolvedTargetLocale,\n\t\tsystemMessage: usesDefaultSystemMessage\n\t\t\t? buildDefaultSystemMessage(resolvedSourceLocale, resolvedTargetLocale)\n\t\t\t: next.systemMessage\n\t};\n\n\tvalidateCatalogPathSemantics(resolved);\n\treturn resolved;\n}\n\nexport function completeAngyConfig(input: AngyConfigInput): TranslationHelperConfig {\n\tassertNonEmptyString(input.basePoPath, \"basePoPath\");\n\tassertNonEmptyString(input.workingPoPath, \"workingPoPath\");\n\tassertNonEmptyString(input.sourceLocale, \"sourceLocale\");\n\tassertNonEmptyString(input.targetLocale, \"targetLocale\");\n\tvalidateLocaleAliasUsage(input.sourceLocale, input.targetLocale);\n\tif (typeof input.apiKey !== \"string\" && typeof input.apiKey !== \"undefined\") {\n\t\tthrow new Error(`[angy] apiKey must be a string when provided. Use an empty string to disable suggestions.`);\n\t}\n\tvalidateRoutePath(input.routePath);\n\tvalidateWatchIgnore(input.watchIgnore);\n\tvalidateSuggestionProvider(input.suggestionProvider);\n\n\treturn {\n\t\tbasePoPath: input.basePoPath,\n\t\tworkingPoPath: input.workingPoPath,\n\t\tsourceLocale: input.sourceLocale,\n\t\ttargetLocale: input.targetLocale,\n\t\troutePath: input.routePath ?? \"/api/translations\",\n\t\tapiKey: input.apiKey ?? \"\",\n\t\tsystemMessage:\n\t\t\tinput.systemMessage ??\n\t\t\tbuildDefaultSystemMessage(input.sourceLocale, input.targetLocale),\n\t\tsuggestionModel: input.suggestionModel ?? \"gpt-4.1-mini\",\n\t\twatchIgnore: input.watchIgnore ?? [\"**/en-working.po\"],\n\t\tsuggestionProvider: input.suggestionProvider\n\t};\n}\n\nexport function defineAngyConfig(config: AngyConfigInput) {\n\treturn resolveConfiguredLocaleAliases(completeAngyConfig(config));\n}\n\nasync function fileExists(path: string) {\n\ttry {\n\t\tawait readFile(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function loadTsConfigModule(path: string) {\n\tconst source = await readFile(path, \"utf8\");\n\tconst transformed = await transform(source, {\n\t\tloader: \"ts\",\n\t\tformat: \"esm\",\n\t\ttarget: \"es2022\"\n\t});\n\tconst tempPath = `${path}.angy.tmp.mjs`;\n\tawait writeFile(tempPath, transformed.code, \"utf8\");\n\n\ttry {\n\t\treturn await import(/* @vite-ignore */ `${pathToFileURL(tempPath).href}?t=${Date.now()}`);\n\t} finally {\n\t\tawait unlink(tempPath).catch(() => undefined);\n\t}\n}\n\nasync function loadJsConfigModule(path: string) {\n\treturn import(/* @vite-ignore */ pathToFileURL(path).href);\n}\n\nexport async function loadAngyConfigFromRoot(root: string) {\n\tif (loadedConfigRoot === root) {\n\t\treturn config;\n\t}\n\n\tfor (const filename of CONFIG_FILENAMES) {\n\t\tconst fullPath = `${root}/${filename}`.replace(/\\\\/g, \"/\");\n\t\tif (!(await fileExists(fullPath))) continue;\n\n\t\tconst module =\n\t\t\tfilename.endsWith(\".ts\")\n\t\t\t\t? await loadTsConfigModule(fullPath)\n\t\t\t\t: await loadJsConfigModule(fullPath);\n\t\tconst raw = (module.default ?? module.config ?? {}) as TranslationHelperUserConfig;\n\t\tconst next = resolveConfiguredLocaleAliases(\n\t\t\tnormalizeTranslationHelperConfig(root, completeAngyConfig(raw as AngyConfigInput))\n\t\t);\n\t\tconfigureTranslationHelper(next);\n\t\tloadedConfigRoot = root;\n\t\treturn config;\n\t}\n\n\tloadedConfigRoot = root;\n\treturn config;\n}\n", "import { json } from \"@sveltejs/kit\";\nimport {\n\tbuildLookupVariants,\n\tcatalogEntryKey,\n\tcreateFuse,\n\tCatalogIntegrityError,\n\treadCatalogPair,\n\tresolveTranslationState\n} from \"./catalog.ts\";\nimport type { NormalizedEntry } from \"./types.ts\";\n\r\nconst DIRECT_MATCH_LIMIT = 5;\nconst MAX_ALTERNATIVES = 300;\nconst TRANSLATED_TARGET = Math.floor(MAX_ALTERNATIVES * 0.2);\nconst UNTRANSLATED_TARGET = MAX_ALTERNATIVES - TRANSLATED_TARGET;\nconst UNTRANSLATED_RANK_BONUS = 0.03;\n\r\ntype Candidate = {\r\n\tentry: NormalizedEntry;\r\n\tscore: number;\r\n\tvariant: string;\r\n};\r\n\r\ntype ScoredEntry = {\r\n\tentry: NormalizedEntry;\r\n\tscore: number;\r\n\tvariant: string;\r\n};\r\n\r\nexport function entryKey(msgid: string, msgctxt: string | null) {\r\n\treturn catalogEntryKey(msgid, msgctxt);\r\n}\r\n\r\nfunction normalizeCurrentPath(currentPath: string) {\r\n\ttry {\r\n\t\treturn new URL(currentPath, \"http://localhost\").pathname;\r\n\t} catch {\r\n\t\treturn currentPath;\r\n\t}\r\n}\r\n\r\nfunction inferPageReference(currentPath: string) {\r\n\tconst normalizedPath = normalizeCurrentPath(currentPath);\r\n\tif (normalizedPath === \"/\") {\r\n\t\treturn \"src/routes/+page.svelte\";\r\n\t}\r\n\r\n\tconst trimmedPath = normalizedPath.replace(/\\/+$/, \"\");\r\n\treturn `src/routes${trimmedPath}/+page.svelte`;\r\n}\r\n\r\nfunction routeLooksRelevant(routeReference: string, refs: string[], extractedComments: string[]) {\r\n\tif (!routeReference) return false;\r\n\r\n\tconst haystack = [...refs, ...extractedComments].join(\" \").toLowerCase();\r\n\treturn haystack.includes(routeReference.toLowerCase());\r\n}\r\n\r\nfunction dedupeCandidates(candidates: Candidate[]) {\r\n\tconst deduped = new Map<string, Candidate>();\r\n\r\n\tfor (const item of candidates) {\r\n\t\tconst id = entryKey(item.entry.msgid, item.entry.msgctxt);\r\n\t\tconst existing = deduped.get(id);\r\n\t\tif (!existing || item.score < existing.score) {\r\n\t\t\tdeduped.set(id, item);\r\n\t\t}\r\n\t}\r\n\r\n\treturn [...deduped.values()];\r\n}\r\n\r\nfunction rankDirectMatches(candidates: Candidate[], routeReference: string) {\n\treturn [...candidates].sort((left, right) => {\n\t\tconst leftRoute = routeLooksRelevant(\n\t\t\trouteReference,\n\t\t\tleft.entry.references,\r\n\t\t\tleft.entry.extractedComments\r\n\t\t)\r\n\t\t\t? -0.08\r\n\t\t\t: 0;\r\n\t\tconst rightRoute = routeLooksRelevant(\n\t\t\trouteReference,\n\t\t\tright.entry.references,\n\t\t\tright.entry.extractedComments\n\t\t)\n\t\t\t? -0.08\n\t\t\t: 0;\n\t\tconst leftUntranslated = !left.entry.hasTranslation ? -UNTRANSLATED_RANK_BONUS : 0;\n\t\tconst rightUntranslated = !right.entry.hasTranslation ? -UNTRANSLATED_RANK_BONUS : 0;\n\n\t\treturn left.score + leftRoute + leftUntranslated - (right.score + rightRoute + rightUntranslated);\n\t});\n}\n\r\nfunction getReferenceTokens(reference: string) {\r\n\treturn reference\r\n\t\t.toLowerCase()\r\n\t\t.split(/[\\/\\[\\].:_-]+/)\r\n\t\t.map((token) => token.trim())\r\n\t\t.filter(Boolean);\r\n}\r\n\r\nfunction getReferenceSimilarity(reference: string, routeReference: string) {\r\n\tconst referenceTokens = new Set(getReferenceTokens(reference));\r\n\tconst routeTokens = getReferenceTokens(routeReference);\r\n\r\n\tif (!routeTokens.length || !referenceTokens.size) return 0;\r\n\r\n\tlet matches = 0;\r\n\tfor (const token of routeTokens) {\r\n\t\tif (referenceTokens.has(token)) {\r\n\t\t\tmatches += 1;\r\n\t\t}\r\n\t}\r\n\r\n\treturn matches / routeTokens.length;\r\n}\r\n\r\nfunction collectSharedReferenceAlternatives(\n\tentries: NormalizedEntry[],\n\tbestEntry: NormalizedEntry,\n\trouteReference: string,\n\texcludedKeys: Set<string>\n) {\r\n\tconst sharedReferences = new Set(bestEntry.references.map((reference) => reference.toLowerCase()));\r\n\r\n\treturn entries\r\n\t\t.filter((entry) => !excludedKeys.has(entryKey(entry.msgid, entry.msgctxt)))\r\n\t\t.map((entry) => {\r\n\t\t\tconst referenceMatches = entry.references.filter((reference) =>\r\n\t\t\t\tsharedReferences.has(reference.toLowerCase())\r\n\t\t\t);\r\n\t\t\tconst routeMatch = entry.references.some((reference) =>\r\n\t\t\t\treference.toLowerCase().includes(routeReference.toLowerCase())\r\n\t\t\t);\r\n\r\n\t\t\tif (!referenceMatches.length && !routeMatch) {\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\tconst referenceSimilarity = Math.max(\n\t\t\t\t0,\n\t\t\t\t...entry.references.map((reference) => getReferenceSimilarity(reference, routeReference))\n\t\t\t);\n\t\t\tconst untranslatedBonus = !entry.hasTranslation ? 0.35 : 0;\n\n\t\t\treturn {\n\t\t\t\tentry,\n\t\t\t\tscore:\n\t\t\t\t\treferenceMatches.length * 100 +\n\t\t\t\t\t(routeMatch ? 25 : 0) +\n\t\t\t\t\treferenceSimilarity +\n\t\t\t\t\tuntranslatedBonus,\n\t\t\t\tvariant: \"shared-reference\"\n\t\t\t};\n\t\t})\n\t\t.filter((item): item is ScoredEntry => Boolean(item))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction collectRouteFillAlternatives(\n\tentries: NormalizedEntry[],\n\trouteReference: string,\n\texcludedKeys: Set<string>\n) {\n\treturn entries\r\n\t\t.filter((entry) => !excludedKeys.has(entryKey(entry.msgid, entry.msgctxt)))\r\n\t\t.map((entry) => {\r\n\t\t\tconst referenceSimilarity = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\t...entry.references.map((reference) => getReferenceSimilarity(reference, routeReference))\r\n\t\t\t);\r\n\r\n\t\t\tif (referenceSimilarity <= 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst untranslatedBonus = !entry.hasTranslation ? 0.2 : 0;\n\n\t\t\treturn {\n\t\t\t\tentry,\n\t\t\t\tscore: referenceSimilarity + untranslatedBonus,\n\t\t\t\tvariant: \"route-reference\"\n\t\t\t};\n\t\t})\n\t\t.filter((item): item is ScoredEntry => Boolean(item))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction collectTranslatedCohesionAlternatives(\r\n\tdirectMatches: Candidate[],\r\n\texcludedKeys: Set<string>\r\n) {\r\n\treturn directMatches\r\n\t\t.filter((item) => item.entry.hasTranslation)\r\n\t\t.filter((item) => !excludedKeys.has(entryKey(item.entry.msgid, item.entry.msgctxt)))\r\n\t\t.map((item) => ({\r\n\t\t\tentry: item.entry,\r\n\t\t\tscore: 1 - item.score,\r\n\t\t\tvariant: \"translated-cohesion\"\r\n\t\t}))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction collectUntranslatedSimilarityAlternatives(\r\n\tdirectMatches: Candidate[],\r\n\texcludedKeys: Set<string>\r\n) {\r\n\treturn directMatches\r\n\t\t.filter((item) => !item.entry.hasTranslation)\r\n\t\t.filter((item) => !excludedKeys.has(entryKey(item.entry.msgid, item.entry.msgctxt)))\r\n\t\t.map((item) => ({\r\n\t\t\tentry: item.entry,\r\n\t\t\tscore: 1 - item.score,\r\n\t\t\tvariant: \"untranslated-similarity\"\r\n\t\t}))\r\n\t\t.sort((left, right) => right.score - left.score);\r\n}\r\n\r\nfunction buildAlternativePool(\r\n\ttopDirectAlternatives: Candidate[],\r\n\tsharedReferenceAlternatives: ScoredEntry[],\r\n\trouteFillAlternatives: ScoredEntry[],\r\n\ttranslatedCohesionAlternatives: ScoredEntry[],\r\n\tuntranslatedSimilarityAlternatives: ScoredEntry[]\r\n) {\r\n\tconst alternatives: ScoredEntry[] = [...topDirectAlternatives];\r\n\tconst selectedKeys = new Set<string>(\r\n\t\ttopDirectAlternatives.map((item) => entryKey(item.entry.msgid, item.entry.msgctxt))\r\n\t);\r\n\r\n\tlet translatedCount = topDirectAlternatives.filter((item) => item.entry.hasTranslation).length;\r\n\tlet untranslatedCount = topDirectAlternatives.length - translatedCount;\r\n\r\n\tconst tryAdd = (item: ScoredEntry, honorQuota = true) => {\r\n\t\tif (alternatives.length >= MAX_ALTERNATIVES) return false;\r\n\r\n\t\tconst id = entryKey(item.entry.msgid, item.entry.msgctxt);\r\n\t\tif (selectedKeys.has(id)) return false;\r\n\r\n\t\tif (honorQuota) {\r\n\t\t\tif (item.entry.hasTranslation && translatedCount >= TRANSLATED_TARGET) return false;\r\n\t\t\tif (!item.entry.hasTranslation && untranslatedCount >= UNTRANSLATED_TARGET) return false;\r\n\t\t}\r\n\r\n\t\tselectedKeys.add(id);\r\n\t\talternatives.push(item);\r\n\r\n\t\tif (item.entry.hasTranslation) {\r\n\t\t\ttranslatedCount += 1;\r\n\t\t} else {\r\n\t\t\tuntranslatedCount += 1;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t};\r\n\r\n\tconst prioritizedSources = [\r\n\t\tsharedReferenceAlternatives,\r\n\t\trouteFillAlternatives,\r\n\t\tuntranslatedSimilarityAlternatives,\r\n\t\ttranslatedCohesionAlternatives\r\n\t];\r\n\r\n\tfor (const source of prioritizedSources) {\r\n\t\tfor (const item of source) {\r\n\t\t\ttryAdd(item, true);\r\n\t\t}\r\n\t}\r\n\r\n\tif (alternatives.length < MAX_ALTERNATIVES) {\r\n\t\tfor (const source of prioritizedSources) {\r\n\t\t\tfor (const item of source) {\r\n\t\t\t\ttryAdd(item, false);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn alternatives.slice(0, MAX_ALTERNATIVES);\r\n}\r\n\r\nexport async function findTranslationContext(\n\tkey: string,\n\tcurrentPath: string\n) {\n\tconst catalogPair = await readCatalogPair({ ensureWorking: true });\n\tconst effectiveEntries = catalogPair.baseEntries.map((entry) => {\n\t\tconst state = resolveTranslationState(entry, catalogPair.workingMap.get(entryKey(entry.msgid, entry.msgctxt)));\n\t\treturn {\n\t\t\t...state.effectiveEntry,\n\t\t\thasTranslation: state.hasTranslation,\n\t\t\tisFuzzy: state.isFuzzy,\n\t\t\ttranslationOrigin: state.translationOrigin\n\t\t};\n\t});\n\tconst effectiveIndex = {\n\t\tentries: effectiveEntries,\n\t\tfuse: createFuse(effectiveEntries)\n\t};\n\n\tconst routeReference = inferPageReference(currentPath);\n\tconst directMatches = rankDirectMatches(\n\t\tdedupeCandidates(\n\t\t\tbuildLookupVariants(key).flatMap((variant) =>\n\t\t\t\teffectiveIndex.fuse.search(variant, { limit: 180 }).map((hit) => ({\n\t\t\t\t\tentry: hit.item,\n\t\t\t\t\tscore: hit.score ?? 1,\n\t\t\t\t\tvariant\n\t\t\t\t}))\n\t\t\t)\n\t\t),\r\n\t\trouteReference\r\n\t);\r\n\r\n\tconst best = directMatches[0];\r\n\tif (!best || best.score > 0.42) {\n\t\treturn null;\n\t}\n\n\tconst effectiveDirectMatches = directMatches;\n\tconst bestEffective = effectiveDirectMatches[0];\n\tconst topDirectAlternatives = effectiveDirectMatches.slice(1, DIRECT_MATCH_LIMIT);\n\tconst excludedKeys = new Set<string>([\r\n\t\tentryKey(best.entry.msgid, best.entry.msgctxt),\r\n\t\t...topDirectAlternatives.map((item) => entryKey(item.entry.msgid, item.entry.msgctxt))\r\n\t]);\r\n\r\n\tconst sharedReferenceAlternatives = collectSharedReferenceAlternatives(\r\n\t\teffectiveEntries,\r\n\t\tbestEffective.entry,\r\n\t\trouteReference,\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\tconst routeFillAlternatives = collectRouteFillAlternatives(\r\n\t\teffectiveEntries,\r\n\t\trouteReference,\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\tconst translatedCohesionAlternatives = collectTranslatedCohesionAlternatives(\r\n\t\teffectiveDirectMatches.slice(DIRECT_MATCH_LIMIT),\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\tconst untranslatedSimilarityAlternatives = collectUntranslatedSimilarityAlternatives(\r\n\t\teffectiveDirectMatches.slice(DIRECT_MATCH_LIMIT),\r\n\t\texcludedKeys\r\n\t);\r\n\r\n\treturn {\n\t\tbest,\n\t\talternatives: buildAlternativePool(\n\t\t\ttopDirectAlternatives,\r\n\t\t\tsharedReferenceAlternatives,\r\n\t\t\trouteFillAlternatives,\r\n\t\t\ttranslatedCohesionAlternatives,\r\n\t\t\tuntranslatedSimilarityAlternatives\n\t\t),\n\t\trouteReference,\n\t\tbaseMap: catalogPair.baseMap,\n\t\tworkingMap: catalogPair.workingMap,\n\t\tcatalogState: {\n\t\t\tstatus: \"ok\" as const,\n\t\t\taffectedCount: catalogPair.rotationImpact.length\n\t\t}\n\t};\n}\n\nexport function toPublicEntry(\n\tentry: NormalizedEntry,\n\tworkingEntry?: NormalizedEntry\n) {\n\tconst state = resolveTranslationState(entry, workingEntry);\n\n\treturn {\n\t\tmsgid: entry.msgid,\n\t\tmsgctxt: entry.msgctxt,\n\t\tmsgidPlural: entry.msgidPlural,\n\t\tmsgstr: state.effectiveEntry.msgstr,\n\t\treferences: entry.references,\n\t\textractedComments: entry.extractedComments,\n\t\tflags: state.effectiveEntry.flags,\n\t\tprevious: state.effectiveEntry.previous,\n\t\tobsolete: state.effectiveEntry.obsolete,\n\t\thasTranslation: state.hasTranslation,\n\t\tisFuzzy: state.isFuzzy,\n\t\tisCommittedToWorking: state.translationOrigin === \"working\",\n\t\tmatchesTargetTranslation: state.translationOrigin === \"base\" && state.hasTranslation,\n\t\ttranslationOrigin: state.translationOrigin,\n\t\ttranslationStatus: state.translationStatus\n\t};\n}\n\nexport function toPublicAlternative(\n\tentry: NormalizedEntry,\n\tscore: number,\n\tworkingEntry?: NormalizedEntry\n) {\n\tconst state = resolveTranslationState(entry, workingEntry);\n\n\treturn {\n\t\tmsgid: entry.msgid,\n\t\tmsgctxt: entry.msgctxt,\n\t\tscore,\n\t\treferences: entry.references,\n\t\tmsgstr: state.effectiveEntry.msgstr,\n\t\thasTranslation: state.hasTranslation,\n\t\tisFuzzy: state.isFuzzy,\n\t\tisCommittedToWorking: state.translationOrigin === \"working\",\n\t\tmatchesTargetTranslation: state.translationOrigin === \"base\" && state.hasTranslation,\n\t\ttranslationOrigin: state.translationOrigin,\n\t\ttranslationStatus: state.translationStatus\n\t};\n}\n\r\nexport async function handleContext(request: Request) {\r\n\tconst data = await request.formData();\r\n\tconst key = data.get(\"translationKey\")?.toString().trim();\r\n\tconst currentPath = data.get(\"currentPath\")?.toString().trim();\r\n\r\n\tif (!key || !currentPath) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"translationKey and currentPath are required\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\r\n\t\t);\r\n\t}\r\n\r\n\tlet baseFound;\n\ttry {\n\t\tbaseFound = await findTranslationContext(key, currentPath);\n\t} catch (error) {\n\t\tif (error instanceof CatalogIntegrityError) {\n\t\t\treturn json(\n\t\t\t\t{\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: error.message,\n\t\t\t\t\tcode: \"catalog_integrity_error\",\n\t\t\t\t\tissues: error.issues\n\t\t\t\t},\n\t\t\t\t{ status: 409 }\n\t\t\t);\n\t\t}\n\n\t\tthrow error;\n\t}\n\n\tif (!baseFound) {\n\t\treturn json(\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"Translation key context not found\"\r\n\t\t\t},\r\n\t\t\t{ status: 404 }\r\n\t\t);\r\n\t}\r\n\r\n\tconst bestBase =\n\t\tbaseFound.baseMap.get(entryKey(baseFound.best.entry.msgid, baseFound.best.entry.msgctxt)) ??\n\t\tbaseFound.best.entry;\n\tconst bestWorking = baseFound.workingMap.get(entryKey(bestBase.msgid, bestBase.msgctxt));\n\r\n\treturn json({\n\t\tsuccess: true,\n\t\tmatch: {\n\t\t\tscore: baseFound.best.score,\n\t\t\tvia: baseFound.best.variant\n\t\t},\n\t\tcatalogState: baseFound.catalogState,\n\t\tentry: toPublicEntry(bestBase, bestWorking),\n\t\talternatives: baseFound.alternatives.map((item) => {\n\t\t\tconst baseAlt =\n\t\t\t\tbaseFound.baseMap.get(entryKey(item.entry.msgid, item.entry.msgctxt)) ?? item.entry;\n\t\t\tconst workingAlt = baseFound.workingMap.get(entryKey(baseAlt.msgid, baseAlt.msgctxt));\n\t\t\treturn toPublicAlternative(baseAlt, item.score, workingAlt);\n\t\t})\n\t});\n}\n", "import { json } from \"@sveltejs/kit\";\nimport type { TranslationContextResult } from \"../client/toggleQA.shared\";\nimport type { SuggestionRequestItem, SuggestionResponseItem } from \"./config.ts\";\nimport { getTranslationHelperConfig } from \"./config.ts\";\n\r\nfunction getEntriesForSuggestions(contextResult: TranslationContextResult) {\r\n\treturn [contextResult.entry, ...contextResult.alternatives];\r\n}\r\n\r\nfunction getTranslatedExamples(contextResult: TranslationContextResult) {\r\n\treturn getEntriesForSuggestions(contextResult)\r\n\t\t.filter((entry) => entry.hasTranslation && entry.msgstr?.[0])\r\n\t\t.slice(0, 30)\r\n\t\t.map((entry) => ({\r\n\t\t\tmsgid: entry.msgid,\r\n\t\t\tmsgctxt: entry.msgctxt,\r\n\t\t\ttranslation: entry.msgstr[0]\r\n\t\t}));\r\n}\r\n\r\nfunction buildUserMessage(\r\n\tcontextResult: TranslationContextResult,\r\n\titems: SuggestionRequestItem[]\r\n) {\r\n\treturn JSON.stringify(\r\n\t\t{\r\n\t\t\ttask: \"Return translation suggestions for the untranslated UI strings.\",\r\n\t\t\toutput_format: {\r\n\t\t\t\titems: [\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tmsgid: \"source string\",\r\n\t\t\t\t\t\tmsgctxt: \"optional context or null\",\r\n\t\t\t\t\t\tsuggestion: \"translated suggestion\"\r\n\t\t\t\t\t}\r\n\t\t\t\t]\r\n\t\t\t},\r\n\t\t\ttranslated_examples: getTranslatedExamples(contextResult),\r\n\t\t\tuntranslated_items: items\r\n\t\t},\r\n\t\tnull,\r\n\t\t2\r\n\t);\r\n}\r\n\r\nfunction parseSuggestions(responseText: string): SuggestionResponseItem[] {\r\n\ttry {\r\n\t\tconst parsed = JSON.parse(responseText);\r\n\t\tconst items = Array.isArray(parsed?.items) ? parsed.items : [];\r\n\t\treturn items.filter(\r\n\t\t\t(item): item is SuggestionResponseItem =>\r\n\t\t\t\ttypeof item?.msgid === \"string\" &&\r\n\t\t\t\t(item.msgctxt === null || typeof item.msgctxt === \"string\") &&\r\n\t\t\t\ttypeof item?.suggestion === \"string\"\r\n\t\t);\r\n\t} catch {\r\n\t\treturn [];\r\n\t}\r\n}\r\n\r\nexport async function handleSuggestions(request: Request) {\n\tconst {\n\t\tapiKey,\n\t\tsuggestionModel,\n\t\tsystemMessage,\n\t\tsourceLocale,\n\t\ttargetLocale,\n\t\tsuggestionProvider\n\t} = getTranslationHelperConfig();\n\n\tconst data = await request.json().catch(() => null);\n\tconst context = data?.context as TranslationContextResult | undefined;\n\tconst items = Array.isArray(data?.items) ? (data.items as SuggestionRequestItem[]) : [];\n\r\n\tif (!context || !items.length) {\r\n\t\treturn json(\r\n\t\t\t{\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: \"context and items are required\"\r\n\t\t\t},\r\n\t\t\t{ status: 400 }\n\t\t);\n\t}\n\n\tif (suggestionProvider) {\n\t\tconst providedItems = await suggestionProvider({\n\t\t\tcontext,\n\t\t\titems,\n\t\t\tsourceLocale,\n\t\t\ttargetLocale,\n\t\t\tsystemMessage,\n\t\t\tmodel: suggestionModel,\n\t\t\tapiKey\n\t\t});\n\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\titems: providedItems\n\t\t});\n\t}\n\n\tif (!apiKey.trim()) {\n\t\tconsole.warn(\"[angy] Suggestions disabled because apiKey is empty.\");\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\tdisabled: true,\n\t\t\titems: []\n\t\t});\n\t}\n\n\ttry {\n\t\tconsole.info(\"[angy] Suggestion request starting.\", {\n\t\t\tmodel: suggestionModel,\n\t\t\tsourceLocale,\n\t\t\ttargetLocale,\n\t\t\titemCount: items.length,\n\t\t\thasApiKey: Boolean(apiKey.trim())\n\t\t});\n\n\t\tconst response = await fetch(\"https://api.openai.com/v1/responses\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t\t\"content-type\": \"application/json\"\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tmodel: suggestionModel,\n\t\t\t\treasoning: {\n\t\t\t\t\teffort: \"medium\"\n\t\t\t\t},\n\t\t\t\tinput: [\n\t\t\t\t\t{\n\t\t\t\t\t\trole: \"system\",\n\t\t\t\t\t\tcontent: [{ type: \"input_text\", text: systemMessage }]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"input_text\", text: buildUserMessage(context, items) }]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\ttext: {\n\t\t\t\t\tformat: {\n\t\t\t\t\t\ttype: \"json_schema\",\n\t\t\t\t\t\tname: \"translation_suggestions\",\n\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tmsgid: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\t\tmsgctxt: { type: [\"string\", \"null\"] },\n\t\t\t\t\t\t\t\t\t\t\tsuggestion: { type: \"string\" }\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\trequired: [\"msgid\", \"msgctxt\", \"suggestion\"]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\trequired: [\"items\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst errorBody = await response.text().catch(() => \"\");\n\t\t\tconsole.error(\"[angy] Suggestion request failed.\", {\n\t\t\t\tstatus: response.status,\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\tbody: errorBody\n\t\t\t});\n\n\t\t\treturn json(\n\t\t\t\t{\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: `Suggestion request failed: ${response.status}`\n\t\t\t\t},\n\t\t\t\t{ status: 502 }\n\t\t\t);\n\t\t}\n\n\t\tconst responseJson = await response.json();\n\tconst responseText =\n\t\tresponseJson?.output_text ??\n\t\tresponseJson?.output\n\t\t\t?.flatMap((item: any) => item?.content ?? [])\n\t\t\t.find((part: any) => part?.text)?.text ??\n\t\t\"\";\n\n\t\treturn json({\n\t\t\tsuccess: true,\n\t\t\titems: parseSuggestions(responseText)\n\t\t});\n\t} catch (error) {\n\t\tconsole.error(\"[angy] Suggestion request threw.\", error);\n\t\treturn json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Suggestion request failed before reaching the model\"\n\t\t\t},\n\t\t\t{ status: 502 }\n\t\t);\n\t}\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["json", "basename", "readFile", "writeFile", "dirname", "extname", "basename", "config", "fileExists", "fileExists", "readFile", "extname", "writeFile", "dirname", "basename", "basename", "json", "json", "json", "json", "json"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@walkinissue/angy",
3
- "version": "0.2.17",
3
+ "version": "0.2.18",
4
4
  "description": "Dev-only SvelteKit translation helper for in-app PO catalog lookup, staging, and commit flows.",
5
5
  "type": "module",
6
6
  "files": [
@@ -11,6 +11,7 @@
11
11
  "scripts": {
12
12
  "dev": "vite dev",
13
13
  "build": "node ./scripts/build.mjs",
14
+ "test": "npm run build && node --test tests/*.test.mjs",
14
15
  "prepare": "npm run build",
15
16
  "prepack": "npm run build",
16
17
  "preview": "vite preview",
@@ -82,4 +83,3 @@
82
83
  "vite": "^6.0.0"
83
84
  }
84
85
  }
85
-