feat: 改为本地数据库 admin的功能

This commit is contained in:
熊潇 2024-10-26 10:29:33 +08:00
parent 947a8507e9
commit 7f410fbaaa
9 changed files with 143 additions and 95 deletions

View File

@ -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);
};

View File

@ -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,

View File

@ -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) {

View File

@ -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');

View File

@ -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 () => {

View 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); // 监听器中的值
});
}

View File

@ -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({

View File

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

View File

@ -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');
}; };