mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat(i18n): 21-language pipeline, landing/docs/API wiring, landing+API translations
Shared Claude Code translation pipeline (scripts/i18n, no API key) plus Astro/VitePress/Scalar i18n wiring. Landing and API reference translated into all 20 languages; docs i18n wiring + English source anchors. The translated docs markdown (apps/docs/<locale>/**, 3,620 files) follows in a companion PR because it exceeds GitHub's per-PR CI file limit.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
// scripts/i18n/lib/shared-i18n.mjs
|
||||
import { SUPPORTED_LOCALES } from "../../../packages/shared/src/i18n/index.ts";
|
||||
|
||||
/** @returns {string[]} all supported locale codes */
|
||||
export function localeCodes() {
|
||||
return SUPPORTED_LOCALES.map((l) => l.code);
|
||||
}
|
||||
|
||||
/**
|
||||
* The exported const name inside a locale file is the code camel-cased:
|
||||
* "de" -> "de", "pt-BR" -> "ptBR", "zh-CN" -> "zhCN".
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
function exportName(code) {
|
||||
return code.replace(/-([a-z])/gi, (_m, c) => c.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the translated `tools` namespace for a locale:
|
||||
* { [toolId]: { name, description } }.
|
||||
* @param {string} code
|
||||
* @returns {Promise<Record<string, { name: string, description: string }>>}
|
||||
*/
|
||||
export async function loadToolStrings(code) {
|
||||
const mod = await import(`../../../packages/shared/src/i18n/${code}.ts`);
|
||||
const dict = mod[exportName(code)];
|
||||
if (!dict?.tools) throw new Error(`No tools namespace in locale ${code}`);
|
||||
return dict.tools;
|
||||
}
|
||||
Reference in New Issue
Block a user