@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,184 @@
1
+ import { B as BaseDto } from './base-dto.class-D7W9iqoU.js';
2
+ import { H as HttpRequest, a as HttpResponse, C as Controller } from './http-response-BAhi8lF4.js';
3
+
4
+ /**
5
+ * @fileoverview Core routing types for the presentation layer.
6
+ *
7
+ * This module provides framework-agnostic routing abstractions that can be
8
+ * used with any HTTP framework (Hono, Fastify, Elysia, etc.).
9
+ *
10
+ * @example Basic route definition
11
+ * ```typescript
12
+ * import type { RouteInput } from '@cosmneo/onion-lasagna/backend/core/presentation';
13
+ *
14
+ * const getUserRoute: RouteInput<GetUserRequestDto, GetUserResponseDto> = {
15
+ * metadata: { path: '/users/{id}', method: 'GET' },
16
+ * controller: getUserController,
17
+ * requestDtoFactory: (req) => GetUserRequestDto.create(req),
18
+ * };
19
+ * ```
20
+ *
21
+ * @module routing
22
+ */
23
+
24
+ /**
25
+ * Standard HTTP methods supported by the routing system.
26
+ *
27
+ * Includes all methods commonly used in RESTful APIs:
28
+ * - `GET` - Retrieve a resource
29
+ * - `POST` - Create a new resource
30
+ * - `PUT` - Replace a resource
31
+ * - `PATCH` - Partially update a resource
32
+ * - `DELETE` - Remove a resource
33
+ * - `OPTIONS` - CORS preflight and capability discovery
34
+ * - `HEAD` - Retrieve headers only (no body)
35
+ */
36
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
37
+ /**
38
+ * HTTP endpoint metadata defining the route's method and path.
39
+ *
40
+ * Path parameters use curly brace syntax (`{param}`) which is framework-agnostic.
41
+ * Each framework adapter converts this to its native format:
42
+ * - Hono/Express: `/users/:id`
43
+ * - Fastify: `/users/:id`
44
+ * - AWS API Gateway: `/users/{id}`
45
+ *
46
+ * The `path` should be the full route path (computed from service + resource + endpoint
47
+ * using `computeRoutePath()` when needed).
48
+ *
49
+ * @example Simple route
50
+ * ```typescript
51
+ * const metadata: RouteMetadata = {
52
+ * path: '/health',
53
+ * method: 'GET',
54
+ * };
55
+ * ```
56
+ *
57
+ * @example Route with path parameters
58
+ * ```typescript
59
+ * const metadata: RouteMetadata = {
60
+ * path: '/users/{userId}/orders/{orderId}',
61
+ * method: 'GET',
62
+ * };
63
+ * ```
64
+ */
65
+ interface RouteMetadata {
66
+ /**
67
+ * Full path pattern for the route.
68
+ *
69
+ * Uses curly brace syntax for path parameters: `/users/{id}`
70
+ *
71
+ * This should be the complete path including service and resource segments.
72
+ * Use `computeRoutePath()` to compute from service, resource, and endpoint metadata.
73
+ *
74
+ * @example '/users'
75
+ * @example '/users/{id}'
76
+ * @example '/organizations/{orgId}/members/{memberId}'
77
+ */
78
+ path: string;
79
+ /**
80
+ * The HTTP method for this route.
81
+ *
82
+ * Accepts either uppercase (`'GET'`) or lowercase (`'get'`) format.
83
+ * Framework adapters normalize to lowercase for registration.
84
+ */
85
+ method: HttpMethod | Uppercase<HttpMethod> | Lowercase<HttpMethod>;
86
+ }
87
+ /**
88
+ * Factory function that creates a validated request DTO from an HTTP request.
89
+ *
90
+ * This factory is called by framework adapters to transform the HTTP request
91
+ * (body, headers, query params, path params) into a validated DTO before passing
92
+ * to the controller.
93
+ *
94
+ * @typeParam TRequestDto - The validated request DTO type (must extend BaseDto)
95
+ *
96
+ * @example Creating from HttpRequest
97
+ * ```typescript
98
+ * const factory: RequestDtoFactory<CreateUserRequestDto> = (req) =>
99
+ * CreateUserRequestDto.create({
100
+ * name: req.body.name,
101
+ * email: req.body.email,
102
+ * });
103
+ * ```
104
+ *
105
+ * @example With path parameters
106
+ * ```typescript
107
+ * const factory: RequestDtoFactory<GetUserRequestDto> = (req) =>
108
+ * GetUserRequestDto.create({
109
+ * userId: req.pathParams?.id,
110
+ * });
111
+ * ```
112
+ */
113
+ type RequestDtoFactory<TRequestDto extends BaseDto<unknown> = BaseDto<unknown>> = (request: HttpRequest) => TRequestDto;
114
+ /**
115
+ * Complete route definition combining metadata, controller, and request factory.
116
+ *
117
+ * This is the primary type used to define routes in a framework-agnostic way.
118
+ * Framework adapters (Hono, Fastify, Elysia) accept arrays of `RouteInput` and
119
+ * register them with the underlying framework.
120
+ *
121
+ * The controller receives a validated `TRequestDto` and returns a `TResponseDto`
122
+ * wrapping an {@link HttpResponse}. Framework adapters extract `.data` from the
123
+ * response DTO to get the actual HTTP response.
124
+ *
125
+ * @typeParam TRequestDto - The validated request DTO type
126
+ * @typeParam TResponseDto - The response DTO type (wraps HttpResponse)
127
+ *
128
+ * @example Single route definition
129
+ * ```typescript
130
+ * const createUserRoute: RouteInput<CreateUserRequestDto, CreateUserResponseDto> = {
131
+ * metadata: { path: '/users', method: 'POST' },
132
+ * controller: createUserController,
133
+ * requestDtoFactory: (req) => CreateUserRequestDto.create(req.body),
134
+ * };
135
+ * ```
136
+ *
137
+ * @example Route array for a resource
138
+ * ```typescript
139
+ * const userRoutes: RouteInput[] = [
140
+ * {
141
+ * metadata: { path: '/users', method: 'GET' },
142
+ * controller: listUsersController,
143
+ * requestDtoFactory: (req) => ListUsersRequestDto.create(req.queryParams),
144
+ * },
145
+ * {
146
+ * metadata: { path: '/users/{id}', method: 'GET' },
147
+ * controller: getUserController,
148
+ * requestDtoFactory: (req) => GetUserRequestDto.create(req.pathParams),
149
+ * },
150
+ * ];
151
+ * ```
152
+ *
153
+ * @example Registering with Hono
154
+ * ```typescript
155
+ * import { registerHonoRoutes } from '@cosmneo/onion-lasagna/backend/frameworks/hono';
156
+ *
157
+ * const app = new Hono();
158
+ * registerHonoRoutes(app, userRoutes, { prefix: '/api/v1' });
159
+ * ```
160
+ */
161
+ interface RouteInput<TRequestDto extends BaseDto<unknown> = BaseDto<unknown>, TResponseDto extends BaseDto<HttpResponse> = BaseDto<HttpResponse>> {
162
+ /**
163
+ * Route metadata defining the HTTP method and path.
164
+ */
165
+ metadata: RouteMetadata;
166
+ /**
167
+ * The controller that handles requests to this route.
168
+ *
169
+ * Receives a validated request DTO and returns a response DTO
170
+ * wrapping an {@link HttpResponse}.
171
+ */
172
+ controller: Controller<TRequestDto, TResponseDto>;
173
+ /**
174
+ * Factory to create a validated request DTO from the raw framework request.
175
+ *
176
+ * The framework adapter calls this factory to transform the raw HTTP request
177
+ * into a validated DTO before invoking the controller.
178
+ *
179
+ * @throws {ObjectValidationError} When the raw request fails DTO validation
180
+ */
181
+ requestDtoFactory: RequestDtoFactory<TRequestDto>;
182
+ }
183
+
184
+ export type { HttpMethod as H, RouteInput as R, RouteMetadata as a, RequestDtoFactory as b };
@@ -0,0 +1,184 @@
1
+ import { B as BaseDto } from './base-dto.class-D7W9iqoU.cjs';
2
+ import { H as HttpRequest, a as HttpResponse, C as Controller } from './http-response-BAhi8lF4.cjs';
3
+
4
+ /**
5
+ * @fileoverview Core routing types for the presentation layer.
6
+ *
7
+ * This module provides framework-agnostic routing abstractions that can be
8
+ * used with any HTTP framework (Hono, Fastify, Elysia, etc.).
9
+ *
10
+ * @example Basic route definition
11
+ * ```typescript
12
+ * import type { RouteInput } from '@cosmneo/onion-lasagna/backend/core/presentation';
13
+ *
14
+ * const getUserRoute: RouteInput<GetUserRequestDto, GetUserResponseDto> = {
15
+ * metadata: { path: '/users/{id}', method: 'GET' },
16
+ * controller: getUserController,
17
+ * requestDtoFactory: (req) => GetUserRequestDto.create(req),
18
+ * };
19
+ * ```
20
+ *
21
+ * @module routing
22
+ */
23
+
24
+ /**
25
+ * Standard HTTP methods supported by the routing system.
26
+ *
27
+ * Includes all methods commonly used in RESTful APIs:
28
+ * - `GET` - Retrieve a resource
29
+ * - `POST` - Create a new resource
30
+ * - `PUT` - Replace a resource
31
+ * - `PATCH` - Partially update a resource
32
+ * - `DELETE` - Remove a resource
33
+ * - `OPTIONS` - CORS preflight and capability discovery
34
+ * - `HEAD` - Retrieve headers only (no body)
35
+ */
36
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
37
+ /**
38
+ * HTTP endpoint metadata defining the route's method and path.
39
+ *
40
+ * Path parameters use curly brace syntax (`{param}`) which is framework-agnostic.
41
+ * Each framework adapter converts this to its native format:
42
+ * - Hono/Express: `/users/:id`
43
+ * - Fastify: `/users/:id`
44
+ * - AWS API Gateway: `/users/{id}`
45
+ *
46
+ * The `path` should be the full route path (computed from service + resource + endpoint
47
+ * using `computeRoutePath()` when needed).
48
+ *
49
+ * @example Simple route
50
+ * ```typescript
51
+ * const metadata: RouteMetadata = {
52
+ * path: '/health',
53
+ * method: 'GET',
54
+ * };
55
+ * ```
56
+ *
57
+ * @example Route with path parameters
58
+ * ```typescript
59
+ * const metadata: RouteMetadata = {
60
+ * path: '/users/{userId}/orders/{orderId}',
61
+ * method: 'GET',
62
+ * };
63
+ * ```
64
+ */
65
+ interface RouteMetadata {
66
+ /**
67
+ * Full path pattern for the route.
68
+ *
69
+ * Uses curly brace syntax for path parameters: `/users/{id}`
70
+ *
71
+ * This should be the complete path including service and resource segments.
72
+ * Use `computeRoutePath()` to compute from service, resource, and endpoint metadata.
73
+ *
74
+ * @example '/users'
75
+ * @example '/users/{id}'
76
+ * @example '/organizations/{orgId}/members/{memberId}'
77
+ */
78
+ path: string;
79
+ /**
80
+ * The HTTP method for this route.
81
+ *
82
+ * Accepts either uppercase (`'GET'`) or lowercase (`'get'`) format.
83
+ * Framework adapters normalize to lowercase for registration.
84
+ */
85
+ method: HttpMethod | Uppercase<HttpMethod> | Lowercase<HttpMethod>;
86
+ }
87
+ /**
88
+ * Factory function that creates a validated request DTO from an HTTP request.
89
+ *
90
+ * This factory is called by framework adapters to transform the HTTP request
91
+ * (body, headers, query params, path params) into a validated DTO before passing
92
+ * to the controller.
93
+ *
94
+ * @typeParam TRequestDto - The validated request DTO type (must extend BaseDto)
95
+ *
96
+ * @example Creating from HttpRequest
97
+ * ```typescript
98
+ * const factory: RequestDtoFactory<CreateUserRequestDto> = (req) =>
99
+ * CreateUserRequestDto.create({
100
+ * name: req.body.name,
101
+ * email: req.body.email,
102
+ * });
103
+ * ```
104
+ *
105
+ * @example With path parameters
106
+ * ```typescript
107
+ * const factory: RequestDtoFactory<GetUserRequestDto> = (req) =>
108
+ * GetUserRequestDto.create({
109
+ * userId: req.pathParams?.id,
110
+ * });
111
+ * ```
112
+ */
113
+ type RequestDtoFactory<TRequestDto extends BaseDto<unknown> = BaseDto<unknown>> = (request: HttpRequest) => TRequestDto;
114
+ /**
115
+ * Complete route definition combining metadata, controller, and request factory.
116
+ *
117
+ * This is the primary type used to define routes in a framework-agnostic way.
118
+ * Framework adapters (Hono, Fastify, Elysia) accept arrays of `RouteInput` and
119
+ * register them with the underlying framework.
120
+ *
121
+ * The controller receives a validated `TRequestDto` and returns a `TResponseDto`
122
+ * wrapping an {@link HttpResponse}. Framework adapters extract `.data` from the
123
+ * response DTO to get the actual HTTP response.
124
+ *
125
+ * @typeParam TRequestDto - The validated request DTO type
126
+ * @typeParam TResponseDto - The response DTO type (wraps HttpResponse)
127
+ *
128
+ * @example Single route definition
129
+ * ```typescript
130
+ * const createUserRoute: RouteInput<CreateUserRequestDto, CreateUserResponseDto> = {
131
+ * metadata: { path: '/users', method: 'POST' },
132
+ * controller: createUserController,
133
+ * requestDtoFactory: (req) => CreateUserRequestDto.create(req.body),
134
+ * };
135
+ * ```
136
+ *
137
+ * @example Route array for a resource
138
+ * ```typescript
139
+ * const userRoutes: RouteInput[] = [
140
+ * {
141
+ * metadata: { path: '/users', method: 'GET' },
142
+ * controller: listUsersController,
143
+ * requestDtoFactory: (req) => ListUsersRequestDto.create(req.queryParams),
144
+ * },
145
+ * {
146
+ * metadata: { path: '/users/{id}', method: 'GET' },
147
+ * controller: getUserController,
148
+ * requestDtoFactory: (req) => GetUserRequestDto.create(req.pathParams),
149
+ * },
150
+ * ];
151
+ * ```
152
+ *
153
+ * @example Registering with Hono
154
+ * ```typescript
155
+ * import { registerHonoRoutes } from '@cosmneo/onion-lasagna/backend/frameworks/hono';
156
+ *
157
+ * const app = new Hono();
158
+ * registerHonoRoutes(app, userRoutes, { prefix: '/api/v1' });
159
+ * ```
160
+ */
161
+ interface RouteInput<TRequestDto extends BaseDto<unknown> = BaseDto<unknown>, TResponseDto extends BaseDto<HttpResponse> = BaseDto<HttpResponse>> {
162
+ /**
163
+ * Route metadata defining the HTTP method and path.
164
+ */
165
+ metadata: RouteMetadata;
166
+ /**
167
+ * The controller that handles requests to this route.
168
+ *
169
+ * Receives a validated request DTO and returns a response DTO
170
+ * wrapping an {@link HttpResponse}.
171
+ */
172
+ controller: Controller<TRequestDto, TResponseDto>;
173
+ /**
174
+ * Factory to create a validated request DTO from the raw framework request.
175
+ *
176
+ * The framework adapter calls this factory to transform the raw HTTP request
177
+ * into a validated DTO before invoking the controller.
178
+ *
179
+ * @throws {ObjectValidationError} When the raw request fails DTO validation
180
+ */
181
+ requestDtoFactory: RequestDtoFactory<TRequestDto>;
182
+ }
183
+
184
+ export type { HttpMethod as H, RouteInput as R, RouteMetadata as a, RequestDtoFactory as b };
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Centralized registry of all error codes used across the application.
3
+ *
4
+ * Error codes are grouped by architectural layer to maintain clear boundaries
5
+ * and make it easy to identify where an error originated.
6
+ *
7
+ * @example Using error codes in custom errors
8
+ * ```typescript
9
+ * import { ErrorCodes } from '@cosmneo/onion-lasagna/backend/core/global';
10
+ *
11
+ * throw new NotFoundError({
12
+ * message: 'User not found',
13
+ * code: ErrorCodes.App.NOT_FOUND,
14
+ * });
15
+ * ```
16
+ *
17
+ * @example Checking error codes programmatically
18
+ * ```typescript
19
+ * if (error.code === ErrorCodes.App.NOT_FOUND) {
20
+ * // Handle not found case
21
+ * }
22
+ * ```
23
+ */
24
+ declare const ErrorCodes: {
25
+ /**
26
+ * Domain layer error codes.
27
+ * Used for business rule violations and invariant failures.
28
+ */
29
+ readonly Domain: {
30
+ /** Generic domain error */
31
+ readonly DOMAIN_ERROR: "DOMAIN_ERROR";
32
+ /** Business invariant was violated */
33
+ readonly INVARIANT_VIOLATION: "INVARIANT_VIOLATION";
34
+ /** Aggregate was partially loaded (missing required relations) */
35
+ readonly PARTIAL_LOAD: "PARTIAL_LOAD";
36
+ };
37
+ /**
38
+ * Application layer (use case) error codes.
39
+ * Used for orchestration failures and business operation errors.
40
+ */
41
+ readonly App: {
42
+ /** Generic use case error */
43
+ readonly USE_CASE_ERROR: "USE_CASE_ERROR";
44
+ /** Requested resource was not found */
45
+ readonly NOT_FOUND: "NOT_FOUND";
46
+ /** Resource state conflict (e.g., duplicate, already exists) */
47
+ readonly CONFLICT: "CONFLICT";
48
+ /** Request is valid but cannot be processed due to business rules */
49
+ readonly UNPROCESSABLE: "UNPROCESSABLE";
50
+ };
51
+ /**
52
+ * Infrastructure layer error codes.
53
+ * Used for data access, external services, and I/O failures.
54
+ */
55
+ readonly Infra: {
56
+ /** Generic infrastructure error */
57
+ readonly INFRA_ERROR: "INFRA_ERROR";
58
+ /** Database operation failed */
59
+ readonly DB_ERROR: "DB_ERROR";
60
+ /** Network connectivity or communication error */
61
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
62
+ /** Operation timed out */
63
+ readonly TIMEOUT_ERROR: "TIMEOUT_ERROR";
64
+ /** External/third-party service error */
65
+ readonly EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR";
66
+ };
67
+ /**
68
+ * Presentation layer error codes.
69
+ * Used for controller, request handling, and authorization errors.
70
+ */
71
+ readonly Presentation: {
72
+ /** Generic controller error */
73
+ readonly CONTROLLER_ERROR: "CONTROLLER_ERROR";
74
+ /** Request denied due to authorization failure */
75
+ readonly ACCESS_DENIED: "ACCESS_DENIED";
76
+ /** Request validation failed (malformed input) */
77
+ readonly INVALID_REQUEST: "INVALID_REQUEST";
78
+ };
79
+ /**
80
+ * Global/cross-cutting error codes.
81
+ * Used for validation and other cross-layer concerns.
82
+ */
83
+ readonly Global: {
84
+ /** Object/schema validation failed */
85
+ readonly OBJECT_VALIDATION_ERROR: "OBJECT_VALIDATION_ERROR";
86
+ };
87
+ };
88
+ /**
89
+ * Type representing all possible domain error codes.
90
+ */
91
+ type DomainErrorCode = (typeof ErrorCodes.Domain)[keyof typeof ErrorCodes.Domain];
92
+ /**
93
+ * Type representing all possible application error codes.
94
+ */
95
+ type AppErrorCode = (typeof ErrorCodes.App)[keyof typeof ErrorCodes.App];
96
+ /**
97
+ * Type representing all possible infrastructure error codes.
98
+ */
99
+ type InfraErrorCode = (typeof ErrorCodes.Infra)[keyof typeof ErrorCodes.Infra];
100
+ /**
101
+ * Type representing all possible presentation error codes.
102
+ */
103
+ type PresentationErrorCode = (typeof ErrorCodes.Presentation)[keyof typeof ErrorCodes.Presentation];
104
+ /**
105
+ * Type representing all possible global error codes.
106
+ */
107
+ type GlobalErrorCode = (typeof ErrorCodes.Global)[keyof typeof ErrorCodes.Global];
108
+ /**
109
+ * Union type of all error codes across all layers.
110
+ *
111
+ * Use this when you need to accept any valid error code.
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * function logError(code: ErrorCode, message: string) {
116
+ * console.error(`[${code}] ${message}`);
117
+ * }
118
+ * ```
119
+ */
120
+ type ErrorCode = DomainErrorCode | AppErrorCode | InfraErrorCode | PresentationErrorCode | GlobalErrorCode;
121
+
122
+ /**
123
+ * Base error class for all application errors with a machine-readable code.
124
+ *
125
+ * Abstract class that extends the native `Error` with:
126
+ * - A `code` property for programmatic error handling
127
+ * - Optional `cause` for error chaining (ES2022 compatible)
128
+ * - A `fromError` static factory pattern for error transformation
129
+ *
130
+ * **Why abstract:** Prevents non-declarative error usage. All errors must
131
+ * be explicitly defined as subclasses to ensure consistent error taxonomy.
132
+ *
133
+ * @example Subclass implementation
134
+ * ```typescript
135
+ * class DbError extends InfraError {
136
+ * static override fromError(cause: unknown): DbError {
137
+ * return new DbError({
138
+ * message: cause instanceof Error ? cause.message : 'Database error',
139
+ * cause,
140
+ * });
141
+ * }
142
+ * }
143
+ * ```
144
+ *
145
+ * @example Usage with wrapErrorAsync
146
+ * ```typescript
147
+ * await wrapErrorAsync(
148
+ * () => this.db.query(...),
149
+ * DbError.fromError,
150
+ * );
151
+ * ```
152
+ */
153
+ declare abstract class CodedError extends Error {
154
+ /** Machine-readable error code for programmatic handling. */
155
+ readonly code: ErrorCode | string;
156
+ /**
157
+ * Creates a new CodedError instance.
158
+ *
159
+ * @param options - Error configuration
160
+ * @param options.message - Human-readable error message
161
+ * @param options.code - Machine-readable error code from ErrorCodes registry or custom string
162
+ * @param options.cause - Optional underlying error that caused this error
163
+ */
164
+ constructor({ message, code, cause, }: {
165
+ message: string;
166
+ code: ErrorCode | string;
167
+ cause?: unknown;
168
+ });
169
+ /**
170
+ * Factory method to create a typed error from a caught error.
171
+ *
172
+ * Subclasses should override this to provide proper error transformation.
173
+ * Designed for use with {@link wrapErrorAsync} and {@link wrapError}.
174
+ *
175
+ * @param _cause - The original caught error
176
+ * @returns A new CodedError instance
177
+ * @throws {Error} If not overridden by subclass
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * class NotFoundError extends UseCaseError {
182
+ * static override fromError(cause: unknown): NotFoundError {
183
+ * return new NotFoundError({
184
+ * message: 'Resource not found',
185
+ * cause,
186
+ * });
187
+ * }
188
+ * }
189
+ * ```
190
+ */
191
+ static fromError(_cause: unknown): CodedError;
192
+ }
193
+
194
+ interface ValidationError {
195
+ field: string;
196
+ message: string;
197
+ }
198
+
199
+ export { type AppErrorCode as A, CodedError as C, type DomainErrorCode as D, ErrorCodes as E, type GlobalErrorCode as G, type InfraErrorCode as I, type PresentationErrorCode as P, type ValidationError as V, type ErrorCode as a };