reest
Version:
A library inspired by NestJS's elegance, specifically designed for efficient serverless API development on AWS Lambda. It streamlines the creation of microservices with automated Swagger documentation and enhanced decorator-based middleware support, makin
150 lines • 7.13 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Controller = void 0;
const express_1 = require("express");
const js2xmlparser = __importStar(require("js2xmlparser"));
const utils_1 = require("../utils");
class Controller {
Middlewares = [];
prefix = Reflect.getMetadata("prefix", this.constructor);
routes = Reflect.getMetadata("routes", this.constructor);
openapiPaths = {};
router;
joinMiddlewares(middlewares) {
this.Middlewares = [...this.Middlewares, ...middlewares];
}
constructor(appContructor) {
this.router = (0, express_1.Router)();
this.routes.forEach((route, index) => {
// Get the parameters metadata
const paramsMetadata = Reflect.getOwnMetadata(`__routeParameters__${route.methodName}`, this.constructor.prototype, route.methodName) || [];
// Get the body metadata
const bodyMetadata = Reflect.getOwnMetadata(`__bodyParameter__${route.methodName}`, this.constructor.prototype, route.methodName) || [];
// Get the query metadata
const queryMetedata = Reflect.getOwnMetadata(`__queryParameters__${route.methodName}`, this.constructor.prototype, route.methodName) || [];
if (route.requestMethod) {
// Add the route to the openapi paths
this.openapiPaths[(0, utils_1.pathFormatter)(this.prefix + route.path)] = {
...this.openapiPaths[(0, utils_1.pathFormatter)(this.prefix + route.path)],
[route.requestMethod]: {
...route.openApi,
parameters: paramsMetadata
.concat(queryMetedata)
.map((param) => ({
name: param.paramName,
in: param.type === "param" ? "path" : "query",
required: param.options?.required === false ? false : true,
description: param.options?.description,
schema: param.options?.schema,
})),
},
};
// Add the requestBody to the openapi paths
bodyMetadata.forEach((param) => {
this.openapiPaths[(0, utils_1.pathFormatter)(this.prefix + route.path)][route.requestMethod].requestBody = {
content: {
[route.multer ? "multipart/form-data" : "application/json"]: {
schema: {
$ref: `#/definitions/${param.options.type.name}`,
},
},
},
};
});
// Add the route to the express router
this.router[route.requestMethod](route.path, this.Middlewares
? route.middlewares
? [...this.Middlewares, ...route.middlewares]
: this.Middlewares
: route.middlewares || [], async (req, res) => {
try {
const args = this.extractParameters(req, paramsMetadata.concat(queryMetedata).concat(bodyMetadata), {
multer: route.multer && {
path: route.multer.path,
single: route.multer.type === "single",
},
});
const result = await this.constructor.prototype[route.methodName](...args);
if (req.headers.accept === "application/xml") {
res.setHeader("Content-Type", "application/xml");
const xml = js2xmlparser.parse("data", result);
return res.send(xml);
}
//interceptor
if (req.meta) {
const interceptors = Reflect.getMetadata("GlobalInterceptors", appContructor);
interceptors?.sort(-1).forEach((interceptor) => {
const req_interceptor = new interceptor();
req_interceptor.data = req.meta[interceptor.name];
req_interceptor.complete();
});
}
delete req.meta;
res.json(result);
}
catch (error) {
res.status(500).json({ error: error.message });
}
});
}
});
}
extractParameters(req, paramsMetadata, options) {
const args = [];
for (const { isObject, type, paramName, parameterIndex, } of paramsMetadata) {
const usedIndexes = [];
if (usedIndexes.includes(parameterIndex)) {
break;
}
usedIndexes.push(parameterIndex);
switch (type) {
case "param":
if (paramName.length === 0) {
break;
}
args[parameterIndex] = req.params[paramName];
break;
case "body":
console.log("body", options);
args[parameterIndex] = options.multer
? {
...req.body,
[options.multer.path]: options.multer.single
? req.file
: req.files,
}
: req.body;
break;
case "query":
args[parameterIndex] = isObject ? req.query : req.query[paramName];
break;
}
}
return args;
}
}
exports.Controller = Controller;
//# sourceMappingURL=Controller.js.map
;