helpers.handler.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. const { validationResult } = require("express-validator");
  2. const signale = require("signale");
  3. const { logger } = require("../config/winston");
  4. const { CustomError } = require("../utils");
  5. const env = require("../env");
  6. // export const ip: Handler = (req, res, next) => {
  7. // req.realIP =
  8. // (req.headers["x-real-ip"] as string) || req.connection.remoteAddress || "";
  9. // return next();
  10. // };
  11. /**
  12. * @type {import("express").Handler}
  13. */
  14. function isHTML(req, res, next) {
  15. const accepts = req.accepts(["json", "html"]);
  16. req.isHTML = accepts === "html";
  17. next();
  18. }
  19. /**
  20. * @type {import("express").Handler}
  21. */
  22. function noRenderLayout(req, res, next) {
  23. res.locals.layout = null;
  24. next();
  25. }
  26. function viewTemplate(template) {
  27. return function (req, res, next) {
  28. req.viewTemplate = template;
  29. next();
  30. }
  31. }
  32. /**
  33. * @type {import("express").ErrorRequestHandler}
  34. */
  35. function error(error, req, res, _next) {
  36. if (env.isDev) {
  37. signale.fatal(error);
  38. }
  39. const message = error instanceof CustomError ? error.message : "An error occurred.";
  40. const statusCode = error.statusCode ?? 500;
  41. if (req.isHTML && req.viewTemplate) {
  42. res.render(req.viewTemplate, { error: message });
  43. return;
  44. }
  45. return res.status(500).json({ error: message });
  46. };
  47. /**
  48. * @type {import("express").Handler}
  49. */
  50. function verify(req, res, next) {
  51. const result = validationResult(req);
  52. if (result.isEmpty()) return next();
  53. const errors = result.array();
  54. const error = errors[0].msg;
  55. res.locals.errors = {};
  56. errors.forEach(e => {
  57. if (res.locals.errors[e.param]) return;
  58. res.locals.errors[e.param] = e.msg;
  59. });
  60. throw new CustomError(error, 400);
  61. }
  62. function query(req, res, next) {
  63. const { admin } = req.user || {};
  64. if (
  65. typeof req.query.limit !== "undefined" &&
  66. typeof req.query.limit !== "string"
  67. ) {
  68. return res.status(400).json({ error: "limit query is not valid." });
  69. }
  70. if (
  71. typeof req.query.skip !== "undefined" &&
  72. typeof req.query.skip !== "string"
  73. ) {
  74. return res.status(400).json({ error: "skip query is not valid." });
  75. }
  76. if (
  77. typeof req.query.search !== "undefined" &&
  78. typeof req.query.search !== "string"
  79. ) {
  80. return res.status(400).json({ error: "search query is not valid." });
  81. }
  82. const limit = parseInt(req.query.limit) || 10;
  83. const skip = parseInt(req.query.skip) || 0;
  84. req.context = {
  85. limit: limit > 50 ? 50 : limit,
  86. skip,
  87. all: admin ? req.query.all === "true" : false
  88. };
  89. next();
  90. };
  91. module.exports = {
  92. error,
  93. isHTML,
  94. noRenderLayout,
  95. query,
  96. verify,
  97. viewTemplate,
  98. }