config.ts•2.21 kB
import type { Config } from './types';
import { promises as fs } from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
// 动态查找项目根目录
async function findRootDir(startDir: string): Promise<string> {
let currentDir = startDir;
while (currentDir !== path.dirname(currentDir)) {
if (await fs.stat(path.join(currentDir, 'package.json')).catch(() => false)) {
return currentDir;
}
currentDir = path.dirname(currentDir);
}
throw new Error('无法找到项目根目录(未找到 package.json)');
}
// 获取当前文件路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 简化的配置验证
const isValidConfig = (data: unknown): data is Config => {
if (!data || typeof data !== 'object') return false;
const config = data as Record<string, unknown>;
const required = [
'workspace',
'network',
'github',
'database',
'brave',
'everything',
'powershell'
];
return required.every(key => key in config);
};
// 配置实例
let config: Config | null = null;
// 配置加载函数
export async function loadConfig(): Promise<Config> {
try {
const rootDir = await findRootDir(__dirname);
const configPath = path.join(rootDir, 'src', 'config.json');
const configContent = await fs.readFile(configPath, 'utf8');
let data;
try {
data = JSON.parse(configContent);
} catch (e) {
throw new Error(`配置文件格式错误: ${configPath}\nJSON 解析失败,请检查语法`);
}
if (!isValidConfig(data)) {
throw new Error('配置文件格式无效,请检查 config.json 中的字段');
}
config = Object.freeze(data);
return config;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
throw new Error('配置文件不存在,请复制 config.example.json 到 config.json 并进行相应配置');
}
throw error;
}
}
// 同步获取配置
export function getConfig(): Config {
if (!config) {
throw new Error('配置未初始化,请先调用 loadConfig()');
}
return config;
}
// 导出 Config 类型
export type { Config };