- packages/core: @aidir/core 底座库(src/pages 页面组件体 1:1 镜像路由树 / kit 站点外壳工厂 / content/blog / scripts) - sites/: 5 个独立 Next.js 网站(ai-stack / launchai / the-ai-ledger / devai-tools / findai) - 每站独立 package.json / next.config / tailwind / messages / .env / 构建 - src/app 约 56 个薄路由文件(re-export 底座页面 + 内联路由段配置 revalidate/dynamic) - src/site/brand.tsx 站点配置 + src/site/home.tsx 站点首页(createMarketingLayout / createHomePage 工厂) - generate-site.mjs: 站点生成器(新增网站 = SITES 加条目,零 Core 修改) - start-all-sites.sh: 一键启动 3001-3005 - next-config.mjs: 底座统一 Next 配置工厂(next-intl + MDX + standalone) - 五站共享同一套 PostgreSQL / Better Auth / Admin(设计文档 §42) - 验证: 5 站 build OK / typecheck OK / 55 路由冒烟 200 / 品牌-内容-截图 差异确认 / 登录-投票-重复检测 e2e PASS
47 lines
1.4 KiB
JavaScript
47 lines
1.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* i18n 键一致性检查:对比 messages/ 下所有语言文件的键集合,
|
|
* 存在差异时打印缺失键并以非零码退出(可挂进 CI)。
|
|
*
|
|
* 用法: pnpm i18n:check
|
|
*/
|
|
import { readFileSync, readdirSync } from "node:fs";
|
|
import { join, dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const messagesDir = join(dirname(fileURLToPath(import.meta.url)), "..", "messages");
|
|
|
|
function flattenKeys(obj, prefix = "") {
|
|
return Object.entries(obj).flatMap(([key, value]) => {
|
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
? flattenKeys(value, path)
|
|
: [path];
|
|
});
|
|
}
|
|
|
|
const files = readdirSync(messagesDir).filter((f) => f.endsWith(".json"));
|
|
const keySets = new Map(
|
|
files.map((f) => [
|
|
f,
|
|
new Set(flattenKeys(JSON.parse(readFileSync(join(messagesDir, f), "utf8")))),
|
|
])
|
|
);
|
|
|
|
const allKeys = new Set([...keySets.values()].flatMap((s) => [...s]));
|
|
let hasError = false;
|
|
|
|
for (const [file, keys] of keySets) {
|
|
const missing = [...allKeys].filter((k) => !keys.has(k));
|
|
if (missing.length > 0) {
|
|
hasError = true;
|
|
console.error(`\n❌ ${file} 缺失 ${missing.length} 个键:`);
|
|
for (const key of missing.sort()) console.error(` - ${key}`);
|
|
}
|
|
}
|
|
|
|
if (hasError) {
|
|
process.exit(1);
|
|
}
|
|
console.log(`✅ i18n 键一致 (${files.join(", ")},共 ${allKeys.size} 个键)`);
|