New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

http-reply

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http-reply - npm Package Compare versions

Comparing version
0.2.2
to
1.0.0
+2
dist/cjs/index.cjs
// This file is auto-generated to support require() default imports
module.exports = require('../index.cjs').default;
"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 };
// 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).
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;
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
}