UNPKG

http-reply

Version:

A lightweight Node.js utility for sending consistent, standardized HTTP responses across your API endpoints

223 lines (219 loc) 8.78 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // index.ts var index_exports = {}; __export(index_exports, { HttpReply: () => HttpReply, default: () => index_default }); module.exports = __toCommonJS(index_exports); // logger.ts var formatMessage = (msg) => { if (typeof msg === "object" && msg !== null) { try { return JSON.stringify(msg, null, 2); } catch { return "[Unserializable Object]"; } } return String(msg); }; var ErrorLog = (error, label = "ERROR") => { console.error(`\x1B[31m[${label}] ${formatMessage(error)}\x1B[0m`); }; // index.ts function isResponseLike(res) { return res && typeof res === "object" && (typeof res.status === "function" && typeof res.json === "function" || typeof res.code === "function" && typeof res.send === "function"); } var HttpReply = class _HttpReply { constructor(config = {}) { this.config = { includeTimestamp: false, includeCode: true, includeMessage: true, includeError: true, includeMetaData: true, enableLogging: true, stringify: false, customFields: {}, dateFormat: "unix", adapter: null, ...config }; } _sendResponse(res, responseBody, statusCode, extraFields = {}) { if (!isResponseLike(res) && typeof this.config.adapter !== "function") { if (this.config.enableLogging) { ErrorLog( `Response object does not match Express or Fastify, and no custom adapter was provided.`, "[HttpReply Error]" ); } throw new Error( `[HttpReply Error] Invalid response object. Must be Express, Fastify, or use a custom adapter.` ); } const response = { ...responseBody }; if (this.config.includeTimestamp) { response.timestamp = this.config.dateFormat === "unix" ? Math.floor(Date.now() / 1e3) : this.config.dateFormat === "iso" ? (/* @__PURE__ */ new Date()).toISOString() : (() => { const msg = `[HttpReply Configuration Error] Invalid "dateFormat": "${this.config.dateFormat}". Expected "iso" or "unix".`; if (this.config.enableLogging) ErrorLog(msg, "[HttpReply Configuration Error]"); throw new Error(msg); })(); } if (!this.config.includeCode) delete response.code; if (!this.config.includeMessage) delete response.message; if (!this.config.includeError) delete response.error; if (!this.config.includeMetaData) delete response.metaData; Object.assign(response, this.config.customFields, extraFields); let payload = response; if (this.config.stringify) { try { payload = JSON.stringify(response); } catch (err) { if (this.config.enableLogging) { ErrorLog(`Failed to stringify response: ${err.message}`, "[HttpReply Error]"); } throw err; } } if (typeof this.config.adapter === "function") { return this.config.adapter(res, statusCode, payload); } if ("status" in res && typeof res.status === "function" && typeof res.json === "function") { return this.config.stringify ? res.status(statusCode).type?.("application/json").send(payload) : res.status(statusCode).json(payload); } if ("code" in res && typeof res.code === "function" && typeof res.send === "function") { return this.config.stringify ? res.code(statusCode).type?.("application/json").send(payload) : res.code(statusCode).send(payload); } } response(res, opts) { const { message = "Api Processed", data = null, metaData = {}, code = 200, error = null, extra = {} } = opts; const body = { message, data, metaData, error, code }; return this._sendResponse(res, body, code, extra); } success(res, opts = {}) { const { message = "Success", data = null, metaData = {}, code = 200, extra = {} } = opts; const body = { message, data, metaData, code }; return this._sendResponse(res, body, code, extra); } created(res, opts = {}) { const { message = "Resource Created Successfully", data = null, metaData = {}, code = 201, extra = {} } = opts; const body = { message, data, metaData, code }; return this._sendResponse(res, body, code, extra); } accepted(res, opts = {}) { const { message = "Accepted", data = null, metaData = {}, code = 202, extra = {} } = opts; const body = { message, data, metaData, code }; return this._sendResponse(res, body, code, extra); } noContent(res, opts = {}) { const { code = 204 } = opts; if (typeof this.config.adapter === "function") { return this.config.adapter(res, code, null); } if ("status" in res && typeof res.status === "function" && typeof res.send === "function") { return res.status(code).send(); } if ("code" in res && typeof res.code === "function" && typeof res.send === "function") { return res.code(code).send(); } } error(res, opts = {}) { const { message = "Internal Server Error", error = null, metaData = {}, code = 500, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } rejected(res, opts = {}) { const { message = "Request Rejected", error = null, metaData = {}, code = 400, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } conflict(res, opts = {}) { const { message = "Conflict", error = null, metaData = {}, code = 409, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } badRequest(res, opts = {}) { const { message = "Bad Request", error = null, metaData = {}, code = 400, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } tooManyRequests(res, opts = {}) { const { message = "Too Many Requests", error = null, metaData = {}, code = 429, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } notImplemented(res, opts = {}) { const { message = "Not Implemented", error = null, metaData = {}, code = 501, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } serviceUnavailable(res, opts = {}) { const { message = "Service Unavailable", error = null, metaData = {}, code = 503, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } forbidden(res, opts = {}) { const { message = "Forbidden", error = null, metaData = {}, code = 403, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } unauthorized(res, opts = {}) { const { message = "Unauthorized", error = null, metaData = {}, code = 401, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } notFound(res, opts = {}) { const { message = "Not Found", error = null, metaData = {}, code = 404, extra = {} } = opts; const body = { message, error, metaData, code }; return this._sendResponse(res, body, code, extra); } static createMethodShortcuts() { const methods = [ "success", "error", "rejected", "created", "forbidden", "unauthorized", "notFound", "response", "accepted", "noContent", "conflict", "tooManyRequests", "badRequest", "notImplemented", "serviceUnavailable" ]; for (const method of methods) { _HttpReply[method] = (res, args = {}) => { const instance = new _HttpReply(); return instance[method](res, args); }; } } }; HttpReply.createMethodShortcuts(); var index_default = HttpReply; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { HttpReply });