// admin router manger import { CustomError, Route } from '@kevisual/router'; import { app, runAppRouterFn } from './app.ts'; import { manager, updateNewCode, removeCode, stopCode, startCode } from './dashboard/manager.ts'; import { loadOne } from './dashboard/load.ts'; import { RouterCodeModel } from './models/code.ts'; import { nanoid } from 'nanoid'; import { convertTsToJs as transform } from '../lib/ts2js.ts'; app .route({ path: 'admin', key: 'getRouterList', }) .define(async (ctx) => { // TODO: routerList 可以不暴露 ctx.body = ctx.queryRouter.getList().filter((r) => !r.path.startsWith('admin')); // ctx.body = router.getList().filter((r) => r.path.startsWith('admin')); return ctx; }) .addTo(app); // remove router export const removeRouter = new Route('admin', 'removeRouter'); removeRouter.run = async (ctx) => { const { path, key } = ctx.query; runAppRouterFn('remove', { path, key }); const routerCode = await RouterCodeModel.findOne({ where: { path, key } }); if (routerCode) { const id = routerCode.id; removeCode(id); await RouterCodeModel.destroy({ where: { id } }); } ctx.body = 'success'; return ctx; }; removeRouter.validator = { path: { type: 'string', required: true, }, key: { type: 'string', required: true, }, }; removeRouter.addTo(app); // remove router by id export const removeRouterById = new Route('admin', 'removeRouterById'); removeRouterById.run = async (ctx) => { const { id } = ctx.query; app.router.removeById(id); runAppRouterFn('removeById', id); removeCode(id); await RouterCodeModel.destroy({ where: { id } }); ctx.body = 'success'; return ctx; }; removeRouterById.validator = { id: { type: 'string', required: true, }, }; removeRouterById.addTo(app); // stop router by id export const stopRouterById = new Route('admin', 'stopRouterById'); stopRouterById.run = async (ctx) => { const { id } = ctx.query; runAppRouterFn('removeById', id); const routerCode = await RouterCodeModel.findByPk(id); if (routerCode) { routerCode.active = false; await routerCode.save(); } stopCode(id); ctx.body = 'success'; return ctx; }; stopRouterById.validator = { id: { type: 'string', required: true, }, }; stopRouterById.addTo(app); // start router by id export const startRouterById = new Route('admin', 'startRouterById'); startRouterById.run = async (ctx) => { const { id } = ctx.query; const routerCode = await RouterCodeModel.findByPk(id); console.log('routerCode', id, routerCode.toJSON()); if (routerCode) { routerCode.active = true; await routerCode.save(); startCode(routerCode); } ctx.body = 'success'; return ctx; }; startRouterById.validator = { id: { type: 'string', required: true, }, }; startRouterById.addTo(app); // add or update router export const updateRouter = new Route('admin', 'updateRouter'); updateRouter.run = async (ctx) => { let { path, key, id, code, middleware, type = 'route' } = ctx.query; if (!path && !key) { ctx.body = 'path and key is required'; ctx.code = 500; return ctx; } let codeRouter: RouterCodeModel | null = null; const codeRouteCheck = await RouterCodeModel.findOne({ where: { path, key } }); // 检查是否存在 if (codeRouteCheck && codeRouteCheck.id !== id) { key = `${key}-${nanoid(6)}`; } if (id) { codeRouter = await RouterCodeModel.findByPk(id); codeRouter.path = path; codeRouter.key = key; codeRouter.code = code; codeRouter.middleware = middleware; try { codeRouter.exec = await transform(code); } catch (e) { ctx.body = e.message.toString(); ctx.code = 500; return ctx; } codeRouter.type = type; await codeRouter.save(); } else { try { const exec = await transform(code); const newCodeRouter = new RouterCodeModel({ path, key, code, exec, type, middleware }); await newCodeRouter.save(); codeRouter = newCodeRouter; } catch (e) { console.error('updateRouter', e); throw new CustomError(e.message.toString()); } } const codeOne = await loadOne(codeRouter); updateNewCode(codeOne); ctx.body = 'success'; return ctx; }; updateRouter.addTo(app); app .route({ path: 'admin', key: 'getRouterApi', description: 'get all router api list, and you can use this api to get router detail by path and key', validator: { origin: { type: 'string', required: false, }, }, }) .define(async (ctx) => { const { origin = 'http://localhost:4000' } = ctx.query; // const routerList = router.getList(); // TODO: routerList 可以不暴露 const routerList = ctx.queryRouter.getList(); const apiList = routerList.map((item: any) => { return { path: item.path, key: item.key, query: `${origin}/api/router?path=${item.path}&key=${item.key}`, description: item.description, validator: item.validator, }; }); const apiKeyObject = apiList.reduce((pre: any, cur: any) => { pre[cur.key] = { path: cur.path, key: cur.key, description: cur.description || '', validator: cur.validator || {}, }; return pre; }, {}); ctx.body = { list: apiList, keyObject: apiKeyObject, }; return ctx; }) .addTo(app);