@marianmeres/http-utils 2.0.1 → 2.1.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/AGENTS.md +197 -0
- package/API.md +459 -0
- package/README.md +42 -159
- package/dist/api.d.ts +57 -17
- package/dist/api.js +60 -29
- package/dist/error.d.ts +58 -3
- package/dist/error.js +76 -22
- package/dist/mod.d.ts +24 -1
- package/dist/mod.js +23 -0
- package/dist/status.d.ts +29 -1
- package/dist/status.js +31 -2
- package/package.json +8 -1
package/dist/error.d.ts
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module error
|
|
3
|
+
*
|
|
4
|
+
* HTTP error classes and utilities for type-safe error handling.
|
|
5
|
+
* Provides specific error classes for well-known HTTP status codes.
|
|
6
|
+
*/
|
|
1
7
|
/**
|
|
2
8
|
* Base HTTP error class. Extends Error with HTTP-specific properties.
|
|
9
|
+
* All specific error classes (NotFound, BadRequest, etc.) extend this class.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* try {
|
|
14
|
+
* await api.get("/resource");
|
|
15
|
+
* } catch (error) {
|
|
16
|
+
* if (error instanceof HttpError) {
|
|
17
|
+
* console.log(error.status); // e.g., 404
|
|
18
|
+
* console.log(error.statusText); // e.g., "Not Found"
|
|
19
|
+
* console.log(error.body); // Response body
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
3
23
|
*/
|
|
4
24
|
declare class HttpError extends Error {
|
|
5
25
|
name: string;
|
|
@@ -8,87 +28,122 @@ declare class HttpError extends Error {
|
|
|
8
28
|
/** HTTP status text (e.g., "Not Found", "Internal Server Error") */
|
|
9
29
|
statusText: string;
|
|
10
30
|
/** Response body (auto-parsed as JSON if possible) */
|
|
11
|
-
body:
|
|
31
|
+
body: unknown;
|
|
12
32
|
}
|
|
33
|
+
/** HTTP 400 Bad Request error. */
|
|
13
34
|
declare class BadRequest extends HttpError {
|
|
14
35
|
name: string;
|
|
15
36
|
status: number;
|
|
16
37
|
statusText: string;
|
|
17
38
|
}
|
|
39
|
+
/** HTTP 401 Unauthorized error. */
|
|
18
40
|
declare class Unauthorized extends HttpError {
|
|
19
41
|
name: string;
|
|
20
42
|
status: number;
|
|
21
43
|
statusText: string;
|
|
22
44
|
}
|
|
45
|
+
/** HTTP 403 Forbidden error. */
|
|
23
46
|
declare class Forbidden extends HttpError {
|
|
24
47
|
name: string;
|
|
25
48
|
status: number;
|
|
26
49
|
statusText: string;
|
|
27
50
|
}
|
|
51
|
+
/** HTTP 404 Not Found error. */
|
|
28
52
|
declare class NotFound extends HttpError {
|
|
29
53
|
name: string;
|
|
30
54
|
status: number;
|
|
31
55
|
statusText: string;
|
|
32
56
|
}
|
|
57
|
+
/** HTTP 405 Method Not Allowed error. */
|
|
33
58
|
declare class MethodNotAllowed extends HttpError {
|
|
34
59
|
name: string;
|
|
35
60
|
status: number;
|
|
36
61
|
statusText: string;
|
|
37
62
|
}
|
|
63
|
+
/** HTTP 408 Request Timeout error. */
|
|
38
64
|
declare class RequestTimeout extends HttpError {
|
|
39
65
|
name: string;
|
|
40
66
|
status: number;
|
|
41
67
|
statusText: string;
|
|
42
68
|
}
|
|
69
|
+
/** HTTP 409 Conflict error. */
|
|
43
70
|
declare class Conflict extends HttpError {
|
|
44
71
|
name: string;
|
|
45
72
|
status: number;
|
|
46
73
|
statusText: string;
|
|
47
74
|
}
|
|
75
|
+
/** HTTP 410 Gone error. */
|
|
48
76
|
declare class Gone extends HttpError {
|
|
49
77
|
name: string;
|
|
50
78
|
status: number;
|
|
51
79
|
statusText: string;
|
|
52
80
|
}
|
|
81
|
+
/** HTTP 411 Length Required error. */
|
|
53
82
|
declare class LengthRequired extends HttpError {
|
|
54
83
|
name: string;
|
|
55
84
|
status: number;
|
|
56
85
|
statusText: string;
|
|
57
86
|
}
|
|
87
|
+
/** HTTP 422 Unprocessable Content error. */
|
|
58
88
|
declare class UnprocessableContent extends HttpError {
|
|
59
89
|
name: string;
|
|
60
90
|
status: number;
|
|
61
91
|
statusText: string;
|
|
62
92
|
}
|
|
93
|
+
/** HTTP 429 Too Many Requests error. */
|
|
63
94
|
declare class TooManyRequests extends HttpError {
|
|
64
95
|
name: string;
|
|
65
96
|
status: number;
|
|
66
97
|
statusText: string;
|
|
67
98
|
}
|
|
99
|
+
/** HTTP 418 I'm a Teapot error. */
|
|
68
100
|
declare class ImATeapot extends HttpError {
|
|
69
101
|
name: string;
|
|
70
102
|
status: number;
|
|
71
103
|
statusText: string;
|
|
72
104
|
}
|
|
105
|
+
/** HTTP 500 Internal Server Error. */
|
|
73
106
|
declare class InternalServerError extends HttpError {
|
|
74
107
|
name: string;
|
|
75
108
|
}
|
|
109
|
+
/** HTTP 501 Not Implemented error. */
|
|
76
110
|
declare class NotImplemented extends HttpError {
|
|
77
111
|
name: string;
|
|
78
112
|
status: number;
|
|
79
113
|
statusText: string;
|
|
80
114
|
}
|
|
115
|
+
/** HTTP 502 Bad Gateway error. */
|
|
81
116
|
declare class BadGateway extends HttpError {
|
|
82
117
|
name: string;
|
|
83
118
|
status: number;
|
|
84
119
|
statusText: string;
|
|
85
120
|
}
|
|
121
|
+
/** HTTP 503 Service Unavailable error. */
|
|
86
122
|
declare class ServiceUnavailable extends HttpError {
|
|
87
123
|
name: string;
|
|
88
124
|
status: number;
|
|
89
125
|
statusText: string;
|
|
90
126
|
}
|
|
91
127
|
export { HttpError, BadRequest, Unauthorized, Forbidden, NotFound, MethodNotAllowed, RequestTimeout, Conflict, Gone, LengthRequired, ImATeapot, UnprocessableContent, TooManyRequests, InternalServerError, NotImplemented, BadGateway, ServiceUnavailable, };
|
|
128
|
+
/**
|
|
129
|
+
* Namespace containing all HTTP error classes for convenient access.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* import { HTTP_ERROR } from "@marianmeres/http-utils";
|
|
134
|
+
*
|
|
135
|
+
* try {
|
|
136
|
+
* await api.get("/resource");
|
|
137
|
+
* } catch (error) {
|
|
138
|
+
* if (error instanceof HTTP_ERROR.NotFound) {
|
|
139
|
+
* console.log("Resource not found");
|
|
140
|
+
* }
|
|
141
|
+
* if (error instanceof HTTP_ERROR.HttpError) {
|
|
142
|
+
* console.log("HTTP error:", error.status);
|
|
143
|
+
* }
|
|
144
|
+
* }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
92
147
|
export declare const HTTP_ERROR: {
|
|
93
148
|
HttpError: typeof HttpError;
|
|
94
149
|
BadRequest: typeof BadRequest;
|
|
@@ -128,7 +183,7 @@ export declare const HTTP_ERROR: {
|
|
|
128
183
|
* console.log(err.body); // { id: 123 }
|
|
129
184
|
* ```
|
|
130
185
|
*/
|
|
131
|
-
export declare const createHttpError: (code: number | string, message?: string | null, body?:
|
|
186
|
+
export declare const createHttpError: (code: number | string, message?: string | null, body?: unknown, cause?: unknown) => HttpError;
|
|
132
187
|
/**
|
|
133
188
|
* Extracts a human-readable error message from various error formats.
|
|
134
189
|
* Tries multiple strategies to find the best message, with fallbacks.
|
|
@@ -146,4 +201,4 @@ export declare const createHttpError: (code: number | string, message?: string |
|
|
|
146
201
|
*
|
|
147
202
|
* @returns A human-readable error message string.
|
|
148
203
|
*/
|
|
149
|
-
export declare const getErrorMessage: (e:
|
|
204
|
+
export declare const getErrorMessage: (e: unknown, stripErrorPrefix?: boolean) => string;
|
package/dist/error.js
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module error
|
|
3
|
+
*
|
|
4
|
+
* HTTP error classes and utilities for type-safe error handling.
|
|
5
|
+
* Provides specific error classes for well-known HTTP status codes.
|
|
6
|
+
*/
|
|
1
7
|
import { HTTP_STATUS } from './status.js';
|
|
2
8
|
/**
|
|
3
9
|
* Base HTTP error class. Extends Error with HTTP-specific properties.
|
|
10
|
+
* All specific error classes (NotFound, BadRequest, etc.) extend this class.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* try {
|
|
15
|
+
* await api.get("/resource");
|
|
16
|
+
* } catch (error) {
|
|
17
|
+
* if (error instanceof HttpError) {
|
|
18
|
+
* console.log(error.status); // e.g., 404
|
|
19
|
+
* console.log(error.statusText); // e.g., "Not Found"
|
|
20
|
+
* console.log(error.body); // Response body
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
4
24
|
*/
|
|
5
25
|
class HttpError extends Error {
|
|
6
26
|
name = 'HttpError';
|
|
@@ -11,94 +31,127 @@ class HttpError extends Error {
|
|
|
11
31
|
/** Response body (auto-parsed as JSON if possible) */
|
|
12
32
|
body = null;
|
|
13
33
|
}
|
|
14
|
-
//
|
|
15
|
-
|
|
34
|
+
// Client error classes (4xx)
|
|
35
|
+
/** HTTP 400 Bad Request error. */
|
|
16
36
|
class BadRequest extends HttpError {
|
|
17
37
|
name = 'HttpBadRequestError';
|
|
18
38
|
status = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.CODE;
|
|
19
39
|
statusText = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.TEXT;
|
|
20
40
|
}
|
|
41
|
+
/** HTTP 401 Unauthorized error. */
|
|
21
42
|
class Unauthorized extends HttpError {
|
|
22
43
|
name = 'HttpUnauthorizedError';
|
|
23
44
|
status = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.CODE;
|
|
24
45
|
statusText = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.TEXT;
|
|
25
46
|
}
|
|
47
|
+
/** HTTP 403 Forbidden error. */
|
|
26
48
|
class Forbidden extends HttpError {
|
|
27
49
|
name = 'HttpForbiddenError';
|
|
28
50
|
status = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.CODE;
|
|
29
51
|
statusText = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.TEXT;
|
|
30
52
|
}
|
|
53
|
+
/** HTTP 404 Not Found error. */
|
|
31
54
|
class NotFound extends HttpError {
|
|
32
55
|
name = 'HttpNotFoundError';
|
|
33
56
|
status = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.CODE;
|
|
34
57
|
statusText = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.TEXT;
|
|
35
58
|
}
|
|
59
|
+
/** HTTP 405 Method Not Allowed error. */
|
|
36
60
|
class MethodNotAllowed extends HttpError {
|
|
37
61
|
name = 'HttpMethodNotAllowedError';
|
|
38
62
|
status = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.CODE;
|
|
39
63
|
statusText = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.TEXT;
|
|
40
64
|
}
|
|
65
|
+
/** HTTP 408 Request Timeout error. */
|
|
41
66
|
class RequestTimeout extends HttpError {
|
|
42
67
|
name = 'HttpRequestTimeoutError';
|
|
43
68
|
status = HTTP_STATUS.ERROR_CLIENT.REQUEST_TIMEOUT.CODE;
|
|
44
69
|
statusText = HTTP_STATUS.ERROR_CLIENT.REQUEST_TIMEOUT.TEXT;
|
|
45
70
|
}
|
|
71
|
+
/** HTTP 409 Conflict error. */
|
|
46
72
|
class Conflict extends HttpError {
|
|
47
73
|
name = 'HttpConflictError';
|
|
48
74
|
status = HTTP_STATUS.ERROR_CLIENT.CONFLICT.CODE;
|
|
49
75
|
statusText = HTTP_STATUS.ERROR_CLIENT.CONFLICT.TEXT;
|
|
50
76
|
}
|
|
77
|
+
/** HTTP 410 Gone error. */
|
|
51
78
|
class Gone extends HttpError {
|
|
52
79
|
name = 'HttpGoneError';
|
|
53
80
|
status = HTTP_STATUS.ERROR_CLIENT.GONE.CODE;
|
|
54
81
|
statusText = HTTP_STATUS.ERROR_CLIENT.GONE.TEXT;
|
|
55
82
|
}
|
|
83
|
+
/** HTTP 411 Length Required error. */
|
|
56
84
|
class LengthRequired extends HttpError {
|
|
57
85
|
name = 'HttpLengthRequiredError';
|
|
58
86
|
status = HTTP_STATUS.ERROR_CLIENT.LENGTH_REQUIRED.CODE;
|
|
59
87
|
statusText = HTTP_STATUS.ERROR_CLIENT.LENGTH_REQUIRED.TEXT;
|
|
60
88
|
}
|
|
89
|
+
/** HTTP 422 Unprocessable Content error. */
|
|
61
90
|
class UnprocessableContent extends HttpError {
|
|
62
91
|
name = 'HttpUnprocessableContentError';
|
|
63
92
|
status = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.CODE;
|
|
64
93
|
statusText = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.TEXT;
|
|
65
94
|
}
|
|
95
|
+
/** HTTP 429 Too Many Requests error. */
|
|
66
96
|
class TooManyRequests extends HttpError {
|
|
67
97
|
name = 'HttpTooManyRequestsError';
|
|
68
98
|
status = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.CODE;
|
|
69
99
|
statusText = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.TEXT;
|
|
70
100
|
}
|
|
101
|
+
/** HTTP 418 I'm a Teapot error. */
|
|
71
102
|
class ImATeapot extends HttpError {
|
|
72
103
|
name = 'HttpImATeapotError';
|
|
73
104
|
status = HTTP_STATUS.ERROR_CLIENT.IM_A_TEAPOT.CODE;
|
|
74
105
|
statusText = HTTP_STATUS.ERROR_CLIENT.IM_A_TEAPOT.TEXT;
|
|
75
106
|
}
|
|
76
|
-
//
|
|
107
|
+
// Server error classes (5xx)
|
|
108
|
+
/** HTTP 500 Internal Server Error. */
|
|
77
109
|
class InternalServerError extends HttpError {
|
|
78
110
|
name = 'HttpInternalServerError';
|
|
79
111
|
}
|
|
112
|
+
/** HTTP 501 Not Implemented error. */
|
|
80
113
|
class NotImplemented extends HttpError {
|
|
81
|
-
name = '
|
|
114
|
+
name = 'HttpNotImplementedError';
|
|
82
115
|
status = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.CODE;
|
|
83
116
|
statusText = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.TEXT;
|
|
84
117
|
}
|
|
118
|
+
/** HTTP 502 Bad Gateway error. */
|
|
85
119
|
class BadGateway extends HttpError {
|
|
86
120
|
name = 'HttpBadGatewayError';
|
|
87
121
|
status = HTTP_STATUS.ERROR_SERVER.BAD_GATEWAY.CODE;
|
|
88
122
|
statusText = HTTP_STATUS.ERROR_SERVER.BAD_GATEWAY.TEXT;
|
|
89
123
|
}
|
|
124
|
+
/** HTTP 503 Service Unavailable error. */
|
|
90
125
|
class ServiceUnavailable extends HttpError {
|
|
91
126
|
name = 'HttpServiceUnavailableError';
|
|
92
127
|
status = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.CODE;
|
|
93
128
|
statusText = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.TEXT;
|
|
94
129
|
}
|
|
95
|
-
// Export individual error classes
|
|
130
|
+
// Export individual error classes for direct imports
|
|
96
131
|
export { HttpError,
|
|
97
132
|
// Client errors
|
|
98
133
|
BadRequest, Unauthorized, Forbidden, NotFound, MethodNotAllowed, RequestTimeout, Conflict, Gone, LengthRequired, ImATeapot, UnprocessableContent, TooManyRequests,
|
|
99
134
|
// Server errors
|
|
100
135
|
InternalServerError, NotImplemented, BadGateway, ServiceUnavailable, };
|
|
101
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Namespace containing all HTTP error classes for convenient access.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* import { HTTP_ERROR } from "@marianmeres/http-utils";
|
|
142
|
+
*
|
|
143
|
+
* try {
|
|
144
|
+
* await api.get("/resource");
|
|
145
|
+
* } catch (error) {
|
|
146
|
+
* if (error instanceof HTTP_ERROR.NotFound) {
|
|
147
|
+
* console.log("Resource not found");
|
|
148
|
+
* }
|
|
149
|
+
* if (error instanceof HTTP_ERROR.HttpError) {
|
|
150
|
+
* console.log("HTTP error:", error.status);
|
|
151
|
+
* }
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
102
155
|
export const HTTP_ERROR = {
|
|
103
156
|
// base
|
|
104
157
|
HttpError,
|
|
@@ -143,9 +196,11 @@ const _wellKnownCtorMap = {
|
|
|
143
196
|
const _maybeJsonParse = (v) => {
|
|
144
197
|
if (typeof v === 'string') {
|
|
145
198
|
try {
|
|
146
|
-
|
|
199
|
+
return JSON.parse(v);
|
|
200
|
+
}
|
|
201
|
+
catch (_e) {
|
|
202
|
+
// ignore parse errors
|
|
147
203
|
}
|
|
148
|
-
catch (e) { }
|
|
149
204
|
}
|
|
150
205
|
return v;
|
|
151
206
|
};
|
|
@@ -211,31 +266,30 @@ export const getErrorMessage = (e, stripErrorPrefix = true) => {
|
|
|
211
266
|
return '';
|
|
212
267
|
// Errors may bubble from various sources which are not always under control.
|
|
213
268
|
// We try our best to extract a meaningful message using common conventions.
|
|
214
|
-
const
|
|
215
|
-
const
|
|
216
|
-
|
|
269
|
+
const err = e;
|
|
270
|
+
const cause = _maybeJsonParse(err?.cause);
|
|
271
|
+
const body = _maybeJsonParse(err?.body);
|
|
272
|
+
let msg = String(
|
|
217
273
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
|
|
218
274
|
// e.cause is the standard prop for error details, so should be considered as
|
|
219
275
|
// the most authoritative (if available)
|
|
220
276
|
// "code" and "message" are my own conventions
|
|
221
|
-
cause?.message ||
|
|
222
|
-
cause?.code ||
|
|
277
|
+
(typeof cause === 'object' ? cause?.message : null) ||
|
|
278
|
+
(typeof cause === 'object' ? cause?.code : null) ||
|
|
223
279
|
(typeof cause === 'string' ? cause : null) ||
|
|
224
280
|
// non-standard "body" is this package's HttpError prop
|
|
225
|
-
body?.error?.message ||
|
|
226
|
-
body?.message ||
|
|
227
|
-
body?.error ||
|
|
281
|
+
(typeof body === 'object' ? body?.error?.message : null) ||
|
|
282
|
+
(typeof body === 'object' ? body?.message : null) ||
|
|
283
|
+
(typeof body === 'object' ? body?.error : null) ||
|
|
228
284
|
(typeof body === 'string' ? body : null) ||
|
|
229
285
|
// the common message from Error ctor (e.g. "Foo" if new TypeError("Foo"))
|
|
230
|
-
|
|
286
|
+
err?.message ||
|
|
231
287
|
// the Error class name (e.g. TypeError)
|
|
232
|
-
|
|
288
|
+
err?.name ||
|
|
233
289
|
// this should handle (almost) everything else (mainly if e is not an Error instance)
|
|
234
|
-
|
|
290
|
+
(typeof err?.toString === 'function' ? err.toString() : null) ||
|
|
235
291
|
// very last fallback if `toString()` was not available (or returned empty)
|
|
236
|
-
'Unknown Error';
|
|
237
|
-
// ensure we're sending string
|
|
238
|
-
msg = `${msg}`;
|
|
292
|
+
'Unknown Error');
|
|
239
293
|
if (stripErrorPrefix) {
|
|
240
294
|
msg = msg.replace(/^[^:]*Error: /i, '');
|
|
241
295
|
}
|
package/dist/mod.d.ts
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module http-utils
|
|
3
|
+
*
|
|
4
|
+
* Opinionated, lightweight HTTP client wrapper for the native `fetch` API.
|
|
5
|
+
* Provides type-safe HTTP errors, convenient defaults, and flexible error handling.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createHttpApi, HTTP_ERROR, HTTP_STATUS } from "@marianmeres/http-utils";
|
|
10
|
+
*
|
|
11
|
+
* const api = createHttpApi("https://api.example.com", {
|
|
12
|
+
* headers: { "Authorization": "Bearer token" }
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* try {
|
|
16
|
+
* const users = await api.get("/users");
|
|
17
|
+
* } catch (error) {
|
|
18
|
+
* if (error instanceof HTTP_ERROR.NotFound) {
|
|
19
|
+
* console.log("Not found:", error.body);
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export { HttpApi, createHttpApi, type DataOptions, type GetOptions, type FetchParams, type ErrorMessageExtractor, type ResponseHeaders, type RequestData, } from "./api.js";
|
|
2
25
|
export { HTTP_ERROR, createHttpError, getErrorMessage } from "./error.js";
|
|
3
26
|
export { HTTP_STATUS } from "./status.js";
|
package/dist/mod.js
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module http-utils
|
|
3
|
+
*
|
|
4
|
+
* Opinionated, lightweight HTTP client wrapper for the native `fetch` API.
|
|
5
|
+
* Provides type-safe HTTP errors, convenient defaults, and flexible error handling.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createHttpApi, HTTP_ERROR, HTTP_STATUS } from "@marianmeres/http-utils";
|
|
10
|
+
*
|
|
11
|
+
* const api = createHttpApi("https://api.example.com", {
|
|
12
|
+
* headers: { "Authorization": "Bearer token" }
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* try {
|
|
16
|
+
* const users = await api.get("/users");
|
|
17
|
+
* } catch (error) {
|
|
18
|
+
* if (error instanceof HTTP_ERROR.NotFound) {
|
|
19
|
+
* console.log("Not found:", error.body);
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
1
24
|
export { HttpApi, createHttpApi, } from "./api.js";
|
|
2
25
|
export { HTTP_ERROR, createHttpError, getErrorMessage } from "./error.js";
|
|
3
26
|
export { HTTP_STATUS } from "./status.js";
|
package/dist/status.d.ts
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @module status
|
|
3
|
+
*
|
|
2
4
|
* HTTP status codes organized by category with convenience shortcuts.
|
|
3
|
-
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* HTTP status codes organized by category with convenience shortcuts.
|
|
8
|
+
*
|
|
9
|
+
* Categories:
|
|
10
|
+
* - `INFO` (1xx): Informational responses
|
|
11
|
+
* - `SUCCESS` (2xx): Successful responses
|
|
12
|
+
* - `REDIRECT` (3xx): Redirection messages
|
|
13
|
+
* - `ERROR_CLIENT` (4xx): Client error responses
|
|
14
|
+
* - `ERROR_SERVER` (5xx): Server error responses
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { HTTP_STATUS } from "@marianmeres/http-utils";
|
|
19
|
+
*
|
|
20
|
+
* // Access by category
|
|
21
|
+
* HTTP_STATUS.SUCCESS.OK.CODE // 200
|
|
22
|
+
* HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.CODE // 404
|
|
23
|
+
*
|
|
24
|
+
* // Direct shortcuts
|
|
25
|
+
* HTTP_STATUS.OK // 200
|
|
26
|
+
* HTTP_STATUS.NOT_FOUND // 404
|
|
27
|
+
*
|
|
28
|
+
* // Lookup by code
|
|
29
|
+
* const info = HTTP_STATUS.findByCode(404);
|
|
30
|
+
* // { CODE: 404, TEXT: "Not Found", _TYPE: "ERROR_CLIENT", _KEY: "NOT_FOUND" }
|
|
31
|
+
* ```
|
|
4
32
|
*/
|
|
5
33
|
export declare class HTTP_STATUS {
|
|
6
34
|
static readonly INFO: {
|
package/dist/status.js
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @module status
|
|
3
|
+
*
|
|
2
4
|
* HTTP status codes organized by category with convenience shortcuts.
|
|
3
|
-
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* HTTP status codes organized by category with convenience shortcuts.
|
|
8
|
+
*
|
|
9
|
+
* Categories:
|
|
10
|
+
* - `INFO` (1xx): Informational responses
|
|
11
|
+
* - `SUCCESS` (2xx): Successful responses
|
|
12
|
+
* - `REDIRECT` (3xx): Redirection messages
|
|
13
|
+
* - `ERROR_CLIENT` (4xx): Client error responses
|
|
14
|
+
* - `ERROR_SERVER` (5xx): Server error responses
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { HTTP_STATUS } from "@marianmeres/http-utils";
|
|
19
|
+
*
|
|
20
|
+
* // Access by category
|
|
21
|
+
* HTTP_STATUS.SUCCESS.OK.CODE // 200
|
|
22
|
+
* HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.CODE // 404
|
|
23
|
+
*
|
|
24
|
+
* // Direct shortcuts
|
|
25
|
+
* HTTP_STATUS.OK // 200
|
|
26
|
+
* HTTP_STATUS.NOT_FOUND // 404
|
|
27
|
+
*
|
|
28
|
+
* // Lookup by code
|
|
29
|
+
* const info = HTTP_STATUS.findByCode(404);
|
|
30
|
+
* // { CODE: 404, TEXT: "Not Found", _TYPE: "ERROR_CLIENT", _KEY: "NOT_FOUND" }
|
|
31
|
+
* ```
|
|
4
32
|
*/
|
|
5
33
|
// prettier-ignore
|
|
6
34
|
export class HTTP_STATUS {
|
|
@@ -126,7 +154,8 @@ export class HTTP_STATUS {
|
|
|
126
154
|
'INFO', 'SUCCESS', 'REDIRECT', 'ERROR_CLIENT', 'ERROR_SERVER',
|
|
127
155
|
];
|
|
128
156
|
for (const _TYPE of keys) {
|
|
129
|
-
|
|
157
|
+
const entries = Object.entries(HTTP_STATUS[_TYPE]);
|
|
158
|
+
for (const [_KEY, data] of entries) {
|
|
130
159
|
if (data.CODE == code) {
|
|
131
160
|
return { ...data, _TYPE, _KEY };
|
|
132
161
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marianmeres/http-utils",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/mod.js",
|
|
6
6
|
"types": "dist/mod.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/mod.d.ts",
|
|
10
|
+
"import": "./dist/mod.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
7
13
|
"author": "Marian Meres",
|
|
8
14
|
"license": "MIT",
|
|
15
|
+
"dependencies": {},
|
|
9
16
|
"repository": {
|
|
10
17
|
"type": "git",
|
|
11
18
|
"url": "git+https://github.com/marianmeres/http-utils.git"
|