@xrystal/dto 26.6.27-v12

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 (87) hide show
  1. package/README.md +724 -0
  2. package/dist/adapters/elysia.cjs +820 -0
  3. package/dist/adapters/elysia.d.ts +138 -0
  4. package/dist/adapters/elysia.js +816 -0
  5. package/dist/adapters/express.cjs +789 -0
  6. package/dist/adapters/express.d.ts +49 -0
  7. package/dist/adapters/express.js +785 -0
  8. package/dist/adapters/index.d.ts +7 -0
  9. package/dist/adapters/node.cjs +790 -0
  10. package/dist/adapters/node.d.ts +27 -0
  11. package/dist/adapters/node.js +786 -0
  12. package/dist/adapters/shared.d.ts +11 -0
  13. package/dist/adapters/socketio.cjs +767 -0
  14. package/dist/adapters/socketio.d.ts +31 -0
  15. package/dist/adapters/socketio.js +763 -0
  16. package/dist/adapters/websocket.cjs +759 -0
  17. package/dist/adapters/websocket.d.ts +31 -0
  18. package/dist/adapters/websocket.js +754 -0
  19. package/dist/core/assemble-log.d.ts +1 -0
  20. package/dist/core/assemble-queue.d.ts +1 -0
  21. package/dist/core/assemble.d.ts +9 -0
  22. package/dist/core/builder.d.ts +49 -0
  23. package/dist/core/config.d.ts +10 -0
  24. package/dist/core/context.d.ts +5 -0
  25. package/dist/core/hooks.d.ts +8 -0
  26. package/dist/core/index.cjs +1002 -0
  27. package/dist/core/index.d.ts +14 -0
  28. package/dist/core/index.js +986 -0
  29. package/dist/core/log-dto.d.ts +1 -0
  30. package/dist/core/metadata.d.ts +6 -0
  31. package/dist/core/plugins.d.ts +10 -0
  32. package/dist/core/presets.d.ts +32 -0
  33. package/dist/core/queue-dto.d.ts +1 -0
  34. package/dist/core/response-dto.d.ts +1 -0
  35. package/dist/core/schema-utils.d.ts +1 -0
  36. package/dist/dto/index.cjs +909 -0
  37. package/dist/dto/index.d.ts +6 -0
  38. package/dist/dto/index.js +898 -0
  39. package/dist/dto/log/assemble.d.ts +3 -0
  40. package/dist/dto/log/builder.d.ts +41 -0
  41. package/dist/dto/log/index.cjs +152 -0
  42. package/dist/dto/log/index.d.ts +3 -0
  43. package/dist/dto/log/index.js +149 -0
  44. package/dist/dto/log/types.d.ts +26 -0
  45. package/dist/dto/queue/assemble.d.ts +2 -0
  46. package/dist/dto/queue/builder.d.ts +35 -0
  47. package/dist/dto/queue/index.cjs +154 -0
  48. package/dist/dto/queue/index.d.ts +3 -0
  49. package/dist/dto/queue/index.js +151 -0
  50. package/dist/dto/queue/types.d.ts +34 -0
  51. package/dist/dto/response/assemble.d.ts +1 -0
  52. package/dist/dto/response/dto.d.ts +39 -0
  53. package/dist/dto/response/index.cjs +179 -0
  54. package/dist/dto/response/index.d.ts +2 -0
  55. package/dist/dto/response/index.js +176 -0
  56. package/dist/dto/runtime/dto.cjs +1318 -0
  57. package/dist/dto/runtime/dto.d.ts +64 -0
  58. package/dist/dto/runtime/dto.js +1315 -0
  59. package/dist/dto/shared/base-dto.d.ts +12 -0
  60. package/dist/dto/shared/schema-utils.d.ts +1 -0
  61. package/dist/enums/node-env.d.ts +5 -0
  62. package/dist/errors/codes.d.ts +15 -0
  63. package/dist/errors/error.d.ts +32 -0
  64. package/dist/errors/index.d.ts +2 -0
  65. package/dist/index.cjs +1482 -0
  66. package/dist/index.d.ts +22 -0
  67. package/dist/index.js +1433 -0
  68. package/dist/types/builder.d.ts +15 -0
  69. package/dist/types/codes.d.ts +7 -0
  70. package/dist/types/context.d.ts +16 -0
  71. package/dist/types/hooks.d.ts +7 -0
  72. package/dist/types/index.d.ts +10 -0
  73. package/dist/types/log.d.ts +1 -0
  74. package/dist/types/metadata.d.ts +7 -0
  75. package/dist/types/options.d.ts +24 -0
  76. package/dist/types/plugin.d.ts +35 -0
  77. package/dist/types/queue.d.ts +1 -0
  78. package/dist/types/response.d.ts +43 -0
  79. package/dist/utils/constants/http.d.ts +2 -0
  80. package/dist/utils/constants/index.d.ts +3 -0
  81. package/dist/utils/constants/security-headers.d.ts +1 -0
  82. package/dist/utils/constants/status-codes.d.ts +35 -0
  83. package/dist/utils/helpers/index.d.ts +2 -0
  84. package/dist/utils/helpers/request-id.d.ts +3 -0
  85. package/dist/utils/helpers/uuid.d.ts +2 -0
  86. package/dist/utils/index.d.ts +2 -0
  87. package/package.json +130 -0
@@ -0,0 +1,767 @@
1
+ 'use strict';
2
+
3
+ // src/utils/helpers/uuid.ts
4
+ function generateUUID() {
5
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
6
+ return crypto.randomUUID();
7
+ }
8
+ const bytes = new Uint8Array(16);
9
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
10
+ crypto.getRandomValues(bytes);
11
+ } else {
12
+ for (let i = 0; i < bytes.length; i++) {
13
+ bytes[i] = Math.floor(Math.random() * 256);
14
+ }
15
+ }
16
+ bytes[6] = bytes[6] & 15 | 64;
17
+ bytes[8] = bytes[8] & 63 | 128;
18
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
19
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
20
+ }
21
+ function isValidUUID(id) {
22
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
23
+ }
24
+
25
+ // src/utils/helpers/request-id.ts
26
+ var DEFAULT_REQUEST_ID_HEADERS = [
27
+ "x-request-id",
28
+ "x-correlation-id",
29
+ "traceparent"
30
+ ];
31
+ function readHeader(req, name) {
32
+ const fromGet = req.get?.(name);
33
+ if (fromGet) return fromGet;
34
+ const headers = req.headers;
35
+ if (!headers) return void 0;
36
+ const direct = headers[name] ?? headers[name.toLowerCase()];
37
+ if (direct === void 0) return void 0;
38
+ return Array.isArray(direct) ? direct[0] : direct;
39
+ }
40
+ function traceIdFromTraceparent(traceparent) {
41
+ const parts = traceparent.trim().split("-");
42
+ if (parts.length < 2) return void 0;
43
+ const traceId = parts[1];
44
+ if (!traceId || !/^[0-9a-f]{32}$/i.test(traceId)) return void 0;
45
+ return `${traceId.slice(0, 8)}-${traceId.slice(8, 12)}-${traceId.slice(12, 16)}-${traceId.slice(16, 20)}-${traceId.slice(20)}`;
46
+ }
47
+ function resolveRequestId(req, headerNames = DEFAULT_REQUEST_ID_HEADERS) {
48
+ for (const name of headerNames) {
49
+ const raw = readHeader(req, name);
50
+ if (!raw?.trim()) continue;
51
+ if (name === "traceparent") {
52
+ const traceId = traceIdFromTraceparent(raw);
53
+ if (traceId) return traceId;
54
+ continue;
55
+ }
56
+ const id = raw.trim();
57
+ if (isValidUUID(id)) return id;
58
+ return id;
59
+ }
60
+ return generateUUID();
61
+ }
62
+
63
+ // src/core/context.ts
64
+ var ContextFactory = class {
65
+ static create(req, options = {}) {
66
+ return {
67
+ requestId: resolveRequestId(req, options.requestIdHeaders),
68
+ startTime: Date.now()
69
+ };
70
+ }
71
+ static fromId(requestId) {
72
+ return {
73
+ requestId,
74
+ startTime: Date.now()
75
+ };
76
+ }
77
+ };
78
+
79
+ // src/utils/constants/status-codes.ts
80
+ var StatusCodes = {
81
+ SUCCESSFUL: {
82
+ OK: 200,
83
+ CREATED: 201,
84
+ ACCEPTED: 202,
85
+ NO_CONTENT: 204
86
+ },
87
+ CLIENT_ERROR: {
88
+ BAD_REQUEST: 400,
89
+ UNAUTHORIZED: 401,
90
+ FORBIDDEN: 403,
91
+ NOT_FOUND: 404,
92
+ CONFLICT: 409,
93
+ UNPROCESSABLE_ENTITY: 422,
94
+ TOO_MANY_REQUESTS: 429
95
+ },
96
+ SERVER_ERROR: {
97
+ INTERNAL_SERVER_ERROR: 500,
98
+ SERVICE_UNAVAILABLE: 503,
99
+ GATEWAY_TIMEOUT: 504
100
+ }
101
+ };
102
+
103
+ // src/errors/codes.ts
104
+ var DefaultCodes = {
105
+ SUCCESS: 0,
106
+ CLIENT: 1,
107
+ SERVER: 2,
108
+ VALIDATION: 3
109
+ };
110
+ function createCodeRegistry(overrides = {}) {
111
+ return { ...DefaultCodes, ...overrides };
112
+ }
113
+ function isSuccessCode(code, codes) {
114
+ return code === codes.SUCCESS;
115
+ }
116
+ function resolveCodeFromHttpStatus(statusCode, codes) {
117
+ if (statusCode >= 200 && statusCode < 300) return codes.SUCCESS;
118
+ if (statusCode === 422) return codes.VALIDATION;
119
+ if (statusCode >= 400 && statusCode < 500) return codes.CLIENT;
120
+ if (statusCode >= 500) return codes.SERVER;
121
+ if (statusCode >= 300 && statusCode < 400) return codes.SUCCESS;
122
+ return codes.CLIENT;
123
+ }
124
+ function defaultMessageForCode(code, codes) {
125
+ if (code === codes.SUCCESS) return "Operation successful";
126
+ if (code === codes.CLIENT) return "Client error";
127
+ if (code === codes.SERVER) return "Internal server error";
128
+ if (code === codes.VALIDATION) return "Validation failed";
129
+ return "Operation failed";
130
+ }
131
+ function resolveStatusFromCode(code, codes) {
132
+ return isSuccessCode(code, codes);
133
+ }
134
+
135
+ // src/core/config.ts
136
+ function resolveBuilderConfig(options = {}) {
137
+ return {
138
+ verbose: options.verbose === true,
139
+ includeStack: options.includeStack,
140
+ withDefaultBody: options.withDefaultBody !== false,
141
+ codes: createCodeRegistry(options.codes),
142
+ hooks: options.hooks,
143
+ plugins: options.plugins ?? []
144
+ };
145
+ }
146
+
147
+ // src/dto/shared/base-dto.ts
148
+ var BaseDTO = class {
149
+ };
150
+
151
+ // src/core/assemble.ts
152
+ function assembleResponseBody(input) {
153
+ const ordered = {
154
+ status: input.status,
155
+ message: input.message
156
+ };
157
+ if (input.payload !== void 0 && Object.keys(input.payload).length > 0) {
158
+ ordered.payload = input.payload;
159
+ }
160
+ ordered.code = input.code;
161
+ return ordered;
162
+ }
163
+
164
+ // src/dto/response/dto.ts
165
+ var ResponseDTO = class _ResponseDTO extends BaseDTO {
166
+ _status;
167
+ _message;
168
+ _code;
169
+ _payload = {};
170
+ static status(value) {
171
+ return new _ResponseDTO().status(value);
172
+ }
173
+ static message(value) {
174
+ return new _ResponseDTO().message(value);
175
+ }
176
+ static code(value) {
177
+ return new _ResponseDTO().code(value);
178
+ }
179
+ static data(data) {
180
+ return new _ResponseDTO().data(data);
181
+ }
182
+ static payload(partial) {
183
+ return new _ResponseDTO().payload(partial);
184
+ }
185
+ static schema(input = {}, codes = DefaultCodes) {
186
+ return new _ResponseDTO().schema(input, codes);
187
+ }
188
+ status(value) {
189
+ this._status = value;
190
+ return this;
191
+ }
192
+ message(msg) {
193
+ this._message = msg;
194
+ return this;
195
+ }
196
+ code(code) {
197
+ this._code = code;
198
+ return this;
199
+ }
200
+ data(data) {
201
+ if (data === void 0) {
202
+ delete this._payload.data;
203
+ } else {
204
+ this._payload.data = data;
205
+ }
206
+ return this;
207
+ }
208
+ payload(partial) {
209
+ this._payload = { ...this._payload, ...partial };
210
+ return this;
211
+ }
212
+ setMeta(meta) {
213
+ this._payload.meta = { ...this._payload.meta ?? {}, ...meta };
214
+ return this;
215
+ }
216
+ paginate(total, page, limit) {
217
+ if (limit <= 0) {
218
+ throw new Error("ResponseDTO.paginate: limit must be greater than 0");
219
+ }
220
+ this._payload.pagination = {
221
+ total,
222
+ page,
223
+ limit,
224
+ totalPages: Math.ceil(total / limit),
225
+ hasNext: page * limit < total
226
+ };
227
+ return this;
228
+ }
229
+ schema(input = {}, codes = DefaultCodes) {
230
+ const { status, message, code, payload } = input;
231
+ if (code !== void 0) {
232
+ this.code(code);
233
+ }
234
+ if (status !== void 0) {
235
+ this.status(status);
236
+ } else if (code !== void 0) {
237
+ this.status(resolveStatusFromCode(code, codes));
238
+ }
239
+ if (message !== void 0) {
240
+ this.message(message);
241
+ }
242
+ if (payload !== void 0) {
243
+ this._payload = { ...payload };
244
+ }
245
+ return this;
246
+ }
247
+ getCode() {
248
+ return this._code;
249
+ }
250
+ getMessage() {
251
+ return this._message;
252
+ }
253
+ setCodeFromHttpStatus(httpStatusCode, codes) {
254
+ if (this._code === void 0) {
255
+ this._code = resolveCodeFromHttpStatus(httpStatusCode, codes);
256
+ }
257
+ return this;
258
+ }
259
+ transformData(fn) {
260
+ const next = new _ResponseDTO();
261
+ next._status = this._status;
262
+ next._message = this._message;
263
+ next._code = this._code;
264
+ next._payload = { ...this._payload };
265
+ if (this._payload.data !== void 0) {
266
+ next._payload.data = fn(this._payload.data);
267
+ }
268
+ return next;
269
+ }
270
+ build(options = {}) {
271
+ const codes = options.codes ?? DefaultCodes;
272
+ const code = this._code ?? (options.httpStatusCode !== void 0 ? resolveCodeFromHttpStatus(options.httpStatusCode, codes) : codes.SUCCESS);
273
+ const status = this._status ?? isSuccessCode(code, codes);
274
+ const message = this._message ?? defaultMessageForCode(code, codes);
275
+ if (options.withDefaultBody === false) {
276
+ return assembleResponseBody({ status, message, code });
277
+ }
278
+ const payload = this.buildPayload();
279
+ return assembleResponseBody({
280
+ status,
281
+ message,
282
+ payload,
283
+ code
284
+ });
285
+ }
286
+ buildPayload() {
287
+ const entries = Object.entries(this._payload).filter(([, value]) => value !== void 0);
288
+ if (entries.length === 0) return void 0;
289
+ return Object.fromEntries(entries);
290
+ }
291
+ };
292
+
293
+ // src/core/metadata.ts
294
+ var MetadataFactory = class {
295
+ static create(options = {}, context) {
296
+ return {
297
+ requestId: context?.requestId ?? generateUUID(),
298
+ serverTime: (/* @__PURE__ */ new Date()).toISOString(),
299
+ statusCode: 200,
300
+ ...options
301
+ };
302
+ }
303
+ };
304
+
305
+ // src/core/plugins.ts
306
+ function sortPlugins(plugins) {
307
+ return [...plugins].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
308
+ }
309
+ var PluginRegistry = class {
310
+ plugins;
311
+ constructor(plugins = []) {
312
+ this.plugins = sortPlugins(plugins);
313
+ }
314
+ runBeforeBuild(ctx) {
315
+ for (const plugin of this.plugins) {
316
+ plugin.beforeBuild?.(ctx);
317
+ }
318
+ }
319
+ runAfterBuild(result, ctx) {
320
+ let current = result;
321
+ for (const plugin of this.plugins) {
322
+ const next = plugin.afterBuild?.(current, ctx);
323
+ if (next) current = next;
324
+ }
325
+ return current;
326
+ }
327
+ runBeforeDispatch(result, ctx) {
328
+ let current = result;
329
+ for (const plugin of this.plugins) {
330
+ const next = plugin.beforeDispatch?.(current, ctx);
331
+ if (next) current = next;
332
+ }
333
+ return current;
334
+ }
335
+ runAfterDispatch(result, ctx) {
336
+ for (const plugin of this.plugins) {
337
+ plugin.afterDispatch?.(result, ctx);
338
+ }
339
+ }
340
+ };
341
+
342
+ // src/core/presets.ts
343
+ var ResponsePresets = class {
344
+ builder;
345
+ codes;
346
+ constructor(builder, codes) {
347
+ this.builder = builder;
348
+ this.codes = codes;
349
+ }
350
+ applyExtras(extras) {
351
+ if (extras && Object.keys(extras).length > 0) {
352
+ this.builder.payload(extras);
353
+ }
354
+ }
355
+ dispatch() {
356
+ return this.builder.build();
357
+ }
358
+ resolveFailureArgs(dataOrMessage, messageOrExtras, extras) {
359
+ if (typeof dataOrMessage === "string") {
360
+ return {
361
+ message: dataOrMessage,
362
+ extras: typeof messageOrExtras === "string" ? extras : messageOrExtras
363
+ };
364
+ }
365
+ return {
366
+ data: dataOrMessage,
367
+ message: typeof messageOrExtras === "string" ? messageOrExtras : void 0,
368
+ extras: typeof messageOrExtras === "string" ? extras : messageOrExtras
369
+ };
370
+ }
371
+ failure(httpStatus, code, dataOrMessage, messageOrExtras, extras) {
372
+ const resolved = this.resolveFailureArgs(dataOrMessage, messageOrExtras, extras);
373
+ this.builder.httpStatus(httpStatus).code(code).status(false).message(resolved.message ?? defaultMessageForCode(code, this.codes)).data(resolved.data);
374
+ this.applyExtras(resolved.extras);
375
+ return this.dispatch();
376
+ }
377
+ ok(data, message, extras) {
378
+ this.builder.httpStatus(StatusCodes.SUCCESSFUL.OK).code(this.codes.SUCCESS).status(true).message(message ?? defaultMessageForCode(this.codes.SUCCESS, this.codes)).data(data);
379
+ this.applyExtras(extras);
380
+ return this.dispatch();
381
+ }
382
+ created(data, message, extras) {
383
+ this.builder.httpStatus(StatusCodes.SUCCESSFUL.CREATED).code(this.codes.SUCCESS).status(true).message(message ?? defaultMessageForCode(this.codes.SUCCESS, this.codes)).data(data);
384
+ this.applyExtras(extras);
385
+ return this.dispatch();
386
+ }
387
+ accepted(message, extras) {
388
+ this.builder.httpStatus(StatusCodes.SUCCESSFUL.ACCEPTED).code(this.codes.SUCCESS).status(true).message(message ?? defaultMessageForCode(this.codes.SUCCESS, this.codes));
389
+ this.applyExtras(extras);
390
+ return this.dispatch();
391
+ }
392
+ noContent(extras) {
393
+ this.builder.httpStatus(StatusCodes.SUCCESSFUL.NO_CONTENT).code(this.codes.SUCCESS).status(true).message("").data(void 0);
394
+ this.applyExtras(extras);
395
+ return this.dispatch();
396
+ }
397
+ /** Generic client failure — HTTP 400, CLIENT code */
398
+ fail(dataOrMessage, messageOrExtras, extras) {
399
+ return this.failure(StatusCodes.CLIENT_ERROR.BAD_REQUEST, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
400
+ }
401
+ /** Generic server failure — HTTP 500, SERVER code */
402
+ error(dataOrMessage, messageOrExtras, extras) {
403
+ return this.failure(
404
+ StatusCodes.SERVER_ERROR.INTERNAL_SERVER_ERROR,
405
+ this.codes.SERVER,
406
+ dataOrMessage,
407
+ messageOrExtras,
408
+ extras
409
+ );
410
+ }
411
+ badRequest(dataOrMessage, messageOrExtras, extras) {
412
+ return this.failure(StatusCodes.CLIENT_ERROR.BAD_REQUEST, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
413
+ }
414
+ unauthorized(dataOrMessage, messageOrExtras, extras) {
415
+ return this.failure(StatusCodes.CLIENT_ERROR.UNAUTHORIZED, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
416
+ }
417
+ forbidden(dataOrMessage, messageOrExtras, extras) {
418
+ return this.failure(StatusCodes.CLIENT_ERROR.FORBIDDEN, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
419
+ }
420
+ notFound(dataOrMessage, messageOrExtras, extras) {
421
+ return this.failure(StatusCodes.CLIENT_ERROR.NOT_FOUND, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
422
+ }
423
+ conflict(dataOrMessage, messageOrExtras, extras) {
424
+ return this.failure(StatusCodes.CLIENT_ERROR.CONFLICT, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
425
+ }
426
+ unprocessable(dataOrMessage, messageOrExtras, extras) {
427
+ return this.failure(
428
+ StatusCodes.CLIENT_ERROR.UNPROCESSABLE_ENTITY,
429
+ this.codes.VALIDATION,
430
+ dataOrMessage,
431
+ messageOrExtras,
432
+ extras
433
+ );
434
+ }
435
+ tooManyRequests(dataOrMessage, messageOrExtras, extras) {
436
+ return this.failure(StatusCodes.CLIENT_ERROR.TOO_MANY_REQUESTS, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
437
+ }
438
+ internalServerError(dataOrMessage, messageOrExtras, extras) {
439
+ return this.failure(
440
+ StatusCodes.SERVER_ERROR.INTERNAL_SERVER_ERROR,
441
+ this.codes.SERVER,
442
+ dataOrMessage,
443
+ messageOrExtras,
444
+ extras
445
+ );
446
+ }
447
+ serviceUnavailable(dataOrMessage, messageOrExtras, extras) {
448
+ return this.failure(
449
+ StatusCodes.SERVER_ERROR.SERVICE_UNAVAILABLE,
450
+ this.codes.SERVER,
451
+ dataOrMessage,
452
+ messageOrExtras,
453
+ extras
454
+ );
455
+ }
456
+ gatewayTimeout(dataOrMessage, messageOrExtras, extras) {
457
+ return this.failure(
458
+ StatusCodes.SERVER_ERROR.GATEWAY_TIMEOUT,
459
+ this.codes.SERVER,
460
+ dataOrMessage,
461
+ messageOrExtras,
462
+ extras
463
+ );
464
+ }
465
+ };
466
+
467
+ // src/errors/error.ts
468
+ var ResponseError = class extends Error {
469
+ code;
470
+ httpStatus;
471
+ payload;
472
+ constructor(options = {}) {
473
+ const codes = createCodeRegistry(options.codes);
474
+ const code = options.code ?? codes.SERVER;
475
+ const message = options.message ?? defaultMessageForCode(code, codes);
476
+ super(message, { cause: options.cause });
477
+ this.name = "ResponseError";
478
+ this.code = code;
479
+ this.httpStatus = options.httpStatus ?? codeToDefaultHttpStatus(code, codes);
480
+ if (options.payload !== void 0) {
481
+ this.payload = options.payload;
482
+ }
483
+ }
484
+ toJSON() {
485
+ return {
486
+ name: this.name,
487
+ message: this.message,
488
+ code: this.code,
489
+ httpStatus: this.httpStatus,
490
+ payload: this.payload
491
+ };
492
+ }
493
+ };
494
+ function isResponseError(value) {
495
+ return value instanceof ResponseError;
496
+ }
497
+ function codeToDefaultHttpStatus(code, codes) {
498
+ if (code === codes.SUCCESS) return 200;
499
+ if (code === codes.CLIENT) return 400;
500
+ if (code === codes.SERVER) return 500;
501
+ if (code === codes.VALIDATION) return 422;
502
+ return 500;
503
+ }
504
+
505
+ // src/core/builder.ts
506
+ var Builder = class {
507
+ dispatcher;
508
+ options;
509
+ context;
510
+ plugins;
511
+ body;
512
+ _statusCode = StatusCodes.SUCCESSFUL.OK;
513
+ _headers = {};
514
+ _cookies = [];
515
+ _presets;
516
+ constructor(dispatcher, options = {}, context) {
517
+ this.dispatcher = dispatcher;
518
+ this.options = resolveBuilderConfig(options);
519
+ this.context = context;
520
+ this.plugins = new PluginRegistry(this.options.plugins);
521
+ this.body = new ResponseDTO();
522
+ }
523
+ get dto() {
524
+ return this.body;
525
+ }
526
+ httpStatus(code) {
527
+ this._statusCode = code;
528
+ this.body.setCodeFromHttpStatus(code, this.options.codes);
529
+ return this;
530
+ }
531
+ code(code) {
532
+ this.body.code(code);
533
+ return this;
534
+ }
535
+ status(value) {
536
+ this.body.status(value);
537
+ return this;
538
+ }
539
+ message(msg) {
540
+ this.body.message(msg);
541
+ return this;
542
+ }
543
+ data(data) {
544
+ this.body.data(data);
545
+ return this;
546
+ }
547
+ payload(partial) {
548
+ this.body.payload(partial);
549
+ return this;
550
+ }
551
+ schema(input = {}) {
552
+ this.body.schema(input, this.options.codes);
553
+ return this;
554
+ }
555
+ setMeta(meta) {
556
+ this.body.setMeta(meta);
557
+ return this;
558
+ }
559
+ withMetadata(options = {}) {
560
+ const generated = MetadataFactory.create(
561
+ { statusCode: this._statusCode, ...options },
562
+ { requestId: this.context?.requestId }
563
+ );
564
+ return this.setMeta(generated);
565
+ }
566
+ paginate(total, page, limit) {
567
+ this.body.paginate(total, page, limit);
568
+ return this;
569
+ }
570
+ setHeaders(keyOrHeaders, value) {
571
+ if (typeof keyOrHeaders === "string") {
572
+ if (value !== void 0) {
573
+ this._headers[keyOrHeaders] = value;
574
+ }
575
+ } else {
576
+ this._headers = { ...this._headers, ...keyOrHeaders };
577
+ }
578
+ return this;
579
+ }
580
+ header(key, value) {
581
+ return this.setHeaders(key, value);
582
+ }
583
+ setCookies(nameOrCookies, valueOrOptions, options) {
584
+ if (typeof nameOrCookies === "string") {
585
+ if (typeof valueOrOptions === "string") {
586
+ this._cookies.push({ name: nameOrCookies, value: valueOrOptions, options });
587
+ }
588
+ } else {
589
+ const sharedOptions = typeof valueOrOptions === "object" ? valueOrOptions : void 0;
590
+ for (const [name, value] of Object.entries(nameOrCookies)) {
591
+ this._cookies.push({ name, value, options: sharedOptions });
592
+ }
593
+ }
594
+ return this;
595
+ }
596
+ fromError(error) {
597
+ if (isResponseError(error)) {
598
+ return this.httpStatus(error.httpStatus).code(error.code).message(error.message).payload(error.payload ? { ...error.payload } : {}).data(void 0);
599
+ }
600
+ return this.httpStatus(StatusCodes.SERVER_ERROR.INTERNAL_SERVER_ERROR).code(this.options.codes.SERVER).message(this.resolvePublicErrorMessage(error)).data(void 0);
601
+ }
602
+ async wrap(promise) {
603
+ try {
604
+ this.data(await promise);
605
+ return this;
606
+ } catch (error) {
607
+ this.fromError(error);
608
+ this.options.hooks?.emit("error", {
609
+ error,
610
+ message: this.body.getMessage(),
611
+ statusCode: this._statusCode,
612
+ code: this.body.getCode() ?? resolveCodeFromHttpStatus(this._statusCode, this.options.codes)
613
+ });
614
+ return this;
615
+ }
616
+ }
617
+ transform(fn) {
618
+ const next = this;
619
+ next.body = this.body.transformData(fn);
620
+ return next;
621
+ }
622
+ when(condition, fn) {
623
+ if (condition) fn(this);
624
+ return this;
625
+ }
626
+ get as() {
627
+ if (!this._presets) {
628
+ this._presets = new ResponsePresets(this, this.options.codes);
629
+ }
630
+ return this._presets;
631
+ }
632
+ build() {
633
+ const pluginCtx = this.createPluginContext();
634
+ this.options.hooks?.emit("before_build", { statusCode: this._statusCode });
635
+ this.plugins.runBeforeBuild(pluginCtx);
636
+ const body = this.body.build({
637
+ codes: this.options.codes,
638
+ withDefaultBody: this.options.withDefaultBody,
639
+ httpStatusCode: this._statusCode
640
+ });
641
+ let result = {
642
+ body,
643
+ statusCode: this._statusCode,
644
+ headers: { ...this._headers },
645
+ cookies: [...this._cookies]
646
+ };
647
+ result = this.plugins.runAfterBuild(result, pluginCtx);
648
+ this.emitHook("after_build", result);
649
+ if (this.dispatcher) {
650
+ result = this.plugins.runBeforeDispatch(result, pluginCtx);
651
+ this.emitHook("before_dispatch", result);
652
+ const dispatched = this.dispatcher.dispatch(result);
653
+ this.plugins.runAfterDispatch(result, pluginCtx);
654
+ this.emitHook("after_dispatch", result);
655
+ return dispatched ?? result;
656
+ }
657
+ return result;
658
+ }
659
+ resolvePublicErrorMessage(error) {
660
+ if (!this.options.verbose && !isResponseError(error)) {
661
+ return defaultMessageForCode(this.options.codes.SERVER, this.options.codes);
662
+ }
663
+ if (error instanceof Error) {
664
+ if (this.options.includeStack && error.stack) return error.stack;
665
+ return error.message || defaultMessageForCode(this.options.codes.SERVER, this.options.codes);
666
+ }
667
+ if (typeof error === "string") return error;
668
+ return defaultMessageForCode(this.options.codes.SERVER, this.options.codes);
669
+ }
670
+ createPluginContext() {
671
+ return {
672
+ builder: this,
673
+ context: this.context,
674
+ options: this.options,
675
+ codes: this.options.codes
676
+ };
677
+ }
678
+ emitHook(event, result) {
679
+ const hooks = this.options.hooks;
680
+ if (!hooks?.hasListeners(event)) return;
681
+ hooks.emit(event, structuredClone(result));
682
+ }
683
+ };
684
+ function createBuilderProxy(dispatcher, options = {}, context) {
685
+ const instance = new Builder(dispatcher, options, context);
686
+ return new Proxy(instance, {
687
+ get(target, prop, receiver) {
688
+ const value = Reflect.get(target, prop, receiver);
689
+ if (typeof value === "function") {
690
+ return value.bind(target);
691
+ }
692
+ return value;
693
+ }
694
+ });
695
+ }
696
+
697
+ // src/adapters/shared.ts
698
+ function createBuilderRuntime(dispatcher, options, context) {
699
+ const builderOptions = {
700
+ verbose: options.verbose,
701
+ includeStack: options.includeStack,
702
+ withDefaultBody: options.withDefaultBody,
703
+ codes: options.codes,
704
+ hooks: options.hooks,
705
+ plugins: options.plugins
706
+ };
707
+ return {
708
+ context,
709
+ codes: resolveBuilderConfig(builderOptions).codes,
710
+ builder: createBuilderProxy(dispatcher, builderOptions, context)
711
+ };
712
+ }
713
+
714
+ // src/adapters/socketio.ts
715
+ var SocketIoDispatcher = class {
716
+ socket;
717
+ event;
718
+ constructor(socket, event = "response") {
719
+ this.socket = socket;
720
+ this.event = event;
721
+ }
722
+ dispatch(result) {
723
+ this.socket.emit(this.event, result.body);
724
+ return result;
725
+ }
726
+ };
727
+ var SocketIoAdapter = class {
728
+ options;
729
+ constructor(options = {}) {
730
+ this.options = {
731
+ event: "response",
732
+ ...options
733
+ };
734
+ }
735
+ attach(socket) {
736
+ const context = ContextFactory.create({
737
+ headers: socket.handshake?.headers
738
+ }, {
739
+ requestIdHeaders: this.options.requestIdHeaders
740
+ });
741
+ const runtime = createBuilderRuntime(
742
+ new SocketIoDispatcher(socket, this.options.event),
743
+ this.options,
744
+ context
745
+ );
746
+ socket.ctx = runtime.context;
747
+ socket.builder = runtime.builder;
748
+ return runtime;
749
+ }
750
+ handler() {
751
+ return (socket, next) => {
752
+ try {
753
+ this.attach(socket);
754
+ next?.();
755
+ } catch (error) {
756
+ next?.(error instanceof Error ? error : new Error(String(error)));
757
+ }
758
+ };
759
+ }
760
+ };
761
+ function socketIoMiddleware(options = {}) {
762
+ return new SocketIoAdapter(options).handler();
763
+ }
764
+
765
+ exports.SocketIoAdapter = SocketIoAdapter;
766
+ exports.SocketIoDispatcher = SocketIoDispatcher;
767
+ exports.socketIoMiddleware = socketIoMiddleware;