Files
ai-device/scripts/generate-voice-aliases.mjs
2026-06-11 16:28:00 +08:00

99 lines
3.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* scripts/generate-voice-aliases.mjs
*
* 读取 intelligent_cabin/config/voice_aliases.yml
* 生成 src/lib/nlu/voice-aliases.gen.ts构建时嵌入运行时无需 HTTP 请求)
*
* 用法:
* node scripts/generate-voice-aliases.mjs
* 或在 package.json 的 prebuild / predev 中调用
*/
import { readFileSync, writeFileSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, "..");
// ── 极简 YAML 解析(只处理本文件的结构,无需外部依赖)────────────────────
function parseSimpleYaml(text) {
const lines = text.split("\n");
const result = {};
let currentKey = null;
let currentListKey = null;
let currentObject = result;
for (const raw of lines) {
const line = raw;
const stripped = raw.trimStart();
if (!stripped || stripped.startsWith("#")) continue;
const indent = raw.length - stripped.length;
// 顶级 keyindent = 0
if (indent === 0 && stripped.endsWith(":")) {
currentKey = stripped.slice(0, -1).trim();
result[currentKey] = {};
currentObject = result[currentKey];
currentListKey = null;
continue;
}
// intent_aliases 下的子 keyindent = 2
if (indent === 2 && stripped.endsWith(":")) {
currentListKey = stripped.slice(0, -1).trim();
if (!Array.isArray(currentObject[currentListKey])) {
currentObject[currentListKey] = [];
}
continue;
}
// list itemsindent = 2 for top-level lists, indent = 4 for nested
if (stripped.startsWith("- ")) {
const value = stripped.slice(2).trim().replace(/^["']|["']$/g, "");
if (indent === 2 && !currentListKey) {
// top-level list under result key
if (!Array.isArray(result[currentKey])) {
result[currentKey] = [];
}
result[currentKey].push(value);
} else if (indent === 4 && currentListKey) {
currentObject[currentListKey].push(value);
}
continue;
}
}
return result;
}
// ── 读取 YAML ────────────────────────────────────────────────────────────────
const yamlPath = resolve(ROOT, "intelligent_cabin/config/voice_aliases.yml");
const raw = readFileSync(yamlPath, "utf8");
const parsed = parseSimpleYaml(raw);
const affirmWords = parsed["affirm_words"] ?? [];
const denyWords = parsed["deny_words"] ?? [];
const cancelWords = parsed["cancel_words"] ?? [];
const intentAliases = parsed["intent_aliases"] ?? {};
// ── 生成 TypeScript ───────────────────────────────────────────────────────────
const ts = `// AUTO-GENERATED — do not edit manually
// Source: intelligent_cabin/config/voice_aliases.yml
// Regenerate: node scripts/generate-voice-aliases.mjs
export const AFFIRM_WORDS: readonly string[] = ${JSON.stringify(affirmWords, null, 2)} as const;
export const DENY_WORDS: readonly string[] = ${JSON.stringify(denyWords, null, 2)} as const;
export const CANCEL_WORDS: readonly string[] = ${JSON.stringify(cancelWords, null, 2)} as const;
export const INTENT_ALIASES: Readonly<Record<string, readonly string[]>> = ${JSON.stringify(intentAliases, null, 2)} as const;
`;
const outPath = resolve(ROOT, "src/lib/nlu/voice-aliases.gen.ts");
writeFileSync(outPath, ts, "utf8");
console.log(`✅ Generated: ${outPath}`);