http-response-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matteo Teodori
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/matteo-teodori/http-response-kit/main/logo.png" alt="http-response-kit logo" width="300" />
3
+ </p>
4
+
5
+ > 🚀 A professional HTTP error and response formatting library for Node.js
6
+
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-16+-green.svg)](https://nodejs.org/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+
11
+ ## Features
12
+
13
+ - ✅ **Complete HTTP Status Codes** - All 4xx and 5xx error codes + 1xx, 2xx, 3xx
14
+ - ✅ **TypeScript First** - Full type safety and IntelliSense support
15
+ - ✅ **Factory Methods** - Convenient `HttpError.notFound()`, `HttpError.badRequest()`, etc.
16
+ - ✅ **Customizable** - Override default messages, add metadata, configure globally
17
+ - ✅ **Zero Dependencies** - Lightweight and fast
18
+ - ✅ **ESM & CommonJS** - Works everywhere
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install http-response-kit
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```typescript
29
+ import { HttpError, HttpResponse, configure } from 'http-response-kit';
30
+
31
+ // Throw HTTP errors
32
+ throw HttpError.notFound('User not found');
33
+ throw HttpError.badRequest('Invalid email format');
34
+ throw HttpError.unauthorized('Token expired');
35
+
36
+ // Or use status codes directly
37
+ throw new HttpError(404, { message: 'User not found' });
38
+ throw new HttpError(429, { message: 'Slow down!', retryAfter: 60 });
39
+
40
+ // Format success responses
41
+ const response = HttpResponse.success({
42
+ data: { id: 1, name: 'John' },
43
+ message: 'User retrieved successfully'
44
+ });
45
+ // { success: true, status_code: 200, data: {...}, message: '...' }
46
+
47
+ // Format error responses
48
+ const error = HttpError.notFound('User not found');
49
+ const errorResponse = HttpResponse.error(error);
50
+ // { success: false, status_code: 404, error: { type: 'not_found', ... } }
51
+ ```
52
+
53
+ ## Usage with Express
54
+
55
+ ```typescript
56
+ import express from 'express';
57
+ import { HttpError, HttpResponse, configure } from 'http-response-kit';
58
+
59
+ const app = express();
60
+
61
+ // Configure library
62
+ configure({
63
+ isDevelopment: process.env.NODE_ENV === 'development',
64
+ includeTimestamp: true,
65
+ });
66
+
67
+ // Your routes
68
+ app.get('/users/:id', async (req, res) => {
69
+ try {
70
+ const user = await findUser(req.params.id);
71
+ if (!user) {
72
+ throw HttpError.notFound('User not found');
73
+ }
74
+ res.json(HttpResponse.ok(user));
75
+ } catch (err) {
76
+ const error = HttpError.fromError(err);
77
+ res.status(error.code).json(HttpResponse.error(error));
78
+ }
79
+ });
80
+
81
+ // Global error handler
82
+ app.use((err, req, res, next) => {
83
+ const error = HttpError.fromError(err);
84
+ res.status(error.code).json(HttpResponse.error(error));
85
+ });
86
+ ```
87
+
88
+ ## API Reference
89
+
90
+ ### HttpSuccessCode (1xx Informational)
91
+
92
+ | Enum | Code | Description |
93
+ |------|------|-------------|
94
+ | `CONTINUE` | 100 | Continue with request |
95
+ | `SWITCHING_PROTOCOLS` | 101 | Switching protocols |
96
+ | `PROCESSING` | 102 | Processing request |
97
+ | `EARLY_HINTS` | 103 | Early hints |
98
+
99
+ ### HttpSuccessCode (2xx Success)
100
+
101
+ | Enum | Code | Description |
102
+ |------|------|-------------|
103
+ | `OK` | 200 | Request succeeded |
104
+ | `CREATED` | 201 | Resource created |
105
+ | `ACCEPTED` | 202 | Request accepted for processing |
106
+ | `NON_AUTHORITATIVE_INFORMATION` | 203 | Non-authoritative information |
107
+ | `NO_CONTENT` | 204 | No content to return |
108
+ | `RESET_CONTENT` | 205 | Reset content |
109
+ | `PARTIAL_CONTENT` | 206 | Partial content |
110
+ | `MULTI_STATUS` | 207 | Multi-status response |
111
+ | `ALREADY_REPORTED` | 208 | Already reported |
112
+ | `IM_USED` | 226 | IM used |
113
+
114
+ ### HttpRedirectCode (3xx Redirect)
115
+
116
+ | Enum | Code | Description |
117
+ |------|------|-------------|
118
+ | `MULTIPLE_CHOICES` | 300 | Multiple choices available |
119
+ | `MOVED_PERMANENTLY` | 301 | Resource moved permanently |
120
+ | `FOUND` | 302 | Resource found at different URI |
121
+ | `SEE_OTHER` | 303 | See other resource |
122
+ | `NOT_MODIFIED` | 304 | Resource not modified |
123
+ | `USE_PROXY` | 305 | Use proxy |
124
+ | `TEMPORARY_REDIRECT` | 307 | Temporary redirect |
125
+ | `PERMANENT_REDIRECT` | 308 | Permanent redirect |
126
+
127
+ ### HttpError
128
+
129
+ #### Factory Methods (4xx Client Errors)
130
+
131
+ | Method | Code | Description |
132
+ |--------|------|-------------|
133
+ | `HttpError.badRequest()` | 400 | Bad Request |
134
+ | `HttpError.unauthorized()` | 401 | Unauthorized |
135
+ | `HttpError.paymentRequired()` | 402 | Payment Required |
136
+ | `HttpError.forbidden()` | 403 | Forbidden |
137
+ | `HttpError.notFound()` | 404 | Not Found |
138
+ | `HttpError.methodNotAllowed()` | 405 | Method Not Allowed |
139
+ | `HttpError.notAcceptable()` | 406 | Not Acceptable |
140
+ | `HttpError.proxyAuthenticationRequired()` | 407 | Proxy Auth Required |
141
+ | `HttpError.requestTimeout()` | 408 | Request Timeout |
142
+ | `HttpError.conflict()` | 409 | Conflict |
143
+ | `HttpError.gone()` | 410 | Gone |
144
+ | `HttpError.lengthRequired()` | 411 | Length Required |
145
+ | `HttpError.preconditionFailed()` | 412 | Precondition Failed |
146
+ | `HttpError.payloadTooLarge()` | 413 | Payload Too Large |
147
+ | `HttpError.uriTooLong()` | 414 | URI Too Long |
148
+ | `HttpError.unsupportedMediaType()` | 415 | Unsupported Media Type |
149
+ | `HttpError.rangeNotSatisfiable()` | 416 | Range Not Satisfiable |
150
+ | `HttpError.expectationFailed()` | 417 | Expectation Failed |
151
+ | `HttpError.imATeapot()` | 418 | I'm a Teapot |
152
+ | `HttpError.misdirectedRequest()` | 421 | Misdirected Request |
153
+ | `HttpError.unprocessableEntity()` | 422 | Unprocessable Entity |
154
+ | `HttpError.locked()` | 423 | Locked |
155
+ | `HttpError.failedDependency()` | 424 | Failed Dependency |
156
+ | `HttpError.tooEarly()` | 425 | Too Early |
157
+ | `HttpError.upgradeRequired()` | 426 | Upgrade Required |
158
+ | `HttpError.preconditionRequired()` | 428 | Precondition Required |
159
+ | `HttpError.tooManyRequests()` | 429 | Too Many Requests |
160
+ | `HttpError.requestHeaderFieldsTooLarge()` | 431 | Header Fields Too Large |
161
+ | `HttpError.unavailableForLegalReasons()` | 451 | Unavailable For Legal Reasons |
162
+
163
+ #### Factory Methods (5xx Server Errors)
164
+
165
+ | Method | Code | Description |
166
+ |--------|------|-------------|
167
+ | `HttpError.internalServerError()` | 500 | Internal Server Error |
168
+ | `HttpError.notImplemented()` | 501 | Not Implemented |
169
+ | `HttpError.badGateway()` | 502 | Bad Gateway |
170
+ | `HttpError.serviceUnavailable()` | 503 | Service Unavailable |
171
+ | `HttpError.gatewayTimeout()` | 504 | Gateway Timeout |
172
+ | `HttpError.httpVersionNotSupported()` | 505 | HTTP Version Not Supported |
173
+ | `HttpError.variantAlsoNegotiates()` | 506 | Variant Also Negotiates |
174
+ | `HttpError.insufficientStorage()` | 507 | Insufficient Storage |
175
+ | `HttpError.loopDetected()` | 508 | Loop Detected |
176
+ | `HttpError.bandwidthLimitExceeded()` | 509 | Bandwidth Limit Exceeded |
177
+ | `HttpError.notExtended()` | 510 | Not Extended |
178
+ | `HttpError.networkAuthenticationRequired()` | 511 | Network Auth Required |
179
+
180
+ #### Utility Methods
181
+
182
+ ```typescript
183
+ // Convert any error to HttpError
184
+ const httpError = HttpError.fromError(unknownError);
185
+
186
+ // Check if error is HttpError
187
+ if (HttpError.isHttpError(error)) { ... }
188
+
189
+ // Check error category
190
+ error.isClientError(); // 4xx
191
+ error.isServerError(); // 5xx
192
+
193
+ // Add metadata
194
+ throw HttpError.badRequest('Validation failed', {
195
+ fields: ['email', 'password']
196
+ });
197
+ ```
198
+
199
+ ### HttpResponse
200
+
201
+ ```typescript
202
+ // Success responses
203
+ HttpResponse.success({ data, message, statusCode, metadata });
204
+ HttpResponse.ok(data, message);
205
+ HttpResponse.created(data, message);
206
+ HttpResponse.accepted(data, message);
207
+ HttpResponse.noContent();
208
+
209
+ // Error responses
210
+ HttpResponse.error(httpError);
211
+ HttpResponse.fromError(anyError);
212
+
213
+ // Paginated responses
214
+ HttpResponse.paginated(items, {
215
+ page: 1,
216
+ limit: 10,
217
+ total: 100
218
+ });
219
+ ```
220
+
221
+ ### Configuration
222
+
223
+ ```typescript
224
+ import { configure } from 'http-response-kit';
225
+
226
+ configure({
227
+ // Enable stack traces in error responses
228
+ isDevelopment: true,
229
+
230
+ // Include timestamps in all responses
231
+ includeTimestamp: true,
232
+
233
+ // Custom default messages per status code
234
+ customMessages: {
235
+ 404: 'Oops! This page went on vacation 🏝️',
236
+ 500: 'Well, this is embarrassing... 🤖'
237
+ },
238
+
239
+ // Custom response transformer
240
+ responseTransformer: (response) => ({
241
+ ...response,
242
+ api_version: 'v1'
243
+ })
244
+ });
245
+ ```
246
+
247
+ ## Status Code Enums
248
+
249
+ ```typescript
250
+ import {
251
+ HttpSuccessCode,
252
+ HttpClientErrorCode,
253
+ HttpServerErrorCode,
254
+ HttpRedirectCode,
255
+ HttpInfoCode
256
+ } from 'http-response-kit';
257
+
258
+ // Use enums for type safety
259
+ HttpSuccessCode.OK // 200
260
+ HttpSuccessCode.CREATED // 201
261
+ HttpSuccessCode.NO_CONTENT // 204
262
+ HttpClientErrorCode.NOT_FOUND // 404
263
+ HttpServerErrorCode.INTERNAL_SERVER_ERROR // 500
264
+ ```
265
+
266
+ ## Changelog
267
+
268
+ See [CHANGELOG.md](CHANGELOG.md) for detailed release notes.
269
+
270
+ ## License
271
+
272
+ MIT © [Matteo Teodori](https://github.com/matteo-teodori)