diff --git a/src/admin/app.ts b/src/admin/app.ts index 216d7b9..b7eeb69 100644 --- a/src/admin/app.ts +++ b/src/admin/app.ts @@ -1,5 +1,24 @@ import { App } from '@kevisual/router'; import { sequelize } from './modules/sequelize.ts'; - +import { emitter } from './modules/event.ts'; export { sequelize }; 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); +}; diff --git a/src/admin/dashboard/load.ts b/src/admin/dashboard/load.ts index 591cd10..37b7fdb 100644 --- a/src/admin/dashboard/load.ts +++ b/src/admin/dashboard/load.ts @@ -1,5 +1,5 @@ // import { router } from '../../modules/router.ts'; -import { app } from '../app.ts'; +import { runAppRouterFn } from '../app.ts'; import { Route } from '@kevisual/router'; import { RouterCodeModel, RouterCode } from '../models/code.ts'; @@ -42,8 +42,8 @@ export const loadOne = async (item: RouterCodeModel) => { const codeRunRoute = new Route(path, key, { id }); codeRunRoute.run = fn; codeRunRoute.middleware = middleware; - app.router.removeById(id); // TODO: - app.router.add(codeRunRoute); + runAppRouterFn('removeById', id); + runAppRouterFn('add', codeRunRoute); return { ...item.toJSON(), path, @@ -92,7 +92,7 @@ export const load = async function () { const codeRunRoute = new Route(path, key, { id }); codeRunRoute.run = fn; codeRunRoute.middleware = middleware; - app.router.add(codeRunRoute); + runAppRouterFn('add', codeRunRoute); return { ...item.toJSON(), path, diff --git a/src/admin/dashboard/manager.ts b/src/admin/dashboard/manager.ts index 46f34dc..90f5e3a 100644 --- a/src/admin/dashboard/manager.ts +++ b/src/admin/dashboard/manager.ts @@ -1,6 +1,7 @@ import { EventEmitter, once } from 'stream'; import { load, CodeManager, CodeStatus, loadOne } from './load.ts'; import { RouterCodeModel, TableIsExist } from '../models/code.ts'; +import { emitter } from '../modules/event.ts'; export enum LoadStatus { LOADING = 'loading', @@ -46,10 +47,7 @@ export const startCode = async (code: RouterCodeModel) => { } }; -// 事件 -export const events = new EventEmitter(); - -once(events, 'loaded') +once(emitter, 'loaded') .then(() => { manager.loaded = LoadStatus.LOADED; console.log('manager loaded'); @@ -63,7 +61,7 @@ const init = async function () { const r = await load(); manager.list = r; - events.emit('loaded'); + emitter.emit('loaded'); }; TableIsExist().then(async (res) => { if (res) { diff --git a/src/admin/manager.ts b/src/admin/manager.ts index d8aacb1..f9be632 100644 --- a/src/admin/manager.ts +++ b/src/admin/manager.ts @@ -14,18 +14,22 @@ managerRouter.run = async (ctx) => { managerRouter.addTo(app); // get manager list -export const managerList = new Route('admin', 'getManagerList'); -managerList.run = async (ctx) => { - ctx.body = manager.list; - // TODO: - const routerList = app.router.getList().filter((r) => !r.path.startsWith('admin')); - ctx.body = { - list: manager.list, - routerList, - }; - return ctx; -}; -managerList.addTo(app); +app + .route({ + path: 'admin', + key: 'getManagerList', + }) + .define(async (ctx) => { + ctx.body = manager.list; + // TODO: routerList 可以不暴露 + const routerList = ctx.queryRouter.getList().filter((r) => !r.path.startsWith('admin')); + ctx.body = { + list: manager.list, + routerList, + }; + return ctx; + }) + .addTo(app); // get manager one export const managerOne = new Route('admin', 'getManagerOne'); diff --git a/src/admin/models/code.ts b/src/admin/models/code.ts index 13f4f4b..063f31c 100644 --- a/src/admin/models/code.ts +++ b/src/admin/models/code.ts @@ -101,13 +101,15 @@ RouterCodeModel.sync({ alter: true, logging: false }) }) .catch((e) => { console.error('RouterCodeModel sync', e.message); - RouterCodeModel.sync({ force: true }) - .then((res) => { - console.log('RouterCodeModel force sync', res); - }) - .catch((e) => { - console.error('RouterCodeModel force sync error'); - }); + if (!TableIsExist()) { + RouterCodeModel.sync({ force: true }) + .then((res) => { + console.log('RouterCodeModel force sync', res); + }) + .catch((e) => { + console.error('RouterCodeModel force sync error'); + }); + } }); export const TableIsExist = async () => { diff --git a/src/admin/modules/event.ts b/src/admin/modules/event.ts new file mode 100644 index 0000000..b93646b --- /dev/null +++ b/src/admin/modules/event.ts @@ -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); // 监听器中的值 + }); +} diff --git a/src/admin/modules/sequelize.ts b/src/admin/modules/sequelize.ts index 04882c7..8a35d2f 100644 --- a/src/admin/modules/sequelize.ts +++ b/src/admin/modules/sequelize.ts @@ -14,7 +14,7 @@ const checkFileExistsSync = (filePath: string) => { }; const config = useConfig<{ flowPath: string }>(); 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)) { fs.mkdirSync(envisionPath, { recursive: true }); @@ -24,7 +24,7 @@ if (!path.isAbsolute(flowPath)) { flowPath = path.join(process.cwd(), flowPath); } if (!flowPath.endsWith('.sqlite')) { - flowPath = path.join(flowPath, 'flow.sqlite'); + flowPath = path.join(flowPath, 'db.sqlite'); } // connect to db export const sequelize = new Sequelize({ diff --git a/src/admin/router.ts b/src/admin/router.ts index 3db48e7..3593729 100644 --- a/src/admin/router.ts +++ b/src/admin/router.ts @@ -1,30 +1,30 @@ // admin router manger 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 { 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) => { - // TODO: - ctx.body = app.router.getList().filter((r) => !r.path.startsWith('admin')); - // ctx.body = router.getList().filter((r) => r.path.startsWith('admin')); - return ctx; -}; - -getRouterList.addTo(app); +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; - // TODO: - // router.remove({ path, key }); - app.router.remove({ path, key }); + runAppRouterFn('remove', { path, key }); const routerCode = await RouterCodeModel.findOne({ where: { path, key } }); if (routerCode) { const id = routerCode.id; @@ -49,9 +49,8 @@ removeRouter.addTo(app); export const removeRouterById = new Route('admin', 'removeRouterById'); removeRouterById.run = async (ctx) => { const { id } = ctx.query; - // router.removeById(id); - // TODO: app.router.removeById(id); + runAppRouterFn('removeById', id); removeCode(id); await RouterCodeModel.destroy({ where: { id } }); ctx.body = 'success'; @@ -68,8 +67,7 @@ removeRouterById.addTo(app); export const stopRouterById = new Route('admin', 'stopRouterById'); stopRouterById.run = async (ctx) => { const { id } = ctx.query; - // TODO - app.router.removeById(id); + runAppRouterFn('removeById', id); const routerCode = await RouterCodeModel.findByPk(id); if (routerCode) { routerCode.active = false; @@ -159,42 +157,45 @@ updateRouter.run = async (ctx) => { }; updateRouter.addTo(app); -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(); - // TODO: - const routerList = app.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, +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, }; - }); - 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; -}; -getRouterApi.validator = { - origin: { - type: 'string', - required: false, - }, -}; - -getRouterApi.addTo(app); + return ctx; + }) + .addTo(app); diff --git a/src/models/code.ts b/src/models/code.ts index f92badb..063f31c 100644 --- a/src/models/code.ts +++ b/src/models/code.ts @@ -101,17 +101,21 @@ RouterCodeModel.sync({ alter: true, logging: false }) }) .catch((e) => { console.error('RouterCodeModel sync', e.message); - RouterCodeModel.sync({ force: true }) - .then((res) => { - console.log('RouterCodeModel force sync', res); - }) - .catch((e) => { - console.error('RouterCodeModel force sync error'); - }); + if (!TableIsExist()) { + RouterCodeModel.sync({ force: true }) + .then((res) => { + console.log('RouterCodeModel force sync', res); + }) + .catch((e) => { + console.error('RouterCodeModel force sync error'); + }); + } }); export const TableIsExist = async () => { // 判断cf_router_code表是否存在 - const tableIsExist = await sequelize.getQueryInterface().showAllTables(); + const tableIsExist = await sequelize.getQueryInterface().showAllTables({ + logging: false, + }); return tableIsExist.includes('cf_router_code'); };