UNPKG

env-manage-plugin

Version:

A dev env plugin that integrates an Express server with request proxying capabilities.

190 lines (189 loc) 8.94 kB
import { v4 as uuidv4 } from "uuid"; import { DevServerQuerySchema, } from "../types/index.js"; import { AppError } from "../utils/errors.js"; import { devServerLogger } from "../utils/logger.js"; /** * 开发服务器服务类 * 负责处理开发服务器(devServer)的核心业务逻辑,包括增删改查、关联环境校验等操作 * 依赖开发服务器仓库(DevServerRepo)和环境仓库(EnvRepo)实现数据持久化与关联业务处理 */ class DevServerService { /** * 构造函数 - 通过依赖注入初始化仓库实例 * @param devServerRepo - 开发服务器仓库实例,用于devServer数据的持久化操作 * @param envRepo - 环境仓库实例,用于关联环境的校验与操作 */ constructor(devServerRepo, envRepo) { this.devServerRepo = devServerRepo; this.envRepo = envRepo; } /** * 添加新开发服务器 * 1. 校验输入参数合法性 2. 检查服务器URL是否已存在 3. 生成唯一ID 4. 保存新服务器 * @param devServerItem - 待添加的开发服务器信息(不含ID) * @returns {void} * @throws {AppError} 当输入参数不合法时抛出 * @throws {AppError} 当服务器URL已存在时抛出 */ handleAddDevServer(devServerItem) { const validData = devServerItem; devServerLogger.info(validData, "准备添加开发服务器"); // 检查服务器URL是否已存在(URL作为唯一标识) const existingServer = this.devServerRepo.findOneByUrl(validData.devServerUrl); if (existingServer) { throw new AppError(`添加失败,开发服务器【${existingServer.devServerUrl}】已存在`); } // 生成唯一ID并组装完整服务器信息(默认状态为未关联) const newDevServer = { ...validData, id: uuidv4(), }; // 保存开发服务器 this.devServerRepo.addDevServer(newDevServer); devServerLogger.info(newDevServer, "开发服务器添加成功"); } /** * 删除指定开发服务器 * 1. 校验输入参数 2. 检查服务器是否存在 3. 检查是否关联环境(关联则禁止删除) 4. 执行删除 * @param devServerItem - 包含待删除服务器ID的对象 * @returns {void} * @throws {AppError} 当输入参数不合法时抛出 * @throws {AppError} 当服务器不存在时抛出 * @throws {AppError} 当服务器已关联环境时抛出(避免数据关联异常) */ handleDeleteDevServer(devServerItem) { // 参数校验 const { id } = devServerItem; devServerLogger.info(devServerItem, "准备删除开发服务器"); // 检查服务器是否存在 const existingServer = this.devServerRepo.findOneById(devServerItem); if (!existingServer) { throw new AppError(`删除失败,开发服务器【${id}】不存在`); } // 检查服务器是否已关联环境(关联环境时禁止删除,避免环境依赖异常) const linkedEnvs = this.envRepo.findEnvsByDevServerId(id); if (linkedEnvs.length > 0) { throw new AppError(`删除失败,开发服务器【${existingServer.name}】已关联 ${linkedEnvs.length} 个环境,请先解除关联`); } // 执行删除 this.devServerRepo.deleteDevServer(devServerItem); devServerLogger.info(devServerItem, "开发服务器删除成功"); } /** * 更新开发服务器信息 * 1. 校验输入参数 2. 检查服务器是否存在 3. 若更新URL则校验唯一性 4. 执行更新(同步修订号) * @param devServerItem - 包含待更新服务器ID及字段的对象 * @returns {void} * @throws {AppError} 当输入参数不合法时抛出 * @throws {AppError} 当服务器不存在时抛出 * @throws {AppError} 当更新的URL已存在时抛出 */ handleUpdateDevServer(devServerItem) { // 参数校验 const { id } = devServerItem; devServerLogger.info(devServerItem, "准备更新开发服务器"); // 检查服务器是否存在 const existingServer = this.devServerRepo.findOneById({ id }); if (!existingServer) { throw new AppError(`更新失败,开发服务器【${id}】不存在`); } const validData = devServerItem; // 若更新了URL,需校验新URL的唯一性 if (validData.devServerUrl && validData.devServerUrl !== existingServer.devServerUrl) { const conflictServer = this.devServerRepo.findOneByUrl(validData.devServerUrl); if (conflictServer) { throw new AppError(`更新失败,URL【${validData.devServerUrl}】已被其他开发服务器使用`); } } // 组装更新数据(同步元数据修订号) const updatedServer = { ...existingServer, ...validData, }; // 执行更新 this.devServerRepo.update(updatedServer); devServerLogger.info(updatedServer, "开发服务器更新成功"); } /** * 获取所有开发服务器列表 * @returns {DevServerModel[]} 开发服务器信息数组 */ handleGetList() { const list = this.devServerRepo.getAll(); devServerLogger.info(`查询到${list.length}个开发服务器`); return list; } /** * 根据ID查询单个开发服务器 * @param devServer - 包含待查询服务器ID的对象 * @returns {DevServerModel | undefined} 匹配的开发服务器信息(不存在则返回undefined) * @throws {AppError} 当输入参数不合法时抛出 */ findOneById(devServer) { // 参数校验 const validationResult = DevServerQuerySchema.safeParse(devServer); if (!validationResult.success) { throw new AppError(`查询开发服务器失败:参数不合法 - ${JSON.stringify(validationResult.error.issues)}`); } const server = this.devServerRepo.findOneById(validationResult.data); devServerLogger.info(`查询开发服务器【${devServer.id}】结果:${server ? "存在" : "不存在"}`); return server; } /** * 关联开发服务器到环境(更新服务器状态为"linked") * 1. 校验参数 2. 检查服务器/环境是否存在 3. 更新服务器关联状态 * @param devServerId - 开发服务器ID * @param envId - 关联的环境ID * @returns {void} * @throws {AppError} 当参数不合法或资源不存在时抛出 */ handleLinkToEnv(devServerId, envId) { // 校验ID格式(简化校验,实际可通过Schema补充) if (!devServerId || !envId) { throw new AppError("关联失败:开发服务器ID和环境ID不能为空"); } devServerLogger.info(`准备关联开发服务器【${devServerId}】到环境【${envId}】`); // 检查开发服务器是否存在 const devServer = this.devServerRepo.findOneById({ id: devServerId }); if (!devServer) { throw new AppError(`关联失败,开发服务器【${devServerId}】不存在`); } // 检查环境是否存在 const env = this.envRepo.findOneById(envId); if (!env) { throw new AppError(`关联失败,环境【${envId}】不存在`); } // 更新开发服务器状态为"已关联" // this.handleUpdateDevServer({ // id: devServerId, // status: "linked", // linkedEnvId: envId, // 记录关联的环境ID(需确保Schema支持该字段) // }); devServerLogger.info(`开发服务器【${devServerId}】已成功关联到环境【${envId}】`); } /** * 解除开发服务器与环境的关联(更新服务器状态为"unlinked") * @param devServerId - 开发服务器ID * @returns {void} * @throws {AppError} 当服务器不存在或参数不合法时抛出 */ handleUnlinkFromEnv(devServerId) { if (!devServerId) { throw new AppError("解除关联失败:开发服务器ID不能为空"); } devServerLogger.info(`准备解除开发服务器【${devServerId}】的环境关联`); const devServer = this.devServerRepo.findOneById({ id: devServerId }); if (!devServer) { throw new AppError(`解除关联失败,开发服务器【${devServerId}】不存在`); } // 更新服务器状态为"未关联",清空关联的环境ID // this.handleUpdateDevServer({ // id: devServerId, // status: "unlinked", // linkedEnvId: undefined, // }); devServerLogger.info(`开发服务器【${devServerId}】已解除环境关联`); } } export { DevServerService };