import { fileURLToPath } from 'node:url'; import { dirname, join, resolve } from 'node:path'; import { readFileSync, readdirSync, existsSync } from 'node:fs'; // 本文件位于 /scripts/lib/paths.mjs → 上溯两级为 monorepo 根 export const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..'); export const HOST_PROJECT = join(ROOT, 'YouleNexus'); export const FRAMEWORK_SRC = join(HOST_PROJECT, 'assets', 'framework'); export const GAMES_DIR = join(ROOT, 'games'); export const SEED_DIR = join(ROOT, 'templates', 'game-seed'); export const BUILD_WORKSPACE = join(ROOT, 'build-workspace'); // 子游戏的皮肤覆盖目录 export function gameOverrideDir(projectDir) { return join(projectDir, 'assets', 'game', 'override'); } // 某工程(宿主真源,或实体化后的临时工作区)的 framework/ui 目录。 // check-skin 与 build-game(composeSkin) 共用同一份推导,不各自拼路径(唯一权威)。 export function frameworkUiDirOf(projectDir) { return join(projectDir, 'assets', 'framework', 'ui'); } export const FRAMEWORK_UI_DIR = frameworkUiDirOf(HOST_PROJECT); export function readCreatorVersion(projectDir) { try { const pkg = JSON.parse(readFileSync(join(projectDir, 'package.json'), 'utf8')); return pkg?.creator?.version ?? null; } catch { return null; } } export function listGameProjects(gamesDir = GAMES_DIR) { if (!existsSync(gamesDir)) return []; return readdirSync(gamesDir, { withFileTypes: true }) .filter((d) => d.isDirectory()) .map((d) => join(gamesDir, d.name)) .filter((dir) => existsSync(join(dir, 'package.json'))); }