#!/usr/bin/env node import { join } from 'node:path'; import { existsSync } from 'node:fs'; import { pathToFileURL } from 'node:url'; import { FRAMEWORK_UI_DIR, GAMES_DIR, gameOverrideDir } from './lib/paths.mjs'; import { listCoverableAssets, validateOverrides } from './lib/skin.mjs'; /** 校验某子游戏的皮肤覆盖。opts 可注入路径用于测试。 */ export function checkSkin(gameName, opts = {}) { const gamesDir = opts.gamesDir ?? GAMES_DIR; const frameworkUiDir = opts.frameworkUiDir ?? FRAMEWORK_UI_DIR; const projectDir = join(gamesDir, gameName); if (!existsSync(projectDir)) { throw new Error(`找不到子游戏工程:${projectDir}`); } // override 目录不存在 = 该子游戏不换肤,合法 const { matched, errors } = validateOverrides(frameworkUiDir, gameOverrideDir(projectDir)); return { matched, errors, frameworkTotal: listCoverableAssets(frameworkUiDir).length }; } // CLI 入口:有错误则退出码 1 if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { const name = process.argv[2]; if (!name) { console.error('用法: npm run check-skin '); process.exit(1); } const { matched, errors, frameworkTotal } = checkSkin(name); console.log(`皮肤命中 ${matched.length} 处,框架可覆盖资源共 ${frameworkTotal} 个`); if (errors.length === 0) { console.log('OK: override 全部合法。'); process.exit(0); } console.error(`\n发现 ${errors.length} 处问题(子游戏 ${name}):`); for (const e of errors) { console.error(` [${e.code}] ${e.path}\n ${e.message}`); } process.exit(1); }