import * as fs from "fs"; import * as path from "path"; import { saveRoutesToDb, loadRoutesFromDb, loadServerConfig, saveServerConfig, loadIpRulesFromDb, } from "./db"; import { getActiveRoutes } from "./route-matching"; import { state } from "./state"; import type { AppConfig, RouteApiNameMap, RouteEnabledMap } from "./types"; // 验证mock文件是否存在 export function validateMockFiles(): void { console.log(`[CONFIG] 验证mock文件...`); const missingFiles: Array<{ route: string; filePath: string; fullPath: string; }> = []; const activeRoutes = getActiveRoutes(); for (const [route, filePath] of Object.entries(activeRoutes)) { const fullPath = path.join(__dirname, "..", filePath); if (!fs.existsSync(fullPath)) { missingFiles.push({ route, filePath, fullPath }); console.warn( `[CONFIG] 警告: mock文件不存在 - ${filePath} (用于路由: ${route})`, ); } } if (missingFiles.length > 0) { console.log( `[CONFIG] 缺少 ${missingFiles.length} 个mock文件,请创建这些文件`, ); } else { console.log(`[CONFIG] 所有mock文件验证通过`); } } // 从 SQLite 加载全部配置 export async function loadConfig(): Promise { try { state.config = await loadServerConfig(); const dbMappings = await loadRoutesFromDb(); state.rawRoutes = dbMappings.routes; state.rawRouteStatuses = dbMappings.routeStatuses; state.routeEnabledMap = dbMappings.routeEnabledMap; state.routeApiNameMap = dbMappings.routeApiNameMap; state.ipRules = await loadIpRulesFromDb(); const activeCount = Object.values(state.routeEnabledMap).filter( (v) => v !== false, ).length; console.log( `[CONFIG] 配置已加载(路由 ${activeCount} 条)${state.config.mockEnabled !== false ? "" : "(mock 已关闭,全部走代理)"}`, ); validateMockFiles(); } catch (error) { console.error(`[CONFIG] 加载配置失败:`, error); state.rawRoutes = {}; state.rawRouteStatuses = {}; state.routeEnabledMap = {}; state.routeApiNameMap = {}; state.ipRules = []; state.config = { cacheConfig: true, reloadOnChange: true, defaultContentType: "application/json", proxyPort: 8879, targetHost: "localhost", targetPort: 80, targetHttps: false, }; } } // 保存服务器配置到 SQLite export async function saveConfig(nextConfig: AppConfig): Promise { await saveServerConfig(nextConfig); state.config = nextConfig; } // 保存路由配置到 SQLite 并刷新内存 export async function saveRoutes( routes: Record, routeStatuses: Record, routeEnabledMap: RouteEnabledMap = {}, routeApiNameMap: RouteApiNameMap = {}, ): Promise { await saveRoutesToDb(routes, routeStatuses, routeEnabledMap, routeApiNameMap); const dbMappings = await loadRoutesFromDb(); state.rawRoutes = dbMappings.routes; state.rawRouteStatuses = dbMappings.routeStatuses; state.routeEnabledMap = dbMappings.routeEnabledMap; state.routeApiNameMap = dbMappings.routeApiNameMap; } // 重新从 SQLite 加载全部配置 export async function reloadConfig(): Promise { const oldCount = Object.values(state.routeEnabledMap).filter( (v) => v !== false, ).length; await loadConfig(); const newCount = Object.values(state.routeEnabledMap).filter( (v) => v !== false, ).length; console.log( `[CONFIG] 配置重载完成 (路由数: ${oldCount} -> ${newCount})`, ); }