202 lines
5.3 KiB
TypeScript
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);
|