feat: 改为本地数据库 admin的功能
This commit is contained in:
parent
947a8507e9
commit
7f410fbaaa
@ -1,5 +1,24 @@
|
|||||||
import { App } from '@kevisual/router';
|
import { App } from '@kevisual/router';
|
||||||
import { sequelize } from './modules/sequelize.ts';
|
import { sequelize } from './modules/sequelize.ts';
|
||||||
|
import { emitter } from './modules/event.ts';
|
||||||
export { sequelize };
|
export { sequelize };
|
||||||
export const app = new App();
|
export const app = new App();
|
||||||
|
|
||||||
|
export const runAppRouterFn = async (key: string, params: any) => {
|
||||||
|
emitter.emit(`router.fn`, key, params);
|
||||||
|
};
|
||||||
|
const runListener = async (app: App) => {
|
||||||
|
emitter.on('router.fn', (key, params) => {
|
||||||
|
if (!app.router[key]) {
|
||||||
|
console.error('router key not found:', key);
|
||||||
|
} else {
|
||||||
|
app.router[key](params);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
runListener(app);
|
||||||
|
|
||||||
|
export const appendTo = (realApp: App) => {
|
||||||
|
realApp.importApp(app);
|
||||||
|
runListener(realApp);
|
||||||
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// import { router } from '../../modules/router.ts';
|
// import { router } from '../../modules/router.ts';
|
||||||
import { app } from '../app.ts';
|
import { runAppRouterFn } from '../app.ts';
|
||||||
|
|
||||||
import { Route } from '@kevisual/router';
|
import { Route } from '@kevisual/router';
|
||||||
import { RouterCodeModel, RouterCode } from '../models/code.ts';
|
import { RouterCodeModel, RouterCode } from '../models/code.ts';
|
||||||
@ -42,8 +42,8 @@ export const loadOne = async (item: RouterCodeModel) => {
|
|||||||
const codeRunRoute = new Route(path, key, { id });
|
const codeRunRoute = new Route(path, key, { id });
|
||||||
codeRunRoute.run = fn;
|
codeRunRoute.run = fn;
|
||||||
codeRunRoute.middleware = middleware;
|
codeRunRoute.middleware = middleware;
|
||||||
app.router.removeById(id); // TODO:
|
runAppRouterFn('removeById', id);
|
||||||
app.router.add(codeRunRoute);
|
runAppRouterFn('add', codeRunRoute);
|
||||||
return {
|
return {
|
||||||
...item.toJSON(),
|
...item.toJSON(),
|
||||||
path,
|
path,
|
||||||
@ -92,7 +92,7 @@ export const load = async function () {
|
|||||||
const codeRunRoute = new Route(path, key, { id });
|
const codeRunRoute = new Route(path, key, { id });
|
||||||
codeRunRoute.run = fn;
|
codeRunRoute.run = fn;
|
||||||
codeRunRoute.middleware = middleware;
|
codeRunRoute.middleware = middleware;
|
||||||
app.router.add(codeRunRoute);
|
runAppRouterFn('add', codeRunRoute);
|
||||||
return {
|
return {
|
||||||
...item.toJSON(),
|
...item.toJSON(),
|
||||||
path,
|
path,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { EventEmitter, once } from 'stream';
|
import { EventEmitter, once } from 'stream';
|
||||||
import { load, CodeManager, CodeStatus, loadOne } from './load.ts';
|
import { load, CodeManager, CodeStatus, loadOne } from './load.ts';
|
||||||
import { RouterCodeModel, TableIsExist } from '../models/code.ts';
|
import { RouterCodeModel, TableIsExist } from '../models/code.ts';
|
||||||
|
import { emitter } from '../modules/event.ts';
|
||||||
|
|
||||||
export enum LoadStatus {
|
export enum LoadStatus {
|
||||||
LOADING = 'loading',
|
LOADING = 'loading',
|
||||||
@ -46,10 +47,7 @@ export const startCode = async (code: RouterCodeModel) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 事件
|
once(emitter, 'loaded')
|
||||||
export const events = new EventEmitter();
|
|
||||||
|
|
||||||
once(events, 'loaded')
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
manager.loaded = LoadStatus.LOADED;
|
manager.loaded = LoadStatus.LOADED;
|
||||||
console.log('manager loaded');
|
console.log('manager loaded');
|
||||||
@ -63,7 +61,7 @@ const init = async function () {
|
|||||||
const r = await load();
|
const r = await load();
|
||||||
manager.list = r;
|
manager.list = r;
|
||||||
|
|
||||||
events.emit('loaded');
|
emitter.emit('loaded');
|
||||||
};
|
};
|
||||||
TableIsExist().then(async (res) => {
|
TableIsExist().then(async (res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
|
@ -14,18 +14,22 @@ managerRouter.run = async (ctx) => {
|
|||||||
managerRouter.addTo(app);
|
managerRouter.addTo(app);
|
||||||
|
|
||||||
// get manager list
|
// get manager list
|
||||||
export const managerList = new Route('admin', 'getManagerList');
|
app
|
||||||
managerList.run = async (ctx) => {
|
.route({
|
||||||
|
path: 'admin',
|
||||||
|
key: 'getManagerList',
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
ctx.body = manager.list;
|
ctx.body = manager.list;
|
||||||
// TODO:
|
// TODO: routerList 可以不暴露
|
||||||
const routerList = app.router.getList().filter((r) => !r.path.startsWith('admin'));
|
const routerList = ctx.queryRouter.getList().filter((r) => !r.path.startsWith('admin'));
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
list: manager.list,
|
list: manager.list,
|
||||||
routerList,
|
routerList,
|
||||||
};
|
};
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
})
|
||||||
managerList.addTo(app);
|
.addTo(app);
|
||||||
|
|
||||||
// get manager one
|
// get manager one
|
||||||
export const managerOne = new Route('admin', 'getManagerOne');
|
export const managerOne = new Route('admin', 'getManagerOne');
|
||||||
|
@ -101,6 +101,7 @@ RouterCodeModel.sync({ alter: true, logging: false })
|
|||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('RouterCodeModel sync', e.message);
|
console.error('RouterCodeModel sync', e.message);
|
||||||
|
if (!TableIsExist()) {
|
||||||
RouterCodeModel.sync({ force: true })
|
RouterCodeModel.sync({ force: true })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('RouterCodeModel force sync', res);
|
console.log('RouterCodeModel force sync', res);
|
||||||
@ -108,6 +109,7 @@ RouterCodeModel.sync({ alter: true, logging: false })
|
|||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('RouterCodeModel force sync error');
|
console.error('RouterCodeModel force sync error');
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const TableIsExist = async () => {
|
export const TableIsExist = async () => {
|
||||||
|
20
src/admin/modules/event.ts
Normal file
20
src/admin/modules/event.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { EventEmitter, once } from 'stream';
|
||||||
|
|
||||||
|
// 事件
|
||||||
|
export const emitter = new EventEmitter();
|
||||||
|
|
||||||
|
// 异步触发事件 demo
|
||||||
|
export const asyncEmit = (emitter: EventEmitter, eventName: string) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
emitter.once(eventName, (value: any) => resolve(value));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
setTimeout(() => {
|
||||||
|
emitter.emit('asyncEvent', '监听器中的值');
|
||||||
|
}, 1000);
|
||||||
|
asyncEmit(emitter, 'asyncEvent').then((result) => {
|
||||||
|
console.log(result); // 监听器中的值
|
||||||
|
});
|
||||||
|
}
|
@ -14,7 +14,7 @@ const checkFileExistsSync = (filePath: string) => {
|
|||||||
};
|
};
|
||||||
const config = useConfig<{ flowPath: string }>();
|
const config = useConfig<{ flowPath: string }>();
|
||||||
export const envisionPath = path.join(os.homedir(), '.config', 'envision');
|
export const envisionPath = path.join(os.homedir(), '.config', 'envision');
|
||||||
const configPath = path.join(os.homedir(), '.config', 'envision', 'flow.sqlite');
|
const configPath = path.join(os.homedir(), '.config', 'envision', 'db.sqlite');
|
||||||
|
|
||||||
if (!checkFileExistsSync(envisionPath)) {
|
if (!checkFileExistsSync(envisionPath)) {
|
||||||
fs.mkdirSync(envisionPath, { recursive: true });
|
fs.mkdirSync(envisionPath, { recursive: true });
|
||||||
@ -24,7 +24,7 @@ if (!path.isAbsolute(flowPath)) {
|
|||||||
flowPath = path.join(process.cwd(), flowPath);
|
flowPath = path.join(process.cwd(), flowPath);
|
||||||
}
|
}
|
||||||
if (!flowPath.endsWith('.sqlite')) {
|
if (!flowPath.endsWith('.sqlite')) {
|
||||||
flowPath = path.join(flowPath, 'flow.sqlite');
|
flowPath = path.join(flowPath, 'db.sqlite');
|
||||||
}
|
}
|
||||||
// connect to db
|
// connect to db
|
||||||
export const sequelize = new Sequelize({
|
export const sequelize = new Sequelize({
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
// admin router manger
|
// admin router manger
|
||||||
import { CustomError, Route } from '@kevisual/router';
|
import { CustomError, Route } from '@kevisual/router';
|
||||||
import { app } from './app.ts';
|
import { app, runAppRouterFn } from './app.ts';
|
||||||
import { manager, updateNewCode, removeCode, stopCode, startCode } from './dashboard/manager.ts';
|
import { manager, updateNewCode, removeCode, stopCode, startCode } from './dashboard/manager.ts';
|
||||||
import { loadOne } from './dashboard/load.ts';
|
import { loadOne } from './dashboard/load.ts';
|
||||||
import { RouterCodeModel } from './models/code.ts';
|
import { RouterCodeModel } from './models/code.ts';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { convertTsToJs as transform } from '../lib/ts2js.ts';
|
import { convertTsToJs as transform } from '../lib/ts2js.ts';
|
||||||
|
|
||||||
export const getRouterList = new Route('admin', 'getRouterList');
|
app
|
||||||
|
.route({
|
||||||
getRouterList.run = async (ctx) => {
|
path: 'admin',
|
||||||
// TODO:
|
key: 'getRouterList',
|
||||||
ctx.body = app.router.getList().filter((r) => !r.path.startsWith('admin'));
|
})
|
||||||
|
.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'));
|
// ctx.body = router.getList().filter((r) => r.path.startsWith('admin'));
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
})
|
||||||
|
.addTo(app);
|
||||||
getRouterList.addTo(app);
|
|
||||||
|
|
||||||
// remove router
|
// remove router
|
||||||
export const removeRouter = new Route('admin', 'removeRouter');
|
export const removeRouter = new Route('admin', 'removeRouter');
|
||||||
removeRouter.run = async (ctx) => {
|
removeRouter.run = async (ctx) => {
|
||||||
const { path, key } = ctx.query;
|
const { path, key } = ctx.query;
|
||||||
// TODO:
|
runAppRouterFn('remove', { path, key });
|
||||||
// router.remove({ path, key });
|
|
||||||
app.router.remove({ path, key });
|
|
||||||
const routerCode = await RouterCodeModel.findOne({ where: { path, key } });
|
const routerCode = await RouterCodeModel.findOne({ where: { path, key } });
|
||||||
if (routerCode) {
|
if (routerCode) {
|
||||||
const id = routerCode.id;
|
const id = routerCode.id;
|
||||||
@ -49,9 +49,8 @@ removeRouter.addTo(app);
|
|||||||
export const removeRouterById = new Route('admin', 'removeRouterById');
|
export const removeRouterById = new Route('admin', 'removeRouterById');
|
||||||
removeRouterById.run = async (ctx) => {
|
removeRouterById.run = async (ctx) => {
|
||||||
const { id } = ctx.query;
|
const { id } = ctx.query;
|
||||||
// router.removeById(id);
|
|
||||||
// TODO:
|
|
||||||
app.router.removeById(id);
|
app.router.removeById(id);
|
||||||
|
runAppRouterFn('removeById', id);
|
||||||
removeCode(id);
|
removeCode(id);
|
||||||
await RouterCodeModel.destroy({ where: { id } });
|
await RouterCodeModel.destroy({ where: { id } });
|
||||||
ctx.body = 'success';
|
ctx.body = 'success';
|
||||||
@ -68,8 +67,7 @@ removeRouterById.addTo(app);
|
|||||||
export const stopRouterById = new Route('admin', 'stopRouterById');
|
export const stopRouterById = new Route('admin', 'stopRouterById');
|
||||||
stopRouterById.run = async (ctx) => {
|
stopRouterById.run = async (ctx) => {
|
||||||
const { id } = ctx.query;
|
const { id } = ctx.query;
|
||||||
// TODO
|
runAppRouterFn('removeById', id);
|
||||||
app.router.removeById(id);
|
|
||||||
const routerCode = await RouterCodeModel.findByPk(id);
|
const routerCode = await RouterCodeModel.findByPk(id);
|
||||||
if (routerCode) {
|
if (routerCode) {
|
||||||
routerCode.active = false;
|
routerCode.active = false;
|
||||||
@ -159,13 +157,23 @@ updateRouter.run = async (ctx) => {
|
|||||||
};
|
};
|
||||||
updateRouter.addTo(app);
|
updateRouter.addTo(app);
|
||||||
|
|
||||||
export const getRouterApi = new Route('admin', 'getRouterApi');
|
app
|
||||||
getRouterApi.description = 'get all router api list, and you can use this api to get router detail by path and key';
|
.route({
|
||||||
getRouterApi.run = async (ctx) => {
|
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 { origin = 'http://localhost:4000' } = ctx.query;
|
||||||
// const routerList = router.getList();
|
// const routerList = router.getList();
|
||||||
// TODO:
|
// TODO: routerList 可以不暴露
|
||||||
const routerList = app.router.getList();
|
const routerList = ctx.queryRouter.getList();
|
||||||
const apiList = routerList.map((item: any) => {
|
const apiList = routerList.map((item: any) => {
|
||||||
return {
|
return {
|
||||||
path: item.path,
|
path: item.path,
|
||||||
@ -189,12 +197,5 @@ getRouterApi.run = async (ctx) => {
|
|||||||
keyObject: apiKeyObject,
|
keyObject: apiKeyObject,
|
||||||
};
|
};
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
})
|
||||||
getRouterApi.validator = {
|
.addTo(app);
|
||||||
origin: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
getRouterApi.addTo(app);
|
|
||||||
|
@ -101,6 +101,7 @@ RouterCodeModel.sync({ alter: true, logging: false })
|
|||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('RouterCodeModel sync', e.message);
|
console.error('RouterCodeModel sync', e.message);
|
||||||
|
if (!TableIsExist()) {
|
||||||
RouterCodeModel.sync({ force: true })
|
RouterCodeModel.sync({ force: true })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log('RouterCodeModel force sync', res);
|
console.log('RouterCodeModel force sync', res);
|
||||||
@ -108,10 +109,13 @@ RouterCodeModel.sync({ alter: true, logging: false })
|
|||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('RouterCodeModel force sync error');
|
console.error('RouterCodeModel force sync error');
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const TableIsExist = async () => {
|
export const TableIsExist = async () => {
|
||||||
// 判断cf_router_code表是否存在
|
// 判断cf_router_code表是否存在
|
||||||
const tableIsExist = await sequelize.getQueryInterface().showAllTables();
|
const tableIsExist = await sequelize.getQueryInterface().showAllTables({
|
||||||
|
logging: false,
|
||||||
|
});
|
||||||
return tableIsExist.includes('cf_router_code');
|
return tableIsExist.includes('cf_router_code');
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user