@tdsoft/express-routing-wrapper
Version:
Package gives you level of abstraction/wrapping of express router(s), endpoints and middlewares, additionally defining subrouters makes tree structure possible and easily discoverable by root router.
75 lines (66 loc) • 2.49 kB
JavaScript
const logger = console; // temporary
const _ = require("lodash");
const createError = require("http-errors");
class ApiEndpoint {
constructor({
access, method,
reqBody, reqDbModel, reqQuery, reqCookies, reqHeaders, reqPath,
resBody, resDbModel, resCookies
},
cb = () => logger.warn("Endpoint has no cb provided!")) {
this.def = {method};
this.def.access = {...access};
this.def.req = {
body: reqBody,
dbModel: reqDbModel,
query: reqQuery,
cookies: reqCookies,
headers: reqHeaders,
path: reqPath
};
this.def.res = {body: resBody, dbModel: resDbModel, cookies: resCookies};
this.cb = cb;
}
async expressFn(req, res, next) {
const credentials = await this._checkAccessRights(req, res, next);
if (credentials.err) return;
const errorMsgs = [
...this.checkBodyParams(req),
...this.checkQueryParams(req),
];
// logger.debug(`this.cb: `, this.cb, this.cb());
if (errorMsgs.length) {
next(createError.BadRequest(errorMsgs.join("</br>\n")));
} else {
try {
return await this.cb(req, res, next);
} catch (error) {
logger.error(`Error caught: `, error);
return next(error);
}
}
}
async _checkAccessRights(req, res, next) {
const {access} = this.def;
if (access && access.level && access.cb) {
return await access.cb(req, res, next, access.level);
}
return {};
}
_checkRequiredParams(reqAcess, paramsObj, paramsDesc = "") {
const reqBodyFields = _.chain(paramsObj)
.reduce((reducer, v, field) => [...reducer, (v.required && field)], [])
.compact().value();
//.map((v, key) => key);
const notPassedFields = reqBodyFields.reduce((reducer, field) => (reqAcess[field]) ? reducer :
[...reducer, `Passed${paramsDesc} parameters don't contain required "${field}" field.`], []);
return notPassedFields;
}
checkBodyParams(req) {
return this._checkRequiredParams(req.body, this.def.body, " body");
}
checkQueryParams(req) {
return this._checkRequiredParams(req.query, this.def.query, " query");
}
}
module.exports = ApiEndpoint;