@xrystal/dto 26.6.27-v13 → 26.6.27-v15

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 (76) hide show
  1. package/README.md +273 -38
  2. package/dist/adapters/elysia.cjs +244 -236
  3. package/dist/adapters/elysia.js +244 -237
  4. package/dist/adapters/express.cjs +241 -237
  5. package/dist/adapters/express.js +241 -237
  6. package/dist/adapters/fetch.cjs +826 -0
  7. package/dist/adapters/fetch.js +821 -0
  8. package/dist/adapters/node.cjs +261 -238
  9. package/dist/adapters/node.js +261 -238
  10. package/dist/adapters/socketio.cjs +208 -209
  11. package/dist/adapters/socketio.js +208 -209
  12. package/dist/adapters/websocket.cjs +211 -207
  13. package/dist/adapters/websocket.js +211 -207
  14. package/dist/dto/adapters/bind.d.ts +40 -0
  15. package/dist/dto/adapters/elysia.d.ts +1 -0
  16. package/dist/dto/adapters/express.d.ts +1 -0
  17. package/dist/dto/adapters/fetch.d.ts +1 -0
  18. package/dist/dto/adapters/http.d.ts +150 -0
  19. package/dist/dto/adapters/node.d.ts +1 -0
  20. package/dist/dto/adapters/realtime.d.ts +39 -0
  21. package/dist/dto/adapters/socketio.d.ts +1 -0
  22. package/dist/dto/adapters/websocket.d.ts +1 -0
  23. package/dist/dto/factories.d.ts +11 -0
  24. package/dist/dto/index.cjs +554 -510
  25. package/dist/dto/index.d.ts +4 -5
  26. package/dist/dto/index.js +539 -511
  27. package/dist/dto/log/index.cjs +20 -39
  28. package/dist/dto/log/index.js +20 -39
  29. package/dist/dto/queue/index.cjs +20 -33
  30. package/dist/dto/queue/index.js +20 -33
  31. package/dist/dto/response/index.cjs +237 -83
  32. package/dist/dto/response/index.js +223 -84
  33. package/dist/dto/runtime/index.cjs +526 -497
  34. package/dist/dto/runtime/index.d.ts +71 -4
  35. package/dist/dto/runtime/index.js +526 -498
  36. package/dist/dto/{response → send}/builder.d.ts +7 -6
  37. package/dist/dto/send/index.d.ts +7 -0
  38. package/dist/dto/{response → send}/presets.d.ts +23 -19
  39. package/dist/dto/send/transport.d.ts +50 -0
  40. package/dist/dto/{log/builder.d.ts → shapes/log.d.ts} +28 -12
  41. package/dist/dto/{queue/builder.d.ts → shapes/queue.d.ts} +36 -9
  42. package/dist/dto/{response/dto.d.ts → shapes/response.d.ts} +8 -6
  43. package/dist/dto/shared.d.ts +15 -0
  44. package/dist/index.cjs +488 -445
  45. package/dist/index.d.ts +13 -13
  46. package/dist/index.js +477 -446
  47. package/dist/types/builder.d.ts +2 -1
  48. package/dist/types/index.d.ts +1 -1
  49. package/dist/types/log.d.ts +1 -1
  50. package/dist/types/plugin.d.ts +1 -1
  51. package/dist/types/queue.d.ts +1 -1
  52. package/package.json +6 -1
  53. package/dist/adapters/elysia.d.ts +0 -138
  54. package/dist/adapters/express.d.ts +0 -49
  55. package/dist/adapters/index.d.ts +0 -1
  56. package/dist/adapters/node.d.ts +0 -27
  57. package/dist/adapters/shared.d.ts +0 -11
  58. package/dist/adapters/socketio.d.ts +0 -31
  59. package/dist/adapters/websocket.d.ts +0 -31
  60. package/dist/dto/log/assemble.d.ts +0 -3
  61. package/dist/dto/log/index.d.ts +0 -3
  62. package/dist/dto/log/types.d.ts +0 -26
  63. package/dist/dto/queue/assemble.d.ts +0 -2
  64. package/dist/dto/queue/index.d.ts +0 -3
  65. package/dist/dto/queue/types.d.ts +0 -34
  66. package/dist/dto/response/assemble.d.ts +0 -9
  67. package/dist/dto/response/config.d.ts +0 -10
  68. package/dist/dto/response/index.d.ts +0 -7
  69. package/dist/dto/runtime/context.d.ts +0 -5
  70. package/dist/dto/runtime/dto.d.ts +0 -64
  71. package/dist/dto/runtime/hooks.d.ts +0 -8
  72. package/dist/dto/runtime/metadata.d.ts +0 -6
  73. package/dist/dto/shared/base-dto.d.ts +0 -12
  74. package/dist/dto/shared/schema-utils.d.ts +0 -1
  75. /package/dist/dto/{response → send}/plugins.d.ts +0 -0
  76. /package/dist/{enums/node-env.d.ts → utils/constants/enums.d.ts} +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  var elysia = require('elysia');
4
4
 
5
- // src/adapters/elysia.ts
5
+ // src/dto/adapters/http.ts
6
6
 
7
7
  // src/utils/constants/security-headers.ts
8
8
  var DEFAULT_SECURITY_HEADERS = {
@@ -16,88 +16,6 @@ var DEFAULT_SECURITY_HEADERS = {
16
16
  "X-DNS-Prefetch-Control": "off"
17
17
  };
18
18
 
19
- // src/utils/constants/http.ts
20
- var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([204, 205, 304]);
21
- function shouldSendResponseBody(statusCode) {
22
- return !NO_BODY_STATUS_CODES.has(statusCode);
23
- }
24
-
25
- // src/utils/helpers/uuid.ts
26
- function generateUUID() {
27
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
28
- return crypto.randomUUID();
29
- }
30
- const bytes = new Uint8Array(16);
31
- if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
32
- crypto.getRandomValues(bytes);
33
- } else {
34
- for (let i = 0; i < bytes.length; i++) {
35
- bytes[i] = Math.floor(Math.random() * 256);
36
- }
37
- }
38
- bytes[6] = bytes[6] & 15 | 64;
39
- bytes[8] = bytes[8] & 63 | 128;
40
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
41
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
42
- }
43
- function isValidUUID(id) {
44
- return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
45
- }
46
-
47
- // src/utils/helpers/request-id.ts
48
- var DEFAULT_REQUEST_ID_HEADERS = [
49
- "x-request-id",
50
- "x-correlation-id",
51
- "traceparent"
52
- ];
53
- function readHeader(req, name) {
54
- const fromGet = req.get?.(name);
55
- if (fromGet) return fromGet;
56
- const headers = req.headers;
57
- if (!headers) return void 0;
58
- const direct = headers[name] ?? headers[name.toLowerCase()];
59
- if (direct === void 0) return void 0;
60
- return Array.isArray(direct) ? direct[0] : direct;
61
- }
62
- function traceIdFromTraceparent(traceparent) {
63
- const parts = traceparent.trim().split("-");
64
- if (parts.length < 2) return void 0;
65
- const traceId = parts[1];
66
- if (!traceId || !/^[0-9a-f]{32}$/i.test(traceId)) return void 0;
67
- return `${traceId.slice(0, 8)}-${traceId.slice(8, 12)}-${traceId.slice(12, 16)}-${traceId.slice(16, 20)}-${traceId.slice(20)}`;
68
- }
69
- function resolveRequestId(req, headerNames = DEFAULT_REQUEST_ID_HEADERS) {
70
- for (const name of headerNames) {
71
- const raw = readHeader(req, name);
72
- if (!raw?.trim()) continue;
73
- if (name === "traceparent") {
74
- const traceId = traceIdFromTraceparent(raw);
75
- if (traceId) return traceId;
76
- continue;
77
- }
78
- const id = raw.trim();
79
- if (isValidUUID(id)) return id;
80
- return id;
81
- }
82
- return generateUUID();
83
- }
84
-
85
- // src/dto/runtime/context.ts
86
- var ContextFactory = class {
87
- static create(req, options = {}) {
88
- return {
89
- requestId: resolveRequestId(req, options.requestIdHeaders),
90
- startTime: Date.now()
91
- };
92
- }
93
- static fromId(requestId) {
94
- return {
95
- requestId,
96
- startTime: Date.now()
97
- };
98
- }
99
- };
100
-
101
19
  // src/utils/constants/status-codes.ts
102
20
  var StatusCodes = {
103
21
  SUCCESSFUL: {
@@ -154,7 +72,9 @@ function resolveStatusFromCode(code, codes) {
154
72
  return isSuccessCode(code, codes);
155
73
  }
156
74
 
157
- // src/dto/response/config.ts
75
+ // src/dto/shared.ts
76
+ var BaseDTO = class {
77
+ };
158
78
  function resolveBuilderConfig(options = {}) {
159
79
  return {
160
80
  verbose: options.verbose === true,
@@ -166,61 +86,29 @@ function resolveBuilderConfig(options = {}) {
166
86
  };
167
87
  }
168
88
 
169
- // src/dto/runtime/metadata.ts
170
- var MetadataFactory = class {
171
- static create(options = {}, context) {
172
- return {
173
- requestId: context?.requestId ?? generateUUID(),
174
- serverTime: (/* @__PURE__ */ new Date()).toISOString(),
175
- statusCode: 200,
176
- ...options
177
- };
89
+ // src/utils/helpers/uuid.ts
90
+ function generateUUID() {
91
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
92
+ return crypto.randomUUID();
178
93
  }
179
- };
180
-
181
- // src/errors/error.ts
182
- var ResponseError = class extends Error {
183
- code;
184
- httpStatus;
185
- payload;
186
- constructor(options = {}) {
187
- const codes = createCodeRegistry(options.codes);
188
- const code = options.code ?? codes.SERVER;
189
- const message = options.message ?? defaultMessageForCode(code, codes);
190
- super(message, { cause: options.cause });
191
- this.name = "ResponseError";
192
- this.code = code;
193
- this.httpStatus = options.httpStatus ?? codeToDefaultHttpStatus(code, codes);
194
- if (options.payload !== void 0) {
195
- this.payload = options.payload;
94
+ const bytes = new Uint8Array(16);
95
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
96
+ crypto.getRandomValues(bytes);
97
+ } else {
98
+ for (let i = 0; i < bytes.length; i++) {
99
+ bytes[i] = Math.floor(Math.random() * 256);
196
100
  }
197
101
  }
198
- toJSON() {
199
- return {
200
- name: this.name,
201
- message: this.message,
202
- code: this.code,
203
- httpStatus: this.httpStatus,
204
- payload: this.payload
205
- };
206
- }
207
- };
208
- function isResponseError(value) {
209
- return value instanceof ResponseError;
102
+ bytes[6] = bytes[6] & 15 | 64;
103
+ bytes[8] = bytes[8] & 63 | 128;
104
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
105
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
210
106
  }
211
- function codeToDefaultHttpStatus(code, codes) {
212
- if (code === codes.SUCCESS) return 200;
213
- if (code === codes.CLIENT) return 400;
214
- if (code === codes.SERVER) return 500;
215
- if (code === codes.VALIDATION) return 422;
216
- return 500;
107
+ function isValidUUID(id) {
108
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
217
109
  }
218
110
 
219
- // src/dto/shared/base-dto.ts
220
- var BaseDTO = class {
221
- };
222
-
223
- // src/dto/response/assemble.ts
111
+ // src/dto/shapes/response.ts
224
112
  function assembleResponseBody(input) {
225
113
  const ordered = {
226
114
  status: input.status,
@@ -232,8 +120,6 @@ function assembleResponseBody(input) {
232
120
  ordered.code = input.code;
233
121
  return ordered;
234
122
  }
235
-
236
- // src/dto/response/dto.ts
237
123
  var ResponseDTO = class _ResponseDTO extends BaseDTO {
238
124
  _status;
239
125
  _message;
@@ -270,11 +156,8 @@ var ResponseDTO = class _ResponseDTO extends BaseDTO {
270
156
  return this;
271
157
  }
272
158
  data(data) {
273
- if (data === void 0) {
274
- delete this._payload.data;
275
- } else {
276
- this._payload.data = data;
277
- }
159
+ if (data === void 0) delete this._payload.data;
160
+ else this._payload.data = data;
278
161
  return this;
279
162
  }
280
163
  payload(partial) {
@@ -286,9 +169,7 @@ var ResponseDTO = class _ResponseDTO extends BaseDTO {
286
169
  return this;
287
170
  }
288
171
  paginate(total, page, limit) {
289
- if (limit <= 0) {
290
- throw new Error("ResponseDTO.paginate: limit must be greater than 0");
291
- }
172
+ if (limit <= 0) throw new Error("ResponseDTO.paginate: limit must be greater than 0");
292
173
  this._payload.pagination = {
293
174
  total,
294
175
  page,
@@ -300,20 +181,11 @@ var ResponseDTO = class _ResponseDTO extends BaseDTO {
300
181
  }
301
182
  schema(input = {}, codes = DefaultCodes) {
302
183
  const { status, message, code, payload } = input;
303
- if (code !== void 0) {
304
- this.code(code);
305
- }
306
- if (status !== void 0) {
307
- this.status(status);
308
- } else if (code !== void 0) {
309
- this.status(resolveStatusFromCode(code, codes));
310
- }
311
- if (message !== void 0) {
312
- this.message(message);
313
- }
314
- if (payload !== void 0) {
315
- this._payload = { ...payload };
316
- }
184
+ if (code !== void 0) this.code(code);
185
+ if (status !== void 0) this.status(status);
186
+ else if (code !== void 0) this.status(resolveStatusFromCode(code, codes));
187
+ if (message !== void 0) this.message(message);
188
+ if (payload !== void 0) this._payload = { ...payload };
317
189
  return this;
318
190
  }
319
191
  getCode() {
@@ -323,9 +195,7 @@ var ResponseDTO = class _ResponseDTO extends BaseDTO {
323
195
  return this._message;
324
196
  }
325
197
  setCodeFromHttpStatus(httpStatusCode, codes) {
326
- if (this._code === void 0) {
327
- this._code = resolveCodeFromHttpStatus(httpStatusCode, codes);
328
- }
198
+ if (this._code === void 0) this._code = resolveCodeFromHttpStatus(httpStatusCode, codes);
329
199
  return this;
330
200
  }
331
201
  transformData(fn) {
@@ -348,12 +218,7 @@ var ResponseDTO = class _ResponseDTO extends BaseDTO {
348
218
  return assembleResponseBody({ status, message, code });
349
219
  }
350
220
  const payload = this.buildPayload();
351
- return assembleResponseBody({
352
- status,
353
- message,
354
- payload,
355
- code
356
- });
221
+ return assembleResponseBody({ status, message, payload, code });
357
222
  }
358
223
  buildPayload() {
359
224
  const entries = Object.entries(this._payload).filter(([, value]) => value !== void 0);
@@ -362,7 +227,106 @@ var ResponseDTO = class _ResponseDTO extends BaseDTO {
362
227
  }
363
228
  };
364
229
 
365
- // src/dto/response/plugins.ts
230
+ // src/utils/helpers/request-id.ts
231
+ var DEFAULT_REQUEST_ID_HEADERS = [
232
+ "x-request-id",
233
+ "x-correlation-id",
234
+ "traceparent"
235
+ ];
236
+ function readHeader(req, name) {
237
+ const fromGet = req.get?.(name);
238
+ if (fromGet) return fromGet;
239
+ const headers = req.headers;
240
+ if (!headers) return void 0;
241
+ const direct = headers[name] ?? headers[name.toLowerCase()];
242
+ if (direct === void 0) return void 0;
243
+ return Array.isArray(direct) ? direct[0] : direct;
244
+ }
245
+ function traceIdFromTraceparent(traceparent) {
246
+ const parts = traceparent.trim().split("-");
247
+ if (parts.length < 2) return void 0;
248
+ const traceId = parts[1];
249
+ if (!traceId || !/^[0-9a-f]{32}$/i.test(traceId)) return void 0;
250
+ return `${traceId.slice(0, 8)}-${traceId.slice(8, 12)}-${traceId.slice(12, 16)}-${traceId.slice(16, 20)}-${traceId.slice(20)}`;
251
+ }
252
+ function resolveRequestId(req, headerNames = DEFAULT_REQUEST_ID_HEADERS) {
253
+ for (const name of headerNames) {
254
+ const raw = readHeader(req, name);
255
+ if (!raw?.trim()) continue;
256
+ if (name === "traceparent") {
257
+ const traceId = traceIdFromTraceparent(raw);
258
+ if (traceId) return traceId;
259
+ continue;
260
+ }
261
+ const id = raw.trim();
262
+ if (isValidUUID(id)) return id;
263
+ return id;
264
+ }
265
+ return generateUUID();
266
+ }
267
+
268
+ // src/dto/factories.ts
269
+ var ContextFactory = class {
270
+ static create(req, options = {}) {
271
+ return {
272
+ requestId: resolveRequestId(req, options.requestIdHeaders),
273
+ startTime: Date.now()
274
+ };
275
+ }
276
+ static fromId(requestId) {
277
+ return { requestId, startTime: Date.now() };
278
+ }
279
+ };
280
+ var MetadataFactory = class {
281
+ static create(options = {}, context) {
282
+ return {
283
+ requestId: context?.requestId ?? generateUUID(),
284
+ serverTime: (/* @__PURE__ */ new Date()).toISOString(),
285
+ statusCode: 200,
286
+ ...options
287
+ };
288
+ }
289
+ };
290
+
291
+ // src/errors/error.ts
292
+ var ResponseError = class extends Error {
293
+ code;
294
+ httpStatus;
295
+ payload;
296
+ constructor(options = {}) {
297
+ const codes = createCodeRegistry(options.codes);
298
+ const code = options.code ?? codes.SERVER;
299
+ const message = options.message ?? defaultMessageForCode(code, codes);
300
+ super(message, { cause: options.cause });
301
+ this.name = "ResponseError";
302
+ this.code = code;
303
+ this.httpStatus = options.httpStatus ?? codeToDefaultHttpStatus(code, codes);
304
+ if (options.payload !== void 0) {
305
+ this.payload = options.payload;
306
+ }
307
+ }
308
+ toJSON() {
309
+ return {
310
+ name: this.name,
311
+ message: this.message,
312
+ code: this.code,
313
+ httpStatus: this.httpStatus,
314
+ payload: this.payload
315
+ };
316
+ }
317
+ };
318
+ function isResponseError(value) {
319
+ return value instanceof ResponseError;
320
+ }
321
+ function codeToDefaultHttpStatus(code, codes) {
322
+ if (code === codes.SUCCESS) return 200;
323
+ if (code === codes.CLIENT) return 400;
324
+ if (code === codes.SERVER) return 500;
325
+ if (code === codes.VALIDATION) return 422;
326
+ return 500;
327
+ }
328
+
329
+ // src/dto/send/plugins.ts
366
330
  function sortPlugins(plugins) {
367
331
  return [...plugins].sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
368
332
  }
@@ -399,7 +363,80 @@ var PluginRegistry = class {
399
363
  }
400
364
  };
401
365
 
402
- // src/dto/response/presets.ts
366
+ // src/utils/constants/http.ts
367
+ var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([204, 205, 304]);
368
+ function shouldSendResponseBody(statusCode) {
369
+ return !NO_BODY_STATUS_CODES.has(statusCode);
370
+ }
371
+
372
+ // src/dto/send/transport.ts
373
+ var JSON_CONTENT_TYPE = "application/json; charset=utf-8";
374
+ function normalizeHeaderValue(value) {
375
+ return Array.isArray(value) ? value.join(", ") : String(value);
376
+ }
377
+ function toHeaderRecord(headers) {
378
+ const record = {};
379
+ for (const [key, value] of Object.entries(headers)) {
380
+ record[key] = normalizeHeaderValue(value);
381
+ }
382
+ return record;
383
+ }
384
+ function serializeSetCookie(cookie) {
385
+ let header = `${cookie.name}=${cookie.value}`;
386
+ const options = cookie.options ?? {};
387
+ if (options.maxAge !== void 0) header += `; Max-Age=${options.maxAge}`;
388
+ if (typeof options.domain === "string") header += `; Domain=${options.domain}`;
389
+ if (typeof options.path === "string") header += `; Path=${options.path}`;
390
+ if (options.expires instanceof Date) header += `; Expires=${options.expires.toUTCString()}`;
391
+ if (options.httpOnly === true) header += "; HttpOnly";
392
+ if (options.secure === true) header += "; Secure";
393
+ if (typeof options.sameSite === "string") header += `; SameSite=${options.sameSite}`;
394
+ return header;
395
+ }
396
+ function buildSetCookieHeaders(cookies) {
397
+ return cookies.map(serializeSetCookie);
398
+ }
399
+ function applyElysiaTransport(result, sink) {
400
+ sink.status = result.statusCode;
401
+ sink.headers = {
402
+ ...sink.headers ?? {},
403
+ ...toHeaderRecord(result.headers)
404
+ };
405
+ for (const cookieHeader of buildSetCookieHeaders(result.cookies)) {
406
+ const existing = sink.headers["Set-Cookie"];
407
+ sink.headers["Set-Cookie"] = existing ? `${existing}, ${cookieHeader}` : cookieHeader;
408
+ }
409
+ if (shouldSendResponseBody(result.statusCode)) {
410
+ sink.headers["Content-Type"] = JSON_CONTENT_TYPE;
411
+ return result.body;
412
+ }
413
+ return null;
414
+ }
415
+ function dispatchResult(result, sink, plugins, pluginCtx, emitHook) {
416
+ if (!sink) {
417
+ return result;
418
+ }
419
+ let next = plugins.runBeforeDispatch(result, pluginCtx);
420
+ emitHook("before_dispatch", next);
421
+ const dispatched = sink.dispatch(next);
422
+ plugins.runAfterDispatch(next, pluginCtx);
423
+ emitHook("after_dispatch", next);
424
+ return dispatched ?? next;
425
+ }
426
+
427
+ // src/dto/send/presets.ts
428
+ var PresetTerminal = class {
429
+ #builder;
430
+ constructor(builder) {
431
+ this.#builder = builder;
432
+ }
433
+ build() {
434
+ return this.#builder.build();
435
+ }
436
+ send() {
437
+ return this.#builder.send();
438
+ }
439
+ };
403
440
  var ResponsePresets = class {
404
441
  builder;
405
442
  codes;
@@ -412,9 +449,6 @@ var ResponsePresets = class {
412
449
  this.builder.payload(extras);
413
450
  }
414
451
  }
415
- dispatch() {
416
- return this.builder.build();
417
- }
418
452
  resolveFailureArgs(dataOrMessage, messageOrExtras, extras) {
419
453
  if (typeof dataOrMessage === "string") {
420
454
  return {
@@ -428,31 +462,34 @@ var ResponsePresets = class {
428
462
  extras: typeof messageOrExtras === "string" ? extras : messageOrExtras
429
463
  };
430
464
  }
465
+ terminal() {
466
+ return new PresetTerminal(this.builder);
467
+ }
431
468
  failure(httpStatus, code, dataOrMessage, messageOrExtras, extras) {
432
469
  const resolved = this.resolveFailureArgs(dataOrMessage, messageOrExtras, extras);
433
470
  this.builder.httpStatus(httpStatus).code(code).status(false).message(resolved.message ?? defaultMessageForCode(code, this.codes)).data(resolved.data);
434
471
  this.applyExtras(resolved.extras);
435
- return this.dispatch();
472
+ return this.terminal();
436
473
  }
437
474
  ok(data, message, extras) {
438
475
  this.builder.httpStatus(StatusCodes.SUCCESSFUL.OK).code(this.codes.SUCCESS).status(true).message(message ?? defaultMessageForCode(this.codes.SUCCESS, this.codes)).data(data);
439
476
  this.applyExtras(extras);
440
- return this.dispatch();
477
+ return this.terminal();
441
478
  }
442
479
  created(data, message, extras) {
443
480
  this.builder.httpStatus(StatusCodes.SUCCESSFUL.CREATED).code(this.codes.SUCCESS).status(true).message(message ?? defaultMessageForCode(this.codes.SUCCESS, this.codes)).data(data);
444
481
  this.applyExtras(extras);
445
- return this.dispatch();
482
+ return this.terminal();
446
483
  }
447
484
  accepted(message, extras) {
448
485
  this.builder.httpStatus(StatusCodes.SUCCESSFUL.ACCEPTED).code(this.codes.SUCCESS).status(true).message(message ?? defaultMessageForCode(this.codes.SUCCESS, this.codes));
449
486
  this.applyExtras(extras);
450
- return this.dispatch();
487
+ return this.terminal();
451
488
  }
452
489
  noContent(extras) {
453
490
  this.builder.httpStatus(StatusCodes.SUCCESSFUL.NO_CONTENT).code(this.codes.SUCCESS).status(true).message("").data(void 0);
454
491
  this.applyExtras(extras);
455
- return this.dispatch();
492
+ return this.terminal();
456
493
  }
457
494
  fail(dataOrMessage, messageOrExtras, extras) {
458
495
  return this.failure(StatusCodes.CLIENT_ERROR.BAD_REQUEST, this.codes.CLIENT, dataOrMessage, messageOrExtras, extras);
@@ -522,9 +559,9 @@ var ResponsePresets = class {
522
559
  }
523
560
  };
524
561
 
525
- // src/dto/response/builder.ts
562
+ // src/dto/send/builder.ts
526
563
  var Builder = class {
527
- dispatcher;
564
+ sink;
528
565
  options;
529
566
  context;
530
567
  plugins;
@@ -533,8 +570,8 @@ var Builder = class {
533
570
  _headers = {};
534
571
  _cookies = [];
535
572
  _presets;
536
- constructor(dispatcher, options = {}, context) {
537
- this.dispatcher = dispatcher;
573
+ constructor(sink, options = {}, context) {
574
+ this.sink = sink;
538
575
  this.options = resolveBuilderConfig(options);
539
576
  this.context = context;
540
577
  this.plugins = new PluginRegistry(this.options.plugins);
@@ -666,16 +703,19 @@ var Builder = class {
666
703
  };
667
704
  result = this.plugins.runAfterBuild(result, pluginCtx);
668
705
  this.emitHook("after_build", result);
669
- if (this.dispatcher) {
670
- result = this.plugins.runBeforeDispatch(result, pluginCtx);
671
- this.emitHook("before_dispatch", result);
672
- const dispatched = this.dispatcher.dispatch(result);
673
- this.plugins.runAfterDispatch(result, pluginCtx);
674
- this.emitHook("after_dispatch", result);
675
- return dispatched ?? result;
676
- }
677
706
  return result;
678
707
  }
708
+ send() {
709
+ const pluginCtx = this.createPluginContext();
710
+ const result = this.build();
711
+ return dispatchResult(
712
+ result,
713
+ this.sink,
714
+ this.plugins,
715
+ pluginCtx,
716
+ (event, payload) => this.emitHook(event, payload)
717
+ );
718
+ }
679
719
  resolvePublicErrorMessage(error) {
680
720
  if (!this.options.verbose && !isResponseError(error)) {
681
721
  return defaultMessageForCode(this.options.codes.SERVER, this.options.codes);
@@ -701,8 +741,8 @@ var Builder = class {
701
741
  hooks.emit(event, structuredClone(result));
702
742
  }
703
743
  };
704
- function createBuilderProxy(dispatcher, options = {}, context) {
705
- const instance = new Builder(dispatcher, options, context);
744
+ function createBuilderProxy(sink, options = {}, context) {
745
+ const instance = new Builder(sink, options, context);
706
746
  return new Proxy(instance, {
707
747
  get(target, prop, receiver) {
708
748
  const value = Reflect.get(target, prop, receiver);
@@ -714,8 +754,8 @@ function createBuilderProxy(dispatcher, options = {}, context) {
714
754
  });
715
755
  }
716
756
 
717
- // src/adapters/shared.ts
718
- function createBuilderRuntime(dispatcher, options, context) {
757
+ // src/dto/runtime/index.ts
758
+ function createBuilderRuntime(sink, options, context) {
719
759
  const builderOptions = {
720
760
  verbose: options.verbose,
721
761
  includeStack: options.includeStack,
@@ -727,40 +767,25 @@ function createBuilderRuntime(dispatcher, options, context) {
727
767
  return {
728
768
  context,
729
769
  codes: resolveBuilderConfig(builderOptions).codes,
730
- builder: createBuilderProxy(dispatcher, builderOptions, context)
770
+ builder: createBuilderProxy(sink, builderOptions, context)
731
771
  };
732
772
  }
733
773
 
734
- // src/adapters/elysia.ts
774
+ // src/dto/adapters/http.ts
775
+ function elysiaSink(set) {
776
+ return { dispatch: (result) => applyElysiaTransport(result, set) };
777
+ }
735
778
  function createElysiaDerive(options = {}) {
736
779
  return ({ request, set }) => {
737
- const context = ContextFactory.create({
738
- headers: headersToRecord(request.headers)
739
- }, {
740
- requestIdHeaders: options.requestIdHeaders
741
- });
780
+ const context = ContextFactory.create(
781
+ { headers: headersToRecord(request.headers) },
782
+ { requestIdHeaders: options.requestIdHeaders }
783
+ );
742
784
  if (options.withDefaultHeaders !== false) {
743
785
  const headers = options.defaultHeaders ?? DEFAULT_SECURITY_HEADERS;
744
786
  set.headers = { ...set.headers ?? {}, ...headers };
745
787
  }
746
- const runtime = createBuilderRuntime(
747
- {
748
- dispatch(result) {
749
- set.status = result.statusCode;
750
- set.headers = {
751
- ...set.headers ?? {},
752
- ...normalizeHeaders(result.headers),
753
- "Content-Type": "application/json; charset=utf-8"
754
- };
755
- if (!shouldSendResponseBody(result.statusCode)) {
756
- return null;
757
- }
758
- return result.body;
759
- }
760
- },
761
- options,
762
- context
763
- );
788
+ const runtime = createBuilderRuntime(elysiaSink(set), options, context);
764
789
  return {
765
790
  builder: runtime.builder,
766
791
  requestId: runtime.context.requestId,
@@ -769,11 +794,10 @@ function createElysiaDerive(options = {}) {
769
794
  };
770
795
  }
771
796
  var ElysiaAdapter = class {
772
- options;
773
797
  constructor(options = {}) {
774
798
  this.options = options;
775
799
  }
776
- /** Elysia plugin — adds `builder`, `requestId`, `startTime` to the handler context */
800
+ options;
777
801
  plugin() {
778
802
  const derive = createElysiaDerive(this.options);
779
803
  return new elysia.Elysia({ name: "x" }).derive(
@@ -784,12 +808,6 @@ var ElysiaAdapter = class {
784
808
  })
785
809
  );
786
810
  }
787
- middleware() {
788
- return this.plugin();
789
- }
790
- handler() {
791
- return this.plugin();
792
- }
793
811
  };
794
812
  function elysiaMiddleware(options = {}) {
795
813
  return new ElysiaAdapter(options).plugin();
@@ -801,18 +819,8 @@ function headersToRecord(headers) {
801
819
  });
802
820
  return record;
803
821
  }
804
- function normalizeHeaders(headers) {
805
- const normalized = {};
806
- for (const [key, value] of Object.entries(headers)) {
807
- if (Array.isArray(value)) {
808
- normalized[key] = value.join(", ");
809
- } else {
810
- normalized[key] = String(value);
811
- }
812
- }
813
- return normalized;
814
- }
815
822
 
816
823
  exports.ElysiaAdapter = ElysiaAdapter;
817
824
  exports.createElysiaDerive = createElysiaDerive;
818
825
  exports.elysiaMiddleware = elysiaMiddleware;
826
+ exports.elysiaSink = elysiaSink;