Skip to main content
Glama
db.ts19.3 kB
import 'dotenv/config'; import { promises as fs } from 'fs'; import path from 'path'; import { randomUUID } from 'crypto'; // 数据接口定义 export interface TaskInput { name: string; method: string; url: string; query?: object; headers?: object; body?: object; hopeRes: string; } export interface TaskUpdateInput { name?: string; method?: string; url?: string; query?: object; headers?: object; body?: object; hopeRes?: string; res?: string; review?: string; suggest?: string; isFinish?: boolean; status?: boolean; } export interface ApiResponse<T> { state: number; message: string; data: T | null; } // 测试表数据结构 export interface TestTable { uuid: string; name: string; status: boolean; isFinish: boolean; createTime: string; updatedAt: string; } // 测试任务数据结构 export interface TestTask { uuid: string; testTableUuid: string; name: string; url: string; method: string; query?: object; headers?: object; body?: object; hopeRes: string; res?: string; review?: string; suggest?: string; isFinish: boolean; status: boolean; createTime: string; updatedAt: string; } // JSON数据库类 class JsonDatabase { private dataDir: string; private testTablesFile: string; private testTasksFile: string; constructor() { this.dataDir = path.join(process.cwd(), 'data'); this.testTablesFile = path.join(this.dataDir, '测试表.json'); this.testTasksFile = path.join(this.dataDir, '测试任务.json'); this.initDatabase(); } /** * 初始化数据库,创建数据目录和文件 */ private async initDatabase() { try { // 创建数据目录 await fs.mkdir(this.dataDir, { recursive: true }); // 检查并创建测试表文件 try { await fs.access(this.testTablesFile); } catch { await fs.writeFile(this.testTablesFile, JSON.stringify([], null, 2)); } // 检查并创建测试任务文件 try { await fs.access(this.testTasksFile); } catch { await fs.writeFile(this.testTasksFile, JSON.stringify([], null, 2)); } } catch (error) { console.error('初始化数据库失败:', error); } } /** * 读取测试表数据 */ private async readTestTables(): Promise<TestTable[]> { try { const data = await fs.readFile(this.testTablesFile, 'utf-8'); return JSON.parse(data); } catch (error) { console.error('读取测试表数据失败:', error); return []; } } /** * 写入测试表数据 */ private async writeTestTables(tables: TestTable[]): Promise<void> { try { await fs.writeFile(this.testTablesFile, JSON.stringify(tables, null, 2)); } catch (error) { console.error('写入测试表数据失败:', error); throw error; } } /** * 读取测试任务数据 */ private async readTestTasks(): Promise<TestTask[]> { try { const data = await fs.readFile(this.testTasksFile, 'utf-8'); return JSON.parse(data); } catch (error) { console.error('读取测试任务数据失败:', error); return []; } } /** * 写入测试任务数据 */ private async writeTestTasks(tasks: TestTask[]): Promise<void> { try { await fs.writeFile(this.testTasksFile, JSON.stringify(tasks, null, 2)); } catch (error) { console.error('写入测试任务数据失败:', error); throw error; } } /** * 生成当前时间戳 */ private getCurrentTimestamp(): string { return new Date().toISOString(); } /** * 创建测试计划和任务 */ async createTestPlanWithTasks(planName: string, tasks: Array<TaskInput>): Promise<ApiResponse<{plan: TestTable, tasks: TestTask[]}>> { try { const currentTime = this.getCurrentTimestamp(); // 创建测试计划 const testPlan: TestTable = { uuid: randomUUID(), name: planName, status: true, isFinish: false, createTime: currentTime, updatedAt: currentTime }; // 读取现有测试表 const existingTables = await this.readTestTables(); existingTables.push(testPlan); await this.writeTestTables(existingTables); // 创建测试任务 const createdTasks: TestTask[] = tasks.map(task => ({ uuid: randomUUID(), testTableUuid: testPlan.uuid, name: task.name, method: task.method, url: task.url, query: task.query, headers: task.headers, body: task.body, hopeRes: task.hopeRes, res: undefined, review: undefined, suggest: undefined, isFinish: false, status: true, createTime: currentTime, updatedAt: currentTime })); // 读取现有任务并添加新任务 const existingTasks = await this.readTestTasks(); existingTasks.push(...createdTasks); await this.writeTestTasks(existingTasks); return { state: 1, message: '创建成功', data: { plan: testPlan, tasks: createdTasks } }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '创建失败', data: null }; } } /** * 根据UUID更新任务 */ async updateTaskByUuid(uuid: string, updateData: TaskUpdateInput): Promise<ApiResponse<TestTask>> { try { const tasks = await this.readTestTasks(); const taskIndex = tasks.findIndex(task => task.uuid === uuid); if (taskIndex === -1) { return { state: 0, message: '任务不存在', data: null }; } // 更新任务数据 const updatedTask = { ...tasks[taskIndex], ...updateData, updatedAt: this.getCurrentTimestamp() }; tasks[taskIndex] = updatedTask; await this.writeTestTasks(tasks); return { state: 1, message: '更新成功', data: updatedTask }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '更新失败', data: null }; } } /** * 根据表UUID获取任务列表 */ async getTasksByTableUuid(tableUuid: string): Promise<ApiResponse<TestTask[]>> { try { const tasks = await this.readTestTasks(); const filteredTasks = tasks .filter(task => task.testTableUuid === tableUuid) .sort((a, b) => new Date(a.createTime).getTime() - new Date(b.createTime).getTime()); return { state: 1, message: '查询成功', data: filteredTasks }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '查询失败', data: null }; } } /** * 获取所有测试表或根据UUID获取特定表的任务 */ async getAllTable(uuid?: string): Promise<ApiResponse<TestTable[] | TestTask[]>> { try { if (uuid) { // 先检查测试计划是否存在 const tables = await this.readTestTables(); const tableExists = tables.some(table => table.uuid === uuid); if (!tableExists) { return { state: 0, message: '测试计划不存在', data: null }; } const tasks = await this.readTestTasks(); const filteredTasks = tasks.filter(task => task.testTableUuid === uuid); return { state: 1, message: '查询成功', data: filteredTasks }; } else { const tables = await this.readTestTables(); return { state: 1, message: '查询成功', data: tables }; } } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '查询失败', data: null }; } } /** * 向计划添加任务 */ async addTasksToPlan(uuid: string, tasks: Array<TaskInput>): Promise<ApiResponse<TestTask[]>> { try { const currentTime = this.getCurrentTimestamp(); // 创建新任务 const createdTasks: TestTask[] = tasks.map(task => ({ uuid: randomUUID(), testTableUuid: uuid, name: task.name, method: task.method, url: task.url, query: task.query, headers: task.headers, body: task.body, hopeRes: task.hopeRes, res: undefined, review: undefined, suggest: undefined, isFinish: false, status: true, createTime: currentTime, updatedAt: currentTime })); // 读取现有任务并添加新任务 const existingTasks = await this.readTestTasks(); existingTasks.push(...createdTasks); await this.writeTestTasks(existingTasks); return { state: 1, message: `成功在${uuid}计划表增加任务`, data: createdTasks }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '创建失败', data: null }; } } /** * 批量更新任务总结 */ async updateTaskWithSummary(tasks: Array<{uuid: string, summary: string, suggest?: string}>): Promise<ApiResponse<TestTask[]>> { try { const allTasks = await this.readTestTasks(); const updatedTasks: TestTask[] = []; const currentTime = this.getCurrentTimestamp(); for (const taskUpdate of tasks) { const taskIndex = allTasks.findIndex(task => task.uuid === taskUpdate.uuid); if (taskIndex !== -1) { allTasks[taskIndex] = { ...allTasks[taskIndex], review: taskUpdate.summary, suggest: taskUpdate.suggest || undefined, isFinish: true, status: true, updatedAt: currentTime }; updatedTasks.push(allTasks[taskIndex]); } } await this.writeTestTasks(allTasks); return { state: 1, message: `成功为${tasks.length}个任务添加总结`, data: updatedTasks }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '批量更新失败', data: null }; } } /** * 获取所有测试计划 */ async getAllPlans(): Promise<ApiResponse<TestTable[]>> { try { const tables = await this.readTestTables(); return { state: 1, message: '查询成功', data: tables }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '查询失败', data: null }; } } /** * 根据UUID获取单个测试计划 */ async getTestPlanById(uuid: string): Promise<ApiResponse<TestTable>> { try { const tables = await this.readTestTables(); const table = tables.find(table => table.uuid === uuid); if (!table) { return { state: 0, message: '测试计划不存在', data: null }; } return { state: 1, message: '查询成功', data: table }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '查询失败', data: null }; } } /** * 根据ID获取单个测试计划(别名方法) */ async getPlanById(id: string): Promise<ApiResponse<TestTable>> { return this.getTestPlanById(id); } /** * 删除测试计划(别名方法) */ async deletePlan(id: string): Promise<ApiResponse<boolean>> { return this.deleteTestPlan(id); } /** * 删除测试计划及其相关任务 */ async deleteTestPlan(uuid: string): Promise<ApiResponse<boolean>> { try { const tables = await this.readTestTables(); const tableIndex = tables.findIndex(table => table.uuid === uuid); if (tableIndex === -1) { return { state: 0, message: '测试计划不存在', data: null }; } // 删除测试计划 tables.splice(tableIndex, 1); await this.writeTestTables(tables); // 删除相关任务 const tasks = await this.readTestTasks(); const filteredTasks = tasks.filter(task => task.testTableUuid !== uuid); await this.writeTestTasks(filteredTasks); return { state: 1, message: '删除成功', data: true }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '删除失败', data: null }; } } /** * 获取所有测试任务 */ async getAllTasks(): Promise<ApiResponse<TestTask[]>> { try { const tasks = await this.readTestTasks(); return { state: 1, message: '查询成功', data: tasks }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '查询失败', data: null }; } } /** * 根据UUID获取单个测试任务 */ async getTaskById(uuid: string): Promise<ApiResponse<TestTask>> { try { const tasks = await this.readTestTasks(); const task = tasks.find(task => task.uuid === uuid); if (!task) { return { state: 0, message: '测试任务不存在', data: null }; } return { state: 1, message: '查询成功', data: task }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '查询失败', data: null }; } } /** * 删除测试任务 */ async deleteTask(uuid: string): Promise<ApiResponse<boolean>> { try { const tasks = await this.readTestTasks(); const taskIndex = tasks.findIndex(task => task.uuid === uuid); if (taskIndex === -1) { return { state: 0, message: '测试任务不存在', data: null }; } // 删除任务 tasks.splice(taskIndex, 1); await this.writeTestTasks(tasks); return { state: 1, message: '删除成功', data: true }; } catch (error) { return { state: 0, message: error instanceof Error ? error.message : '删除失败', data: null }; } } } // 创建数据库实例 const jsonDb = new JsonDatabase(); // 导出数据库客户端,保持与原有接口一致 export const dbClient = { createTestPlanWithTasks: jsonDb.createTestPlanWithTasks.bind(jsonDb), updateTaskByUuid: jsonDb.updateTaskByUuid.bind(jsonDb), getTasksByTableUuid: jsonDb.getTasksByTableUuid.bind(jsonDb), getAllTable: jsonDb.getAllTable.bind(jsonDb), addTasksToPlan: jsonDb.addTasksToPlan.bind(jsonDb), updateTaskWithSummary: jsonDb.updateTaskWithSummary.bind(jsonDb), getTestPlanById: jsonDb.getTestPlanById.bind(jsonDb), deleteTestPlan: jsonDb.deleteTestPlan.bind(jsonDb), getAllTasks: jsonDb.getAllTasks.bind(jsonDb), getTaskById: jsonDb.getTaskById.bind(jsonDb), deleteTask: jsonDb.deleteTask.bind(jsonDb), getAllPlans: jsonDb.getAllPlans.bind(jsonDb), getPlanById: jsonDb.getPlanById.bind(jsonDb), deletePlan: jsonDb.deletePlan.bind(jsonDb) };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/FactrueSolin/api-test-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server