"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.appendModelData = exports.successfulResponse = exports.errorHandler = exports.asyncHandler = exports.asyncMiddlewareHandler = void 0;
const utils_1 = require("./utils");
/**
* @example
* const { asyncMiddlewareHandler } = require("emfrest/middleware")
*
* const anAsyncFunction = asyncMiddlewareHandler((req, res, next) => {
* const data = await something()
*
* next()
* })
*
* @description Wrapper for any async middleware functions.
*
* @param {Function} fn Async express middleware function to be wrapped.
*
* @returns {Promise<any>} A resolved promise or an error.
*/
const asyncMiddlewareHandler = (fn) => {
return (req, res, next) => {
return Promise.resolve(fn(req, res, next)).catch(next);
};
};
exports.asyncMiddlewareHandler = asyncMiddlewareHandler;
/**
* @example
* const { asyncHandler } = require("emfrest/middleware")
*
* @example <caption>Usage</caption>
* const anAsyncFunction = asyncHandler((a, b, c, d, e, ...rest) => {
* const data = await something()
*
* return datas
* })
*
* @description Wrapper for any async functions. Handles the error
*
* @param {Function} fn Async function to be wrapped. This function can have any number of parameters.
*
* @returns {Promise<any>} A resolved promise or an error.
*/
function asyncHandler(fn) {
return function (...params) {
return Promise.resolve(fn(...params)).catch(params[2] ? params[2] : () => { });
};
}
exports.asyncHandler = asyncHandler;
/**
* @example
* const { errorHandler } = require("emfrest")
*
* @example <caption>Usage</caption>
* app.use(errorHandler);
*
* @description Function to send a response with an error.
*
* @param {Error} err Error object.
* @param {Request} req Express request object.
* @param {Response} res Express response object.
* @param {Next} next Express next function.
*/
const errorHandler = (err, req, res, next) => {
let error = { ...err };
error.message = err.message;
// Log to console for dev
console.log(err);
// Mongoose bad ObjectId
if (err.name === "CastError") {
const message = `Resource not found`;
error = new utils_1.ErrorResponse(message, 404);
}
// Mongoose duplicate key
if (err.code === 11000) {
const message = "Duplicate field value entered";
error = new utils_1.ErrorResponse(message, 400);
}
// Mongoose validation error
if (err.name === "ValidationError") {
const message = Object.values(err.errors)
.map((val) => val.message)
.join(", ");
error = new utils_1.ErrorResponse(message, 400);
}
res.status(error.statusCode || 500).json({
success: false,
error: error.message || "Server Error",
});
};
exports.errorHandler = errorHandler;
/**
* @example
* const { successfulResponse } = require("emfrest/middleware")
*
* @example <caption>Usage</caption>
* successfulResponse(
* res,
* 200,
* `The documents were successfully found.`,
* data
* );
*
* @description Function to send a successful response.
*
* @param {Response} res Express response object.
* @param {number} statusCode Http status code for the response.
* @param {string} message Message for the response body.
* @param {any} data Any data to send with the reponse.
*/
const successfulResponse = (res, statusCode, message, data) => {
res.status(statusCode).json({
success: true,
message: message,
data: data,
});
};
exports.successfulResponse = successfulResponse;
/**
* @example
* const { appendModelData } = require("emfrest/middleware")
*
* @example <caption>Usage</caption>
* router
* .route(`/:${modelName}Id`)
* .get(appendModelData(model, modelName), getOneByIdController)
* .put(appendModelData(model, modelName), updateOneByIdController)
* .delete(appendModelData(model, modelName), deleteOneByIdController);
*
* @description Middleware function to add model and modelName to the request object. Makes req.emfrest_model and req.emfrest_modelName accessible.
*
* @param {mongoose.model} model Mongoose model.
* @param {string} modelName Model name (singular).
*
* @returns {function} An express middleware function
*/
const appendModelData = (model, modelName) => {
return (req, res, next) => {
req.emfrest_model = model;
req.emfrest_modelName = modelName;
next();
};
};
exports.appendModelData = appendModelData;