UNPKG

fast-controllers

Version:

class based controllers, and implied folder route mapping for Fastify

167 lines (166 loc) 6.95 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = fastControllers; exports.prepareController = prepareController; const node_path_1 = __importDefault(require("node:path")); const node_fs_1 = __importDefault(require("node:fs")); const node_module_1 = require("node:module"); const FastControllerException_InvalidControllerPath_1 = __importDefault(require("./exceptions/FastControllerException_InvalidControllerPath")); const FastController_1 = require("./FastController"); const requireController = (0, node_module_1.createRequire)(__filename); function fastControllers(instance, options) { if (!options || !options.path || !node_path_1.default.isAbsolute(options.path)) { throw new FastControllerException_InvalidControllerPath_1.default(options.path || 'undefined'); } return scanControllers(options.path) .then(paths => { return Promise.all(paths.map(path => { return Promise.resolve(requireController(path)).then(module => { return { controller: module.default ?? module, route: path.substring(options.path.length) .toLowerCase() .replace(/index\/?$/, '') .replace(/\\/g, '/') .replace(/\/+$/, '') }; }); })); }) .then(modules => { const scopedModules = {}; modules.forEach(module => { if (!scopedModules[module.controller.scope]) scopedModules[module.controller.scope] = new Array(); scopedModules[module.controller.scope]?.push(module); }); return scopedModules; }) .then(scopedModules => { return Promise.all(Object.keys(scopedModules).map(scope => { return instance.register((_scope, _, next) => { scopedModules[scope]?.forEach(module => { const controller = new module.controller(instance, module.route); if (!controller.schema) { _scope.route(controller); } else { controller.methods.forEach(method => { const controllerInstance = new module.controller(instance, module.route); _scope.route(prepareController(controllerInstance, method)); }); } }); next(); }); })); }); } function scanControllers(controllerPath) { return new Promise((resolve) => { function scan(cPath) { const paths = new Array(); node_fs_1.default.readdirSync(cPath, { withFileTypes: true }).forEach(entry => { if (entry.isDirectory() && !entry.name.startsWith('.')) { paths.push(...scan(node_path_1.default.join(cPath, entry.name))); } else if (entry.isFile() && !entry.name.endsWith('.map')) { let modulePath = node_path_1.default.join(cPath, entry.name); paths.push(modulePath.substring(0, modulePath.lastIndexOf('.'))); } }); return paths; } resolve(scan(controllerPath)); }); } function prepareController(controller, method) { controller.method = method.toUpperCase(); const lMethod = method.toLowerCase(); if (controller.params) { if (typeof controller.params === 'object' && controller.params.hasOwnProperty(lMethod)) { controller.params = controller.params[lMethod]; } if (typeof controller.params === 'string') { controller.url = node_path_1.default.posix.join(controller.url, controller.params); } else if (Array.isArray(controller.params)) { controller.url = node_path_1.default.posix.join(controller.url, ...controller.params.map(param => `:${param}`)); } } if (controller.schema?.params) { if (controller.schema.params.hasOwnProperty(lMethod)) { controller.schema.params = controller.schema.params[lMethod]; } else { FastController_1.METHODS.forEach(method => { if (controller.schema?.params && controller.schema?.params.hasOwnProperty(method.toLowerCase())) { delete controller.schema.params[method]; } }); } } if (controller.schema?.querystring) { if (controller.schema.querystring.hasOwnProperty(lMethod)) { controller.schema.querystring = controller.schema.querystring[lMethod]; } else { FastController_1.METHODS.forEach(method => { if (controller.schema?.querystring && controller.schema?.querystring.hasOwnProperty(method.toLowerCase())) { delete controller.schema.querystring[method]; } }); } } if (controller.schema?.response) { if (controller.schema.response.hasOwnProperty(lMethod)) { controller.schema.response = controller.schema.response[lMethod]; } else { FastController_1.METHODS.forEach(method => { if (controller.schema?.response && controller.schema?.response.hasOwnProperty(method.toLowerCase())) { delete controller.schema.response[method]; } }); } } if (controller.method === 'GET') { if (controller.schema?.body) { delete controller.schema.body; } } if (controller.schema?.body) { if (controller.schema.body.hasOwnProperty(lMethod)) { controller.schema.body = controller.schema.body[lMethod]; } else { FastController_1.METHODS.forEach(method => { if (controller.schema?.body && controller.schema?.body.hasOwnProperty(method.toLowerCase())) { delete controller.schema.body[method]; } }); if (Object.keys(controller.schema.body).length === 0) { delete controller.schema.body; } } } if (controller.schema) { const schema = controller.schema; const scalarKeys = ['operationId', 'summary', 'description']; scalarKeys.forEach(key => { const value = schema[key]; if (value && typeof value === 'object') { if (value.hasOwnProperty(lMethod)) { schema[key] = value[lMethod]; } else { delete schema[key]; } } }); } return controller; }