code-center/src/admin/router.ts

202 lines
5.3 KiB
TypeScript

// 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);