From 22f341bf55ff5c69dc95309a2565fcdc05c3ba1f Mon Sep 17 00:00:00 2001 From: fernandomema Date: Fri, 19 Apr 2024 13:32:23 +0200 Subject: [PATCH] feat: Add module routes system --- src/ZumitoFramework.ts | 9 +++++++-- src/definitions/FrameworkRouter.ts | 11 +++++++++++ src/definitions/Module.ts | 28 ++++++++++++++++++++++++++++ src/index.ts | 2 ++ src/services/ModuleManager.ts | 6 +----- 5 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 src/definitions/FrameworkRouter.ts diff --git a/src/ZumitoFramework.ts b/src/ZumitoFramework.ts index 8c7aa0e..d03388e 100644 --- a/src/ZumitoFramework.ts +++ b/src/ZumitoFramework.ts @@ -100,7 +100,7 @@ export class ZumitoFramework { * @see {@link TranslationManager} */ translations: TranslationManager; - routes: any; + routes: Map void>; /** * The database models loaded in the framework. @@ -162,6 +162,7 @@ export class ZumitoFramework { this.events = new Map(); this.translations = new TranslationManager(); this.models = []; + this.routes = new Map(); this.eventManager = new EventManager(); if (settings.logLevel) { @@ -188,12 +189,12 @@ export class ZumitoFramework { private async initialize() { await this.initializeDatabase(); await this.initializeDiscordClient(); - this.startApiServer(); this.eventManager.addEventEmitter('discord', this.client); this.eventManager.addEventEmitter('framework', this.eventEmitter); await this.registerModules(); + this.startApiServer(); await this.refreshSlashCommands(); if (this.settings.statusOptions) { this.statusManager = new StatusManager(this, this.settings.statusOptions); @@ -254,6 +255,10 @@ export class ZumitoFramework { //Route Prefixes //this.app.use("/", indexRouter); //this.app.use("/api/", apiRouter); + console.log(this.routes.size); + this.routes.forEach((router, path) => { + this.app.use(path, router); + }); // throw 404 if URL not found this.app.all('*', function (req, res) { diff --git a/src/definitions/FrameworkRouter.ts b/src/definitions/FrameworkRouter.ts new file mode 100644 index 0000000..91f7690 --- /dev/null +++ b/src/definitions/FrameworkRouter.ts @@ -0,0 +1,11 @@ +import { Request, Response } from 'express'; + +export abstract class FrameworkRouter { + basePath: string = ''; + + constructor(basePath: string) { + this.basePath = basePath; + } + + abstract getRoutes(): Map void>; +} \ No newline at end of file diff --git a/src/definitions/Module.ts b/src/definitions/Module.ts index afaab03..3596c9e 100644 --- a/src/definitions/Module.ts +++ b/src/definitions/Module.ts @@ -12,6 +12,8 @@ import { } from 'discord.js'; import { DatabaseModel } from './DatabaseModel.js'; import { CommandManager } from '../services/CommandManager.js'; +import { Request, Response } from 'express'; +import { FrameworkRouter } from "./FrameworkRouter.js"; export abstract class Module { protected path: string; @@ -19,6 +21,8 @@ export abstract class Module { protected commands: CommandManager; protected events: Map = new Map(); protected models: Array = []; + protected routes: Map void> = new Map(); + protected commandManager: CommandManager; @@ -34,6 +38,7 @@ export abstract class Module { await this.registerEvents(); await this.registerTranslations(); await this.registerModels(); + await this.registerRoutes(); } async registerCommands() { @@ -165,4 +170,27 @@ export abstract class Module { getModels(): Array { return this.models; } + + async registerRoutes(subpath = '') { + if (!fs.existsSync(path.join(this.path, 'routes', subpath))) return; + const files = fs.readdirSync(path.join(this.path, 'routes', subpath)); + for (const file of files) { + if (file.endsWith('.js') || file.endsWith('.ts')) { + const Router: any = await import('file://' + `${this.path}/routes/${subpath}/${file}`).then(r => Object.values(r)[0]); + if (Router.prototype instanceof FrameworkRouter) { + const router = new Router(subpath ? '/' + subpath : ''); + this.routes = new Map([...this.routes, ...router.getRoutes()]); + } else { + console.warn(`[🔄🟡 ] ${subpath}/${file} is not a valid router on module ${this.constructor.name} \n It must extend the FrameworkRouter class instead of ${Router.prototype}`); + continue; + } + } else if (fs.lstatSync(path.join(this.path, 'routes', subpath, file)).isDirectory()) { + await this.registerRoutes(path.join(subpath, file)); + } + } + } + + getRoutes(): Map void> { + return this.routes; + } } diff --git a/src/index.ts b/src/index.ts index efcda13..ee21e0d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,6 +27,7 @@ import { TranslationManager } from './services/TranslationManager.js'; import { ZumitoFramework } from './ZumitoFramework.js'; import * as discord from 'discord.js'; import { EventParameters } from './definitions/parameters/EventParameters.js'; +import { FrameworkRouter } from './definitions/FrameworkRouter.js'; export { ZumitoFramework, @@ -54,4 +55,5 @@ export { StatusManagerOptions, discord, EventParameters, + FrameworkRouter, }; diff --git a/src/services/ModuleManager.ts b/src/services/ModuleManager.ts index 6051ae7..b1bd51b 100644 --- a/src/services/ModuleManager.ts +++ b/src/services/ModuleManager.ts @@ -66,12 +66,8 @@ export class ModuleManager { this.framework.models.push(model); }); - /* - // Register module routes - this.routes = new Map([...this.routes, ...moduleInstance.getRoutes()]); - - */ + this.framework.routes = new Map([...this.framework.routes, ...module.getRoutes()] as any); } async instanceModule(module: any, rootPath: string, name?: string) {