UNPKG

ckn.backend

Version:

CKN Framework for Backend

114 lines (105 loc) 4.86 kB
import {Middleware} from "../core/Middleware.js"; import {File} from "ckn.stream"; import {Controller} from "./Controller.js"; import fs from "fs"; import path from "path"; class ModuleMiddleware extends Middleware { constructor() { super(); this.priority = 1; this.modulesFolder = 'modules'; } async #loadModules(backend) { let modulesDirectoryPath = File.join(this.modulesFolder); let modules = []; let modulesDirectory = modulesDirectoryPath.toDirectory(); if (modulesDirectory.isExist) { for (let directory of modulesDirectory.directories) { let moduleName = directory.path.replace(this.modulesFolder, "").match(/^[\/\\]?(\w+)/)[1]; let moduleConfigFile = File.join(directory.path, "module.js").toFile(); if (moduleConfigFile.isExist) { modules[moduleName] = await import("file://"+moduleConfigFile.fullPath); let appClassName = Object.keys(modules[moduleName])[0]; modules[moduleName] = new modules[moduleName][appClassName](); modules[moduleName].name = moduleName; modules[moduleName].directory = directory; this.log.info("[OK]", `Module ${moduleName} has been loaded with configuration in ${moduleConfigFile.fullPath}`); } } } return modules; } async #loadController(backend, module, controllerClass) { let controller = new controllerClass(); controller.name = controller.constructor.name; this.log.info(`[OK] Controller '${controller.constructor.name}' is loading.`) let serviceNames = Object.keys(controller); for (let serviceName of serviceNames) { let service = controller[serviceName]; if (service.process && typeof service === "object") { service.name = serviceName; await this.#loadService(backend, module, controller, service); } } return controller; } async #loadService(backend, module, controller, service) { let method = service.method ? service.method : Controller.Method.GET; let url = service.url != null ? service.url : service.name; url = File.join(module.url, controller.url, url); if (url == ".") url = ""; let process = service.process; this.log.info(`[OK] Service '${url}' is loading.`) switch (method) { case Controller.Method.GET: this.log.info(`GET: URL: ${"/" + url}`); backend.get("/" + url, process); break; case Controller.Method.POST: this.log.info(`POST: URL: ${"/" + url}`); backend.post("/" + url, process); break; case Controller.Method.PUT: this.log.info(`PUT: URL: ${"/" + url}`); backend.put("/" + url, process); break; case Controller.Method.PATCH: this.log.info(`PATCH: URL: ${"/" + url}`); backend.patch("/" + url, process); break; case Controller.Method.DELETE: this.log.info(`DELETE: URL: ${"/" + url}`); backend.delete("/" + url, process); break; } } async #loadView(backend, module) { let path = File.join(module.directory.path, "views"); if (path.toDirectory().isExist) { module.views.push(File.join(module.directory.path, "views")); } } async onStartingServer(backend, next) { if (!fs.existsSync(path.resolve(process.cwd(), this.modulesFolder))) { fs.mkdirSync(path.resolve(process.cwd(), this.modulesFolder)); } let modules = await this.#loadModules(backend); for (let module of modules.values()) { this.log.info(`[OK] Module '${module.name}' is loading.`) let controllerDirectoryPath = File.join(this.modulesFolder, module.name, "controllers"); for (let controllerFilePath of controllerDirectoryPath.toDirectory().allFiles) { let controllerClasses = await import("file://"+path.resolve(controllerFilePath.fullPath)); let items = Object.values(controllerClasses); for (let controllerClass of items) { let controller = await this.#loadController(backend, module, controllerClass); module.controllers[controller.constructor.name] = controller; } } await this.#loadView(backend, module); } backend.modules = modules; this.log.info(`[OK] Modules have been loaded.`); next(); } } export {ModuleMiddleware}