http-response-kit 1.1.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 -281
  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 -527
  26. package/dist/index.d.ts +75 -527
  27. package/dist/index.js +440 -188
  28. package/dist/index.js.map +1 -0
  29. package/dist/index.mjs +18 -939
  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 -53
package/dist/index.d.mts CHANGED
@@ -1,282 +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<T = unknown> {
48
- /** Response data payload */
49
- data?: T;
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
- /** Fallback status code for unknown errors */
66
- fallbackCode?: number;
67
- }
68
- /**
69
- * Global library configuration
70
- */
71
- interface LibraryConfig {
72
- /** Enable development mode (includes stack traces) */
73
- isDevelopment?: boolean;
74
- /** Include timestamp in responses */
75
- includeTimestamp?: boolean;
76
- /** Custom default messages per error code */
77
- customMessages?: Partial<Record<number, string>>;
78
- /** Custom response transformer */
79
- responseTransformer?: (response: Record<string, unknown>) => Record<string, unknown>;
80
- }
81
- /**
82
- * Standard success response structure.
83
- * The index signature `[key: string]: unknown` allows additional fields via
84
- * `additionalFields`, but extra properties will be typed as `unknown` at compile time.
85
- */
86
- interface SuccessResponse<T = unknown> {
87
- success: true;
88
- status_code: number;
89
- timestamp?: string;
90
- data?: T;
91
- message?: string;
92
- metadata?: Record<string, unknown>;
93
- [key: string]: unknown;
94
- }
95
- /**
96
- * Standard error response structure.
97
- * The index signature `[key: string]: unknown` allows additional fields via
98
- * `additionalFields`, but extra properties will be typed as `unknown` at compile time.
99
- */
100
- interface ErrorResponse {
101
- success: false;
102
- status_code: number;
103
- timestamp?: string;
104
- retry_after?: number;
105
- error: {
106
- type: string;
107
- title: string;
108
- message: string;
109
- details?: string;
110
- stack?: string;
111
- };
112
- metadata?: Record<string, unknown>;
113
- [key: string]: unknown;
114
- }
115
- /**
116
- * Input parameters for paginated responses
117
- */
118
- interface PaginationInput {
119
- /** Current page number */
120
- page: number;
121
- /** Items per page */
122
- limit: number;
123
- /** Total number of items */
124
- total: number;
125
- /** Optional pre-computed total pages (overrides auto-calculation) */
126
- totalPages?: number;
127
- }
128
- /**
129
- * Pagination metadata included in paginated responses
130
- */
131
- interface PaginationMeta {
132
- page: number;
133
- limit: number;
134
- total: number;
135
- total_pages: number;
136
- has_next: boolean;
137
- has_prev: boolean;
138
- }
139
-
140
- /**
141
- * HTTP Response Kit - Status Code Enums
142
- * @module constants/status-codes
143
- */
144
- /**
145
- * HTTP 4xx Client Error codes
146
- */
147
- declare enum HttpClientErrorCode {
148
- BAD_REQUEST = 400,
149
- UNAUTHORIZED = 401,
150
- PAYMENT_REQUIRED = 402,
151
- FORBIDDEN = 403,
152
- NOT_FOUND = 404,
153
- METHOD_NOT_ALLOWED = 405,
154
- NOT_ACCEPTABLE = 406,
155
- PROXY_AUTHENTICATION_REQUIRED = 407,
156
- REQUEST_TIMEOUT = 408,
157
- CONFLICT = 409,
158
- GONE = 410,
159
- LENGTH_REQUIRED = 411,
160
- PRECONDITION_FAILED = 412,
161
- PAYLOAD_TOO_LARGE = 413,
162
- URI_TOO_LONG = 414,
163
- UNSUPPORTED_MEDIA_TYPE = 415,
164
- RANGE_NOT_SATISFIABLE = 416,
165
- EXPECTATION_FAILED = 417,
166
- IM_A_TEAPOT = 418,
167
- MISDIRECTED_REQUEST = 421,
168
- UNPROCESSABLE_ENTITY = 422,
169
- LOCKED = 423,
170
- FAILED_DEPENDENCY = 424,
171
- TOO_EARLY = 425,
172
- UPGRADE_REQUIRED = 426,
173
- PRECONDITION_REQUIRED = 428,
174
- TOO_MANY_REQUESTS = 429,
175
- REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
176
- UNAVAILABLE_FOR_LEGAL_REASONS = 451
177
- }
178
- /**
179
- * HTTP 5xx Server Error codes
180
- */
181
- declare enum HttpServerErrorCode {
182
- INTERNAL_SERVER_ERROR = 500,
183
- NOT_IMPLEMENTED = 501,
184
- BAD_GATEWAY = 502,
185
- SERVICE_UNAVAILABLE = 503,
186
- GATEWAY_TIMEOUT = 504,
187
- HTTP_VERSION_NOT_SUPPORTED = 505,
188
- VARIANT_ALSO_NEGOTIATES = 506,
189
- INSUFFICIENT_STORAGE = 507,
190
- LOOP_DETECTED = 508,
191
- BANDWIDTH_LIMIT_EXCEEDED = 509,
192
- NOT_EXTENDED = 510,
193
- NETWORK_AUTHENTICATION_REQUIRED = 511
194
- }
195
- /**
196
- * All HTTP Error codes (4xx + 5xx)
197
- */
198
- declare const HttpErrorCode: {
199
- readonly [x: number]: string;
200
- readonly INTERNAL_SERVER_ERROR: HttpServerErrorCode.INTERNAL_SERVER_ERROR;
201
- readonly NOT_IMPLEMENTED: HttpServerErrorCode.NOT_IMPLEMENTED;
202
- readonly BAD_GATEWAY: HttpServerErrorCode.BAD_GATEWAY;
203
- readonly SERVICE_UNAVAILABLE: HttpServerErrorCode.SERVICE_UNAVAILABLE;
204
- readonly GATEWAY_TIMEOUT: HttpServerErrorCode.GATEWAY_TIMEOUT;
205
- readonly HTTP_VERSION_NOT_SUPPORTED: HttpServerErrorCode.HTTP_VERSION_NOT_SUPPORTED;
206
- readonly VARIANT_ALSO_NEGOTIATES: HttpServerErrorCode.VARIANT_ALSO_NEGOTIATES;
207
- readonly INSUFFICIENT_STORAGE: HttpServerErrorCode.INSUFFICIENT_STORAGE;
208
- readonly LOOP_DETECTED: HttpServerErrorCode.LOOP_DETECTED;
209
- readonly BANDWIDTH_LIMIT_EXCEEDED: HttpServerErrorCode.BANDWIDTH_LIMIT_EXCEEDED;
210
- readonly NOT_EXTENDED: HttpServerErrorCode.NOT_EXTENDED;
211
- readonly NETWORK_AUTHENTICATION_REQUIRED: HttpServerErrorCode.NETWORK_AUTHENTICATION_REQUIRED;
212
- readonly BAD_REQUEST: HttpClientErrorCode.BAD_REQUEST;
213
- readonly UNAUTHORIZED: HttpClientErrorCode.UNAUTHORIZED;
214
- readonly PAYMENT_REQUIRED: HttpClientErrorCode.PAYMENT_REQUIRED;
215
- readonly FORBIDDEN: HttpClientErrorCode.FORBIDDEN;
216
- readonly NOT_FOUND: HttpClientErrorCode.NOT_FOUND;
217
- readonly METHOD_NOT_ALLOWED: HttpClientErrorCode.METHOD_NOT_ALLOWED;
218
- readonly NOT_ACCEPTABLE: HttpClientErrorCode.NOT_ACCEPTABLE;
219
- readonly PROXY_AUTHENTICATION_REQUIRED: HttpClientErrorCode.PROXY_AUTHENTICATION_REQUIRED;
220
- readonly REQUEST_TIMEOUT: HttpClientErrorCode.REQUEST_TIMEOUT;
221
- readonly CONFLICT: HttpClientErrorCode.CONFLICT;
222
- readonly GONE: HttpClientErrorCode.GONE;
223
- readonly LENGTH_REQUIRED: HttpClientErrorCode.LENGTH_REQUIRED;
224
- readonly PRECONDITION_FAILED: HttpClientErrorCode.PRECONDITION_FAILED;
225
- readonly PAYLOAD_TOO_LARGE: HttpClientErrorCode.PAYLOAD_TOO_LARGE;
226
- readonly URI_TOO_LONG: HttpClientErrorCode.URI_TOO_LONG;
227
- readonly UNSUPPORTED_MEDIA_TYPE: HttpClientErrorCode.UNSUPPORTED_MEDIA_TYPE;
228
- readonly RANGE_NOT_SATISFIABLE: HttpClientErrorCode.RANGE_NOT_SATISFIABLE;
229
- readonly EXPECTATION_FAILED: HttpClientErrorCode.EXPECTATION_FAILED;
230
- readonly IM_A_TEAPOT: HttpClientErrorCode.IM_A_TEAPOT;
231
- readonly MISDIRECTED_REQUEST: HttpClientErrorCode.MISDIRECTED_REQUEST;
232
- readonly UNPROCESSABLE_ENTITY: HttpClientErrorCode.UNPROCESSABLE_ENTITY;
233
- readonly LOCKED: HttpClientErrorCode.LOCKED;
234
- readonly FAILED_DEPENDENCY: HttpClientErrorCode.FAILED_DEPENDENCY;
235
- readonly TOO_EARLY: HttpClientErrorCode.TOO_EARLY;
236
- readonly UPGRADE_REQUIRED: HttpClientErrorCode.UPGRADE_REQUIRED;
237
- readonly PRECONDITION_REQUIRED: HttpClientErrorCode.PRECONDITION_REQUIRED;
238
- readonly TOO_MANY_REQUESTS: HttpClientErrorCode.TOO_MANY_REQUESTS;
239
- readonly REQUEST_HEADER_FIELDS_TOO_LARGE: HttpClientErrorCode.REQUEST_HEADER_FIELDS_TOO_LARGE;
240
- readonly UNAVAILABLE_FOR_LEGAL_REASONS: HttpClientErrorCode.UNAVAILABLE_FOR_LEGAL_REASONS;
241
- };
242
- type HttpErrorCode = HttpClientErrorCode | HttpServerErrorCode;
243
- /**
244
- * HTTP 2xx Success codes
245
- */
246
- declare enum HttpSuccessCode {
247
- OK = 200,
248
- CREATED = 201,
249
- ACCEPTED = 202,
250
- NON_AUTHORITATIVE_INFORMATION = 203,
251
- NO_CONTENT = 204,
252
- RESET_CONTENT = 205,
253
- PARTIAL_CONTENT = 206,
254
- MULTI_STATUS = 207,
255
- ALREADY_REPORTED = 208,
256
- IM_USED = 226
257
- }
258
- /**
259
- * HTTP 3xx Redirect codes
260
- */
261
- declare enum HttpRedirectCode {
262
- MULTIPLE_CHOICES = 300,
263
- MOVED_PERMANENTLY = 301,
264
- FOUND = 302,
265
- SEE_OTHER = 303,
266
- NOT_MODIFIED = 304,
267
- USE_PROXY = 305,
268
- TEMPORARY_REDIRECT = 307,
269
- PERMANENT_REDIRECT = 308
270
- }
271
- /**
272
- * HTTP 1xx Informational codes
273
- */
274
- declare enum HttpInfoCode {
275
- CONTINUE = 100,
276
- SWITCHING_PROTOCOLS = 101,
277
- PROCESSING = 102,
278
- EARLY_HINTS = 103
279
- }
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';
280
3
 
281
4
  /**
282
5
  * HTTP Response Kit - Error Definitions
@@ -315,284 +38,109 @@ declare const HttpInfoDefinitions: Record<number, HttpSuccessInfo>;
315
38
  declare function getSuccessDefinition(code: number): HttpSuccessInfo;
316
39
 
317
40
  /**
318
- * HTTP Response Kit - HttpError Class
319
- * @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
320
48
  */
321
49
 
50
+ /** A factory produced by {@link createErrorCatalog} */
51
+ type CatalogFactory = (message?: string, options?: Omit<HttpErrorOptions, 'errorCode'>) => HttpError;
322
52
  /**
323
- * Custom HTTP Error class that extends the native Error class.
324
- * 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).
325
57
  *
326
58
  * @example
327
59
  * ```ts
328
- * // Basic usage with status code
329
- * throw new HttpError(404);
330
- * throw new HttpError(HttpErrorCode.NOT_FOUND);
331
- *
332
- * // With custom message
333
- * throw new HttpError(404, { message: 'User not found' });
334
- *
335
- * // With metadata
336
- * throw new HttpError(400, {
337
- * message: 'Validation failed',
338
- * 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 },
339
64
  * });
340
65
  *
341
- * // Using factory methods
342
- * throw HttpError.notFound('Resource not found');
343
- * 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
344
68
  * ```
345
69
  */
346
- declare class HttpError extends Error {
347
- /** HTTP status code */
348
- readonly code: number;
349
- /** Lowercase error type identifier */
350
- readonly type: string;
351
- /** Human-readable error title */
352
- readonly title: string;
353
- /** Default error description from definition */
354
- readonly details: string;
355
- /** Additional error metadata */
356
- readonly metadata?: Record<string, unknown>;
357
- /** Original error cause */
358
- readonly cause?: Error;
359
- /** Retry-after time in seconds (if applicable) */
360
- readonly retryAfter?: number;
361
- /**
362
- * Creates a new HttpError instance
363
- *
364
- * @param code - HTTP status code (e.g., 404, 500)
365
- * @param options - Optional configuration
366
- */
367
- constructor(code: HttpClientErrorCode | HttpServerErrorCode | number, options?: HttpErrorOptions);
368
- /**
369
- * Convert error to plain object for JSON serialization
370
- */
371
- toJSON(): Record<string, unknown>;
372
- /** 400 Bad Request */
373
- static badRequest(message?: string, metadata?: Record<string, unknown>): HttpError;
374
- /** 401 Unauthorized */
375
- static unauthorized(message?: string, metadata?: Record<string, unknown>): HttpError;
376
- /** 402 Payment Required */
377
- static paymentRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
378
- /** 403 Forbidden */
379
- static forbidden(message?: string, metadata?: Record<string, unknown>): HttpError;
380
- /** 404 Not Found */
381
- static notFound(message?: string, metadata?: Record<string, unknown>): HttpError;
382
- /** 405 Method Not Allowed */
383
- static methodNotAllowed(message?: string, metadata?: Record<string, unknown>): HttpError;
384
- /** 406 Not Acceptable */
385
- static notAcceptable(message?: string, metadata?: Record<string, unknown>): HttpError;
386
- /** 407 Proxy Authentication Required */
387
- static proxyAuthenticationRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
388
- /** 408 Request Timeout */
389
- static requestTimeout(message?: string, metadata?: Record<string, unknown>): HttpError;
390
- /** 409 Conflict */
391
- static conflict(message?: string, metadata?: Record<string, unknown>): HttpError;
392
- /** 410 Gone */
393
- static gone(message?: string, metadata?: Record<string, unknown>): HttpError;
394
- /** 411 Length Required */
395
- static lengthRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
396
- /** 412 Precondition Failed */
397
- static preconditionFailed(message?: string, metadata?: Record<string, unknown>): HttpError;
398
- /** 413 Payload Too Large */
399
- static payloadTooLarge(message?: string, metadata?: Record<string, unknown>): HttpError;
400
- /** 414 URI Too Long */
401
- static uriTooLong(message?: string, metadata?: Record<string, unknown>): HttpError;
402
- /** 415 Unsupported Media Type */
403
- static unsupportedMediaType(message?: string, metadata?: Record<string, unknown>): HttpError;
404
- /** 416 Range Not Satisfiable */
405
- static rangeNotSatisfiable(message?: string, metadata?: Record<string, unknown>): HttpError;
406
- /** 417 Expectation Failed */
407
- static expectationFailed(message?: string, metadata?: Record<string, unknown>): HttpError;
408
- /** 418 I'm a Teapot */
409
- static imATeapot(message?: string, metadata?: Record<string, unknown>): HttpError;
410
- /** 421 Misdirected Request */
411
- static misdirectedRequest(message?: string, metadata?: Record<string, unknown>): HttpError;
412
- /** 422 Unprocessable Entity */
413
- static unprocessableEntity(message?: string, metadata?: Record<string, unknown>): HttpError;
414
- /** 423 Locked */
415
- static locked(message?: string, metadata?: Record<string, unknown>): HttpError;
416
- /** 424 Failed Dependency */
417
- static failedDependency(message?: string, metadata?: Record<string, unknown>): HttpError;
418
- /** 425 Too Early */
419
- static tooEarly(message?: string, metadata?: Record<string, unknown>): HttpError;
420
- /** 426 Upgrade Required */
421
- static upgradeRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
422
- /** 428 Precondition Required */
423
- static preconditionRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
424
- /** 429 Too Many Requests */
425
- static tooManyRequests(message?: string, retryAfter?: number, metadata?: Record<string, unknown>): HttpError;
426
- /** 431 Request Header Fields Too Large */
427
- static requestHeaderFieldsTooLarge(message?: string, metadata?: Record<string, unknown>): HttpError;
428
- /** 451 Unavailable For Legal Reasons */
429
- static unavailableForLegalReasons(message?: string, metadata?: Record<string, unknown>): HttpError;
430
- /** 500 Internal Server Error */
431
- static internalServerError(message?: string, metadata?: Record<string, unknown>): HttpError;
432
- /** 501 Not Implemented */
433
- static notImplemented(message?: string, metadata?: Record<string, unknown>): HttpError;
434
- /** 502 Bad Gateway */
435
- static badGateway(message?: string, metadata?: Record<string, unknown>): HttpError;
436
- /** 503 Service Unavailable */
437
- static serviceUnavailable(message?: string, retryAfter?: number, metadata?: Record<string, unknown>): HttpError;
438
- /** 504 Gateway Timeout */
439
- static gatewayTimeout(message?: string, metadata?: Record<string, unknown>): HttpError;
440
- /** 505 HTTP Version Not Supported */
441
- static httpVersionNotSupported(message?: string, metadata?: Record<string, unknown>): HttpError;
442
- /** 506 Variant Also Negotiates */
443
- static variantAlsoNegotiates(message?: string, metadata?: Record<string, unknown>): HttpError;
444
- /** 507 Insufficient Storage */
445
- static insufficientStorage(message?: string, metadata?: Record<string, unknown>): HttpError;
446
- /** 508 Loop Detected */
447
- static loopDetected(message?: string, metadata?: Record<string, unknown>): HttpError;
448
- /** 509 Bandwidth Limit Exceeded */
449
- static bandwidthLimitExceeded(message?: string, metadata?: Record<string, unknown>): HttpError;
450
- /** 510 Not Extended */
451
- static notExtended(message?: string, metadata?: Record<string, unknown>): HttpError;
452
- /** 511 Network Authentication Required */
453
- static networkAuthenticationRequired(message?: string, metadata?: Record<string, unknown>): HttpError;
454
- /**
455
- * Create an HttpError from a status code with default definition values.
456
- * Semantic alias for `new HttpError(code)`.
457
- */
458
- static fromStatus(code: HttpClientErrorCode | HttpServerErrorCode | number, options?: HttpErrorOptions): HttpError;
459
- /**
460
- * Create an HttpError from an unknown error
461
- */
462
- static fromError(error: unknown, fallbackCode?: number): HttpError;
463
- /**
464
- * Check if an error is an HttpError
465
- */
466
- static isHttpError(error: unknown): error is HttpError;
467
- /**
468
- * Check if error is a client error (4xx)
469
- */
470
- isClientError(): boolean;
471
- /**
472
- * Check if error is a server error (5xx)
473
- */
474
- isServerError(): boolean;
475
- }
476
-
477
- /**
478
- * HTTP Response Kit - HttpResponse Class
479
- * @module responses/HttpResponse
480
- */
70
+ declare function createErrorCatalog<T extends Record<string, CatalogEntry>>(catalog: T): {
71
+ [K in keyof T]: CatalogFactory;
72
+ };
481
73
 
482
74
  /**
483
- * Utility class for formatting HTTP responses.
484
- * Provides consistent structure for both success and error responses.
75
+ * HTTP Response Kit - System/socket error mapping
485
76
  *
486
- * @example
487
- * ```ts
488
- * // Success response
489
- * const response = HttpResponse.success({
490
- * data: { id: 1, name: 'John' },
491
- * message: 'User created successfully',
492
- * statusCode: 201
493
- * });
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:
494
80
  *
495
- * // Error response
496
- * const error = new HttpError(404, { message: 'User not found' });
497
- * 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
498
84
  *
499
- * // Express integration
500
- * app.get('/user/:id', (req, res) => {
501
- * try {
502
- * const user = findUser(req.params.id);
503
- * const response = HttpResponse.success({ data: user });
504
- * res.status(response.status_code).json(response);
505
- * } catch (err) {
506
- * const response = HttpResponse.error(HttpError.fromError(err));
507
- * res.status(response.status_code).json(response);
508
- * }
509
- * });
510
- * ```
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
511
91
  */
512
- declare class HttpResponse {
513
- /**
514
- * Format a success response
515
- *
516
- * @param config - Success response configuration
517
- * @returns Formatted success response object
518
- */
519
- static success<T = unknown>(config?: SuccessResponseConfig<T>): SuccessResponse<T>;
520
- /**
521
- * Format an error response
522
- *
523
- * @param error - HttpError instance
524
- * @param config - Optional error response configuration
525
- * @returns Formatted error response object
526
- */
527
- static error(error: HttpError, config?: ErrorResponseConfig): ErrorResponse;
528
- /**
529
- * Format a response from any error (converts to HttpError first)
530
- *
531
- * @param error - Any error type
532
- * @param config - Optional error response configuration
533
- * @returns Formatted error response object
534
- */
535
- static fromError(error: unknown, config?: ErrorResponseConfig): ErrorResponse;
536
- /** 200 OK */
537
- static ok<T = unknown>(data?: T, message?: string): SuccessResponse<T>;
538
- /** 201 Created */
539
- static created<T = unknown>(data?: T, message?: string): SuccessResponse<T>;
540
- /** 202 Accepted */
541
- static accepted<T = unknown>(data?: T, message?: string): SuccessResponse<T>;
542
- /** 204 No Content */
543
- static noContent(): SuccessResponse<never>;
544
- /** 206 Partial Content */
545
- static partialContent<T = unknown>(data?: T, message?: string): SuccessResponse<T>;
546
- /** 304 Not Modified — Note: 304 is a 3xx redirect code, included here as a convenience method */
547
- static notModified(): SuccessResponse<never>;
548
- /**
549
- * Check if a response is a success response
550
- */
551
- static isSuccess(response: SuccessResponse | ErrorResponse): response is SuccessResponse;
552
- /**
553
- * Check if a response is an error response
554
- */
555
- static isError(response: SuccessResponse | ErrorResponse): response is ErrorResponse;
556
- /**
557
- * Create a paginated success response
558
- */
559
- static paginated<T = unknown>(data: T[], pagination: PaginationInput, message?: string): SuccessResponse<T[]>;
560
- }
561
92
 
562
93
  /**
563
- * HTTP Response Kit - Library Configuration
564
- * @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.
565
96
  */
566
-
97
+ declare const SystemErrorStatusMap: Readonly<Record<string, number>>;
567
98
  /**
568
- * 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.
569
102
  *
570
- * @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.
571
106
  *
572
107
  * @example
573
108
  * ```ts
574
- * configure({
575
- * isDevelopment: true,
576
- * includeTimestamp: false,
577
- * customMessages: {
578
- * 404: 'Oops! This page went on vacation 🏝️',
579
- * 500: 'Well, this is embarrassing... 🤖'
580
- * },
581
- * });
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> } }
582
115
  * ```
583
116
  */
584
- declare function configure(config: Partial<LibraryConfig>): void;
117
+ declare function mapSystemError(error: unknown): HttpError | undefined;
118
+
585
119
  /**
586
- * Get the current library configuration
120
+ * HTTP Response Kit - RFC 9457 Problem Details helpers
121
+ * @module responses/problem
587
122
  */
588
- declare function getConfig(): Readonly<LibraryConfig>;
123
+
124
+ /**
125
+ * The media type for RFC 9457 Problem Details responses.
126
+ * Set it as `Content-Type` when sending problem bodies.
127
+ */
128
+ declare const PROBLEM_CONTENT_TYPE = "application/problem+json";
589
129
  /**
590
- * 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
+ * ```
591
139
  */
592
- declare function resetConfig(): void;
140
+ declare function toProblem(error: unknown, options?: ProblemOptions): ProblemDetails;
593
141
  /**
594
- * Check if running in development mode
142
+ * Type guard for Problem Details objects
595
143
  */
596
- declare function isDevelopment(): boolean;
144
+ declare function isProblemDetails(value: unknown): value is ProblemDetails;
597
145
 
598
- 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 PaginationInput, type PaginationMeta, 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 };