xypriss 9.10.22 → 9.10.23

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.
@@ -4,54 +4,100 @@
4
4
  // Helpers
5
5
  // ---------------------------------------------------------------------------
6
6
  /**
7
- * Derives a compact, uppercase error code from a {@link SupportedStatus} key.
7
+ * Derives a compact, uppercase code from a {@link SupportedStatus} key.
8
+ * Error codes start with `"E"`, success codes start with `"S"`.
8
9
  *
9
10
  * @example
10
- * buildErrorCode("BAD_REQUEST") // → "EBADR"
11
- * buildErrorCode("INTERNAL_SERVER_ERR") // → "EINTE"
11
+ * buildStatusCode("BAD_REQUEST") // → "EBADR"
12
+ * buildStatusCode("INTERNAL_SERVER_ERR") // → "EINTE"
13
+ * buildStatusCode("OK") // → "SOK"
14
+ * buildStatusCode("CREATED") // → "SCREA"
12
15
  *
13
- * @param status - The status key to convert.
14
- * @returns A 5-character string starting with `"E"`.
16
+ * @param status - The status key to convert.
17
+ * @param success - Whether this is a success response.
18
+ * @returns A short uppercase code prefixed with `"S"` or `"E"`.
15
19
  */
16
- function buildErrorCode(status) {
17
- // Remove all underscores, take first 4 chars, prepend "E"
18
- return "E" + status.replace(/_/g, "").slice(0, 4).toUpperCase();
20
+ function buildStatusCode(status, success) {
21
+ const prefix = success ? "S" : "E";
22
+ return prefix + status.replace(/_/g, "").slice(0, 4).toUpperCase();
19
23
  }
20
24
  // ---------------------------------------------------------------------------
21
25
  // Default HTTP status code registry
22
26
  // ---------------------------------------------------------------------------
23
27
  const DEFAULT_CONFIGS = {
28
+ // 2xx
29
+ OK: 200,
30
+ CREATED: 201,
31
+ ACCEPTED: 202,
32
+ NO_CONTENT: 204,
33
+ // 3xx
34
+ MOVED_PERMANENTLY: 301,
35
+ FOUND: 302,
36
+ NOT_MODIFIED: 304,
37
+ // 4xx
24
38
  BAD_REQUEST: 400,
39
+ UNAUTHORIZED: 401,
40
+ FORBIDDEN: 403,
25
41
  NOT_FOUND: 404,
42
+ METHOD_NOT_ALLOWED: 405,
43
+ NOT_ACCEPTABLE: 406,
44
+ REQUEST_TIMEOUT: 408,
45
+ CONFLICT: 409,
46
+ GONE: 410,
47
+ PRECONDITION_FAILED: 412,
48
+ PAYLOAD_TOO_LARGE: 413,
49
+ UNSUPPORTED_MEDIA_TYPE: 415,
50
+ EXPECTATION_FAILED: 417,
51
+ IM_A_TEAPOT: 418,
52
+ UNPROCESSABLE_ENTITY: 422,
53
+ LOCKED: 423,
26
54
  TOO_MANY_REQUEST: 429,
55
+ // 5xx
27
56
  INTERNAL_SERVER_ERR: 500,
57
+ NOT_IMPLEMENTED: 501,
58
+ BAD_GATEWAY: 502,
59
+ SERVICE_UNAVAILABLE: 503,
60
+ GATEWAY_TIMEOUT: 504,
28
61
  };
29
62
  // ---------------------------------------------------------------------------
30
63
  // Send class
31
64
  // ---------------------------------------------------------------------------
32
65
  /**
33
- * A structured HTTP response helper that standardises all error responses
34
- * across the application.
66
+ * A structured HTTP response helper that standardises all responses across
67
+ * the application — both success and error paths.
35
68
  *
36
69
  * Every method sends a JSON body conforming to {@link IResTemplate}, ensuring
37
- * consistent error shapes for API consumers regardless of where the error
70
+ * consistent shapes for API consumers regardless of where the response
38
71
  * originates.
39
72
  *
40
73
  * @example
41
74
  * ```ts
42
75
  * const send = new Send(res);
43
76
  *
44
- * // 400 validation failure
45
- * send.badRequest("The 'email' field is required.");
77
+ * // ── 2xx ──────────────────────────────────────────────────────────────────
78
+ * send.ok("User fetched.", { id: 1, name: "Alice" });
79
+ * send.created("User created.", { id: 42 });
80
+ * send.accepted("Your export is being processed.");
81
+ * send.noContent();
46
82
  *
47
- * // 404 resource missing
83
+ * // ── 4xx ──────────────────────────────────────────────────────────────────
84
+ * send.badRequest("The 'email' field is required.");
85
+ * send.unauthorized("Please log in to continue.");
86
+ * send.forbidden("You do not have permission to access this resource.");
48
87
  * send.notFound("User not found.", { userId: 42 });
88
+ * send.methodNotAllowed("POST is not allowed on this endpoint.");
89
+ * send.conflict("A user with this email already exists.");
90
+ * send.gone("This resource has been permanently deleted.");
91
+ * send.unprocessableEntity("Validation failed.", { fields: { email: "Invalid format" } });
92
+ * send.tooManyRequest("Rate limit reached. Try again in 60 seconds.");
93
+ * send.payloadTooLarge("File exceeds the 10 MB limit.");
94
+ * send.unsupportedMediaType("Only application/json is accepted.");
49
95
  *
50
- * // 429 rate limit exceeded
51
- * send.tooManyRequest("Too many requests. Please slow down.");
52
- *
53
- * // 500 – unexpected failure
96
+ * // ── 5xx ──────────────────────────────────────────────────────────────────
54
97
  * send.internalError("An unexpected error occurred.");
98
+ * send.notImplemented("This feature is not yet available.");
99
+ * send.serviceUnavailable("The server is temporarily down for maintenance.");
100
+ * send.gatewayTimeout("The upstream service did not respond in time.");
55
101
  * ```
56
102
  */
57
103
  class Send {
@@ -59,16 +105,121 @@ class Send {
59
105
  * Creates a new `Send` instance bound to the given response object.
60
106
  *
61
107
  * @param res - The active `XyPrisResponse` to write into.
62
- * @param configs - Optional override for the default status-code registry.
63
- * Useful for non-standard or custom HTTP codes.
108
+ * @param configs - Optional overrides for the default status-code registry
109
+ * and display options.
64
110
  */
65
111
  constructor(res, configs = {
66
112
  includeServerName: true,
67
113
  statusCode: {},
68
114
  }) {
69
- // -------------------------------------------------------------------------
70
- // Public methods
71
- // -------------------------------------------------------------------------
115
+ // =========================================================================
116
+ // 2xx — Success
117
+ // =========================================================================
118
+ /**
119
+ * Sends a **200 OK** response.
120
+ *
121
+ * The standard success response for GET, PUT, PATCH, or DELETE requests
122
+ * that return a body.
123
+ *
124
+ * @param message - Human-readable confirmation.
125
+ * @param data - Payload to return to the client.
126
+ *
127
+ * @example
128
+ * send.ok("User fetched successfully.", { id: 1, name: "Alice" });
129
+ */
130
+ this.ok = (message, data) => {
131
+ this.dispatch("OK", "OK", true, message, data);
132
+ };
133
+ /**
134
+ * Sends a **201 Created** response.
135
+ *
136
+ * Use after successfully creating a new resource.
137
+ * Consider also setting a `Location` header pointing to the new resource.
138
+ *
139
+ * @param message - Human-readable confirmation.
140
+ * @param data - The newly created resource or its identifier.
141
+ *
142
+ * @example
143
+ * send.created("User created.", { id: 42 });
144
+ */
145
+ this.created = (message, data) => {
146
+ this.dispatch("CREATED", "Created", true, message, data);
147
+ };
148
+ /**
149
+ * Sends a **202 Accepted** response.
150
+ *
151
+ * Use when the request has been accepted but processing will happen
152
+ * asynchronously (e.g. background jobs, email dispatch, report generation).
153
+ *
154
+ * @param message - Human-readable explanation of what will happen.
155
+ * @param data - Optional tracking info (e.g. job ID).
156
+ *
157
+ * @example
158
+ * send.accepted("Your export is being processed.", { jobId: "abc-123" });
159
+ */
160
+ this.accepted = (message, data) => {
161
+ this.dispatch("ACCEPTED", "Accepted", true, message, data);
162
+ };
163
+ /**
164
+ * Sends a **204 No Content** response.
165
+ *
166
+ * Use after a successful DELETE or an action that produces no body.
167
+ * RFC 7231 forbids a body for 204 — this method sends status only.
168
+ *
169
+ * @example
170
+ * send.noContent();
171
+ */
172
+ this.noContent = () => {
173
+ this.res.status(this.configs["NO_CONTENT"]).end();
174
+ };
175
+ // =========================================================================
176
+ // 3xx — Redirection
177
+ // =========================================================================
178
+ /**
179
+ * Sends a **301 Moved Permanently** response.
180
+ *
181
+ * Use when a resource has been permanently relocated. Clients and search
182
+ * engines should update their references.
183
+ *
184
+ * @param message - Optional explanation or the new URL.
185
+ * @param data - Optional payload (e.g. `{ location: "https://…" }`).
186
+ *
187
+ * @example
188
+ * send.movedPermanently("This endpoint has moved.", { location: "/v2/users" });
189
+ */
190
+ this.movedPermanently = (message, data) => {
191
+ this.dispatch("MOVED_PERMANENTLY", "Moved Permanently", false, message, data);
192
+ };
193
+ /**
194
+ * Sends a **302 Found** response.
195
+ *
196
+ * Use for temporary redirects. The client should continue using the
197
+ * original URL for future requests.
198
+ *
199
+ * @param message - Optional explanation or the temporary URL.
200
+ * @param data - Optional payload (e.g. `{ location: "https://…" }`).
201
+ *
202
+ * @example
203
+ * send.found("Redirecting to login.", { location: "/auth/login" });
204
+ */
205
+ this.found = (message, data) => {
206
+ this.dispatch("FOUND", "Found", false, message, data);
207
+ };
208
+ /**
209
+ * Sends a **304 Not Modified** response.
210
+ *
211
+ * Use with conditional requests (`If-None-Match`, `If-Modified-Since`).
212
+ * Tells the client its cached version is still valid.
213
+ *
214
+ * @example
215
+ * send.notModified();
216
+ */
217
+ this.notModified = () => {
218
+ this.res.status(this.configs["NOT_MODIFIED"]).end();
219
+ };
220
+ // =========================================================================
221
+ // 4xx — Client Errors
222
+ // =========================================================================
72
223
  /**
73
224
  * Sends a **400 Bad Request** response.
74
225
  *
@@ -83,7 +234,38 @@ class Send {
83
234
  * send.badRequest("Validation failed.", { fields: { email: "Invalid format" } });
84
235
  */
85
236
  this.badRequest = (message, data) => {
86
- this.dispatch("BAD_REQUEST", "Bad Request", message, data);
237
+ this.dispatch("BAD_REQUEST", "Bad Request", false, message, data);
238
+ };
239
+ /**
240
+ * Sends a **401 Unauthorized** response.
241
+ *
242
+ * Use when the request lacks valid authentication credentials.
243
+ * Despite the name, this is an *authentication* failure — not authorisation.
244
+ *
245
+ * @param message - Human-readable explanation (avoid leaking token details).
246
+ * @param data - Optional payload (e.g. `{ authScheme: "Bearer" }`).
247
+ *
248
+ * @example
249
+ * send.unauthorized("Authentication token is missing or expired.");
250
+ */
251
+ this.unauthorized = (message, data) => {
252
+ this.dispatch("UNAUTHORIZED", "Unauthorized", false, message, data);
253
+ };
254
+ /**
255
+ * Sends a **403 Forbidden** response.
256
+ *
257
+ * Use when the client is authenticated but lacks permission to access
258
+ * the resource. Unlike 401, re-authenticating will not help.
259
+ *
260
+ * @param message - Human-readable explanation of the permission boundary.
261
+ * @param data - Optional payload (e.g. required role/scope info).
262
+ *
263
+ * @example
264
+ * send.forbidden("You do not have permission to delete this resource.");
265
+ * send.forbidden("Admin role required.", { requiredRole: "admin" });
266
+ */
267
+ this.forbidden = (message, data) => {
268
+ this.dispatch("FORBIDDEN", "Forbidden", false, message, data);
87
269
  };
88
270
  /**
89
271
  * Sends a **404 Not Found** response.
@@ -98,7 +280,193 @@ class Send {
98
280
  * send.notFound("Resource not found.", { id: "42" });
99
281
  */
100
282
  this.notFound = (message, data) => {
101
- this.dispatch("NOT_FOUND", "Not Found", message, data);
283
+ this.dispatch("NOT_FOUND", "Not Found", false, message, data);
284
+ };
285
+ /**
286
+ * Sends a **405 Method Not Allowed** response.
287
+ *
288
+ * Use when the HTTP method used is not supported on the target endpoint.
289
+ * Always pair this with an `Allow` header listing permitted methods.
290
+ *
291
+ * @param message - Human-readable explanation of the allowed methods.
292
+ * @param data - Optional payload (e.g. `{ allowedMethods: ["GET", "POST"] }`).
293
+ *
294
+ * @example
295
+ * send.methodNotAllowed("Only GET and POST are allowed on this route.");
296
+ * send.methodNotAllowed("Method not allowed.", { allowedMethods: ["GET", "POST"] });
297
+ */
298
+ this.methodNotAllowed = (message, data) => {
299
+ this.dispatch("METHOD_NOT_ALLOWED", "Method Not Allowed", false, message, data);
300
+ };
301
+ /**
302
+ * Sends a **406 Not Acceptable** response.
303
+ *
304
+ * Use when the server cannot produce a response matching the client's
305
+ * `Accept` header (content-type negotiation failure).
306
+ *
307
+ * @param message - Human-readable explanation of supported content types.
308
+ * @param data - Optional payload (e.g. `{ supportedTypes: ["application/json"] }`).
309
+ *
310
+ * @example
311
+ * send.notAcceptable("This API only serves application/json.");
312
+ */
313
+ this.notAcceptable = (message, data) => {
314
+ this.dispatch("NOT_ACCEPTABLE", "Not Acceptable", false, message, data);
315
+ };
316
+ /**
317
+ * Sends a **408 Request Timeout** response.
318
+ *
319
+ * Use when the server times out waiting for the client to complete its
320
+ * request within the allowed time window.
321
+ *
322
+ * @param message - Human-readable explanation of the timeout.
323
+ * @param data - Optional payload (e.g. `{ timeoutMs: 5000 }`).
324
+ *
325
+ * @example
326
+ * send.requestTimeout("The request took too long. Please try again.");
327
+ */
328
+ this.requestTimeout = (message, data) => {
329
+ this.dispatch("REQUEST_TIMEOUT", "Request Timeout", false, message, data);
330
+ };
331
+ /**
332
+ * Sends a **409 Conflict** response.
333
+ *
334
+ * Use when the request conflicts with the current state of the resource
335
+ * (e.g. duplicate entry, optimistic-lock violation, concurrent edit clash).
336
+ *
337
+ * @param message - Human-readable explanation of the conflict.
338
+ * @param data - Optional payload (e.g. the conflicting resource).
339
+ *
340
+ * @example
341
+ * send.conflict("A user with this email already exists.");
342
+ * send.conflict("Edit conflict detected.", { existingVersion: 3, yourVersion: 2 });
343
+ */
344
+ this.conflict = (message, data) => {
345
+ this.dispatch("CONFLICT", "Conflict", false, message, data);
346
+ };
347
+ /**
348
+ * Sends a **410 Gone** response.
349
+ *
350
+ * Use when a resource has been *permanently* deleted and will not return.
351
+ * Prefer 404 when you don't want to reveal whether the resource ever existed.
352
+ *
353
+ * @param message - Human-readable explanation of the permanent removal.
354
+ * @param data - Optional payload (e.g. deletion date).
355
+ *
356
+ * @example
357
+ * send.gone("This account has been permanently deleted.");
358
+ */
359
+ this.gone = (message, data) => {
360
+ this.dispatch("GONE", "Gone", false, message, data);
361
+ };
362
+ /**
363
+ * Sends a **412 Precondition Failed** response.
364
+ *
365
+ * Use when a conditional request (`If-Match`, `If-Unmodified-Since`) fails
366
+ * because the precondition evaluated to false on the server.
367
+ *
368
+ * @param message - Human-readable explanation of the failed precondition.
369
+ * @param data - Optional payload (e.g. current ETag or last-modified date).
370
+ *
371
+ * @example
372
+ * send.preconditionFailed("ETag mismatch — resource was modified since your last fetch.");
373
+ */
374
+ this.preconditionFailed = (message, data) => {
375
+ this.dispatch("PRECONDITION_FAILED", "Precondition Failed", false, message, data);
376
+ };
377
+ /**
378
+ * Sends a **413 Payload Too Large** response.
379
+ *
380
+ * Use when the request body exceeds the server's or route's size limit.
381
+ *
382
+ * @param message - Human-readable explanation including the size limit when safe.
383
+ * @param data - Optional payload (e.g. `{ maxBytes: 10_485_760 }`).
384
+ *
385
+ * @example
386
+ * send.payloadTooLarge("File exceeds the 10 MB limit.");
387
+ * send.payloadTooLarge("Request body too large.", { maxBytes: 10_485_760 });
388
+ */
389
+ this.payloadTooLarge = (message, data) => {
390
+ this.dispatch("PAYLOAD_TOO_LARGE", "Payload Too Large", false, message, data);
391
+ };
392
+ /**
393
+ * Sends a **415 Unsupported Media Type** response.
394
+ *
395
+ * Use when the `Content-Type` or encoding sent by the client is not
396
+ * supported by the endpoint.
397
+ *
398
+ * @param message - Human-readable explanation of accepted media types.
399
+ * @param data - Optional payload (e.g. `{ acceptedTypes: ["application/json"] }`).
400
+ *
401
+ * @example
402
+ * send.unsupportedMediaType("Only application/json payloads are accepted.");
403
+ */
404
+ this.unsupportedMediaType = (message, data) => {
405
+ this.dispatch("UNSUPPORTED_MEDIA_TYPE", "Unsupported Media Type", false, message, data);
406
+ };
407
+ /**
408
+ * Sends a **417 Expectation Failed** response.
409
+ *
410
+ * Use when the `Expect` request-header field could not be satisfied by
411
+ * the server.
412
+ *
413
+ * @param message - Human-readable explanation of the unmet expectation.
414
+ * @param data - Optional payload.
415
+ *
416
+ * @example
417
+ * send.expectationFailed("The 'Expect: 100-continue' header could not be satisfied.");
418
+ */
419
+ this.expectationFailed = (message, data) => {
420
+ this.dispatch("EXPECTATION_FAILED", "Expectation Failed", false, message, data);
421
+ };
422
+ /**
423
+ * Sends a **418 I'm a Teapot** response.
424
+ *
425
+ * An April Fools' joke defined in RFC 2324. Occasionally used as a
426
+ * catch-all for intentionally refused requests (e.g. blocking bots).
427
+ *
428
+ * @param message - Whatever you want. The world is your teapot.
429
+ * @param data - Optional payload.
430
+ *
431
+ * @example
432
+ * send.imATeapot("I refuse to brew coffee because I am, permanently, a teapot.");
433
+ */
434
+ this.imATeapot = (message, data) => {
435
+ this.dispatch("IM_A_TEAPOT", "I'm a Teapot", false, message, data);
436
+ };
437
+ /**
438
+ * Sends a **422 Unprocessable Entity** response.
439
+ *
440
+ * Use when the request is well-formed but contains semantic errors that
441
+ * prevent it from being processed (e.g. domain validation failures,
442
+ * business rule violations). Preferred over 400 for schema-valid but
443
+ * logically invalid payloads.
444
+ *
445
+ * @param message - Human-readable explanation of why processing failed.
446
+ * @param data - Optional payload (e.g. structured validation errors per field).
447
+ *
448
+ * @example
449
+ * send.unprocessableEntity("The 'birthDate' must be in the past.");
450
+ * send.unprocessableEntity("Validation errors.", { fields: { age: "Must be ≥ 18" } });
451
+ */
452
+ this.unprocessableEntity = (message, data) => {
453
+ this.dispatch("UNPROCESSABLE_ENTITY", "Unprocessable Entity", false, message, data);
454
+ };
455
+ /**
456
+ * Sends a **423 Locked** response.
457
+ *
458
+ * Use when the resource being accessed is locked (e.g. being edited by
459
+ * another user, or under an administrative hold).
460
+ *
461
+ * @param message - Human-readable explanation of why the resource is locked.
462
+ * @param data - Optional payload (e.g. lock owner, estimated unlock time).
463
+ *
464
+ * @example
465
+ * send.locked("This document is currently being edited by another user.");
466
+ * send.locked("Resource is locked.", { lockedBy: "alice@example.com", until: "2025-06-01T12:00:00Z" });
467
+ */
468
+ this.locked = (message, data) => {
469
+ this.dispatch("LOCKED", "Locked", false, message, data);
102
470
  };
103
471
  /**
104
472
  * Sends a **429 Too Many Requests** response.
@@ -114,8 +482,11 @@ class Send {
114
482
  * send.tooManyRequest("Quota exceeded.", { retryAfter: 60 });
115
483
  */
116
484
  this.tooManyRequest = (message, data) => {
117
- this.dispatch("TOO_MANY_REQUEST", "Too Many Requests", message, data);
485
+ this.dispatch("TOO_MANY_REQUEST", "Too Many Requests", false, message, data);
118
486
  };
487
+ // =========================================================================
488
+ // 5xx — Server Errors
489
+ // =========================================================================
119
490
  /**
120
491
  * Sends a **500 Internal Server Error** response.
121
492
  *
@@ -129,7 +500,71 @@ class Send {
129
500
  * send.internalError("An unexpected error occurred. Please try again later.");
130
501
  */
131
502
  this.internalError = (message, data) => {
132
- this.dispatch("INTERNAL_SERVER_ERR", "Internal Server Error", message, data);
503
+ this.dispatch("INTERNAL_SERVER_ERR", "Internal Server Error", false, message, data);
504
+ };
505
+ /**
506
+ * Sends a **501 Not Implemented** response.
507
+ *
508
+ * Use when the server does not support the functionality required to
509
+ * fulfil the request (e.g. an HTTP method that is recognised but not
510
+ * implemented on this server, or a feature under development).
511
+ *
512
+ * @param message - Human-readable explanation of what is not implemented.
513
+ * @param data - Optional payload (e.g. planned availability date).
514
+ *
515
+ * @example
516
+ * send.notImplemented("The PATCH method is not yet supported on this resource.");
517
+ */
518
+ this.notImplemented = (message, data) => {
519
+ this.dispatch("NOT_IMPLEMENTED", "Not Implemented", false, message, data);
520
+ };
521
+ /**
522
+ * Sends a **502 Bad Gateway** response.
523
+ *
524
+ * Use when this server, acting as a gateway or proxy, received an invalid
525
+ * response from an upstream server.
526
+ *
527
+ * @param message - Human-readable explanation safe to expose to the client.
528
+ * @param data - Optional payload (e.g. upstream service identifier).
529
+ *
530
+ * @example
531
+ * send.badGateway("The payment provider returned an unexpected response.");
532
+ */
533
+ this.badGateway = (message, data) => {
534
+ this.dispatch("BAD_GATEWAY", "Bad Gateway", false, message, data);
535
+ };
536
+ /**
537
+ * Sends a **503 Service Unavailable** response.
538
+ *
539
+ * Use when the server is temporarily unable to handle the request due to
540
+ * maintenance, overload, or a dependency outage. Pair with a
541
+ * `Retry-After` header when the downtime window is known.
542
+ *
543
+ * @param message - Human-readable explanation including estimated recovery time when available.
544
+ * @param data - Optional payload (e.g. `{ retryAfter: "2025-06-01T06:00:00Z" }`).
545
+ *
546
+ * @example
547
+ * send.serviceUnavailable("Scheduled maintenance until 06:00 UTC.");
548
+ * send.serviceUnavailable("Server overloaded.", { retryAfter: "2025-06-01T06:00:00Z" });
549
+ */
550
+ this.serviceUnavailable = (message, data) => {
551
+ this.dispatch("SERVICE_UNAVAILABLE", "Service Unavailable", false, message, data);
552
+ };
553
+ /**
554
+ * Sends a **504 Gateway Timeout** response.
555
+ *
556
+ * Use when this server, acting as a gateway or proxy, did not receive a
557
+ * timely response from an upstream server.
558
+ *
559
+ * @param message - Human-readable explanation of which upstream timed out.
560
+ * @param data - Optional payload (e.g. upstream service name, timeout duration).
561
+ *
562
+ * @example
563
+ * send.gatewayTimeout("The database did not respond within the allowed time.");
564
+ * send.gatewayTimeout("Upstream timeout.", { service: "payments-api", timeoutMs: 5000 });
565
+ */
566
+ this.gatewayTimeout = (message, data) => {
567
+ this.dispatch("GATEWAY_TIMEOUT", "Gateway Timeout", false, message, data);
133
568
  };
134
569
  this.res = res;
135
570
  this.configs = { ...DEFAULT_CONFIGS, ...configs.statusCode };
@@ -143,22 +578,21 @@ class Send {
143
578
  * Resolves the status code, builds the full response body, and flushes it.
144
579
  *
145
580
  * @param statusKey - One of the {@link SupportedStatus} keys.
146
- * @param errorLabel - Human-readable short label for the error type.
147
- * @param message - Optional caller-supplied message; falls back to `errorLabel`.
581
+ * @param label - Human-readable short label for the status type.
582
+ * @param success - Whether this is a success response.
583
+ * @param message - Optional caller-supplied message; falls back to `label`.
148
584
  * @param data - Optional payload to attach to the response body.
149
585
  */
150
- dispatch(statusKey, errorLabel, message, data) {
586
+ dispatch(statusKey, label, success, message, data) {
151
587
  const statusCode = this.configs[statusKey];
152
588
  const body = {
153
- success: false,
154
- message: message ?? errorLabel,
155
- serverName: this.includeServerName
156
- ? this.serverName
157
- : undefined,
589
+ success,
590
+ message: message ?? label,
591
+ ...(this.includeServerName && { serverName: this.serverName }),
158
592
  ...(data !== undefined && { data }),
159
593
  details: {
160
- error: errorLabel,
161
- errorCode: buildErrorCode(statusKey),
594
+ error: label,
595
+ errorCode: buildStatusCode(statusKey, success),
162
596
  statusCode,
163
597
  },
164
598
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Send.js","sources":["../../../../src/utils/Send.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAsFA;AACA;AACA;AAEA;;;;;;;;;AASG;AACH,SAAS,cAAc,CAAC,MAAuB,EAAA;;IAE7C,OAAO,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE;AACjE;AAEA;AACA;AACA;AAEA,MAAM,eAAe,GAAe;AAClC,IAAA,WAAW,EAAE,GAAG;AAChB,IAAA,SAAS,EAAE,GAAG;AACd,IAAA,gBAAgB,EAAE,GAAG;AACrB,IAAA,mBAAmB,EAAE,GAAG;CACzB;AAED;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;MACU,IAAI,CAAA;AAMf;;;;;;AAMG;IACH,WAAA,CACE,GAAmB,EACnB,OAAA,GAGK;AACH,QAAA,iBAAiB,EAAE,IAAI;AACvB,QAAA,UAAU,EAAE,EAAE;AACf,KAAA,EAAA;;;;AAiDH;;;;;;;;;;;;AAYG;AACI,QAAA,IAAA,CAAA,UAAU,GAAiB,CAAC,OAAO,EAAE,IAAI,KAAI;YAClD,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAC5D,QAAA,CAAC;AAED;;;;;;;;;;;AAWG;AACI,QAAA,IAAA,CAAA,QAAQ,GAAiB,CAAC,OAAO,EAAE,IAAI,KAAI;YAChD,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AACxD,QAAA,CAAC;AAED;;;;;;;;;;;;AAYG;AACI,QAAA,IAAA,CAAA,cAAc,GAAiB,CAAC,OAAO,EAAE,IAAI,KAAI;YACtD,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,EAAE,IAAI,CAAC;AACvE,QAAA,CAAC;AAED;;;;;;;;;;;AAWG;AACI,QAAA,IAAA,CAAA,aAAa,GAAiB,CAAC,OAAO,EAAE,IAAI,KAAI;YACrD,IAAI,CAAC,QAAQ,CACX,qBAAqB,EACrB,uBAAuB,EACvB,OAAO,EACP,IAAI,CACL;AACH,QAAA,CAAC;AApHC,QAAA,IAAI,CAAC,GAAG,GAAG,GAAG;AACd,QAAA,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE;QAC5D,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ;AACvC,QAAA,IAAI,CAAC,iBAAiB,GAAG,OAAO,EAAE,iBAAkB;IACtD;;;;AAMA;;;;;;;AAOG;AACK,IAAA,QAAQ,CACd,SAA0B,EAC1B,UAAkB,EAClB,OAAgB,EAChB,IAAc,EAAA;QAEd,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;AAE1C,QAAA,MAAM,IAAI,GAAiB;AACzB,YAAA,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,OAAO,IAAI,UAAU;YAC9B,UAAU,EAAE,IAAI,CAAC;kBACb,IAAI,CAAC;AACP,kBAAG,SAA4B;YACjC,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC;AACnC,YAAA,OAAO,EAAE;AACP,gBAAA,KAAK,EAAE,UAAU;AACjB,gBAAA,SAAS,EAAE,cAAc,CAAC,SAAS,CAAC;gBACpC,UAAU;AACX,aAAA;SACF;AAED,QAAA,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IACxC;AA4ED;;;;"}
1
+ {"version":3,"file":"Send.js","sources":["../../../../src/utils/Send.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}