| // This file is auto-generated to support require() default imports | ||
| module.exports = require('../index.cjs').default; |
+222
| "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 | ||
| }); |
| type ResponseLike = { | ||
| status: (code: number) => any; | ||
| json: (body: any) => any; | ||
| type?: (mime: string) => any; | ||
| send: (body?: any) => any; | ||
| } | { | ||
| code: (code: number) => any; | ||
| send: (body?: any) => any; | ||
| type?: (mime: string) => any; | ||
| }; | ||
| type AdapterFunction = (res: any, statusCode: number, payload: any) => any; | ||
| interface HttpReplyConfig { | ||
| includeTimestamp?: boolean; | ||
| includeCode?: boolean; | ||
| includeMessage?: boolean; | ||
| includeError?: boolean; | ||
| includeMetaData?: boolean; | ||
| enableLogging?: boolean; | ||
| stringify?: boolean; | ||
| customFields?: Record<string, any>; | ||
| dateFormat?: "iso" | "unix"; | ||
| adapter?: AdapterFunction | null; | ||
| } | ||
| interface HttpReplyOptions { | ||
| message?: string; | ||
| data?: any; | ||
| metaData?: Record<string, any>; | ||
| code?: number; | ||
| error?: any; | ||
| extra?: Record<string, any>; | ||
| } | ||
| declare class HttpReply { | ||
| private config; | ||
| constructor(config?: HttpReplyConfig); | ||
| private _sendResponse; | ||
| response(res: ResponseLike, opts: HttpReplyOptions): any; | ||
| success(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| created(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| accepted(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| noContent(res: ResponseLike, opts?: { | ||
| message?: string; | ||
| code?: number; | ||
| extra?: Record<string, any>; | ||
| }): any; | ||
| error(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| rejected(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| conflict(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| badRequest(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| tooManyRequests(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| notImplemented(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| serviceUnavailable(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| forbidden(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| unauthorized(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| notFound(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| static createMethodShortcuts(): void; | ||
| } | ||
| export { HttpReply, HttpReply as default }; |
| type ResponseLike = { | ||
| status: (code: number) => any; | ||
| json: (body: any) => any; | ||
| type?: (mime: string) => any; | ||
| send: (body?: any) => any; | ||
| } | { | ||
| code: (code: number) => any; | ||
| send: (body?: any) => any; | ||
| type?: (mime: string) => any; | ||
| }; | ||
| type AdapterFunction = (res: any, statusCode: number, payload: any) => any; | ||
| interface HttpReplyConfig { | ||
| includeTimestamp?: boolean; | ||
| includeCode?: boolean; | ||
| includeMessage?: boolean; | ||
| includeError?: boolean; | ||
| includeMetaData?: boolean; | ||
| enableLogging?: boolean; | ||
| stringify?: boolean; | ||
| customFields?: Record<string, any>; | ||
| dateFormat?: "iso" | "unix"; | ||
| adapter?: AdapterFunction | null; | ||
| } | ||
| interface HttpReplyOptions { | ||
| message?: string; | ||
| data?: any; | ||
| metaData?: Record<string, any>; | ||
| code?: number; | ||
| error?: any; | ||
| extra?: Record<string, any>; | ||
| } | ||
| declare class HttpReply { | ||
| private config; | ||
| constructor(config?: HttpReplyConfig); | ||
| private _sendResponse; | ||
| response(res: ResponseLike, opts: HttpReplyOptions): any; | ||
| success(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| created(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| accepted(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| noContent(res: ResponseLike, opts?: { | ||
| message?: string; | ||
| code?: number; | ||
| extra?: Record<string, any>; | ||
| }): any; | ||
| error(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| rejected(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| conflict(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| badRequest(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| tooManyRequests(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| notImplemented(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| serviceUnavailable(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| forbidden(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| unauthorized(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| notFound(res: ResponseLike, opts?: HttpReplyOptions): any; | ||
| static createMethodShortcuts(): void; | ||
| } | ||
| export { HttpReply, HttpReply as default }; |
+195
| // 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; | ||
| export { | ||
| HttpReply, | ||
| index_default as default | ||
| }; |
+27
-4
| { | ||
| "name": "http-reply", | ||
| "version": "0.2.2", | ||
| "version": "1.0.0", | ||
| "description": "A lightweight Node.js utility for sending consistent, standardized HTTP responses across your API endpoints", | ||
| "main": "index.js", | ||
| "main": "./dist/index.js", | ||
| "module": "./dist/cjs/index.cjs", | ||
| "types": "./dist/index.d.ts", | ||
| "type": "module", | ||
| "exports": { | ||
| ".": { | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/cjs/index.cjs", | ||
| "types": "./dist/index.d.ts" | ||
| } | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "README.md", | ||
| "LICENSE" | ||
| ], | ||
| "scripts": { | ||
| "build": "tsup", | ||
| "dev": "tsup --watch", | ||
| "postbuild": "node makeExportFile.js", | ||
| "clean": "rm -rf dist", | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
@@ -11,3 +30,3 @@ }, | ||
| "type": "git", | ||
| "url": "git+https://github.com/HarshDev1809/http-reply.git" | ||
| "url": "https://github.com/HarshDev1809/http-reply.git" | ||
| }, | ||
@@ -41,3 +60,7 @@ "keywords": [ | ||
| }, | ||
| "homepage": "https://github.com/HarshDev1809/http-reply#readme" | ||
| "homepage": "https://github.com/HarshDev1809/http-reply#readme", | ||
| "devDependencies": { | ||
| "tsup": "^8.5.0", | ||
| "typescript": "^5.8.3" | ||
| } | ||
| } |
+69
-70
| # HttpReply | ||
| A lightweight, flexible Node.js utility for standardizing HTTP responses in Express, Fastify, or custom server frameworks. `HttpReply` provides a consistent way to format and send HTTP responses with customizable options, including support for timestamps, error logging, and custom adapters. | ||
| A lightweight, flexible Node.js utility for standardizing HTTP responses in Express, Fastify, or custom server frameworks. `HttpReply` provides a consistent, customizable way to format and send HTTP responses, with support for timestamps, error logging, and custom adapters. Available as both ES6 modules and CommonJS, with no need for `.default` in ES module imports. | ||
| ## Features | ||
| - **Framework Agnostic**: Works with Express, Fastify, or custom adapters. | ||
| - **Framework Agnostic**: Compatible with Express, Fastify, or custom frameworks via adapters. | ||
| - **Standardized Responses**: Ensures consistent response structure across your API. | ||
| - **Configurable**: Customize response fields, timestamps, and logging behavior. | ||
| - **Static Methods**: Easily send responses without instantiating the class. | ||
| - **Configurable Options**: Customize response fields, timestamps, logging, and more. | ||
| - **Static Methods**: Send responses without instantiating the class. | ||
| - **Error Handling**: Built-in validation and logging for invalid configurations or response objects. | ||
| - **TypeScript Support**: Fully typed for TypeScript users (types included). | ||
| - **TypeScript Support**: Fully typed with included TypeScript declarations. | ||
| - **ES6 and CommonJS Support**: Use with `import` or `require`, no `.default` required for ES modules. | ||
@@ -19,3 +20,3 @@ ## Installation | ||
| ```bash | ||
| npm i http-reply | ||
| npm install http-reply | ||
| ``` | ||
@@ -25,22 +26,33 @@ | ||
| ### Basic Setup | ||
| ### Importing the Package | ||
| Require the `HttpReply` class and use it in your Express or Fastify application. | ||
| The package supports both ES6 modules and CommonJS: | ||
| ```javascript | ||
| const HttpReply = require("http-reply"); | ||
| // ES6 Module | ||
| import { HttpReply } from 'http-reply'; | ||
| // Express example | ||
| const express = require("express"); | ||
| // CommonJS | ||
| const { HttpReply } = require('http-reply'); | ||
| ``` | ||
| ### Basic Example (Express) | ||
| Use `HttpReply` to send standardized responses in your Express or Fastify application. | ||
| ```javascript | ||
| import { HttpReply } from 'http-reply'; | ||
| import express from 'express'; | ||
| const app = express(); | ||
| app.get("/example", (req, res) => { | ||
| app.get('/example', (req, res) => { | ||
| HttpReply.success(res, { | ||
| message: "Operation successful", | ||
| data: { user: "John Doe" }, | ||
| metaData: { requestId: "12345" }, | ||
| message: 'Operation successful', | ||
| data: { user: 'John Doe' }, | ||
| metaData: { requestId: '12345' }, | ||
| }); | ||
| }); | ||
| app.listen(3000, () => console.log("Server running on port 3000")); | ||
| app.listen(3000, () => console.log('Server running on port 3000')); | ||
| ``` | ||
@@ -50,8 +62,8 @@ | ||
| You can create a centralized `HttpReply` instance with predefined configuration in a dedicated file (e.g., `responder.js`) and import it across your application. | ||
| Create a centralized `HttpReply` instance for consistent configuration across your application. | ||
| Create a file named `responder.js`: | ||
| Create a file (e.g., `responder.js`): | ||
| ```javascript | ||
| const HttpReply = require('http-reply'); | ||
| import { HttpReply } from 'http-reply'; | ||
@@ -62,17 +74,19 @@ const reply = new HttpReply({ | ||
| enableLogging: true, | ||
| customFields: { apiVersion: '1.0.0' }, | ||
| }); | ||
| module.exports = reply; | ||
| export default reply; | ||
| ``` | ||
| Then, import and use it in your routes: | ||
| Use it in your routes: | ||
| ```javascript | ||
| const reply = require("./responder"); | ||
| const express = require("express"); | ||
| import reply from './responder'; | ||
| import express from 'express'; | ||
| const app = express(); | ||
| app.get("/example", (req, res) => { | ||
| app.get('/example', (req, res) => { | ||
| reply.success(res, { | ||
| message: "Custom response", | ||
| message: 'Custom response', | ||
| data: { id: 1 }, | ||
@@ -82,40 +96,20 @@ }); | ||
| app.listen(3000, () => console.log("Server running on port 3000")); | ||
| app.listen(3000, () => console.log('Server running on port 3000')); | ||
| ``` | ||
| ### Creating an Instance with Custom Configuration | ||
| ### Static Methods | ||
| You can instantiate `HttpReply` with custom configuration options. | ||
| Use static methods for quick responses without instantiation: | ||
| ```javascript | ||
| const HttpReply = require("http-reply"); | ||
| import { HttpReply } from 'http-reply'; | ||
| const reply = new HttpReply({ | ||
| includeTimestamp: true, | ||
| dateFormat: "iso", | ||
| enableLogging: true, | ||
| customFields: { version: "1.0.0" }, | ||
| }); | ||
| app.get("/custom", (req, res) => { | ||
| reply.success(res, { | ||
| message: "Custom response", | ||
| data: { id: 1 }, | ||
| }); | ||
| }); | ||
| ``` | ||
| ### Static Methods | ||
| Use static methods for quick responses without instantiation. | ||
| ```javascript | ||
| HttpReply.created(res, { | ||
| message: "User created", | ||
| data: { id: 123, name: "Jane Doe" }, | ||
| message: 'User created', | ||
| data: { id: 123, name: 'Jane Doe' }, | ||
| }); | ||
| HttpReply.notFound(res, { | ||
| message: "Resource not found", | ||
| error: "Invalid ID", | ||
| message: 'Resource not found', | ||
| error: 'Invalid ID', | ||
| }); | ||
@@ -126,6 +120,6 @@ ``` | ||
| `HttpReply` supports the following response methods, each corresponding to common HTTP status codes: | ||
| `HttpReply` provides methods for common HTTP status codes: | ||
| | Method | Status Code | Description | | ||
| | -------------------- | ----------- | ---------------------------------------- | | ||
| |----------------------|-------------|------------------------------------------| | ||
| | `success` | 200 | Successful request | | ||
@@ -148,6 +142,6 @@ | `created` | 201 | Resource created successfully | | ||
| When creating an instance of `HttpReply`, you can pass a configuration object with the following options: | ||
| Customize `HttpReply` with the following options when creating an instance: | ||
| | Option | Type | Default | Description | | ||
| | ------------------ | -------- | -------- | ------------------------------------------------------------------------ | | ||
| |--------------------|----------|----------|--------------------------------------------------------------------------| | ||
| | `includeTimestamp` | Boolean | `false` | Include a timestamp in the response (`iso` or `unix` format). | | ||
@@ -162,14 +156,15 @@ | `includeCode` | Boolean | `true` | Include the status code in the response body. | | ||
| | `dateFormat` | String | `'unix'` | Format for timestamps (`'iso'` or `'unix'`). | | ||
| | `adapter` | Function | `null` | Custom adapter function for non-Express/Fastify frameworks. | | ||
| | `adapter` | Function | `null` | Custom adapter for non-Express/Fastify frameworks. | | ||
| ### Custom Adapter Example | ||
| For frameworks other than Express or Fastify, provide a custom adapter. | ||
| For non-Express/Fastify frameworks, provide a custom adapter: | ||
| ```javascript | ||
| import { HttpReply } from 'http-reply'; | ||
| const reply = new HttpReply({ | ||
| adapter: (res, statusCode, payload) => { | ||
| // Custom response handling | ||
| res.writeStatusCode(statusCode); | ||
| res.writeBody(payload); | ||
| res.setStatusCode(statusCode); | ||
| res.setBody(payload); | ||
| return res; | ||
@@ -180,4 +175,4 @@ }, | ||
| reply.success(res, { | ||
| message: "Custom adapter response", | ||
| data: { key: "value" }, | ||
| message: 'Custom adapter response', | ||
| data: { key: 'value' }, | ||
| }); | ||
@@ -192,4 +187,4 @@ ``` | ||
| HttpReply.success(res, { | ||
| message: "User fetched", | ||
| data: { id: 1, name: "John" }, | ||
| message: 'User fetched', | ||
| data: { id: 1, name: 'John' }, | ||
| metaData: { total: 1 }, | ||
@@ -205,3 +200,4 @@ }); | ||
| "data": { "id": 1, "name": "John" }, | ||
| "metaData": { "total": 1 } | ||
| "metaData": { "total": 1 }, | ||
| "code": 200 | ||
| } | ||
@@ -217,3 +213,4 @@ ``` | ||
| "metaData": { "total": 1 }, | ||
| "timestamp": "2025-05-27T17:52:00.000Z" | ||
| "code": 200, | ||
| "timestamp": "2025-06-13T17:25:00.000Z" | ||
| } | ||
@@ -229,3 +226,3 @@ ``` | ||
| Contributions are welcome! Please follow these steps: | ||
| We welcome contributions! To contribute: | ||
@@ -238,2 +235,4 @@ 1. Fork the repository. | ||
| Please ensure your code follows the project's coding standards and includes tests where applicable. | ||
| ## License | ||
@@ -245,2 +244,2 @@ | ||
| For questions or support, open an issue on the [GitHub repository](https://github.com/HarshDev1809/http-reply/issues) or contact the maintainer at [dev182000@gmail.com](dev182000@gmail.com). | ||
| For questions or support, open an issue on the [GitHub repository](https://github.com/HarshDev1809/http-reply/issues) or contact the maintainer at [dev182000@gmail.com](mailto:dev182000@gmail.com). |
-272
| const { ErrorLog } = require("./logger"); | ||
| function isResponseLike(res) { | ||
| return ( | ||
| res && | ||
| typeof res === "object" && | ||
| ((typeof res.status === "function" && typeof res.json === "function") || | ||
| (typeof res.code === "function" && typeof res.send === "function")) | ||
| ); | ||
| } | ||
| class HttpReply { | ||
| constructor(config = {}) { | ||
| this.config = { | ||
| includeTimestamp: false, | ||
| includeCode: true, | ||
| includeMessage: true, | ||
| includeError: true, | ||
| includeMetaData: true, | ||
| enableLogging: true, | ||
| stringify: false, | ||
| customFields: {}, | ||
| dateFormat: "unix", // 'iso', 'unix' | ||
| adapter: null, // Optional custom adapter | ||
| ...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 }; | ||
| // Timestamp | ||
| if (this.config.includeTimestamp) { | ||
| if (this.config.dateFormat === "unix") { | ||
| response.timestamp = Math.floor(Date.now() / 1000); | ||
| } else if (this.config.dateFormat === "iso") { | ||
| response.timestamp = new Date().toISOString(); | ||
| } else { | ||
| if (this.config.enableLogging) { | ||
| ErrorLog( | ||
| `Invalid "dateFormat" value: "${this.config.dateFormat}". Expected "iso" or "unix".`, | ||
| "[HttpReply Configuration Error]" | ||
| ); | ||
| } | ||
| throw new Error( | ||
| `[HttpReply Configuration Error] Invalid "dateFormat" value: "${this.config.dateFormat}". Expected "iso" or "unix".` | ||
| ); | ||
| } | ||
| } | ||
| // Cleanup unwanted fields | ||
| 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; | ||
| // Merge customFields and extraFields | ||
| Object.assign(response, this.config.customFields, extraFields); | ||
| // Handle stringify | ||
| 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; | ||
| } | ||
| } | ||
| // Send response via adapter if provided | ||
| if (typeof this.config.adapter === "function") { | ||
| return this.config.adapter(res, statusCode, payload); | ||
| } | ||
| // Express style response | ||
| if (typeof res.status === "function" && typeof res.json === "function") { | ||
| if (this.config.stringify) { | ||
| return res.status(statusCode).type("application/json").send(payload); | ||
| } | ||
| return res.status(statusCode).json(payload); | ||
| } | ||
| // Fastify style response | ||
| if (typeof res.code === "function" && typeof res.send === "function") { | ||
| if (this.config.stringify) { | ||
| return res.code(statusCode).type("application/json").send(payload); | ||
| } | ||
| return res.code(statusCode).send(payload); | ||
| } | ||
| } | ||
| response( | ||
| res, | ||
| { | ||
| message = "Api Processed", | ||
| data = null, | ||
| metaData = {}, | ||
| code = 200, | ||
| error = null, | ||
| extra = {}, | ||
| } | ||
| ) { | ||
| const body = { message, data, metaData, error }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| success( | ||
| res, | ||
| { message = "Success", data = null, metaData = {}, code = 200, extra = {} } = {} | ||
| ) { | ||
| const body = { message, data, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| accepted( | ||
| res, | ||
| { message = "Accepted", data = null, metaData = {}, code = 202, extra = {} } = {} | ||
| ) { | ||
| const body = { message, data, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| noContent(res, { message = "No Content", code = 204, extra = {} } = {}) { | ||
| // No content: Send no body | ||
| if (typeof this.config.adapter === "function") { | ||
| return this.config.adapter(res, code, null); | ||
| } | ||
| if (typeof res.status === "function" && typeof res.send === "function") { | ||
| return res.status(code).send(); | ||
| } | ||
| if (typeof res.code === "function" && typeof res.send === "function") { | ||
| return res.code(code).send(); | ||
| } | ||
| } | ||
| conflict( | ||
| res, | ||
| { message = "Conflict", error = null, metaData = {}, code = 409, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| tooManyRequests( | ||
| res, | ||
| { message = "Too Many Requests", error = null, metaData = {}, code = 429, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| badRequest( | ||
| res, | ||
| { message = "Bad Request", error = null, metaData = {}, code = 400, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| notImplemented( | ||
| res, | ||
| { message = "Not Implemented", error = null, metaData = {}, code = 501, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| serviceUnavailable( | ||
| res, | ||
| { message = "Service Unavailable", error = null, metaData = {}, code = 503, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| error( | ||
| res, | ||
| { message = "Internal Server Error", error = null, metaData = {}, code = 500, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| rejected( | ||
| res, | ||
| { message = "Request Rejected", error = null, metaData = {}, code = 400, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| created( | ||
| res, | ||
| { message = "Resource Created Successfully", data = null, metaData = {}, code = 201, extra = {} } = {} | ||
| ) { | ||
| const body = { message, data, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| forbidden( | ||
| res, | ||
| { message = "Forbidden", error = null, metaData = {}, code = 403, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| unauthorized( | ||
| res, | ||
| { message = "Unauthorized", error = null, metaData = {}, code = 401, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| notFound( | ||
| res, | ||
| { message = "Not Found", error = null, metaData = {}, code = 404, extra = {} } = {} | ||
| ) { | ||
| const body = { message, error, metaData }; | ||
| return this._sendResponse(res, body, code, extra); | ||
| } | ||
| } | ||
| const methods = [ | ||
| "success", | ||
| "error", | ||
| "rejected", | ||
| "created", | ||
| "forbidden", | ||
| "unauthorized", | ||
| "notFound", | ||
| "response", | ||
| "accepted", | ||
| "noContent", | ||
| "conflict", | ||
| "tooManyRequests", | ||
| "badRequest", | ||
| "notImplemented", | ||
| "serviceUnavailable", | ||
| ]; | ||
| methods.forEach((method) => { | ||
| HttpReply[method] = function (res, args = {}) { | ||
| const instance = new HttpReply(); | ||
| // For noContent, only pass res and args as message/code object | ||
| if (method === "noContent") { | ||
| return instance.noContent(res, args); | ||
| } | ||
| return instance[method](res, args); | ||
| }; | ||
| }); | ||
| module.exports = HttpReply; | ||
-27
| const Log = (message, label = 'INFO') => { | ||
| console.log(`[${label}] ${formatMessage(message)}`); | ||
| }; | ||
| const ErrorLog = (error, label = 'ERROR') => { | ||
| console.error(`\x1b[31m[${label}] ${formatMessage(error)}\x1b[0m`); | ||
| }; | ||
| const WarnLog = (warning, label = 'WARN') => { | ||
| console.warn(`\x1b[33m[${label}] ${formatMessage(warning)}\x1b[0m`); | ||
| }; | ||
| // Utility to handle objects, arrays, etc. | ||
| const formatMessage = (msg) => { | ||
| if (typeof msg === 'object') { | ||
| try { | ||
| return JSON.stringify(msg, null); // Pretty print | ||
| } catch (e) { | ||
| return '[Unserializable Object]'; | ||
| } | ||
| } | ||
| return msg; | ||
| }; | ||
| module.exports = { | ||
| Log, ErrorLog, WarnLog | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
31269
69.08%8
60%472
79.47%1
-50%Yes
NaN2
Infinity%231
-0.43%1
Infinity%1
Infinity%