@cosmneo/onion-lasagna 0.1.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 (97) hide show
  1. package/dist/backend/core/global.cjs +283 -0
  2. package/dist/backend/core/global.cjs.map +1 -0
  3. package/dist/backend/core/global.d.cts +294 -0
  4. package/dist/backend/core/global.d.ts +294 -0
  5. package/dist/backend/core/global.js +39 -0
  6. package/dist/backend/core/global.js.map +1 -0
  7. package/dist/backend/core/onion-layers.cjs +2302 -0
  8. package/dist/backend/core/onion-layers.cjs.map +1 -0
  9. package/dist/backend/core/onion-layers.d.cts +1675 -0
  10. package/dist/backend/core/onion-layers.d.ts +1675 -0
  11. package/dist/backend/core/onion-layers.js +1158 -0
  12. package/dist/backend/core/onion-layers.js.map +1 -0
  13. package/dist/backend/core/presentation.cjs +573 -0
  14. package/dist/backend/core/presentation.cjs.map +1 -0
  15. package/dist/backend/core/presentation.d.cts +5 -0
  16. package/dist/backend/core/presentation.d.ts +5 -0
  17. package/dist/backend/core/presentation.js +28 -0
  18. package/dist/backend/core/presentation.js.map +1 -0
  19. package/dist/backend/core/validators/arktype.cjs +947 -0
  20. package/dist/backend/core/validators/arktype.cjs.map +1 -0
  21. package/dist/backend/core/validators/arktype.d.cts +188 -0
  22. package/dist/backend/core/validators/arktype.d.ts +188 -0
  23. package/dist/backend/core/validators/arktype.js +287 -0
  24. package/dist/backend/core/validators/arktype.js.map +1 -0
  25. package/dist/backend/core/validators/typebox.cjs +939 -0
  26. package/dist/backend/core/validators/typebox.cjs.map +1 -0
  27. package/dist/backend/core/validators/typebox.d.cts +189 -0
  28. package/dist/backend/core/validators/typebox.d.ts +189 -0
  29. package/dist/backend/core/validators/typebox.js +281 -0
  30. package/dist/backend/core/validators/typebox.js.map +1 -0
  31. package/dist/backend/core/validators/valibot.cjs +942 -0
  32. package/dist/backend/core/validators/valibot.cjs.map +1 -0
  33. package/dist/backend/core/validators/valibot.d.cts +160 -0
  34. package/dist/backend/core/validators/valibot.d.ts +160 -0
  35. package/dist/backend/core/validators/valibot.js +294 -0
  36. package/dist/backend/core/validators/valibot.js.map +1 -0
  37. package/dist/backend/core/validators/zod.cjs +934 -0
  38. package/dist/backend/core/validators/zod.cjs.map +1 -0
  39. package/dist/backend/core/validators/zod.d.cts +188 -0
  40. package/dist/backend/core/validators/zod.d.ts +188 -0
  41. package/dist/backend/core/validators/zod.js +278 -0
  42. package/dist/backend/core/validators/zod.js.map +1 -0
  43. package/dist/backend/frameworks/elysia.cjs +715 -0
  44. package/dist/backend/frameworks/elysia.cjs.map +1 -0
  45. package/dist/backend/frameworks/elysia.d.cts +208 -0
  46. package/dist/backend/frameworks/elysia.d.ts +208 -0
  47. package/dist/backend/frameworks/elysia.js +251 -0
  48. package/dist/backend/frameworks/elysia.js.map +1 -0
  49. package/dist/backend/frameworks/fastify.cjs +677 -0
  50. package/dist/backend/frameworks/fastify.cjs.map +1 -0
  51. package/dist/backend/frameworks/fastify.d.cts +201 -0
  52. package/dist/backend/frameworks/fastify.d.ts +201 -0
  53. package/dist/backend/frameworks/fastify.js +213 -0
  54. package/dist/backend/frameworks/fastify.js.map +1 -0
  55. package/dist/backend/frameworks/hono.cjs +715 -0
  56. package/dist/backend/frameworks/hono.cjs.map +1 -0
  57. package/dist/backend/frameworks/hono.d.cts +163 -0
  58. package/dist/backend/frameworks/hono.d.ts +163 -0
  59. package/dist/backend/frameworks/hono.js +249 -0
  60. package/dist/backend/frameworks/hono.js.map +1 -0
  61. package/dist/backend/frameworks/nestjs.cjs +260 -0
  62. package/dist/backend/frameworks/nestjs.cjs.map +1 -0
  63. package/dist/backend/frameworks/nestjs.d.cts +168 -0
  64. package/dist/backend/frameworks/nestjs.d.ts +168 -0
  65. package/dist/backend/frameworks/nestjs.js +193 -0
  66. package/dist/backend/frameworks/nestjs.js.map +1 -0
  67. package/dist/base-dto.class-D7W9iqoU.d.cts +146 -0
  68. package/dist/base-dto.class-D7W9iqoU.d.ts +146 -0
  69. package/dist/base-uuid-v7.vo-BPGEIWLM.d.ts +799 -0
  70. package/dist/base-uuid-v7.vo-BjqKX44G.d.cts +799 -0
  71. package/dist/chunk-74IKUOSE.js +116 -0
  72. package/dist/chunk-74IKUOSE.js.map +1 -0
  73. package/dist/chunk-BKZOLGQW.js +29 -0
  74. package/dist/chunk-BKZOLGQW.js.map +1 -0
  75. package/dist/chunk-CGZBV6BD.js +54 -0
  76. package/dist/chunk-CGZBV6BD.js.map +1 -0
  77. package/dist/chunk-DDAHJZVK.js +258 -0
  78. package/dist/chunk-DDAHJZVK.js.map +1 -0
  79. package/dist/chunk-MQD5GXMT.js +171 -0
  80. package/dist/chunk-MQD5GXMT.js.map +1 -0
  81. package/dist/chunk-OKFXZHBC.js +43 -0
  82. package/dist/chunk-OKFXZHBC.js.map +1 -0
  83. package/dist/chunk-RLLWYFPI.js +168 -0
  84. package/dist/chunk-RLLWYFPI.js.map +1 -0
  85. package/dist/chunk-VCHFXT5W.js +425 -0
  86. package/dist/chunk-VCHFXT5W.js.map +1 -0
  87. package/dist/chunk-ZWLYNGO3.js +40 -0
  88. package/dist/chunk-ZWLYNGO3.js.map +1 -0
  89. package/dist/http-response-BAhi8lF4.d.cts +124 -0
  90. package/dist/http-response-BAhi8lF4.d.ts +124 -0
  91. package/dist/index-DingXh7B.d.cts +1187 -0
  92. package/dist/index-tOH7XBa3.d.ts +1187 -0
  93. package/dist/routing.type-DB4pt-d9.d.ts +184 -0
  94. package/dist/routing.type-DF2BIL7x.d.cts +184 -0
  95. package/dist/validation-error.type-kD4_qNZ9.d.cts +199 -0
  96. package/dist/validation-error.type-kD4_qNZ9.d.ts +199 -0
  97. package/package.json +191 -0
@@ -0,0 +1,573 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/backend/core/onion-layers/presentation/index.ts
21
+ var presentation_exports = {};
22
+ __export(presentation_exports, {
23
+ AccessDeniedError: () => AccessDeniedError,
24
+ BaseController: () => BaseController,
25
+ ControllerError: () => ControllerError,
26
+ GuardedController: () => GuardedController,
27
+ InvalidRequestError: () => InvalidRequestError,
28
+ assertHttpResponse: () => assertHttpResponse,
29
+ computeRoutePath: () => computeRoutePath,
30
+ defineSystemMetadata: () => defineSystemMetadata,
31
+ isHttpResponse: () => isHttpResponse
32
+ });
33
+ module.exports = __toCommonJS(presentation_exports);
34
+
35
+ // src/backend/core/global/exceptions/coded-error.error.ts
36
+ var CodedError = class extends Error {
37
+ /** Machine-readable error code for programmatic handling. */
38
+ code;
39
+ /**
40
+ * Creates a new CodedError instance.
41
+ *
42
+ * @param options - Error configuration
43
+ * @param options.message - Human-readable error message
44
+ * @param options.code - Machine-readable error code from ErrorCodes registry or custom string
45
+ * @param options.cause - Optional underlying error that caused this error
46
+ */
47
+ constructor({
48
+ message,
49
+ code,
50
+ cause
51
+ }) {
52
+ super(message);
53
+ this.name = this.constructor.name;
54
+ this.code = code;
55
+ if (cause !== void 0) {
56
+ Object.defineProperty(this, "cause", {
57
+ value: cause,
58
+ writable: false,
59
+ enumerable: false,
60
+ configurable: true
61
+ });
62
+ }
63
+ }
64
+ /**
65
+ * Factory method to create a typed error from a caught error.
66
+ *
67
+ * Subclasses should override this to provide proper error transformation.
68
+ * Designed for use with {@link wrapErrorAsync} and {@link wrapError}.
69
+ *
70
+ * @param _cause - The original caught error
71
+ * @returns A new CodedError instance
72
+ * @throws {Error} If not overridden by subclass
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * class NotFoundError extends UseCaseError {
77
+ * static override fromError(cause: unknown): NotFoundError {
78
+ * return new NotFoundError({
79
+ * message: 'Resource not found',
80
+ * cause,
81
+ * });
82
+ * }
83
+ * }
84
+ * ```
85
+ */
86
+ static fromError(_cause) {
87
+ throw new Error(`${this.name}.fromError() must be implemented by subclass`);
88
+ }
89
+ };
90
+
91
+ // src/backend/core/global/exceptions/error-codes.const.ts
92
+ var ErrorCodes = {
93
+ /**
94
+ * Domain layer error codes.
95
+ * Used for business rule violations and invariant failures.
96
+ */
97
+ Domain: {
98
+ /** Generic domain error */
99
+ DOMAIN_ERROR: "DOMAIN_ERROR",
100
+ /** Business invariant was violated */
101
+ INVARIANT_VIOLATION: "INVARIANT_VIOLATION",
102
+ /** Aggregate was partially loaded (missing required relations) */
103
+ PARTIAL_LOAD: "PARTIAL_LOAD"
104
+ },
105
+ /**
106
+ * Application layer (use case) error codes.
107
+ * Used for orchestration failures and business operation errors.
108
+ */
109
+ App: {
110
+ /** Generic use case error */
111
+ USE_CASE_ERROR: "USE_CASE_ERROR",
112
+ /** Requested resource was not found */
113
+ NOT_FOUND: "NOT_FOUND",
114
+ /** Resource state conflict (e.g., duplicate, already exists) */
115
+ CONFLICT: "CONFLICT",
116
+ /** Request is valid but cannot be processed due to business rules */
117
+ UNPROCESSABLE: "UNPROCESSABLE"
118
+ },
119
+ /**
120
+ * Infrastructure layer error codes.
121
+ * Used for data access, external services, and I/O failures.
122
+ */
123
+ Infra: {
124
+ /** Generic infrastructure error */
125
+ INFRA_ERROR: "INFRA_ERROR",
126
+ /** Database operation failed */
127
+ DB_ERROR: "DB_ERROR",
128
+ /** Network connectivity or communication error */
129
+ NETWORK_ERROR: "NETWORK_ERROR",
130
+ /** Operation timed out */
131
+ TIMEOUT_ERROR: "TIMEOUT_ERROR",
132
+ /** External/third-party service error */
133
+ EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR"
134
+ },
135
+ /**
136
+ * Presentation layer error codes.
137
+ * Used for controller, request handling, and authorization errors.
138
+ */
139
+ Presentation: {
140
+ /** Generic controller error */
141
+ CONTROLLER_ERROR: "CONTROLLER_ERROR",
142
+ /** Request denied due to authorization failure */
143
+ ACCESS_DENIED: "ACCESS_DENIED",
144
+ /** Request validation failed (malformed input) */
145
+ INVALID_REQUEST: "INVALID_REQUEST"
146
+ },
147
+ /**
148
+ * Global/cross-cutting error codes.
149
+ * Used for validation and other cross-layer concerns.
150
+ */
151
+ Global: {
152
+ /** Object/schema validation failed */
153
+ OBJECT_VALIDATION_ERROR: "OBJECT_VALIDATION_ERROR"
154
+ }
155
+ };
156
+
157
+ // src/backend/core/global/exceptions/object-validation.error.ts
158
+ var ObjectValidationError = class _ObjectValidationError extends CodedError {
159
+ /**
160
+ * Array of field-level validation errors.
161
+ *
162
+ * Each entry contains:
163
+ * - `field`: Dot-notation path to the invalid field (e.g., 'user.email')
164
+ * - `message`: Human-readable validation failure message
165
+ */
166
+ validationErrors;
167
+ /**
168
+ * Creates a new ObjectValidationError instance.
169
+ *
170
+ * @param options - Error configuration
171
+ * @param options.message - Human-readable summary message
172
+ * @param options.code - Machine-readable error code (default: 'OBJECT_VALIDATION_ERROR')
173
+ * @param options.cause - Optional underlying error from validation library
174
+ * @param options.validationErrors - Array of field-level validation errors
175
+ */
176
+ constructor({
177
+ message,
178
+ code = ErrorCodes.Global.OBJECT_VALIDATION_ERROR,
179
+ cause,
180
+ validationErrors
181
+ }) {
182
+ super({ message, code, cause });
183
+ this.validationErrors = validationErrors;
184
+ }
185
+ /**
186
+ * Creates an ObjectValidationError from a caught error.
187
+ *
188
+ * @param cause - The original caught error
189
+ * @returns A new ObjectValidationError instance with the cause attached
190
+ */
191
+ static fromError(cause) {
192
+ return new _ObjectValidationError({
193
+ message: cause instanceof Error ? cause.message : "Validation failed",
194
+ cause,
195
+ validationErrors: []
196
+ });
197
+ }
198
+ };
199
+
200
+ // src/backend/core/global/utils/wrap-error.util.ts
201
+ function wrapErrorUnless(fn, errorFactory, passthroughTypes) {
202
+ try {
203
+ return fn();
204
+ } catch (error) {
205
+ if (passthroughTypes.some((Type) => error instanceof Type)) {
206
+ throw error;
207
+ }
208
+ throw errorFactory(error);
209
+ }
210
+ }
211
+ async function wrapErrorUnlessAsync(fn, errorFactory, passthroughTypes) {
212
+ try {
213
+ return await fn();
214
+ } catch (error) {
215
+ if (passthroughTypes.some((Type) => error instanceof Type)) {
216
+ throw error;
217
+ }
218
+ throw errorFactory(error);
219
+ }
220
+ }
221
+
222
+ // src/backend/core/onion-layers/presentation/exceptions/controller.error.ts
223
+ var ControllerError = class _ControllerError extends CodedError {
224
+ /**
225
+ * Creates a new ControllerError instance.
226
+ *
227
+ * @param options - Error configuration
228
+ * @param options.message - Human-readable error description
229
+ * @param options.code - Machine-readable error code (default: 'CONTROLLER_ERROR')
230
+ * @param options.cause - Optional underlying error
231
+ */
232
+ constructor({
233
+ message,
234
+ code = ErrorCodes.Presentation.CONTROLLER_ERROR,
235
+ cause
236
+ }) {
237
+ super({ message, code, cause });
238
+ }
239
+ /**
240
+ * Creates a ControllerError from a caught error.
241
+ *
242
+ * @param cause - The original caught error
243
+ * @returns A new ControllerError instance with the cause attached
244
+ */
245
+ static fromError(cause) {
246
+ return new _ControllerError({
247
+ message: cause instanceof Error ? cause.message : "Controller error",
248
+ cause
249
+ });
250
+ }
251
+ };
252
+
253
+ // src/backend/core/onion-layers/presentation/exceptions/invalid-request.error.ts
254
+ var InvalidRequestError = class _InvalidRequestError extends CodedError {
255
+ /**
256
+ * Array of field-level validation errors.
257
+ *
258
+ * Each entry contains:
259
+ * - `field`: Dot-notation path to the invalid field
260
+ * - `message`: Human-readable validation failure message
261
+ */
262
+ validationErrors;
263
+ /**
264
+ * Creates a new InvalidRequestError instance.
265
+ *
266
+ * @param options - Error configuration
267
+ * @param options.message - Summary of the validation failure
268
+ * @param options.code - Machine-readable error code (default: 'INVALID_REQUEST')
269
+ * @param options.cause - Optional underlying error
270
+ * @param options.validationErrors - Array of field-level validation errors
271
+ */
272
+ constructor({
273
+ message,
274
+ code = ErrorCodes.Presentation.INVALID_REQUEST,
275
+ cause,
276
+ validationErrors
277
+ }) {
278
+ super({ message, code, cause });
279
+ this.validationErrors = validationErrors;
280
+ }
281
+ /**
282
+ * Creates an InvalidRequestError from a caught error.
283
+ *
284
+ * @param cause - The original caught error
285
+ * @returns A new InvalidRequestError instance with the cause attached
286
+ */
287
+ static fromError(cause) {
288
+ return new _InvalidRequestError({
289
+ message: cause instanceof Error ? cause.message : "Invalid request",
290
+ cause,
291
+ validationErrors: []
292
+ });
293
+ }
294
+ };
295
+
296
+ // src/backend/core/onion-layers/presentation/classes/base-controller.class.ts
297
+ var BaseController = class _BaseController {
298
+ /**
299
+ * Creates a new BaseController instance.
300
+ *
301
+ * @param requestMapper - Function to map request DTO to use case input DTO
302
+ * @param useCase - The use case port to execute
303
+ * @param responseMapper - Function to map use case output DTO to response DTO
304
+ */
305
+ constructor(requestMapper, useCase, responseMapper) {
306
+ this.requestMapper = requestMapper;
307
+ this.useCase = useCase;
308
+ this.responseMapper = responseMapper;
309
+ }
310
+ /**
311
+ * Factory method to create a controller from a configuration object.
312
+ *
313
+ * @param config - Controller configuration
314
+ * @returns A new BaseController instance
315
+ */
316
+ static create(config) {
317
+ return new _BaseController(config.requestMapper, config.useCase, config.responseMapper);
318
+ }
319
+ /**
320
+ * Executes the controller pipeline with error wrapping.
321
+ *
322
+ * This is the public entry point that ensures consistent error handling.
323
+ * All errors are wrapped in {@link ControllerError} unless they extend {@link CodedError}.
324
+ *
325
+ * **Do not override this method.** Override {@link pipeline} instead for custom pipeline logic.
326
+ *
327
+ * @param input - The validated request DTO
328
+ * @returns Promise resolving to the validated response DTO
329
+ * @throws {InvalidRequestError} When request mapping/validation fails
330
+ * @throws {ControllerError} When an unexpected error occurs
331
+ * @throws {CodedError} When use case throws a known error type
332
+ */
333
+ async execute(input) {
334
+ return wrapErrorUnlessAsync(
335
+ () => this.pipeline(input),
336
+ (cause) => new ControllerError({
337
+ message: cause instanceof Error ? cause.message : "Controller execution failed",
338
+ cause
339
+ }),
340
+ [CodedError]
341
+ );
342
+ }
343
+ /**
344
+ * Runs the controller pipeline.
345
+ *
346
+ * Orchestrates: `mapRequest → executeUseCase → mapResponse`
347
+ *
348
+ * Override this method to customize the entire pipeline flow, or override
349
+ * individual protected methods ({@link mapRequest}, {@link executeUseCase},
350
+ * {@link mapResponse}) for more granular control.
351
+ *
352
+ * @param input - The validated request DTO
353
+ * @returns Promise resolving to the validated response DTO
354
+ */
355
+ async pipeline(input) {
356
+ const mappedInput = this.mapRequest(input);
357
+ const result = await this.executeUseCase(mappedInput);
358
+ return this.mapResponse(result);
359
+ }
360
+ /**
361
+ * Maps the request DTO to a use case input DTO.
362
+ *
363
+ * Override to add custom pre-processing, logging, or transformation logic.
364
+ * The default implementation uses the configured `requestMapper` and converts
365
+ * {@link ObjectValidationError} to {@link InvalidRequestError}.
366
+ *
367
+ * @param input - The validated request DTO
368
+ * @returns The use case input DTO
369
+ * @throws {InvalidRequestError} When validation fails
370
+ * @throws {ControllerError} When mapping fails unexpectedly
371
+ */
372
+ mapRequest(input) {
373
+ return wrapErrorUnless(
374
+ () => this.requestMapper(input),
375
+ (cause) => {
376
+ if (cause instanceof ObjectValidationError) {
377
+ return new InvalidRequestError({
378
+ message: cause.message,
379
+ cause,
380
+ validationErrors: cause.validationErrors
381
+ });
382
+ }
383
+ return new ControllerError({
384
+ message: cause instanceof Error ? cause.message : "Request mapping failed",
385
+ cause
386
+ });
387
+ },
388
+ [CodedError]
389
+ );
390
+ }
391
+ /**
392
+ * Executes the use case with the mapped input.
393
+ *
394
+ * Override to add custom logic around use case execution, such as:
395
+ * - Logging/tracing
396
+ * - Caching
397
+ * - Retry logic
398
+ * - Multi-use-case orchestration
399
+ *
400
+ * @param input - The use case input DTO
401
+ * @returns Promise resolving to the use case output DTO
402
+ */
403
+ async executeUseCase(input) {
404
+ return this.useCase.execute(input);
405
+ }
406
+ /**
407
+ * Maps the use case output DTO to a response DTO.
408
+ *
409
+ * Override to add custom post-processing, logging, or transformation logic.
410
+ * The default implementation uses the configured `responseMapper`.
411
+ *
412
+ * @param output - The use case output DTO
413
+ * @returns The response DTO
414
+ * @throws {ControllerError} When mapping or validation fails
415
+ */
416
+ mapResponse(output) {
417
+ return wrapErrorUnless(
418
+ () => this.responseMapper(output),
419
+ (cause) => new ControllerError({
420
+ message: cause instanceof ObjectValidationError ? "Response validation failed" : cause instanceof Error ? cause.message : "Response mapping failed",
421
+ cause
422
+ }),
423
+ [CodedError]
424
+ );
425
+ }
426
+ };
427
+
428
+ // src/backend/core/onion-layers/presentation/exceptions/access-denied.error.ts
429
+ var AccessDeniedError = class _AccessDeniedError extends CodedError {
430
+ /**
431
+ * Creates a new AccessDeniedError instance.
432
+ *
433
+ * @param options - Error configuration
434
+ * @param options.message - Description of why access was denied
435
+ * @param options.code - Machine-readable error code (default: 'ACCESS_DENIED')
436
+ * @param options.cause - Optional underlying error
437
+ */
438
+ constructor({
439
+ message,
440
+ code = ErrorCodes.Presentation.ACCESS_DENIED,
441
+ cause
442
+ }) {
443
+ super({ message, code, cause });
444
+ }
445
+ /**
446
+ * Creates an AccessDeniedError from a caught error.
447
+ *
448
+ * @param cause - The original caught error
449
+ * @returns A new AccessDeniedError instance with the cause attached
450
+ */
451
+ static fromError(cause) {
452
+ return new _AccessDeniedError({
453
+ message: cause instanceof Error ? cause.message : "Access denied",
454
+ cause
455
+ });
456
+ }
457
+ };
458
+
459
+ // src/backend/core/onion-layers/presentation/classes/guarded-controller.class.ts
460
+ function createAllowAllGuard() {
461
+ return async () => ({
462
+ isAllowed: true
463
+ });
464
+ }
465
+ var GuardedController = class _GuardedController extends BaseController {
466
+ /** The access guard function for this controller. */
467
+ accessGuard;
468
+ /**
469
+ * Creates a new GuardedController instance.
470
+ *
471
+ * @param requestMapper - Function to map request DTO to use case input DTO
472
+ * @param useCase - The use case port to execute
473
+ * @param responseMapper - Function to map use case output DTO to response DTO
474
+ * @param accessGuard - Optional access guard; defaults to allowing all
475
+ */
476
+ constructor(requestMapper, useCase, responseMapper, accessGuard) {
477
+ super(requestMapper, useCase, responseMapper);
478
+ this.accessGuard = accessGuard ?? createAllowAllGuard();
479
+ }
480
+ /**
481
+ * Factory method to create a guarded controller from a configuration object.
482
+ *
483
+ * @param config - Controller configuration including optional access guard
484
+ * @returns A new GuardedController instance
485
+ */
486
+ static create(config) {
487
+ return new _GuardedController(
488
+ config.requestMapper,
489
+ config.useCase,
490
+ config.responseMapper,
491
+ config.accessGuard
492
+ );
493
+ }
494
+ /**
495
+ * Runs the controller pipeline with access control.
496
+ *
497
+ * Checks the access guard before executing the pipeline.
498
+ * If denied, throws {@link AccessDeniedError}.
499
+ *
500
+ * @param input - The validated request DTO
501
+ * @returns Promise resolving to the validated response DTO
502
+ * @throws {AccessDeniedError} When access guard denies the request
503
+ */
504
+ async pipeline(input) {
505
+ await this.checkAccess(input);
506
+ return super.pipeline(input);
507
+ }
508
+ /**
509
+ * Checks access using the configured guard.
510
+ *
511
+ * Override to customize access control logic.
512
+ *
513
+ * @param input - The validated request DTO
514
+ * @throws {AccessDeniedError} When access is denied
515
+ */
516
+ async checkAccess(input) {
517
+ const result = await this.accessGuard(input);
518
+ if (!result.isAllowed) {
519
+ throw new AccessDeniedError({
520
+ message: result.reason ?? "Access denied"
521
+ });
522
+ }
523
+ }
524
+ };
525
+
526
+ // src/backend/core/onion-layers/presentation/interfaces/types/metadata/system-metadata.type.ts
527
+ function defineSystemMetadata(metadata) {
528
+ return metadata;
529
+ }
530
+
531
+ // src/backend/core/onion-layers/presentation/routing/compute-route-path.util.ts
532
+ function trimSlashes(segment) {
533
+ return segment.replace(/^\/+|\/+$/g, "");
534
+ }
535
+ function computeRoutePath(service, resource, endpoint) {
536
+ const segments = [service.basePath, resource.path, endpoint.path].map(trimSlashes).filter((s) => s.length > 0);
537
+ if (segments.length === 0) {
538
+ return "/";
539
+ }
540
+ return "/" + segments.join("/");
541
+ }
542
+
543
+ // src/backend/core/onion-layers/presentation/utils/http-response.util.ts
544
+ function isHttpResponse(value) {
545
+ return typeof value === "object" && value !== null && "statusCode" in value && typeof value.statusCode === "number";
546
+ }
547
+ function assertHttpResponse(value, context = "value") {
548
+ if (!isHttpResponse(value)) {
549
+ const actualType = value === null ? "null" : value === void 0 ? "undefined" : typeof value;
550
+ const hasStatusCode = typeof value === "object" && value !== null && "statusCode" in value;
551
+ let message = `Expected ${context} to be an HttpResponse with a numeric statusCode, `;
552
+ if (hasStatusCode) {
553
+ const statusCodeType = typeof value["statusCode"];
554
+ message += `but statusCode was ${statusCodeType}`;
555
+ } else {
556
+ message += `but got ${actualType}`;
557
+ }
558
+ throw new Error(message);
559
+ }
560
+ }
561
+ // Annotate the CommonJS export names for ESM import in node:
562
+ 0 && (module.exports = {
563
+ AccessDeniedError,
564
+ BaseController,
565
+ ControllerError,
566
+ GuardedController,
567
+ InvalidRequestError,
568
+ assertHttpResponse,
569
+ computeRoutePath,
570
+ defineSystemMetadata,
571
+ isHttpResponse
572
+ });
573
+ //# sourceMappingURL=presentation.cjs.map