http-response-kit 1.0.0 → 2.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.
Files changed (47) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +357 -272
  3. package/dist/chunk-373JVXMN.mjs +1199 -0
  4. package/dist/chunk-373JVXMN.mjs.map +1 -0
  5. package/dist/chunk-FFRB2EUE.mjs +36 -0
  6. package/dist/chunk-FFRB2EUE.mjs.map +1 -0
  7. package/dist/express.d.mts +50 -0
  8. package/dist/express.d.ts +50 -0
  9. package/dist/express.js +1155 -0
  10. package/dist/express.js.map +1 -0
  11. package/dist/express.mjs +28 -0
  12. package/dist/express.mjs.map +1 -0
  13. package/dist/fastify.d.mts +45 -0
  14. package/dist/fastify.d.ts +45 -0
  15. package/dist/fastify.js +1170 -0
  16. package/dist/fastify.js.map +1 -0
  17. package/dist/fastify.mjs +43 -0
  18. package/dist/fastify.mjs.map +1 -0
  19. package/dist/hono.d.mts +33 -0
  20. package/dist/hono.d.ts +33 -0
  21. package/dist/hono.js +1139 -0
  22. package/dist/hono.js.map +1 -0
  23. package/dist/hono.mjs +18 -0
  24. package/dist/hono.mjs.map +1 -0
  25. package/dist/index.d.mts +75 -493
  26. package/dist/index.d.ts +75 -493
  27. package/dist/index.js +480 -180
  28. package/dist/index.js.map +1 -0
  29. package/dist/index.mjs +18 -891
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/kit-nHfihlKE.d.mts +753 -0
  32. package/dist/kit-nHfihlKE.d.ts +753 -0
  33. package/dist/koa.d.mts +38 -0
  34. package/dist/koa.d.ts +38 -0
  35. package/dist/koa.js +1150 -0
  36. package/dist/koa.js.map +1 -0
  37. package/dist/koa.mjs +24 -0
  38. package/dist/koa.mjs.map +1 -0
  39. package/dist/schemas.d.mts +452 -0
  40. package/dist/schemas.d.ts +452 -0
  41. package/dist/schemas.js +124 -0
  42. package/dist/schemas.js.map +1 -0
  43. package/dist/schemas.mjs +119 -0
  44. package/dist/schemas.mjs.map +1 -0
  45. package/dist/shared-Czwmz6Xa.d.ts +22 -0
  46. package/dist/shared-DYq1Fic4.d.mts +22 -0
  47. package/package.json +104 -49
package/dist/index.d.mts CHANGED
@@ -1,250 +1,5 @@
1
- /**
2
- * HTTP Response Kit - Type Definitions
3
- * @module types
4
- */
5
- /**
6
- * Information structure for HTTP errors
7
- */
8
- interface HttpErrorInfo {
9
- /** Lowercase identifier for the error type */
10
- type: string;
11
- /** Human-readable title */
12
- title: string;
13
- /** HTTP status code */
14
- code: number;
15
- /** Default error description */
16
- details: string;
17
- /** Optional retry-after time in seconds */
18
- retryAfter?: number;
19
- /** Optional resolution suggestion */
20
- resolution?: string;
21
- }
22
- /**
23
- * Configuration options for HttpError
24
- */
25
- interface HttpErrorOptions {
26
- /** Custom error message */
27
- message?: string;
28
- /** Additional metadata */
29
- metadata?: Record<string, unknown>;
30
- /** Original error cause */
31
- cause?: Error;
32
- /** Retry-after time in seconds */
33
- retryAfter?: number;
34
- }
35
- /**
36
- * Information structure for HTTP success responses
37
- */
38
- interface HttpSuccessInfo {
39
- /** HTTP status code */
40
- code: number;
41
- /** Description of the status */
42
- description: string;
43
- }
44
- /**
45
- * Configuration for success responses
46
- */
47
- interface SuccessResponseConfig {
48
- /** Response data payload */
49
- data?: unknown;
50
- /** Custom success message */
51
- message?: string;
52
- /** HTTP status code (default: 200) */
53
- statusCode?: number;
54
- /** Additional metadata */
55
- metadata?: Record<string, unknown>;
56
- }
57
- /**
58
- * Configuration for error responses
59
- */
60
- interface ErrorResponseConfig {
61
- /** Include stack trace in response */
62
- includeStack?: boolean;
63
- /** Additional fields to include */
64
- additionalFields?: Record<string, unknown>;
65
- }
66
- /**
67
- * Global library configuration
68
- */
69
- interface LibraryConfig {
70
- /** Enable development mode (includes stack traces) */
71
- isDevelopment?: boolean;
72
- /** Include timestamp in responses */
73
- includeTimestamp?: boolean;
74
- /** Custom default messages per error code */
75
- customMessages?: Partial<Record<number, string>>;
76
- /** Custom response transformer */
77
- responseTransformer?: (response: Record<string, unknown>) => Record<string, unknown>;
78
- }
79
- /**
80
- * Standard success response structure
81
- */
82
- interface SuccessResponse {
83
- success: true;
84
- status_code: number;
85
- timestamp?: string;
86
- data?: unknown;
87
- message?: string;
88
- metadata?: Record<string, unknown>;
89
- [key: string]: unknown;
90
- }
91
- /**
92
- * Standard error response structure
93
- */
94
- interface ErrorResponse {
95
- success: false;
96
- status_code: number;
97
- timestamp?: string;
98
- error: {
99
- type: string;
100
- title: string;
101
- message: string;
102
- details?: string;
103
- };
104
- metadata?: Record<string, unknown>;
105
- [key: string]: unknown;
106
- }
107
-
108
- /**
109
- * HTTP Response Kit - Status Code Enums
110
- * @module constants/status-codes
111
- */
112
- /**
113
- * HTTP 4xx Client Error codes
114
- */
115
- declare enum HttpClientErrorCode {
116
- BAD_REQUEST = 400,
117
- UNAUTHORIZED = 401,
118
- PAYMENT_REQUIRED = 402,
119
- FORBIDDEN = 403,
120
- NOT_FOUND = 404,
121
- METHOD_NOT_ALLOWED = 405,
122
- NOT_ACCEPTABLE = 406,
123
- PROXY_AUTHENTICATION_REQUIRED = 407,
124
- REQUEST_TIMEOUT = 408,
125
- CONFLICT = 409,
126
- GONE = 410,
127
- LENGTH_REQUIRED = 411,
128
- PRECONDITION_FAILED = 412,
129
- PAYLOAD_TOO_LARGE = 413,
130
- URI_TOO_LONG = 414,
131
- UNSUPPORTED_MEDIA_TYPE = 415,
132
- RANGE_NOT_SATISFIABLE = 416,
133
- EXPECTATION_FAILED = 417,
134
- IM_A_TEAPOT = 418,
135
- MISDIRECTED_REQUEST = 421,
136
- UNPROCESSABLE_ENTITY = 422,
137
- LOCKED = 423,
138
- FAILED_DEPENDENCY = 424,
139
- TOO_EARLY = 425,
140
- UPGRADE_REQUIRED = 426,
141
- PRECONDITION_REQUIRED = 428,
142
- TOO_MANY_REQUESTS = 429,
143
- REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
144
- UNAVAILABLE_FOR_LEGAL_REASONS = 451
145
- }
146
- /**
147
- * HTTP 5xx Server Error codes
148
- */
149
- declare enum HttpServerErrorCode {
150
- INTERNAL_SERVER_ERROR = 500,
151
- NOT_IMPLEMENTED = 501,
152
- BAD_GATEWAY = 502,
153
- SERVICE_UNAVAILABLE = 503,
154
- GATEWAY_TIMEOUT = 504,
155
- HTTP_VERSION_NOT_SUPPORTED = 505,
156
- VARIANT_ALSO_NEGOTIATES = 506,
157
- INSUFFICIENT_STORAGE = 507,
158
- LOOP_DETECTED = 508,
159
- BANDWIDTH_LIMIT_EXCEEDED = 509,
160
- NOT_EXTENDED = 510,
161
- NETWORK_AUTHENTICATION_REQUIRED = 511
162
- }
163
- /**
164
- * All HTTP Error codes (4xx + 5xx)
165
- */
166
- declare const HttpErrorCode: {
167
- readonly [x: number]: string;
168
- readonly INTERNAL_SERVER_ERROR: HttpServerErrorCode.INTERNAL_SERVER_ERROR;
169
- readonly NOT_IMPLEMENTED: HttpServerErrorCode.NOT_IMPLEMENTED;
170
- readonly BAD_GATEWAY: HttpServerErrorCode.BAD_GATEWAY;
171
- readonly SERVICE_UNAVAILABLE: HttpServerErrorCode.SERVICE_UNAVAILABLE;
172
- readonly GATEWAY_TIMEOUT: HttpServerErrorCode.GATEWAY_TIMEOUT;
173
- readonly HTTP_VERSION_NOT_SUPPORTED: HttpServerErrorCode.HTTP_VERSION_NOT_SUPPORTED;
174
- readonly VARIANT_ALSO_NEGOTIATES: HttpServerErrorCode.VARIANT_ALSO_NEGOTIATES;
175
- readonly INSUFFICIENT_STORAGE: HttpServerErrorCode.INSUFFICIENT_STORAGE;
176
- readonly LOOP_DETECTED: HttpServerErrorCode.LOOP_DETECTED;
177
- readonly BANDWIDTH_LIMIT_EXCEEDED: HttpServerErrorCode.BANDWIDTH_LIMIT_EXCEEDED;
178
- readonly NOT_EXTENDED: HttpServerErrorCode.NOT_EXTENDED;
179
- readonly NETWORK_AUTHENTICATION_REQUIRED: HttpServerErrorCode.NETWORK_AUTHENTICATION_REQUIRED;
180
- readonly BAD_REQUEST: HttpClientErrorCode.BAD_REQUEST;
181
- readonly UNAUTHORIZED: HttpClientErrorCode.UNAUTHORIZED;
182
- readonly PAYMENT_REQUIRED: HttpClientErrorCode.PAYMENT_REQUIRED;
183
- readonly FORBIDDEN: HttpClientErrorCode.FORBIDDEN;
184
- readonly NOT_FOUND: HttpClientErrorCode.NOT_FOUND;
185
- readonly METHOD_NOT_ALLOWED: HttpClientErrorCode.METHOD_NOT_ALLOWED;
186
- readonly NOT_ACCEPTABLE: HttpClientErrorCode.NOT_ACCEPTABLE;
187
- readonly PROXY_AUTHENTICATION_REQUIRED: HttpClientErrorCode.PROXY_AUTHENTICATION_REQUIRED;
188
- readonly REQUEST_TIMEOUT: HttpClientErrorCode.REQUEST_TIMEOUT;
189
- readonly CONFLICT: HttpClientErrorCode.CONFLICT;
190
- readonly GONE: HttpClientErrorCode.GONE;
191
- readonly LENGTH_REQUIRED: HttpClientErrorCode.LENGTH_REQUIRED;
192
- readonly PRECONDITION_FAILED: HttpClientErrorCode.PRECONDITION_FAILED;
193
- readonly PAYLOAD_TOO_LARGE: HttpClientErrorCode.PAYLOAD_TOO_LARGE;
194
- readonly URI_TOO_LONG: HttpClientErrorCode.URI_TOO_LONG;
195
- readonly UNSUPPORTED_MEDIA_TYPE: HttpClientErrorCode.UNSUPPORTED_MEDIA_TYPE;
196
- readonly RANGE_NOT_SATISFIABLE: HttpClientErrorCode.RANGE_NOT_SATISFIABLE;
197
- readonly EXPECTATION_FAILED: HttpClientErrorCode.EXPECTATION_FAILED;
198
- readonly IM_A_TEAPOT: HttpClientErrorCode.IM_A_TEAPOT;
199
- readonly MISDIRECTED_REQUEST: HttpClientErrorCode.MISDIRECTED_REQUEST;
200
- readonly UNPROCESSABLE_ENTITY: HttpClientErrorCode.UNPROCESSABLE_ENTITY;
201
- readonly LOCKED: HttpClientErrorCode.LOCKED;
202
- readonly FAILED_DEPENDENCY: HttpClientErrorCode.FAILED_DEPENDENCY;
203
- readonly TOO_EARLY: HttpClientErrorCode.TOO_EARLY;
204
- readonly UPGRADE_REQUIRED: HttpClientErrorCode.UPGRADE_REQUIRED;
205
- readonly PRECONDITION_REQUIRED: HttpClientErrorCode.PRECONDITION_REQUIRED;
206
- readonly TOO_MANY_REQUESTS: HttpClientErrorCode.TOO_MANY_REQUESTS;
207
- readonly REQUEST_HEADER_FIELDS_TOO_LARGE: HttpClientErrorCode.REQUEST_HEADER_FIELDS_TOO_LARGE;
208
- readonly UNAVAILABLE_FOR_LEGAL_REASONS: HttpClientErrorCode.UNAVAILABLE_FOR_LEGAL_REASONS;
209
- };
210
- type HttpErrorCode = HttpClientErrorCode | HttpServerErrorCode;
211
- /**
212
- * HTTP 2xx Success codes
213
- */
214
- declare enum HttpSuccessCode {
215
- OK = 200,
216
- CREATED = 201,
217
- ACCEPTED = 202,
218
- NON_AUTHORITATIVE_INFORMATION = 203,
219
- NO_CONTENT = 204,
220
- RESET_CONTENT = 205,
221
- PARTIAL_CONTENT = 206,
222
- MULTI_STATUS = 207,
223
- ALREADY_REPORTED = 208,
224
- IM_USED = 226
225
- }
226
- /**
227
- * HTTP 3xx Redirect codes
228
- */
229
- declare enum HttpRedirectCode {
230
- MULTIPLE_CHOICES = 300,
231
- MOVED_PERMANENTLY = 301,
232
- FOUND = 302,
233
- SEE_OTHER = 303,
234
- NOT_MODIFIED = 304,
235
- USE_PROXY = 305,
236
- TEMPORARY_REDIRECT = 307,
237
- PERMANENT_REDIRECT = 308
238
- }
239
- /**
240
- * HTTP 1xx Informational codes
241
- */
242
- declare enum HttpInfoCode {
243
- CONTINUE = 100,
244
- SWITCHING_PROTOCOLS = 101,
245
- PROCESSING = 102,
246
- EARLY_HINTS = 103
247
- }
1
+ import { a as HttpErrorInfo, b as HttpSuccessInfo, c as HttpErrorOptions, H as HttpError, C as CatalogEntry, P as ProblemDetails, d as ProblemOptions } from './kit-nHfihlKE.mjs';
2
+ export { e as CursorPaginationInput, E as ErrorResponse, f as ErrorResponseConfig, g as HttpClientErrorCode, h as HttpErrorCode, i as HttpErrorLike, j as HttpInfoCode, k as HttpRedirectCode, l as HttpServerErrorCode, m as HttpSuccessCode, K as KitConfig, n as PaginationInput, o as PaginationMeta, p as ResponseCasing, q as ResponseFormat, R as ResponseKit, S as SuccessResponse, r as SuccessResponseConfig, V as ValidationIssue, s as createResponseKit, t as isErrorResponse, u as isSuccessResponse } from './kit-nHfihlKE.mjs';
248
3
 
249
4
  /**
250
5
  * HTTP Response Kit - Error Definitions
@@ -283,282 +38,109 @@ declare const HttpInfoDefinitions: Record<number, HttpSuccessInfo>;
283
38
  declare function getSuccessDefinition(code: number): HttpSuccessInfo;
284
39
 
285
40
  /**
286
- * HTTP Response Kit - HttpError Class
287
- * @module errors/HttpError
41
+ * HTTP Response Kit - Domain Error Catalog
42
+ *
43
+ * Enterprises need stable, machine-readable application error codes
44
+ * (e.g. "USER_NOT_FOUND", "PLAN_LIMIT_REACHED") that are independent from
45
+ * HTTP status codes. A catalog turns a declarative map into typed factories.
46
+ *
47
+ * @module errors/catalog
288
48
  */
289
49
 
50
+ /** A factory produced by {@link createErrorCatalog} */
51
+ type CatalogFactory = (message?: string, options?: Omit<HttpErrorOptions, 'errorCode'>) => HttpError;
290
52
  /**
291
- * Custom HTTP Error class that extends the native Error class.
292
- * Provides structured error information for HTTP responses.
53
+ * Create a typed catalog of domain errors.
54
+ *
55
+ * Each key becomes the stable `errorCode` (serialized as `error.code` in
56
+ * responses and as the `code` extension in Problem Details).
293
57
  *
294
58
  * @example
295
59
  * ```ts
296
- * // Basic usage with status code
297
- * throw new HttpError(404);
298
- * throw new HttpError(HttpErrorCode.NOT_FOUND);
299
- *
300
- * // With custom message
301
- * throw new HttpError(404, { message: 'User not found' });
302
- *
303
- * // With metadata
304
- * throw new HttpError(400, {
305
- * message: 'Validation failed',
306
- * metadata: { fields: ['email', 'password'] }
60
+ * export const Errors = createErrorCatalog({
61
+ * USER_NOT_FOUND: { status: 404, message: 'User does not exist' },
62
+ * PLAN_LIMIT_REACHED: { status: 402, message: 'Upgrade your plan' },
63
+ * PAYMENT_GATEWAY_DOWN: { status: 502, expose: false },
307
64
  * });
308
65
  *
309
- * // Using factory methods
310
- * throw HttpError.notFound('Resource not found');
311
- * throw HttpError.badRequest('Invalid input');
66
+ * throw Errors.USER_NOT_FOUND(); // default message
67
+ * throw Errors.USER_NOT_FOUND('No user with id 42'); // override message
312
68
  * ```
313
69
  */
314
- declare class HttpError extends Error {
315
- /** HTTP status code */
316
- readonly code: number;
317
- /** Lowercase error type identifier */
318
- readonly type: string;
319
- /** Human-readable error title */
320
- readonly title: string;
321
- /** Additional error metadata */
322
- readonly metadata?: Record<string, unknown>;
323
- /** Original error cause */
324
- readonly cause?: Error;
325
- /** Retry-after time in seconds (if applicable) */
326
- readonly retryAfter?: number;
327
- /**
328
- * Creates a new HttpError instance
329
- *
330
- * @param code - HTTP status code (e.g., 404, 500)
331
- * @param options - Optional configuration
332
- */
333
- constructor(code: number, options?: HttpErrorOptions);
334
- /**
335
- * Convert error to plain object for JSON serialization
336
- */
337
- toJSON(): Record<string, unknown>;
338
- /** 400 Bad Request */
339
- static badRequest(message?: string, metadata?: Record<string, unknown>): HttpError;
340
- /** 401 Unauthorized */
341
- static unauthorized(message?: string, metadata?: Record<string, unknown>): HttpError;
342
- /** 402 Payment Required */
343
- static paymentRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
344
- /** 403 Forbidden */
345
- static forbidden(message?: string, metadata?: Record<string, unknown>): HttpError;
346
- /** 404 Not Found */
347
- static notFound(message?: string, metadata?: Record<string, unknown>): HttpError;
348
- /** 405 Method Not Allowed */
349
- static methodNotAllowed(message?: string, metadata?: Record<string, unknown>): HttpError;
350
- /** 406 Not Acceptable */
351
- static notAcceptable(message?: string, metadata?: Record<string, unknown>): HttpError;
352
- /** 407 Proxy Authentication Required */
353
- static proxyAuthenticationRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
354
- /** 408 Request Timeout */
355
- static requestTimeout(message?: string, metadata?: Record<string, unknown>): HttpError;
356
- /** 409 Conflict */
357
- static conflict(message?: string, metadata?: Record<string, unknown>): HttpError;
358
- /** 410 Gone */
359
- static gone(message?: string, metadata?: Record<string, unknown>): HttpError;
360
- /** 411 Length Required */
361
- static lengthRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
362
- /** 412 Precondition Failed */
363
- static preconditionFailed(message?: string, metadata?: Record<string, unknown>): HttpError;
364
- /** 413 Payload Too Large */
365
- static payloadTooLarge(message?: string, metadata?: Record<string, unknown>): HttpError;
366
- /** 414 URI Too Long */
367
- static uriTooLong(message?: string, metadata?: Record<string, unknown>): HttpError;
368
- /** 415 Unsupported Media Type */
369
- static unsupportedMediaType(message?: string, metadata?: Record<string, unknown>): HttpError;
370
- /** 416 Range Not Satisfiable */
371
- static rangeNotSatisfiable(message?: string, metadata?: Record<string, unknown>): HttpError;
372
- /** 417 Expectation Failed */
373
- static expectationFailed(message?: string, metadata?: Record<string, unknown>): HttpError;
374
- /** 418 I'm a Teapot */
375
- static imATeapot(message?: string, metadata?: Record<string, unknown>): HttpError;
376
- /** 421 Misdirected Request */
377
- static misdirectedRequest(message?: string, metadata?: Record<string, unknown>): HttpError;
378
- /** 422 Unprocessable Entity */
379
- static unprocessableEntity(message?: string, metadata?: Record<string, unknown>): HttpError;
380
- /** 423 Locked */
381
- static locked(message?: string, metadata?: Record<string, unknown>): HttpError;
382
- /** 424 Failed Dependency */
383
- static failedDependency(message?: string, metadata?: Record<string, unknown>): HttpError;
384
- /** 425 Too Early */
385
- static tooEarly(message?: string, metadata?: Record<string, unknown>): HttpError;
386
- /** 426 Upgrade Required */
387
- static upgradeRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
388
- /** 428 Precondition Required */
389
- static preconditionRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
390
- /** 429 Too Many Requests */
391
- static tooManyRequests(message?: string, retryAfter?: number, metadata?: Record<string, unknown>): HttpError;
392
- /** 431 Request Header Fields Too Large */
393
- static requestHeaderFieldsTooLarge(message?: string, metadata?: Record<string, unknown>): HttpError;
394
- /** 451 Unavailable For Legal Reasons */
395
- static unavailableForLegalReasons(message?: string, metadata?: Record<string, unknown>): HttpError;
396
- /** 500 Internal Server Error */
397
- static internalServerError(message?: string, metadata?: Record<string, unknown>): HttpError;
398
- /** 501 Not Implemented */
399
- static notImplemented(message?: string, metadata?: Record<string, unknown>): HttpError;
400
- /** 502 Bad Gateway */
401
- static badGateway(message?: string, metadata?: Record<string, unknown>): HttpError;
402
- /** 503 Service Unavailable */
403
- static serviceUnavailable(message?: string, retryAfter?: number, metadata?: Record<string, unknown>): HttpError;
404
- /** 504 Gateway Timeout */
405
- static gatewayTimeout(message?: string, metadata?: Record<string, unknown>): HttpError;
406
- /** 505 HTTP Version Not Supported */
407
- static httpVersionNotSupported(message?: string, metadata?: Record<string, unknown>): HttpError;
408
- /** 506 Variant Also Negotiates */
409
- static variantAlsoNegotiates(message?: string, metadata?: Record<string, unknown>): HttpError;
410
- /** 507 Insufficient Storage */
411
- static insufficientStorage(message?: string, metadata?: Record<string, unknown>): HttpError;
412
- /** 508 Loop Detected */
413
- static loopDetected(message?: string, metadata?: Record<string, unknown>): HttpError;
414
- /** 509 Bandwidth Limit Exceeded */
415
- static bandwidthLimitExceeded(message?: string, metadata?: Record<string, unknown>): HttpError;
416
- /** 510 Not Extended */
417
- static notExtended(message?: string, metadata?: Record<string, unknown>): HttpError;
418
- /** 511 Network Authentication Required */
419
- static networkAuthenticationRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
420
- /**
421
- * Create an HttpError from an unknown error
422
- */
423
- static fromError(error: unknown, fallbackCode?: number): HttpError;
424
- /**
425
- * Check if an error is an HttpError
426
- */
427
- static isHttpError(error: unknown): error is HttpError;
428
- /**
429
- * Check if error is a client error (4xx)
430
- */
431
- isClientError(): boolean;
432
- /**
433
- * Check if error is a server error (5xx)
434
- */
435
- isServerError(): boolean;
436
- }
437
-
438
- /**
439
- * HTTP Response Kit - HttpResponse Class
440
- * @module responses/HttpResponse
441
- */
70
+ declare function createErrorCatalog<T extends Record<string, CatalogEntry>>(catalog: T): {
71
+ [K in keyof T]: CatalogFactory;
72
+ };
442
73
 
443
74
  /**
444
- * Utility class for formatting HTTP responses.
445
- * Provides consistent structure for both success and error responses.
75
+ * HTTP Response Kit - System/socket error mapping
446
76
  *
447
- * @example
448
- * ```ts
449
- * // Success response
450
- * const response = HttpResponse.success({
451
- * data: { id: 1, name: 'John' },
452
- * message: 'User created successfully',
453
- * statusCode: 201
454
- * });
77
+ * Maps Node.js system errors (socket, DNS, timeout - including the undici
78
+ * codes thrown by Node 18+ global `fetch`) to the semantically correct
79
+ * 5xx HTTP status:
455
80
  *
456
- * // Error response
457
- * const error = new HttpError(404, { message: 'User not found' });
458
- * const errorResponse = HttpResponse.error(error);
81
+ * - upstream refused / reset / unreachable -> 502 Bad Gateway
82
+ * - upstream timed out -> 504 Gateway Timeout
83
+ * - temporary local exhaustion / DNS retry -> 503 Service Unavailable
459
84
  *
460
- * // Express integration
461
- * app.get('/user/:id', (req, res) => {
462
- * try {
463
- * const user = findUser(req.params.id);
464
- * const response = HttpResponse.success({ data: user });
465
- * res.status(response.status_code).json(response);
466
- * } catch (err) {
467
- * const response = HttpResponse.error(HttpError.fromError(err));
468
- * res.status(response.status_code).json(response);
469
- * }
470
- * });
471
- * ```
85
+ * These are NOT new HTTP statuses: socket errors are causes, and this module
86
+ * translates them into the right response. Mapped errors are always
87
+ * `expose: false` (the raw message stays on the instance for logging) and
88
+ * carry the syscall code as `errorCode` for telemetry.
89
+ *
90
+ * @module errors/system-errors
472
91
  */
473
- declare class HttpResponse {
474
- /**
475
- * Format a success response
476
- *
477
- * @param config - Success response configuration
478
- * @returns Formatted success response object
479
- */
480
- static success(config?: SuccessResponseConfig): SuccessResponse;
481
- /**
482
- * Format an error response
483
- *
484
- * @param error - HttpError instance
485
- * @param config - Optional error response configuration
486
- * @returns Formatted error response object
487
- */
488
- static error(error: HttpError, config?: ErrorResponseConfig): ErrorResponse;
489
- /**
490
- * Format a response from any error (converts to HttpError first)
491
- *
492
- * @param error - Any error type
493
- * @param config - Optional error response configuration
494
- * @returns Formatted error response object
495
- */
496
- static fromError(error: unknown, config?: ErrorResponseConfig): ErrorResponse;
497
- /** 200 OK */
498
- static ok(data?: unknown, message?: string): SuccessResponse;
499
- /** 201 Created */
500
- static created(data?: unknown, message?: string): SuccessResponse;
501
- /** 202 Accepted */
502
- static accepted(data?: unknown, message?: string): SuccessResponse;
503
- /** 204 No Content */
504
- static noContent(): SuccessResponse;
505
- /** 206 Partial Content */
506
- static partialContent(data?: unknown, message?: string): SuccessResponse;
507
- /** 304 Not Modified */
508
- static notModified(): SuccessResponse;
509
- /**
510
- * Check if a response is a success response
511
- */
512
- static isSuccess(response: SuccessResponse | ErrorResponse): response is SuccessResponse;
513
- /**
514
- * Check if a response is an error response
515
- */
516
- static isError(response: SuccessResponse | ErrorResponse): response is ErrorResponse;
517
- /**
518
- * Create a paginated success response
519
- */
520
- static paginated(data: unknown[], pagination: {
521
- page: number;
522
- limit: number;
523
- total: number;
524
- totalPages?: number;
525
- }, message?: string): SuccessResponse;
526
- }
527
92
 
528
93
  /**
529
- * HTTP Response Kit - Library Configuration
530
- * @module config
94
+ * Mapping from Node.js / undici error codes to HTTP status codes.
95
+ * Exported so consumers can inspect or extend their own logic on top.
531
96
  */
532
-
97
+ declare const SystemErrorStatusMap: Readonly<Record<string, number>>;
533
98
  /**
534
- * Configure the library globally
99
+ * Map a Node.js system/socket error to the appropriate HttpError
100
+ * (502/503/504), or return `undefined` when the error is not a
101
+ * recognized system error.
535
102
  *
536
- * @param config - Partial configuration to merge with current settings
103
+ * The resulting error is never exposable: clients get the generic status
104
+ * description, while the original message and cause stay available for
105
+ * logging. The syscall code is set as `errorCode` for telemetry.
537
106
  *
538
107
  * @example
539
108
  * ```ts
540
- * configure({
541
- * isDevelopment: true,
542
- * includeTimestamp: false,
543
- * customMessages: {
544
- * 404: 'Oops! This page went on vacation 🏝️',
545
- * 500: 'Well, this is embarrassing... 🤖'
546
- * },
547
- * });
109
+ * try {
110
+ * await fetch('http://upstream.internal/api');
111
+ * } catch (err) {
112
+ * throw mapSystemError(err) ?? HttpError.fromError(err);
113
+ * }
114
+ * // ECONNREFUSED -> 502 { error: { code: 'ECONNREFUSED', message: <generic> } }
548
115
  * ```
549
116
  */
550
- declare function configure(config: Partial<LibraryConfig>): void;
117
+ declare function mapSystemError(error: unknown): HttpError | undefined;
118
+
119
+ /**
120
+ * HTTP Response Kit - RFC 9457 Problem Details helpers
121
+ * @module responses/problem
122
+ */
123
+
551
124
  /**
552
- * Get the current library configuration
125
+ * The media type for RFC 9457 Problem Details responses.
126
+ * Set it as `Content-Type` when sending problem bodies.
553
127
  */
554
- declare function getConfig(): LibraryConfig;
128
+ declare const PROBLEM_CONTENT_TYPE = "application/problem+json";
555
129
  /**
556
- * Reset configuration to defaults
130
+ * Build an RFC 9457 Problem Details object from any error.
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * res
135
+ * .status(problem.status)
136
+ * .set('Content-Type', PROBLEM_CONTENT_TYPE)
137
+ * .json(toProblem(err, { typeBase: 'https://errors.example.com' }));
138
+ * ```
557
139
  */
558
- declare function resetConfig(): void;
140
+ declare function toProblem(error: unknown, options?: ProblemOptions): ProblemDetails;
559
141
  /**
560
- * Check if running in development mode
142
+ * Type guard for Problem Details objects
561
143
  */
562
- declare function isDevelopment(): boolean;
144
+ declare function isProblemDetails(value: unknown): value is ProblemDetails;
563
145
 
564
- export { type ErrorResponse, type ErrorResponseConfig, HttpClientErrorCode, HttpError, HttpErrorCode, HttpErrorDefinitions, type HttpErrorInfo, type HttpErrorOptions, HttpInfoCode, HttpInfoDefinitions, HttpRedirectCode, HttpRedirectDefinitions, HttpResponse, HttpServerErrorCode, HttpSuccessCode, HttpSuccessDefinitions, type HttpSuccessInfo, type LibraryConfig, type SuccessResponse, type SuccessResponseConfig, configure, getConfig, getErrorDefinition, getSuccessDefinition, isDevelopment, resetConfig };
146
+ export { CatalogEntry, type CatalogFactory, HttpError, HttpErrorDefinitions, HttpErrorInfo, HttpErrorOptions, HttpInfoDefinitions, HttpRedirectDefinitions, HttpSuccessDefinitions, HttpSuccessInfo, PROBLEM_CONTENT_TYPE, ProblemDetails, ProblemOptions, SystemErrorStatusMap, createErrorCatalog, getErrorDefinition, getSuccessDefinition, isProblemDetails, mapSystemError, toProblem };