feat: add code-flow base load

This commit is contained in:
2024-06-25 23:56:12 +08:00
parent 5118891c41
commit 776c1287b8
10 changed files with 261 additions and 132 deletions

View File

@@ -2,9 +2,10 @@ import { router } from '../../modules/router.ts';
import { Route } from '@abearxiong/router';
import { RouterCodeModel, RouterCode } from '../../models/code.ts';
enum CodeStatus {
success = 0,
fail = 1,
export enum CodeStatus {
running = 'running',
stop = 'stop',
fail = 'fail',
}
export type CodeManager = {
@@ -16,11 +17,54 @@ const codeDemoRun = `async function run(ctx) {
ctx.body = 'test js';
return ctx;
}`;
export const loadOne = async (item: RouterCodeModel) => {
const { path, key, id, code, project } = item.toJSON();
try {
const fn: any = new Function(
'ctx',
`
${code}
return run(ctx);
`,
);
// run code
const codeRunRoute = new Route(path, key, { id });
codeRunRoute.run = fn;
router.add(codeRunRoute);
return {
path,
key,
id,
project,
fn,
status: CodeStatus.running,
};
} catch (e) {
console.error('error id:', id, '\n', e);
return {
path,
key,
id,
project,
status: CodeStatus.fail,
errorMsg: e.message.toString(),
};
}
};
export const load = async function () {
const codes = await RouterCodeModel.findAll();
const codeManager: CodeManager[] = codes.map((item) => {
const { path, key, id, code, project } = item.toJSON();
console.log('item', item, 'code', item.code);
const { path, key, id, code, project, active } = item.toJSON();
if (!active) {
return {
path,
key,
id,
code,
project,
status: CodeStatus.stop,
};
}
try {
const fn: any = new Function(
'ctx',
@@ -37,9 +81,11 @@ export const load = async function () {
path,
key,
id,
code,
project,
type: item.type,
fn,
status: CodeStatus.success,
status: CodeStatus.running,
};
} catch (e) {
console.error('error id:', id, '\n', e);
@@ -47,7 +93,9 @@ export const load = async function () {
path,
key,
id,
code,
project,
type: item.type,
status: CodeStatus.fail,
errorMsg: e.message.toString(),
};

View File

@@ -1,5 +1,5 @@
import { EventEmitter, once } from 'stream';
import { load, CodeManager } from './load.ts';
import { load, CodeManager, CodeStatus } from './load.ts';
export enum LoadStatus {
LOADING = 'loading',
@@ -11,6 +11,30 @@ export const manager = {
list: [] as CodeManager[],
};
// 更新
export const updateNewCode = (code: CodeManager) => {
const index = manager.list.findIndex((item) => item.id === code.id);
if (index === -1) {
manager.list.push(code);
} else {
manager.list[index] = code;
}
};
// 删除
export const removeCode = (id: string) => {
const index = manager.list.findIndex((item) => item.id === id);
if (index !== -1) {
manager.list.splice(index, 1);
}
};
export const stopCode = (id: string) => {
const index = manager.list.findIndex((item) => item.id === id);
if (index !== -1) {
manager.list[index].status = CodeStatus.stop;
}
};
// 事件
export const events = new EventEmitter();
once(events, 'loaded')
@@ -26,7 +50,7 @@ once(events, 'loaded')
const init = async function () {
const r = await load();
manager.list = r;
events.emit('loaded');
};

View File

@@ -1,13 +1,16 @@
// admin 需要最后运行并在route中进行过滤。
import { Route } from '@abearxiong/router';
import { router } from '../modules/router.ts';
import { manager } from './dashboard/manager.ts';
import { manager, updateNewCode, removeCode, stopCode } from './dashboard/manager.ts';
import { loadOne } from './dashboard/load.ts';
import { RouterCodeModel } from '../models/code.ts';
import { nanoid } from 'nanoid';
export const getRouterList = new Route('admin', 'getRouterList');
getRouterList.run = async (ctx) => {
ctx.body = router.getList().filter((r) => !r.path.startsWith('admin'));
// ctx.body = router.getList().filter((r) => r.path.startsWith('admin'));
ctx.body = router.getList().filter((r) => r.path.startsWith('admin'));
return ctx;
};
@@ -28,27 +31,56 @@ export const removeRouterById = new Route('admin', 'removeRouterById');
removeRouterById.run = async (ctx) => {
const { id } = ctx.query;
router.removeById(id);
removeCode(id);
await RouterCodeModel.destroy({ where: { id } });
ctx.body = 'success';
return ctx;
};
router.add(removeRouterById);
// add router
export const addRouter = new Route('admin', 'addRouter');
addRouter.run = async (ctx) => {
const { path, key } = ctx.query;
router.add(new Route(path, key));
// stop router by id
export const stopRouterById = new Route('admin', 'stopRouterById');
stopRouterById.run = async (ctx) => {
const { id } = ctx.query;
router.removeById(id);
const routerCode = await RouterCodeModel.findByPk(id);
if (routerCode) {
routerCode.active = false;
await routerCode.save();
}
stopCode(id);
ctx.body = 'success';
return ctx;
};
router.add(addRouter);
// update router
// add or update router
export const updateRouter = new Route('admin', 'updateRouter');
updateRouter.run = async (ctx) => {
const { path, key } = ctx.query;
router.add(new Route(path, key));
let { path, key, id, code } = 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;
await codeRouter.save();
} else {
const newCodeRouter = new RouterCodeModel({ path, key, code });
await newCodeRouter.save();
codeRouter = newCodeRouter;
}
const codeOne = await loadOne(codeRouter);
updateNewCode(codeOne);
ctx.body = 'success';
return ctx;
};
@@ -57,7 +89,10 @@ router.add(updateRouter);
// get manager status
export const managerRouter = new Route('admin', 'getManagerStatus');
managerRouter.run = async (ctx) => {
ctx.body = manager.loaded;
ctx.body = {
status: manager.loaded,
msg: 'system is running, and load manager success.',
};
return ctx;
};
router.add(managerRouter);
@@ -68,4 +103,4 @@ managerList.run = async (ctx) => {
ctx.body = manager.list;
return ctx;
};
router.add(managerList);
router.add(managerList);

View File

@@ -6,7 +6,16 @@ import http from 'http';
const config = useConfig();
routerServer.setHandle(handleMessage);
const server = http.createServer(routerServer.callback());
const server = http.createServer((req, res) => {
// 设置跨域
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Max-Age', '86400');
res.setHeader('Content-Type', 'application/json');
// routerServer.handle(req, res);
return routerServer.callback()(req, res);
});
server.listen(config.port, () => {
console.log(`Server running at http://localhost:${config.port}/`);

View File

@@ -8,15 +8,21 @@ export type RouterCode = {
active: boolean;
project: string;
code: string;
type: RouterCodeType;
};
export enum RouterCodeType {
route = 'route',
middleware = 'middleware',
}
export class RouterCodeModel extends Model {
declare id: string;
path: string;
key: string;
active: boolean;
project: string;
public code: string;
declare path: string;
declare key: string;
declare active: boolean;
declare project: string;
declare code: string;
declare type: RouterCodeType;
}
RouterCodeModel.init(
{
@@ -46,6 +52,18 @@ RouterCodeModel.init(
type: DataTypes.STRING,
defaultValue: '',
},
type: {
type: DataTypes.ENUM(RouterCodeType.route, RouterCodeType.middleware),
defaultValue: RouterCodeType.route,
},
middleware: {
type: DataTypes.ARRAY(DataTypes.STRING),
defaultValue: [],
},
next: {
type: DataTypes.STRING,
defaultValue: '',
},
},
{
sequelize,
@@ -53,3 +71,4 @@ RouterCodeModel.init(
},
);
// RouterCodeModel.sync({ alter: true });
// RouterCodeModel.sync({force: true});

View File

@@ -41,13 +41,9 @@ User.init(
export const initializeUser = async () => {
const w = await User.findOne();
const password = '2e8a305521bba54f49638ed25e46adf3';
const password = '2e8a305521bba54f49638ed25e46adf3'; //123456
const salt = '123';
const users = [
{ username: 'admin' },
{ username: 'user' },
{ username: 'root' },
];
const users = [{ username: 'admin' }, { username: 'user' }, { username: 'root' }];
if (!w) {
const newUsers = await User.bulkCreate(
users.map((user) => {