Update project and configurations
This commit is contained in:
98
scripts/generate-voice-aliases.mjs
Normal file
98
scripts/generate-voice-aliases.mjs
Normal file
@@ -0,0 +1,98 @@
|
||||
#!/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;
|
||||
|
||||
// 顶级 key(indent = 0)
|
||||
if (indent === 0 && stripped.endsWith(":")) {
|
||||
currentKey = stripped.slice(0, -1).trim();
|
||||
result[currentKey] = {};
|
||||
currentObject = result[currentKey];
|
||||
currentListKey = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
// intent_aliases 下的子 key(indent = 2)
|
||||
if (indent === 2 && stripped.endsWith(":")) {
|
||||
currentListKey = stripped.slice(0, -1).trim();
|
||||
if (!Array.isArray(currentObject[currentListKey])) {
|
||||
currentObject[currentListKey] = [];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// list items(indent = 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}`);
|
||||
Reference in New Issue
Block a user