feat: perfect router lib add validator
This commit is contained in:
parent
c92f42933e
commit
f3c0707666
20
package-lock.json
generated
20
package-lock.json
generated
@ -9,7 +9,7 @@
|
||||
"version": "0.0.2",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@abearxiong/router": "^0.0.1-alpha.8",
|
||||
"@abearxiong/router": "^0.0.1-alpha.12",
|
||||
"@abearxiong/use-config": "^0.0.1",
|
||||
"@babel/core": "^7.24.7",
|
||||
"@babel/preset-env": "^7.24.7",
|
||||
@ -50,12 +50,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@abearxiong/router": {
|
||||
"version": "0.0.1-alpha.8",
|
||||
"resolved": "https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.8/772276fc4290291f845b0bb7198acc1c439f72e3",
|
||||
"integrity": "sha512-uX9YkeS+TDKKH8y1fShTKgxcXWeawaoLLi/kdX04M84o3sg1vZSic4wxEMuznAjESX/iYIc94vXyE6cevoWVLQ==",
|
||||
"version": "0.0.1-alpha.12",
|
||||
"resolved": "https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.12/ca2bf4832b4f032965b4c579b7bbde04a05f893a",
|
||||
"integrity": "sha512-Hqe8HdxUTCjl31ExVpb1Ro4KuvqsjcbZwcISyzImDe5xN4yMBh3zZCZOTrbSB9OsxukX5rqQ4kvufLWbbfp46g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"nanoid": "^5.0.6"
|
||||
"lodash": "^4.17.21",
|
||||
"nanoid": "^5.0.6",
|
||||
"zod": "^3.23.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@abearxiong/use-config": {
|
||||
@ -8141,6 +8143,14 @@
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.23.8",
|
||||
"resolved": "https://registry.npmmirror.com/zod/-/zod-3.23.8.tgz",
|
||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@abearxiong/router": "^0.0.1-alpha.8",
|
||||
"@abearxiong/router": "^0.0.1-alpha.12",
|
||||
"@abearxiong/use-config": "^0.0.1",
|
||||
"@babel/core": "^7.24.7",
|
||||
"@babel/preset-env": "^7.24.7",
|
||||
|
@ -1,168 +1,2 @@
|
||||
// admin 需要最后运行,并在route中进行过滤。
|
||||
import { Route } from '@abearxiong/router';
|
||||
import { router } from '../modules/router.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';
|
||||
|
||||
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'));
|
||||
return ctx;
|
||||
};
|
||||
|
||||
router.add(getRouterList);
|
||||
|
||||
// remove router
|
||||
export const removeRouter = new Route('admin', 'removeRouter');
|
||||
removeRouter.run = async (ctx) => {
|
||||
const { path, key } = ctx.query;
|
||||
router.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;
|
||||
};
|
||||
router.add(removeRouter);
|
||||
|
||||
// remove router by id
|
||||
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);
|
||||
|
||||
// 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(stopRouterById);
|
||||
|
||||
// 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;
|
||||
};
|
||||
router.add(startRouterById);
|
||||
|
||||
// add or update router
|
||||
export const updateRouter = new Route('admin', 'updateRouter');
|
||||
updateRouter.run = async (ctx) => {
|
||||
let { path, key, id, code, 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;
|
||||
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 });
|
||||
await newCodeRouter.save();
|
||||
codeRouter = newCodeRouter;
|
||||
} catch (e) {
|
||||
ctx.body = e.message.toString();
|
||||
ctx.code = 500;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
const codeOne = await loadOne(codeRouter);
|
||||
updateNewCode(codeOne);
|
||||
|
||||
ctx.body = 'success';
|
||||
return ctx;
|
||||
};
|
||||
router.add(updateRouter);
|
||||
|
||||
// get manager status
|
||||
export const managerRouter = new Route('admin', 'getManagerStatus');
|
||||
managerRouter.run = async (ctx) => {
|
||||
ctx.body = {
|
||||
status: manager.loaded,
|
||||
msg: 'system is running, and load manager success.',
|
||||
};
|
||||
return ctx;
|
||||
};
|
||||
router.add(managerRouter);
|
||||
|
||||
// get manager list
|
||||
export const managerList = new Route('admin', 'getManagerList');
|
||||
managerList.run = async (ctx) => {
|
||||
ctx.body = manager.list;
|
||||
const routerList = router.getList().filter((r) => !r.path.startsWith('admin'));
|
||||
ctx.body = {
|
||||
list: manager.list,
|
||||
routerList,
|
||||
};
|
||||
return ctx;
|
||||
};
|
||||
router.add(managerList);
|
||||
|
||||
// get manager one
|
||||
export const managerOne = new Route('admin', 'getManagerOne');
|
||||
managerOne.run = async (ctx) => {
|
||||
const { id } = ctx.query;
|
||||
const code = manager.list.find((c) => c.id === id);
|
||||
if (code) {
|
||||
ctx.body = code;
|
||||
} else {
|
||||
ctx.body = 'not found';
|
||||
ctx.code = 404;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
};
|
||||
router.add(managerOne);
|
||||
import './router.ts';
|
||||
import './manager.ts';
|
||||
|
55
src/admin/manager.ts
Normal file
55
src/admin/manager.ts
Normal file
@ -0,0 +1,55 @@
|
||||
// admin 需要最后运行,并在route中进行过滤。
|
||||
import { Route } from '@abearxiong/router';
|
||||
import { router } from '../modules/router.ts';
|
||||
import { manager, updateNewCode, removeCode, stopCode, startCode } from './dashboard/manager.ts';
|
||||
import { loadOne } from './dashboard/load.ts';
|
||||
import { RouterCodeModel } from '../models/code.ts';
|
||||
// get manager status
|
||||
export const managerRouter = new Route('admin', 'getManagerStatus');
|
||||
managerRouter.run = async (ctx) => {
|
||||
ctx.body = {
|
||||
status: manager.loaded,
|
||||
msg: 'system is running, and load manager success.',
|
||||
};
|
||||
return ctx;
|
||||
};
|
||||
router.add(managerRouter);
|
||||
|
||||
// get manager list
|
||||
export const managerList = new Route('admin', 'getManagerList');
|
||||
managerList.run = async (ctx) => {
|
||||
ctx.body = manager.list;
|
||||
const routerList = router.getList().filter((r) => !r.path.startsWith('admin'));
|
||||
ctx.body = {
|
||||
list: manager.list,
|
||||
routerList,
|
||||
};
|
||||
return ctx;
|
||||
};
|
||||
router.add(managerList);
|
||||
|
||||
// get manager one
|
||||
export const managerOne = new Route('admin', 'getManagerOne');
|
||||
managerOne.run = async (ctx) => {
|
||||
const verfiy = ctx.currentRoute.verify(ctx);
|
||||
if (verfiy) return;
|
||||
|
||||
const { id } = ctx.query;
|
||||
const code = manager.list.find((c) => c.id === id);
|
||||
if (code) {
|
||||
ctx.body = code;
|
||||
} else {
|
||||
ctx.body = 'not found';
|
||||
ctx.code = 404;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
};
|
||||
managerOne.validator = {
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
|
||||
router.add(managerOne);
|
183
src/admin/router.ts
Normal file
183
src/admin/router.ts
Normal file
@ -0,0 +1,183 @@
|
||||
// admin router manger
|
||||
|
||||
import { Route } from '@abearxiong/router';
|
||||
import { router } from '../modules/router.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';
|
||||
|
||||
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'));
|
||||
return ctx;
|
||||
};
|
||||
|
||||
router.add(getRouterList);
|
||||
|
||||
// remove router
|
||||
export const removeRouter = new Route('admin', 'removeRouter');
|
||||
removeRouter.run = async (ctx) => {
|
||||
const { path, key } = ctx.query;
|
||||
router.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,
|
||||
},
|
||||
};
|
||||
router.add(removeRouter);
|
||||
|
||||
// remove router by id
|
||||
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;
|
||||
};
|
||||
removeRouterById.validator = {
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
router.add(removeRouterById);
|
||||
|
||||
// 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;
|
||||
};
|
||||
stopRouterById.validator = {
|
||||
id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
router.add(stopRouterById);
|
||||
|
||||
// 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,
|
||||
},
|
||||
};
|
||||
router.add(startRouterById);
|
||||
|
||||
// add or update router
|
||||
export const updateRouter = new Route('admin', 'updateRouter');
|
||||
updateRouter.run = async (ctx) => {
|
||||
let { path, key, id, code, 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;
|
||||
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 });
|
||||
await newCodeRouter.save();
|
||||
codeRouter = newCodeRouter;
|
||||
} catch (e) {
|
||||
ctx.body = e.message.toString();
|
||||
ctx.code = 500;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
const codeOne = await loadOne(codeRouter);
|
||||
updateNewCode(codeOne);
|
||||
|
||||
ctx.body = 'success';
|
||||
return ctx;
|
||||
};
|
||||
router.add(updateRouter);
|
||||
|
||||
export const getRouterApi = new Route('admin', 'getRouterApi');
|
||||
getRouterApi.description = 'get all router api list, and you can use this api to get router detail by path and key';
|
||||
getRouterApi.run = async (ctx) => {
|
||||
const { origin = 'http://localhost:4000' } = ctx.query;
|
||||
const routerList = router.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,
|
||||
};
|
||||
});
|
||||
ctx.body = apiList;
|
||||
return ctx;
|
||||
};
|
||||
getRouterApi.validator = {
|
||||
origin: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
},
|
||||
};
|
||||
|
||||
router.add(getRouterApi);
|
@ -13,6 +13,7 @@ export type RouterCode = {
|
||||
middleware: string[];
|
||||
next: string;
|
||||
data: any;
|
||||
validator: any;
|
||||
};
|
||||
|
||||
export enum RouterCodeType {
|
||||
@ -31,7 +32,8 @@ export class RouterCodeModel extends Model {
|
||||
declare type: RouterCodeType;
|
||||
declare middleware: string[];
|
||||
declare next: string; // 如果是中间件,不存在
|
||||
declare data: any;
|
||||
declare data: any; // 内容
|
||||
declare validator: any;
|
||||
}
|
||||
RouterCodeModel.init(
|
||||
{
|
||||
@ -81,6 +83,10 @@ RouterCodeModel.init(
|
||||
type: DataTypes.JSON,
|
||||
defaultValue: {},
|
||||
},
|
||||
validator: {
|
||||
type: DataTypes.JSON,
|
||||
defaultValue: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
|
20
yarn.lock
20
yarn.lock
@ -2,12 +2,14 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@abearxiong/router@^0.0.1-alpha.8":
|
||||
version "0.0.1-alpha.8"
|
||||
resolved "https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.8/772276fc4290291f845b0bb7198acc1c439f72e3"
|
||||
integrity sha512-uX9YkeS+TDKKH8y1fShTKgxcXWeawaoLLi/kdX04M84o3sg1vZSic4wxEMuznAjESX/iYIc94vXyE6cevoWVLQ==
|
||||
"@abearxiong/router@^0.0.1-alpha.12":
|
||||
version "0.0.1-alpha.12"
|
||||
resolved "https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.12/ca2bf4832b4f032965b4c579b7bbde04a05f893a"
|
||||
integrity sha512-Hqe8HdxUTCjl31ExVpb1Ro4KuvqsjcbZwcISyzImDe5xN4yMBh3zZCZOTrbSB9OsxukX5rqQ4kvufLWbbfp46g==
|
||||
dependencies:
|
||||
lodash "^4.17.21"
|
||||
nanoid "^5.0.6"
|
||||
zod "^3.23.8"
|
||||
|
||||
"@abearxiong/use-config@^0.0.1":
|
||||
version "0.0.1"
|
||||
@ -2625,11 +2627,6 @@ fs.realpath@^1.0.0:
|
||||
resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz"
|
||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
||||
|
||||
fsevents@^2.3.2, fsevents@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
function-bind@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz"
|
||||
@ -4776,3 +4773,8 @@ yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zod@^3.23.8:
|
||||
version "3.23.8"
|
||||
resolved "https://registry.npmmirror.com/zod/-/zod-3.23.8.tgz"
|
||||
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
|
||||
|
Loading…
x
Reference in New Issue
Block a user