/** * # 脚本 收集后台 i18n 键并输出 en 词典草稿 * 扫描后台路由/组件中的 t("…") 静态键 + 动态标签映射键(从 admin-menus / common 导入), * 打印当前 en 词典缺失的键清单(JSON 形式,便于翻译补齐)。 * 运行:bun scripts/collect-admin-i18n.ts [--all] * --all 输出全部键;缺省只输出 en.ts 缺失的键。 */ import { readdirSync } from "node:fs"; import { en } from "../src/admin-i18n/locales/en"; import { ADMIN_MENU_GROUPS } from "../src/admin-menus"; import { CONTENT_TYPE_LABEL, INQUIRY_STATUS_LABEL, ORDER_STATUS_LABEL } from "../src/components/admin/common"; const all = process.argv.includes("--all"); const files = [ ...readdirSync("src/routes").filter((f) => f.startsWith("admin")).map((f) => `src/routes/${f}`), ...readdirSync("src/components/admin").map((f) => `src/components/admin/${f}`), ]; const keyRe = /\bt\(\s*"((?:[^"\\]|\\.)*)"/g; const keys = new Set(); for (const f of files) { const src = await Bun.file(f).text(); for (const m of src.matchAll(keyRe)) keys.add(m[1]!); } // 动态键(label 映射值) const dynamicKeys = [ ...Object.values(ORDER_STATUS_LABEL), ...Object.values(INQUIRY_STATUS_LABEL), ...Object.values(CONTENT_TYPE_LABEL), ...ADMIN_MENU_GROUPS.flatMap((g) => [g.label, ...g.children.map((m) => m.label)]), ]; dynamicKeys.forEach((k) => keys.add(k)); const missing = [...keys].filter((k) => !(k in en)).sort(); const list = all ? [...keys].sort() : missing; console.log(`total keys: ${keys.size}, ${all ? "dump all" : "missing in en"}: ${list.length}`); for (const k of list) console.log(JSON.stringify(k));