diff --git a/package.json b/package.json index dea0b7d..60d2cc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "http-error-kit", - "version": "1.0.0", + "version": "1.1.0", "description": "A flexible and customizable error-handling library for HTTP applications. Provides structured error responses with optional formatters, predefined HTTP errors, and extensible error types.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -9,6 +9,16 @@ "./generic": "./dist/general.error.js", "./http": "./dist/http.error.js" }, + "typesVersions": { + "*": { + "generic": [ + "./dist/general.error.d.ts" + ], + "http": [ + "./dist/http.error.d.ts" + ] + } + }, "scripts": { "test": "jest --config jest.config.ts", "build": "tsc --build", diff --git a/src/general.error.ts b/src/general.error.ts index 22d0283..6b9b2d5 100644 --- a/src/general.error.ts +++ b/src/general.error.ts @@ -2,6 +2,7 @@ import { CODES as STATUS_CODES, getStatusDescription, } from "http-response-status-code"; +import { IRawInput } from "./interfaces/input.interface"; /** * Represents a general error with a status code, message, and optional details. @@ -26,6 +27,13 @@ export class KitGeneralError extends Error { */ details: unknown; + /** + * The raw input data associated with this instance. + * @private + * @type {IRawInput} + */ + private rawInputs: IRawInput; + /** * Initializes a new instance of the KitGeneralError class. * @param {number} statusCode - The HTTP status code associated with the error. @@ -38,6 +46,28 @@ export class KitGeneralError extends Error { this.statusCode = statusCode; this.message = message.toString(); this.details = details; + this.rawInputs = { statusCode, message, details, args: [] }; + Object.setPrototypeOf(this, KitGeneralError.prototype); + } + + /** + * Returns the raw input data associated with this instance. + * @returns {IRawInput} The raw input data associated with this instance. + */ + getInputs() { + return this.rawInputs; + } + + /** + * Returns a JSON-compatible object representation of this instance. + * @returns {{statusCode: number, message: string, details: unknown}} A JSON-compatible object representation of this instance. + */ + toJSON() { + return { + statusCode: this.statusCode, + message: this.message, + details: this.details, + }; } } diff --git a/src/http.error.ts b/src/http.error.ts index 3683e70..4615adc 100644 --- a/src/http.error.ts +++ b/src/http.error.ts @@ -136,6 +136,39 @@ export class KitHttpError extends Error { return this; } + + /** + * Returns the raw input data associated with this instance. + * @returns {IRawInput} The raw input data associated with this instance. + */ + getInputs() { + return this.rawInputs; + } + + /** + * Returns a JSON-compatible object representation of this instance. + * If a formatter function is provided (either globally or instance-specific), + * it will be used to format the error details. + * Otherwise, the object will contain the `statusCode`, `message`, and `details` properties. + * @returns {{statusCode: number, message: string, details: unknown}} A JSON-compatible object representation of this instance. + */ + toJSON() { + const formatter = + this.instanceFormatter ?? KitHttpError.defaultFormatter; + if (formatter) { + return formatter( + this.rawInputs.statusCode, + this.rawInputs.message, + this.rawInputs.details, + ...this.rawInputs.args + ); + } + return { + statusCode: this.rawInputs.statusCode, + message: this.rawInputs.message, + details: this.rawInputs.details, + }; + } } /** diff --git a/test/general.error.spec.ts b/test/general.error.spec.ts index b49506f..7a0438c 100644 --- a/test/general.error.spec.ts +++ b/test/general.error.spec.ts @@ -54,6 +54,30 @@ describe("*** Testing KitGeneralError ***", function () { expect(test instanceof KitGeneralError); expect(test.message).toBe("Testing KitGeneralError"); }); + it("Should return raw inputs", function () { + const test = new KitGeneralError( + STATUS_CODES.CODES.HTTP_CODE_400, + "Testing KitGeneralError" + ); + const rawInputs = test.getInputs(); + expect(test instanceof KitGeneralError); + expect(typeof rawInputs).toBe("object"); + expect(rawInputs.statusCode).toBe(STATUS_CODES.CODES.HTTP_CODE_400); + expect(rawInputs.message).toBe("Testing KitGeneralError"); + expect(rawInputs.details).toBe(undefined); + }); + it("Should return proper serialized inputs", function () { + const test = new KitGeneralError( + STATUS_CODES.CODES.HTTP_CODE_400, + "Testing KitGeneralError" + ); + const json = JSON.parse(JSON.stringify(test)); + expect(test instanceof KitGeneralError); + expect(typeof json).toBe("object"); + expect(json.statusCode).toBe(STATUS_CODES.CODES.HTTP_CODE_400); + expect(json.message).toBe("Testing KitGeneralError"); + expect(json.details).toBe(undefined); + }); }); describe("*** Testing BadRequestError ***", function () { diff --git a/test/http.error.spec.ts b/test/http.error.spec.ts index 712ae9d..73b19c5 100644 --- a/test/http.error.spec.ts +++ b/test/http.error.spec.ts @@ -1163,6 +1163,39 @@ describe("*** Testing KitHttpError ***", function () { expect(error.msg).toBe("Testing KitHttpError"); expect(error.details).toEqual({}); }); + it("Should return raw inputs with additional arguments", function () { + const test = new KitHttpError( + STATUS_CODES.HTTP_CODE_400, + "Testing KitHttpError", + {}, + "argument1", + "argument2" + ); + const rawInputs = test.getInputs(); + expect(test instanceof KitHttpError); + expect(typeof rawInputs).toBe("object"); + expect(rawInputs.statusCode).toBe(STATUS_CODES.HTTP_CODE_400); + expect(rawInputs.message).toBe("Testing KitHttpError"); + expect(rawInputs.details).toStrictEqual({}); + expect(rawInputs.args).toBeInstanceOf(Array); + expect(rawInputs.args).toEqual(["argument1", "argument2"]); + }); + it("Should return proper serialized inputs", function () { + const test = new KitHttpError( + STATUS_CODES.HTTP_CODE_400, + "Testing KitHttpError", + {}, + "argument1", + "argument2" + ); + const json = JSON.parse(JSON.stringify(test)); + console.log(json); + expect(test instanceof KitHttpError); + expect(typeof json).toBe("object"); + expect(json.statusCode).toBe(STATUS_CODES.HTTP_CODE_400); + expect(json.message).toBe("Testing KitHttpError"); + expect(json.details).toStrictEqual({}); + }); }); describe("*** Testing KitHttpErrorConfig ***", function () { @@ -1185,6 +1218,11 @@ describe("*** Testing KitHttpErrorConfig ***", function () { describe("*** Testing KitHttpError with global formatter ***", function () { it("Should be an instance of KitHttpError when no formatter is provided", function () { + KitHttpErrorConfig.configureFormatter( + (statusCode, message, details, ...args) => ({ + list: args, + }) + ); const error = new KitHttpError( STATUS_CODES.HTTP_CODE_400, "Testing KitHttpError", @@ -1194,4 +1232,46 @@ describe("*** Testing KitHttpError with global formatter ***", function () { expect(error instanceof KitHttpError); expect(error.list).toEqual(["kit2"]); }); + it("Should return raw inputs", function () { + KitHttpErrorConfig.configureFormatter(() => {}); + const test = new KitHttpError( + STATUS_CODES.HTTP_CODE_400, + "Testing KitHttpError" + ); + const rawInputs = test.getInputs(); + expect(test instanceof KitHttpError); + expect(typeof rawInputs).toBe("object"); + expect(rawInputs.statusCode).toBe(STATUS_CODES.HTTP_CODE_400); + expect(rawInputs.message).toBe("Testing KitHttpError"); + expect(rawInputs.details).toBe(undefined); + expect(rawInputs.args).toStrictEqual([]); + }); + it("Should return proper serialized inputs", function () { + KitHttpErrorConfig.configureFormatter( + (statusCode, message, details, ...args) => { + return { + code: statusCode, + msg: message, + det: details, + arg1: args[0], + arg2: args[1], + }; + } + ); + const test = new KitHttpError( + STATUS_CODES.HTTP_CODE_400, + "Testing KitHttpError", + {}, + "argument1", + "argument2" + ); + const json = JSON.parse(JSON.stringify(test)); + expect(test instanceof KitHttpError); + expect(typeof json).toBe("object"); + expect(json.code).toBe(STATUS_CODES.HTTP_CODE_400); + expect(json.msg).toBe("Testing KitHttpError"); + expect(json.det).toStrictEqual({}); + expect(json.arg1).toBe("argument1"); + expect(json.arg2).toBe("argument2"); + }); }); diff --git a/tsconfig.json b/tsconfig.json index 848c10a..56af8e3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,8 +27,11 @@ "module": "CommonJS" /* Specify what module code is generated. */, "rootDir": "./src" /* Specify the root folder within your source files. */, "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + "baseUrl": "./" /* Specify the base directory to resolve non-relative module names. */, + "paths": { + "http-error-kit/generic": ["./dist/general.error.js"], + "http-error-kit/http": ["./dist/http.error.js"] + } /* Specify a set of entries that re-map imports to additional lookup locations. */, // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */