From c3debd31b448ddc9c66c4f2ea0f5182901c5096b Mon Sep 17 00:00:00 2001 From: srgooglo Date: Tue, 24 Jan 2023 20:07:14 +0100 Subject: [PATCH] update `Controller` generation --- src/server/classes/controller/index.js | 100 ++++++++++++++++++------- 1 file changed, 71 insertions(+), 29 deletions(-) diff --git a/src/server/classes/controller/index.js b/src/server/classes/controller/index.js index 539c419..1f6a9ec 100644 --- a/src/server/classes/controller/index.js +++ b/src/server/classes/controller/index.js @@ -1,13 +1,14 @@ const { EventEmitter } = require("events") +const Endpoint = require("../endpoint") -class Controller { +module.exports = class Controller { constructor(params) { this.params = { ...params } this.internalEvents = new EventEmitter() } - getWSEndpoints() { + __get_ws_endpoints() { if (typeof this.channels !== "object") { return [] } @@ -24,55 +25,96 @@ class Controller { }) } - getEndpoints() { + __get_http_endpoints() { let endpoints = [] - global.VALID_HTTP_METHODS.forEach((httpMethod) => { - if (typeof this[httpMethod] === "object") { - const fixedMethod = global.FIXED_HTTP_METHODS[httpMethod] - const controllerMethods = Object.keys(this[httpMethod]) + global.VALID_HTTP_METHODS.forEach((httpMethodKey) => { + const endpointsByMethod = this.httpEndpoints[httpMethodKey] - controllerMethods.forEach((methodKey) => { - const fn = this[httpMethod][methodKey] + if (typeof endpointsByMethod !== "object") { + return + } - let endpoint = { - method: fixedMethod ?? httpMethod, - route: methodKey, - middlewares: [], - fn: fn, + const fixedMethod = global.FIXED_HTTP_METHODS[httpMethodKey] + const methodEndpoints = Object.entries(endpointsByMethod) + + for (let [endpointKey, endpoint] of methodEndpoints) { + // check if endpoint is a class or an object, if it's a object, create a new class from it extending Endpoint + if (typeof endpoint === "object") { + const objEndpoint = endpoint + + endpoint = class extends Endpoint { + static method = httpMethodKey + static route = objEndpoint.route ?? endpointKey + static enabled = objEndpoint.enabled + static middlewares = objEndpoint.middlewares + + constructor(args) { + super(args) + this.fn = objEndpoint.fn + this.onCatch = objEndpoint.onCatch + this.customHandler = objEndpoint.customHandler + } } + } - if (typeof this.constructor.useRoute === "string") { - endpoint.route = this.constructor.useRoute + endpoint.route - } + // check if endpoint is a class + if (typeof endpoint !== "function") { + throw new Error(`Invalid endpoint. Expected class or object, got ${typeof endpoint}`) + } - if (typeof fn === "object") { - endpoint.middlewares = fn.middlewares - endpoint.fn = fn.fn - endpoint.enabled = fn.enabled - } + // check if controller has a static useRoute property + if (typeof this.constructor.useRoute === "string") { + endpoint.route = `${this.constructor.useRoute}${endpoint.route}` + endpoint.route = endpoint.route.replace(/\/\//g, "/") + } - endpoint.fn = this.createHandler(endpoint.fn) + const endpointInstance = new endpoint() - endpoints.push(endpoint) + const functionHandler = this.__create_default_fn_handler({ + fn: endpointInstance.fn, + onCatch: endpointInstance.onCatch, + customHandler: endpointInstance.customHandler, }) + + const endpointGenerationObject = { + method: fixedMethod ?? httpMethodKey, + route: endpoint.route, + middlewares: endpoint.middlewares, + enabled: endpoint.enabled, + fn: functionHandler, + } + + endpoints.push(endpointGenerationObject) } }) return endpoints } - createHandler = (fn) => { + __create_default_fn_handler = ({ + fn, + onCatch, + customHandler, + }) => { + if (typeof customHandler === "function") { + return customHandler + } + return (...args) => new Promise(async (resolve, reject) => { try { const result = await fn(...args) + return resolve(result) } catch (error) { - this.internalEvents.emit("requestError", error) + this.internalEvents.emit("request:error", error) + + if (typeof onCatch === "function") { + return onCatch(error, ...args) + } + return reject(error) } }) } -} - -module.exports = Controller \ No newline at end of file +} \ No newline at end of file