@rineex/ddd 0.0.0 → 1.0.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.
package/dist/index.d.mts CHANGED
@@ -153,6 +153,17 @@ declare class AggregateId extends ValueObject<string> {
153
153
  * - Values are numeric status codes.
154
154
  * - Frozen to prevent runtime mutation.
155
155
  * - Exporting `HttpStatus` ensures type-safe usage across the codebase.
156
+ * Usage:
157
+ * ```ts
158
+ * import { HttpStatus } from 'path-to-this-file';
159
+ *
160
+ * function handleRequest() {
161
+ * return {
162
+ * statusCode: HttpStatus.OK,
163
+ * body: 'Success',
164
+ * };
165
+ * }
166
+ * ```
156
167
  */
157
168
  declare const HttpStatus: Readonly<{
158
169
  readonly REQUEST_HEADER_FIELDS_TOO_LARGE: 431;
@@ -292,7 +303,11 @@ declare const HttpStatusMessage: {
292
303
  type HttpStatusMessage = (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];
293
304
 
294
305
  /**
295
- * Utility to deeply freeze objects to ensure immutability
306
+ * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.
307
+ *
308
+ * @param obj - The object to be deeply frozen.
309
+ * @param seen - A WeakSet to track already processed objects (for circular references).
310
+ * @returns A deeply frozen version of the input object.
296
311
  */
297
312
  declare function deepFreeze<T>(obj: T, seen?: WeakSet<object>): Readonly<T>;
298
313
 
package/dist/index.d.ts CHANGED
@@ -153,6 +153,17 @@ declare class AggregateId extends ValueObject<string> {
153
153
  * - Values are numeric status codes.
154
154
  * - Frozen to prevent runtime mutation.
155
155
  * - Exporting `HttpStatus` ensures type-safe usage across the codebase.
156
+ * Usage:
157
+ * ```ts
158
+ * import { HttpStatus } from 'path-to-this-file';
159
+ *
160
+ * function handleRequest() {
161
+ * return {
162
+ * statusCode: HttpStatus.OK,
163
+ * body: 'Success',
164
+ * };
165
+ * }
166
+ * ```
156
167
  */
157
168
  declare const HttpStatus: Readonly<{
158
169
  readonly REQUEST_HEADER_FIELDS_TOO_LARGE: 431;
@@ -292,7 +303,11 @@ declare const HttpStatusMessage: {
292
303
  type HttpStatusMessage = (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];
293
304
 
294
305
  /**
295
- * Utility to deeply freeze objects to ensure immutability
306
+ * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.
307
+ *
308
+ * @param obj - The object to be deeply frozen.
309
+ * @param seen - A WeakSet to track already processed objects (for circular references).
310
+ * @returns A deeply frozen version of the input object.
296
311
  */
297
312
  declare function deepFreeze<T>(obj: T, seen?: WeakSet<object>): Readonly<T>;
298
313
 
package/dist/index.js CHANGED
@@ -1,447 +1,2 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
9
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
- var __spreadValues = (a, b) => {
11
- for (var prop in b || (b = {}))
12
- if (__hasOwnProp.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- if (__getOwnPropSymbols)
15
- for (var prop of __getOwnPropSymbols(b)) {
16
- if (__propIsEnum.call(b, prop))
17
- __defNormalProp(a, prop, b[prop]);
18
- }
19
- return a;
20
- };
21
- var __export = (target, all) => {
22
- for (var name in all)
23
- __defProp(target, name, { get: all[name], enumerable: true });
24
- };
25
- var __copyProps = (to, from, except, desc) => {
26
- if (from && typeof from === "object" || typeof from === "function") {
27
- for (let key of __getOwnPropNames(from))
28
- if (!__hasOwnProp.call(to, key) && key !== except)
29
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
30
- }
31
- return to;
32
- };
33
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
34
- // If the importer is in node compatibility mode or this is not an ESM
35
- // file that has been converted to a CommonJS file using a Babel-
36
- // compatible transform (i.e. "__esModule" has not been set), then set
37
- // "default" to the CommonJS "module.exports" for node compatibility.
38
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
39
- mod
40
- ));
41
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
42
-
43
- // src/index.ts
44
- var index_exports = {};
45
- __export(index_exports, {
46
- AggregateId: () => AggregateId,
47
- ApplicationError: () => ApplicationError,
48
- DomainError: () => DomainError,
49
- EntityValidationError: () => EntityValidationError,
50
- HttpStatus: () => HttpStatus,
51
- HttpStatusMessage: () => HttpStatusMessage,
52
- InvalidValueObjectError: () => InvalidValueObjectError,
53
- ValueObject: () => ValueObject,
54
- deepFreeze: () => deepFreeze,
55
- ensureObject: () => ensureObject,
56
- unwrapValueObject: () => unwrapValueObject
57
- });
58
- module.exports = __toCommonJS(index_exports);
59
-
60
- // src/domain/base/domain.error.ts
61
- var getCauseInfo = (cause) => {
62
- if (cause instanceof Error) {
63
- return {
64
- cause: {
65
- message: cause.message,
66
- stack: cause.stack,
67
- name: cause.name
68
- }
69
- };
70
- }
71
- if (cause) {
72
- return { cause };
73
- }
74
- return {};
75
- };
76
- var DomainError = class extends Error {
77
- /**
78
- * @param message - Human-readable error message
79
- * @param code - Stable error code
80
- * @param metadata - Domain-specific structured data; optional `cause` can be included
81
- */
82
- constructor(message, code, metadata = {}) {
83
- super(message, __spreadValues({}, getCauseInfo(metadata.cause)));
84
- Object.setPrototypeOf(this, new.target.prototype);
85
- this.name = new.target.name;
86
- this.code = code;
87
- this.metadata = Object.freeze(__spreadValues({}, metadata));
88
- }
89
- };
90
-
91
- // src/domain/base/vo.ts
92
- var import_es6 = __toESM(require("fast-deep-equal/es6"));
93
-
94
- // src/utils/deep-freeze.util.ts
95
- function deepFreeze(obj, seen = /* @__PURE__ */ new WeakSet()) {
96
- if (obj == null || typeof obj !== "object" && !Array.isArray(obj)) {
97
- return obj;
98
- }
99
- if (Object.isFrozen(obj)) {
100
- return obj;
101
- }
102
- if (seen.has(obj)) {
103
- return obj;
104
- }
105
- seen.add(obj);
106
- if (Array.isArray(obj)) {
107
- obj.forEach((item) => deepFreeze(item, seen));
108
- } else {
109
- for (const key in obj) {
110
- if (Object.hasOwn(obj, key)) {
111
- deepFreeze(obj[key], seen);
112
- }
113
- }
114
- }
115
- return Object.freeze(obj);
116
- }
117
-
118
- // src/domain/base/vo.ts
119
- var ValueObject = class _ValueObject {
120
- get value() {
121
- return this.props;
122
- }
123
- constructor(props) {
124
- this.validate(props);
125
- this.props = deepFreeze(props);
126
- }
127
- /**
128
- * Type guard to check if an unknown object is an instance of ValueObject.
129
- * This is useful for runtime type checking.
130
- *
131
- * @param vo The object to check.
132
- * @returns True if the object is a ValueObject instance, false otherwise.
133
- */
134
- static is(vo) {
135
- return vo instanceof _ValueObject;
136
- }
137
- /**
138
- * Deep equality comparison of ValueObjects
139
- */
140
- equals(other) {
141
- if (!other || !(other instanceof this.constructor)) {
142
- return false;
143
- }
144
- return (0, import_es6.default)(this.props, other.props);
145
- }
146
- };
147
-
148
- // src/domain/errors/entity-validation.error.ts
149
- var EntityValidationError = class extends DomainError {
150
- constructor(message, cause) {
151
- super(message, "ENTITY_VALIDATION_ERROR", { cause });
152
- }
153
- };
154
-
155
- // src/domain/errors/invalid-vo.error.ts
156
- var InvalidValueObjectError = class extends DomainError {
157
- constructor(message) {
158
- super(message, "INVALID_VALUE_OBJECT");
159
- }
160
- };
161
-
162
- // src/domain/value-objects/aggregate-id.vo.ts
163
- var import_uuid = require("uuid");
164
- var import_zod = __toESM(require("zod"));
165
- var _AggregateId = class _AggregateId extends ValueObject {
166
- /**
167
- * Get the UUID of the AggregateId
168
- * @returns The UUID of the AggregateId
169
- */
170
- get uuid() {
171
- return this.value;
172
- }
173
- /**
174
- * Create a new AggregateId
175
- * @param value The value to create the AggregateId from
176
- * @returns The new AggregateId
177
- */
178
- static create(value) {
179
- return new _AggregateId(value);
180
- }
181
- /**
182
- * Create a new AggregateId with a random UUID v4
183
- */
184
- static generate() {
185
- return new _AggregateId((0, import_uuid.v4)());
186
- }
187
- /**
188
- * Check if the AggregateId is empty
189
- * @returns True if the AggregateId is empty, false otherwise
190
- */
191
- isEmpty() {
192
- return !this.value;
193
- }
194
- /**
195
- * Convert the AggregateId to a string
196
- * @returns The string representation of the AggregateId
197
- */
198
- toString() {
199
- return this.value;
200
- }
201
- /**
202
- * Validate the AggregateId
203
- * @param value The value to validate
204
- * @throws InvalidValueObjectException if the value is invalid
205
- */
206
- validate(value) {
207
- const result = _AggregateId.schema.safeParse(value);
208
- if (!result.success) {
209
- throw new InvalidValueObjectError(
210
- `Invalid AggregateId: ${result.error.message}`
211
- );
212
- }
213
- }
214
- };
215
- /**
216
- * The schema for the AggregateId
217
- */
218
- _AggregateId.schema = import_zod.default.uuid();
219
- var AggregateId = _AggregateId;
220
-
221
- // src/gateway/constants/http-code.ts
222
- var HttpStatus = Object.freeze({
223
- REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
224
- NETWORK_AUTHENTICATION_REQUIRED: 511,
225
- NON_AUTHORITATIVE_INFORMATION: 203,
226
- PROXY_AUTHENTICATION_REQUIRED: 407,
227
- UNAVAILABLE_FOR_LEGAL_REASONS: 451,
228
- HTTP_VERSION_NOT_SUPPORTED: 505,
229
- BANDWIDTH_LIMIT_EXCEEDED: 509,
230
- VARIANT_ALSO_NEGOTIATES: 506,
231
- UNSUPPORTED_MEDIA_TYPE: 415,
232
- RANGE_NOT_SATISFIABLE: 416,
233
- PRECONDITION_REQUIRED: 428,
234
- INTERNAL_SERVER_ERROR: 500,
235
- UNPROCESSABLE_ENTITY: 422,
236
- INSUFFICIENT_STORAGE: 507,
237
- SWITCHING_PROTOCOLS: 101,
238
- PRECONDITION_FAILED: 412,
239
- MISDIRECTED_REQUEST: 421,
240
- SERVICE_UNAVAILABLE: 503,
241
- TEMPORARY_REDIRECT: 307,
242
- PERMANENT_REDIRECT: 308,
243
- METHOD_NOT_ALLOWED: 405,
244
- EXPECTATION_FAILED: 417,
245
- MOVED_PERMANENTLY: 301,
246
- PAYLOAD_TOO_LARGE: 413,
247
- FAILED_DEPENDENCY: 424,
248
- TOO_MANY_REQUESTS: 429,
249
- ALREADY_REPORTED: 208,
250
- MULTIPLE_CHOICES: 300,
251
- PAYMENT_REQUIRED: 402,
252
- UPGRADE_REQUIRED: 426,
253
- PARTIAL_CONTENT: 206,
254
- REQUEST_TIMEOUT: 408,
255
- LENGTH_REQUIRED: 411,
256
- NOT_IMPLEMENTED: 501,
257
- GATEWAY_TIMEOUT: 504,
258
- NOT_ACCEPTABLE: 406,
259
- RESET_CONTENT: 205,
260
- LOOP_DETECTED: 508,
261
- MULTI_STATUS: 207,
262
- NOT_MODIFIED: 304,
263
- UNAUTHORIZED: 401,
264
- URI_TOO_LONG: 414,
265
- NOT_EXTENDED: 510,
266
- EARLY_HINTS: 103,
267
- BAD_REQUEST: 400,
268
- IM_A_TEAPOT: 418,
269
- BAD_GATEWAY: 502,
270
- PROCESSING: 102,
271
- NO_CONTENT: 204,
272
- SEE_OTHER: 303,
273
- USE_PROXY: 305,
274
- FORBIDDEN: 403,
275
- NOT_FOUND: 404,
276
- TOO_EARLY: 425,
277
- CONTINUE: 100,
278
- ACCEPTED: 202,
279
- CONFLICT: 409,
280
- CREATED: 201,
281
- IM_USED: 226,
282
- LOCKED: 423,
283
- FOUND: 302,
284
- GONE: 410,
285
- OK: 200
286
- });
287
- var HttpStatusMessage = {
288
- 431: "Request Header Fields Too Large",
289
- 511: "Network Authentication Required",
290
- 203: "Non-Authoritative Information",
291
- 407: "Proxy Authentication Required",
292
- 451: "Unavailable For Legal Reasons",
293
- 505: "HTTP Version Not Supported",
294
- 509: "Bandwidth Limit Exceeded",
295
- 506: "Variant Also Negotiates",
296
- 415: "Unsupported Media Type",
297
- 416: "Range Not Satisfiable",
298
- 428: "Precondition Required",
299
- 500: "Internal Server Error",
300
- 422: "Unprocessable Entity",
301
- 507: "Insufficient Storage",
302
- 101: "Switching Protocols",
303
- 412: "Precondition Failed",
304
- 421: "Misdirected Request",
305
- 503: "Service Unavailable",
306
- 307: "Temporary Redirect",
307
- 308: "Permanent Redirect",
308
- 405: "Method Not Allowed",
309
- 417: "Expectation Failed",
310
- 301: "Moved Permanently",
311
- 413: "Payload Too Large",
312
- 424: "Failed Dependency",
313
- 429: "Too Many Requests",
314
- 208: "Already Reported",
315
- 300: "Multiple Choices",
316
- 402: "Payment Required",
317
- 426: "Upgrade Required",
318
- 206: "Partial Content",
319
- 408: "Request Timeout",
320
- 411: "Length Required",
321
- 501: "Not Implemented",
322
- 504: "Gateway Timeout",
323
- 406: "Not Acceptable",
324
- 205: "Reset Content",
325
- 508: "Loop Detected",
326
- 207: "Multi-Status",
327
- 304: "Not Modified",
328
- 401: "Unauthorized",
329
- 414: "URI Too Long",
330
- 418: "I'm a Teapot",
331
- 510: "Not Extended",
332
- 103: "Early Hints",
333
- 400: "Bad Request",
334
- 502: "Bad Gateway",
335
- 102: "Processing",
336
- 204: "No Content",
337
- 303: "See Other",
338
- 305: "Use Proxy",
339
- 403: "Forbidden",
340
- 404: "Not Found",
341
- 425: "Too Early",
342
- 100: "Continue",
343
- 202: "Accepted",
344
- 226: "I'm Used",
345
- 409: "Conflict",
346
- 201: "Created",
347
- 423: "Locked",
348
- 302: "Found",
349
- 410: "Gone",
350
- 200: "OK"
351
- };
352
-
353
- // src/utils/errors/application.error.ts
354
- var ApplicationError = class extends Error {
355
- constructor({
356
- code = HttpStatusMessage["500"],
357
- isOperational = false,
358
- status = 500,
359
- metadata,
360
- message,
361
- cause
362
- }) {
363
- super(message);
364
- this.name = new.target.name;
365
- this.code = code;
366
- this.status = status;
367
- this.isOperational = isOperational;
368
- this.metadata = metadata;
369
- this.cause = cause;
370
- Error.captureStackTrace(this, new.target);
371
- }
372
- };
373
-
374
- // src/utils/unwrap-vo.util.ts
375
- function unwrapValueObject(input, seen = /* @__PURE__ */ new WeakSet()) {
376
- if (input === null || input === void 0) {
377
- return input;
378
- }
379
- if (typeof input !== "object") {
380
- return input;
381
- }
382
- if (seen.has(input)) {
383
- throw new Error("Circular reference detected in ValueObject unwrap");
384
- }
385
- seen.add(input);
386
- if (Array.isArray(input)) {
387
- const result2 = input.map((item) => unwrapValueObject(item, seen));
388
- seen.delete(input);
389
- return result2;
390
- }
391
- if (input instanceof ValueObject) {
392
- const result2 = unwrapValueObject(input.value, seen);
393
- seen.delete(input);
394
- return result2;
395
- }
396
- if (input instanceof Date) {
397
- seen.delete(input);
398
- return input.toISOString();
399
- }
400
- if (input instanceof Map) {
401
- const result2 = /* @__PURE__ */ new Map();
402
- input.forEach((value, key) => {
403
- result2.set(key, unwrapValueObject(value, seen));
404
- });
405
- seen.delete(input);
406
- return result2;
407
- }
408
- if (input instanceof Set) {
409
- const result2 = new Set(
410
- Array.from(input.values()).map((v) => unwrapValueObject(v, seen))
411
- );
412
- seen.delete(input);
413
- return result2;
414
- }
415
- const result = {};
416
- for (const key in input) {
417
- if (Object.hasOwn(input, key)) {
418
- result[key] = unwrapValueObject(input[key], seen);
419
- }
420
- }
421
- seen.delete(input);
422
- return result;
423
- }
424
- function ensureObject(input) {
425
- if (input === null || input === void 0) {
426
- return {};
427
- }
428
- if (typeof input === "object") {
429
- return input;
430
- }
431
- return { value: input };
432
- }
433
- // Annotate the CommonJS export names for ESM import in node:
434
- 0 && (module.exports = {
435
- AggregateId,
436
- ApplicationError,
437
- DomainError,
438
- EntityValidationError,
439
- HttpStatus,
440
- HttpStatusMessage,
441
- InvalidValueObjectError,
442
- ValueObject,
443
- deepFreeze,
444
- ensureObject,
445
- unwrapValueObject
446
- });
1
+ var y=Object.create;var E=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames,A=Object.getOwnPropertySymbols,L=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty,C=Object.prototype.propertyIsEnumerable;var N=(e,t,r)=>t in e?E(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,l=(e,t)=>{for(var r in t||(t={}))I.call(t,r)&&N(e,r,t[r]);if(A)for(var r of A(t))C.call(t,r)&&N(e,r,t[r]);return e};var P=(e,t)=>{for(var r in t)E(e,r,{get:t[r],enumerable:!0})},_=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of w(t))!I.call(e,o)&&o!==r&&E(e,o,{get:()=>t[o],enumerable:!(a=b(t,o))||a.enumerable});return e};var m=(e,t,r)=>(r=e!=null?y(L(e)):{},_(t||!e||!e.__esModule?E(r,"default",{value:e,enumerable:!0}):r,e)),M=e=>_(E({},"__esModule",{value:!0}),e);var H={};P(H,{AggregateId:()=>p,ApplicationError:()=>f,DomainError:()=>n,EntityValidationError:()=>O,HttpStatus:()=>x,HttpStatusMessage:()=>R,InvalidValueObjectError:()=>d,ValueObject:()=>s,deepFreeze:()=>T,ensureObject:()=>h,unwrapValueObject:()=>c});module.exports=M(H);var V=e=>e instanceof Error?{cause:{message:e.message,stack:e.stack,name:e.name}}:e?{cause:e}:{},n=class extends Error{constructor(t,r,a={}){super(t,l({},V(a.cause))),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name,this.code=r,this.metadata=Object.freeze(l({},a))}};var S=m(require("fast-deep-equal/es6"));function T(e,t=new WeakSet){if(e==null||typeof e!="object"&&!Array.isArray(e)||Object.isFrozen(e)||t.has(e))return e;if(t.add(e),Array.isArray(e))e.forEach(r=>T(r,t));else for(let r in e)Object.hasOwn(e,r)&&T(e[r],t);return Object.freeze(e)}var s=class e{get value(){return this.props}constructor(t){this.validate(t),this.props=T(t)}static is(t){return t instanceof e}equals(t){return!t||!(t instanceof this.constructor)?!1:(0,S.default)(this.props,t.props)}};var O=class extends n{constructor(t,r){super(t,"ENTITY_VALIDATION_ERROR",{cause:r})}};var d=class extends n{constructor(t){super(t,"INVALID_VALUE_OBJECT")}};var U=require("uuid"),D=m(require("zod"));var i=class i extends s{get uuid(){return this.value}static create(t){return new i(t)}static generate(){return new i((0,U.v4)())}isEmpty(){return!this.value}toString(){return this.value}validate(t){let r=i.schema.safeParse(t);if(!r.success)throw new d(`Invalid AggregateId: ${r.error.message}`)}};i.schema=D.default.uuid();var p=i;var x=Object.freeze({REQUEST_HEADER_FIELDS_TOO_LARGE:431,NETWORK_AUTHENTICATION_REQUIRED:511,NON_AUTHORITATIVE_INFORMATION:203,PROXY_AUTHENTICATION_REQUIRED:407,UNAVAILABLE_FOR_LEGAL_REASONS:451,HTTP_VERSION_NOT_SUPPORTED:505,BANDWIDTH_LIMIT_EXCEEDED:509,VARIANT_ALSO_NEGOTIATES:506,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,PRECONDITION_REQUIRED:428,INTERNAL_SERVER_ERROR:500,UNPROCESSABLE_ENTITY:422,INSUFFICIENT_STORAGE:507,SWITCHING_PROTOCOLS:101,PRECONDITION_FAILED:412,MISDIRECTED_REQUEST:421,SERVICE_UNAVAILABLE:503,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,METHOD_NOT_ALLOWED:405,EXPECTATION_FAILED:417,MOVED_PERMANENTLY:301,PAYLOAD_TOO_LARGE:413,FAILED_DEPENDENCY:424,TOO_MANY_REQUESTS:429,ALREADY_REPORTED:208,MULTIPLE_CHOICES:300,PAYMENT_REQUIRED:402,UPGRADE_REQUIRED:426,PARTIAL_CONTENT:206,REQUEST_TIMEOUT:408,LENGTH_REQUIRED:411,NOT_IMPLEMENTED:501,GATEWAY_TIMEOUT:504,NOT_ACCEPTABLE:406,RESET_CONTENT:205,LOOP_DETECTED:508,MULTI_STATUS:207,NOT_MODIFIED:304,UNAUTHORIZED:401,URI_TOO_LONG:414,NOT_EXTENDED:510,EARLY_HINTS:103,BAD_REQUEST:400,IM_A_TEAPOT:418,BAD_GATEWAY:502,PROCESSING:102,NO_CONTENT:204,SEE_OTHER:303,USE_PROXY:305,FORBIDDEN:403,NOT_FOUND:404,TOO_EARLY:425,CONTINUE:100,ACCEPTED:202,CONFLICT:409,CREATED:201,IM_USED:226,LOCKED:423,FOUND:302,GONE:410,OK:200}),R={431:"Request Header Fields Too Large",511:"Network Authentication Required",203:"Non-Authoritative Information",407:"Proxy Authentication Required",451:"Unavailable For Legal Reasons",505:"HTTP Version Not Supported",509:"Bandwidth Limit Exceeded",506:"Variant Also Negotiates",415:"Unsupported Media Type",416:"Range Not Satisfiable",428:"Precondition Required",500:"Internal Server Error",422:"Unprocessable Entity",507:"Insufficient Storage",101:"Switching Protocols",412:"Precondition Failed",421:"Misdirected Request",503:"Service Unavailable",307:"Temporary Redirect",308:"Permanent Redirect",405:"Method Not Allowed",417:"Expectation Failed",301:"Moved Permanently",413:"Payload Too Large",424:"Failed Dependency",429:"Too Many Requests",208:"Already Reported",300:"Multiple Choices",402:"Payment Required",426:"Upgrade Required",206:"Partial Content",408:"Request Timeout",411:"Length Required",501:"Not Implemented",504:"Gateway Timeout",406:"Not Acceptable",205:"Reset Content",508:"Loop Detected",207:"Multi-Status",304:"Not Modified",401:"Unauthorized",414:"URI Too Long",418:"I'm a Teapot",510:"Not Extended",103:"Early Hints",400:"Bad Request",502:"Bad Gateway",102:"Processing",204:"No Content",303:"See Other",305:"Use Proxy",403:"Forbidden",404:"Not Found",425:"Too Early",100:"Continue",202:"Accepted",226:"I'm Used",409:"Conflict",201:"Created",423:"Locked",302:"Found",410:"Gone",200:"OK"};var f=class extends Error{constructor({code:t=R[500],isOperational:r=!1,status:a=500,metadata:o,message:u,cause:g}){super(u),this.name=new.target.name,this.code=t,this.status=a,this.isOperational=r,this.metadata=o,this.cause=g,Error.captureStackTrace(this,new.target)}};function c(e,t=new WeakSet){if(e==null||typeof e!="object")return e;if(t.has(e))throw new Error("Circular reference detected in ValueObject unwrap");if(t.add(e),Array.isArray(e)){let a=e.map(o=>c(o,t));return t.delete(e),a}if(e instanceof s){let a=c(e.value,t);return t.delete(e),a}if(e instanceof Date)return t.delete(e),e.toISOString();if(e instanceof Map){let a=new Map;return e.forEach((o,u)=>{a.set(u,c(o,t))}),t.delete(e),a}if(e instanceof Set){let a=new Set(Array.from(e.values()).map(o=>c(o,t)));return t.delete(e),a}let r={};for(let a in e)Object.hasOwn(e,a)&&(r[a]=c(e[a],t));return t.delete(e),r}function h(e){return e==null?{}:typeof e=="object"?e:{value:e}}0&&(module.exports={AggregateId,ApplicationError,DomainError,EntityValidationError,HttpStatus,HttpStatusMessage,InvalidValueObjectError,ValueObject,deepFreeze,ensureObject,unwrapValueObject});
447
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/domain/base/domain.error.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["export * from './application';\nexport * from './domain/base/domain.error';\nexport * from './domain/base/vo';\nexport * from './domain/errors/entity-validation.error';\nexport * from './domain/errors/invalid-vo.error';\nexport * from './domain/value-objects/aggregate-id.vo';\nexport * from './gateway/constants/http-code';\nexport * from './utils';\n","export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (\n !other ||\n !(other instanceof (this.constructor as typeof ValueObject))\n ) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as any)[key], seen); // Use 'any' here as T[key] might not be assignable to T for deepFreeze's input\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { ValueObject } from '../base/vo';\n\n/**\n * AggregateId is a ValueObject that represents a unique identifier for an aggregate.\n */\nexport class AggregateId extends ValueObject<string> {\n /**\n * The schema for the AggregateId\n */\n private static readonly schema = z.uuid();\n\n /**\n * Get the UUID of the AggregateId\n * @returns The UUID of the AggregateId\n */\n public get uuid(): string {\n return this.value;\n }\n\n /**\n * Create a new AggregateId\n * @param value The value to create the AggregateId from\n * @returns The new AggregateId\n */\n public static create(value: string): AggregateId {\n return new AggregateId(value);\n }\n\n /**\n * Create a new AggregateId with a random UUID v4\n */\n public static generate(): AggregateId {\n return new AggregateId(v4());\n }\n\n /**\n * Check if the AggregateId is empty\n * @returns True if the AggregateId is empty, false otherwise\n */\n public isEmpty(): boolean {\n return !this.value;\n }\n\n /**\n * Convert the AggregateId to a string\n * @returns The string representation of the AggregateId\n */\n public toString(): string {\n return this.value;\n }\n\n /**\n * Validate the AggregateId\n * @param value The value to validate\n * @throws InvalidValueObjectException if the value is invalid\n */\n protected validate(value: string): void {\n const result = AggregateId.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid AggregateId: ${result.error.message}`,\n );\n }\n }\n}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,IAAM,eAAe,CAAC,UAA6B;AAEjD,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,OAAO;AAAA,QACL,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,QACb,MAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO;AACT,WAAO,EAAE,MAAM;AAAA,EACjB;AAGA,SAAO,CAAC;AACV;AAsBO,IAAe,cAAf,cAAmC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWpC,YACR,SACA,MACA,WAAgC,CAAC,GACjC;AACA,UAAM,SAAS,mBAAK,aAAa,SAAS,KAAK,EAAG;AAGlD,WAAO,eAAe,MAAM,WAAW,SAAS;AAEhD,SAAK,OAAO,WAAW;AACvB,SAAK,OAAO;AACZ,SAAK,WAAW,OAAO,OAAO,mBAAK,SAAU;AAAA,EAC/C;AACF;;;ACvEA,iBAAsB;;;ACGf,SAAS,WACd,KACA,OAAO,oBAAI,QAAgB,GACd;AAEb,MAAI,OAAO,QAAS,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,GAAI;AACnE,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,SAAS,GAAG,GAAG;AACxB,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,IAAI,GAAa,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,OAAK,IAAI,GAAa;AAGtB,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,QAAI,QAAQ,UAAQ,WAAW,MAAM,IAAI,CAAC;AAAA,EAC5C,OAAO;AAEL,eAAW,OAAO,KAAK;AACrB,UAAI,OAAO,OAAO,KAAK,GAAG,GAAG;AAC3B,mBAAY,IAAY,GAAG,GAAG,IAAI;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,OAAO,GAAG;AAC1B;;;ADjCO,IAAe,cAAf,MAAe,aAAe;AAAA,EACnC,IAAI,QAAW;AACb,WAAO,KAAK;AAAA,EACd;AAAA,EAIU,YAAY,OAAU;AAC9B,SAAK,SAAS,KAAK;AACnB,SAAK,QAAQ,WAAW,KAAK;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAc,GAAG,IAAyC;AACxD,WAAO,cAAc;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKO,OAAO,OAAiC;AAC7C,QACE,CAAC,SACD,EAAE,iBAAkB,KAAK,cACzB;AACA,aAAO;AAAA,IACT;AAEA,eAAO,WAAAA,SAAU,KAAK,OAAO,MAAM,KAAK;AAAA,EAC1C;AAOF;;;AEzCO,IAAM,wBAAN,cAAoC,YAAY;AAAA,EACrD,YAAY,SAAiB,OAAe;AAC1C,UAAM,SAAS,2BAA2B,EAAE,MAAM,CAAC;AAAA,EACrD;AACF;;;ACPO,IAAM,0BAAN,cAAsC,YAAY;AAAA,EACvD,YAAY,SAAiB;AAC3B,UAAM,SAAS,sBAAsB;AAAA,EACvC;AACF;;;ACNA,kBAAmB;AACnB,iBAAc;AAQP,IAAM,eAAN,MAAM,qBAAoB,YAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAUnD,IAAW,OAAe;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAc,OAAO,OAA4B;AAC/C,WAAO,IAAI,aAAY,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,WAAwB;AACpC,WAAO,IAAI,iBAAY,gBAAG,CAAC;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAmB;AACxB,WAAO,CAAC,KAAK;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAmB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,SAAS,OAAqB;AACtC,UAAM,SAAS,aAAY,OAAO,UAAU,KAAK;AAEjD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI;AAAA,QACR,wBAAwB,OAAO,MAAM,OAAO;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AACF;AAAA;AAAA;AAAA;AA5Da,aAIa,SAAS,WAAAC,QAAE,KAAK;AAJnC,IAAM,cAAN;;;ACEA,IAAM,aAAa,OAAO,OAAO;AAAA,EACtC,iCAAiC;AAAA,EACjC,iCAAiC;AAAA,EACjC,+BAA+B;AAAA,EAC/B,+BAA+B;AAAA,EAE/B,+BAA+B;AAAA,EAC/B,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EAEtB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EAEpB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,WAAW;AAAA,EAEX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AACN,CAAU;AAMH,IAAM,oBAAoB;AAAA,EAC/B,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;;;AC/GO,IAAe,mBAAf,cAAwC,MAAM;AAAA,EAYnD,YAAY;AAAA,IACV,OAAO,kBAAkB,KAAK;AAAA,IAC9B,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAgB;AACd,UAAM,OAAO;AAEb,SAAK,OAAO,WAAW;AACvB,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,QAAQ;AAEb,UAAM,kBAAkB,MAAM,UAAU;AAAA,EAC1C;AACF;;;ACpDO,SAAS,kBACd,OACA,OAAO,oBAAI,QAAQ,GACG;AACtB,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,KAAK,IAAI,KAAK,GAAG;AAEnB,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AAEA,OAAK,IAAI,KAAK;AAEd,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAMC,UAAS,MAAM,IAAI,UAAQ,kBAAkB,MAAM,IAAI,CAAC;AAC9D,SAAK,OAAO,KAAK;AACjB,WAAOA;AAAA,EACT;AAEA,MAAI,iBAAiB,aAAa;AAChC,UAAMA,UAAS,kBAAkB,MAAM,OAAO,IAAI;AAClD,SAAK,OAAO,KAAK;AACjB,WAAOA;AAAA,EACT;AAEA,MAAI,iBAAiB,MAAM;AACzB,SAAK,OAAO,KAAK;AACjB,WAAO,MAAM,YAAY;AAAA,EAC3B;AAEA,MAAI,iBAAiB,KAAK;AACxB,UAAMA,UAAS,oBAAI,IAAI;AACvB,UAAM,QAAQ,CAAC,OAAO,QAAQ;AAC5B,MAAAA,QAAO,IAAI,KAAK,kBAAkB,OAAO,IAAI,CAAC;AAAA,IAChD,CAAC;AACD,SAAK,OAAO,KAAK;AACjB,WAAOA;AAAA,EACT;AAEA,MAAI,iBAAiB,KAAK;AACxB,UAAMA,UAAS,IAAI;AAAA,MACjB,MAAM,KAAK,MAAM,OAAO,CAAC,EAAE,IAAI,OAAK,kBAAkB,GAAG,IAAI,CAAC;AAAA,IAChE;AACA,SAAK,OAAO,KAAK;AACjB,WAAOA;AAAA,EACT;AAGA,QAAM,SAAkC,CAAC;AAEzC,aAAW,OAAO,OAAO;AACvB,QAAI,OAAO,OAAO,OAAO,GAAG,GAAG;AAC7B,aAAO,GAAG,IAAI,kBAAmB,MAAc,GAAG,GAAG,IAAI;AAAA,IAC3D;AAAA,EACF;AAEA,OAAK,OAAO,KAAK;AACjB,SAAO;AACT;AAEO,SAAS,aAAgB,OAAqC;AACnE,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO,CAAC;AAAA,EACV;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAGA,SAAO,EAAE,OAAO,MAAM;AACxB;","names":["deepEqual","z","result"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/domain/base/domain.error.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["export * from './application';\nexport * from './domain/base/domain.error';\nexport * from './domain/base/vo';\nexport * from './domain/errors/entity-validation.error';\nexport * from './domain/errors/invalid-vo.error';\nexport * from './domain/value-objects/aggregate-id.vo';\nexport * from './gateway/constants/http-code';\nexport * from './utils';\n","export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (\n !other ||\n !(other instanceof (this.constructor as typeof ValueObject))\n ) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.\n *\n * @param obj - The object to be deeply frozen.\n * @param seen - A WeakSet to track already processed objects (for circular references).\n * @returns A deeply frozen version of the input object.\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { ValueObject } from '../base/vo';\n\n/**\n * AggregateId is a ValueObject that represents a unique identifier for an aggregate.\n */\nexport class AggregateId extends ValueObject<string> {\n /**\n * The schema for the AggregateId\n */\n private static readonly schema = z.uuid();\n\n /**\n * Get the UUID of the AggregateId\n * @returns The UUID of the AggregateId\n */\n public get uuid(): string {\n return this.value;\n }\n\n /**\n * Create a new AggregateId\n * @param value The value to create the AggregateId from\n * @returns The new AggregateId\n */\n public static create(value: string): AggregateId {\n return new AggregateId(value);\n }\n\n /**\n * Create a new AggregateId with a random UUID v4\n */\n public static generate(): AggregateId {\n return new AggregateId(v4());\n }\n\n /**\n * Check if the AggregateId is empty\n * @returns True if the AggregateId is empty, false otherwise\n */\n public isEmpty(): boolean {\n return !this.value;\n }\n\n /**\n * Convert the AggregateId to a string\n * @returns The string representation of the AggregateId\n */\n public toString(): string {\n return this.value;\n }\n\n /**\n * Validate the AggregateId\n * @param value The value to validate\n * @throws InvalidValueObjectException if the value is invalid\n */\n protected validate(value: string): void {\n const result = AggregateId.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid AggregateId: ${result.error.message}`,\n );\n }\n }\n}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n * Usage:\n * ```ts\n * import { HttpStatus } from 'path-to-this-file';\n *\n * function handleRequest() {\n * return {\n * statusCode: HttpStatus.OK,\n * body: 'Success',\n * };\n * }\n * ```\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":"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","names":["index_exports","__export","AggregateId","ApplicationError","DomainError","EntityValidationError","HttpStatus","HttpStatusMessage","InvalidValueObjectError","ValueObject","deepFreeze","ensureObject","unwrapValueObject","__toCommonJS","getCauseInfo","cause","DomainError","message","code","metadata","__spreadValues","import_es6","deepFreeze","obj","seen","item","key","ValueObject","_ValueObject","props","deepFreeze","vo","other","deepEqual","EntityValidationError","DomainError","message","cause","InvalidValueObjectError","DomainError","message","import_uuid","import_zod","_AggregateId","ValueObject","value","result","InvalidValueObjectError","z","AggregateId","HttpStatus","HttpStatusMessage","ApplicationError","code","HttpStatusMessage","isOperational","status","metadata","message","cause","unwrapValueObject","input","seen","result","item","ValueObject","value","key","v","ensureObject"]}
package/dist/index.mjs CHANGED
@@ -1,404 +1,2 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
- var __hasOwnProp = Object.prototype.hasOwnProperty;
4
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __spreadValues = (a, b) => {
7
- for (var prop in b || (b = {}))
8
- if (__hasOwnProp.call(b, prop))
9
- __defNormalProp(a, prop, b[prop]);
10
- if (__getOwnPropSymbols)
11
- for (var prop of __getOwnPropSymbols(b)) {
12
- if (__propIsEnum.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- }
15
- return a;
16
- };
17
-
18
- // src/domain/base/domain.error.ts
19
- var getCauseInfo = (cause) => {
20
- if (cause instanceof Error) {
21
- return {
22
- cause: {
23
- message: cause.message,
24
- stack: cause.stack,
25
- name: cause.name
26
- }
27
- };
28
- }
29
- if (cause) {
30
- return { cause };
31
- }
32
- return {};
33
- };
34
- var DomainError = class extends Error {
35
- /**
36
- * @param message - Human-readable error message
37
- * @param code - Stable error code
38
- * @param metadata - Domain-specific structured data; optional `cause` can be included
39
- */
40
- constructor(message, code, metadata = {}) {
41
- super(message, __spreadValues({}, getCauseInfo(metadata.cause)));
42
- Object.setPrototypeOf(this, new.target.prototype);
43
- this.name = new.target.name;
44
- this.code = code;
45
- this.metadata = Object.freeze(__spreadValues({}, metadata));
46
- }
47
- };
48
-
49
- // src/domain/base/vo.ts
50
- import deepEqual from "fast-deep-equal/es6";
51
-
52
- // src/utils/deep-freeze.util.ts
53
- function deepFreeze(obj, seen = /* @__PURE__ */ new WeakSet()) {
54
- if (obj == null || typeof obj !== "object" && !Array.isArray(obj)) {
55
- return obj;
56
- }
57
- if (Object.isFrozen(obj)) {
58
- return obj;
59
- }
60
- if (seen.has(obj)) {
61
- return obj;
62
- }
63
- seen.add(obj);
64
- if (Array.isArray(obj)) {
65
- obj.forEach((item) => deepFreeze(item, seen));
66
- } else {
67
- for (const key in obj) {
68
- if (Object.hasOwn(obj, key)) {
69
- deepFreeze(obj[key], seen);
70
- }
71
- }
72
- }
73
- return Object.freeze(obj);
74
- }
75
-
76
- // src/domain/base/vo.ts
77
- var ValueObject = class _ValueObject {
78
- get value() {
79
- return this.props;
80
- }
81
- constructor(props) {
82
- this.validate(props);
83
- this.props = deepFreeze(props);
84
- }
85
- /**
86
- * Type guard to check if an unknown object is an instance of ValueObject.
87
- * This is useful for runtime type checking.
88
- *
89
- * @param vo The object to check.
90
- * @returns True if the object is a ValueObject instance, false otherwise.
91
- */
92
- static is(vo) {
93
- return vo instanceof _ValueObject;
94
- }
95
- /**
96
- * Deep equality comparison of ValueObjects
97
- */
98
- equals(other) {
99
- if (!other || !(other instanceof this.constructor)) {
100
- return false;
101
- }
102
- return deepEqual(this.props, other.props);
103
- }
104
- };
105
-
106
- // src/domain/errors/entity-validation.error.ts
107
- var EntityValidationError = class extends DomainError {
108
- constructor(message, cause) {
109
- super(message, "ENTITY_VALIDATION_ERROR", { cause });
110
- }
111
- };
112
-
113
- // src/domain/errors/invalid-vo.error.ts
114
- var InvalidValueObjectError = class extends DomainError {
115
- constructor(message) {
116
- super(message, "INVALID_VALUE_OBJECT");
117
- }
118
- };
119
-
120
- // src/domain/value-objects/aggregate-id.vo.ts
121
- import { v4 } from "uuid";
122
- import z from "zod";
123
- var _AggregateId = class _AggregateId extends ValueObject {
124
- /**
125
- * Get the UUID of the AggregateId
126
- * @returns The UUID of the AggregateId
127
- */
128
- get uuid() {
129
- return this.value;
130
- }
131
- /**
132
- * Create a new AggregateId
133
- * @param value The value to create the AggregateId from
134
- * @returns The new AggregateId
135
- */
136
- static create(value) {
137
- return new _AggregateId(value);
138
- }
139
- /**
140
- * Create a new AggregateId with a random UUID v4
141
- */
142
- static generate() {
143
- return new _AggregateId(v4());
144
- }
145
- /**
146
- * Check if the AggregateId is empty
147
- * @returns True if the AggregateId is empty, false otherwise
148
- */
149
- isEmpty() {
150
- return !this.value;
151
- }
152
- /**
153
- * Convert the AggregateId to a string
154
- * @returns The string representation of the AggregateId
155
- */
156
- toString() {
157
- return this.value;
158
- }
159
- /**
160
- * Validate the AggregateId
161
- * @param value The value to validate
162
- * @throws InvalidValueObjectException if the value is invalid
163
- */
164
- validate(value) {
165
- const result = _AggregateId.schema.safeParse(value);
166
- if (!result.success) {
167
- throw new InvalidValueObjectError(
168
- `Invalid AggregateId: ${result.error.message}`
169
- );
170
- }
171
- }
172
- };
173
- /**
174
- * The schema for the AggregateId
175
- */
176
- _AggregateId.schema = z.uuid();
177
- var AggregateId = _AggregateId;
178
-
179
- // src/gateway/constants/http-code.ts
180
- var HttpStatus = Object.freeze({
181
- REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
182
- NETWORK_AUTHENTICATION_REQUIRED: 511,
183
- NON_AUTHORITATIVE_INFORMATION: 203,
184
- PROXY_AUTHENTICATION_REQUIRED: 407,
185
- UNAVAILABLE_FOR_LEGAL_REASONS: 451,
186
- HTTP_VERSION_NOT_SUPPORTED: 505,
187
- BANDWIDTH_LIMIT_EXCEEDED: 509,
188
- VARIANT_ALSO_NEGOTIATES: 506,
189
- UNSUPPORTED_MEDIA_TYPE: 415,
190
- RANGE_NOT_SATISFIABLE: 416,
191
- PRECONDITION_REQUIRED: 428,
192
- INTERNAL_SERVER_ERROR: 500,
193
- UNPROCESSABLE_ENTITY: 422,
194
- INSUFFICIENT_STORAGE: 507,
195
- SWITCHING_PROTOCOLS: 101,
196
- PRECONDITION_FAILED: 412,
197
- MISDIRECTED_REQUEST: 421,
198
- SERVICE_UNAVAILABLE: 503,
199
- TEMPORARY_REDIRECT: 307,
200
- PERMANENT_REDIRECT: 308,
201
- METHOD_NOT_ALLOWED: 405,
202
- EXPECTATION_FAILED: 417,
203
- MOVED_PERMANENTLY: 301,
204
- PAYLOAD_TOO_LARGE: 413,
205
- FAILED_DEPENDENCY: 424,
206
- TOO_MANY_REQUESTS: 429,
207
- ALREADY_REPORTED: 208,
208
- MULTIPLE_CHOICES: 300,
209
- PAYMENT_REQUIRED: 402,
210
- UPGRADE_REQUIRED: 426,
211
- PARTIAL_CONTENT: 206,
212
- REQUEST_TIMEOUT: 408,
213
- LENGTH_REQUIRED: 411,
214
- NOT_IMPLEMENTED: 501,
215
- GATEWAY_TIMEOUT: 504,
216
- NOT_ACCEPTABLE: 406,
217
- RESET_CONTENT: 205,
218
- LOOP_DETECTED: 508,
219
- MULTI_STATUS: 207,
220
- NOT_MODIFIED: 304,
221
- UNAUTHORIZED: 401,
222
- URI_TOO_LONG: 414,
223
- NOT_EXTENDED: 510,
224
- EARLY_HINTS: 103,
225
- BAD_REQUEST: 400,
226
- IM_A_TEAPOT: 418,
227
- BAD_GATEWAY: 502,
228
- PROCESSING: 102,
229
- NO_CONTENT: 204,
230
- SEE_OTHER: 303,
231
- USE_PROXY: 305,
232
- FORBIDDEN: 403,
233
- NOT_FOUND: 404,
234
- TOO_EARLY: 425,
235
- CONTINUE: 100,
236
- ACCEPTED: 202,
237
- CONFLICT: 409,
238
- CREATED: 201,
239
- IM_USED: 226,
240
- LOCKED: 423,
241
- FOUND: 302,
242
- GONE: 410,
243
- OK: 200
244
- });
245
- var HttpStatusMessage = {
246
- 431: "Request Header Fields Too Large",
247
- 511: "Network Authentication Required",
248
- 203: "Non-Authoritative Information",
249
- 407: "Proxy Authentication Required",
250
- 451: "Unavailable For Legal Reasons",
251
- 505: "HTTP Version Not Supported",
252
- 509: "Bandwidth Limit Exceeded",
253
- 506: "Variant Also Negotiates",
254
- 415: "Unsupported Media Type",
255
- 416: "Range Not Satisfiable",
256
- 428: "Precondition Required",
257
- 500: "Internal Server Error",
258
- 422: "Unprocessable Entity",
259
- 507: "Insufficient Storage",
260
- 101: "Switching Protocols",
261
- 412: "Precondition Failed",
262
- 421: "Misdirected Request",
263
- 503: "Service Unavailable",
264
- 307: "Temporary Redirect",
265
- 308: "Permanent Redirect",
266
- 405: "Method Not Allowed",
267
- 417: "Expectation Failed",
268
- 301: "Moved Permanently",
269
- 413: "Payload Too Large",
270
- 424: "Failed Dependency",
271
- 429: "Too Many Requests",
272
- 208: "Already Reported",
273
- 300: "Multiple Choices",
274
- 402: "Payment Required",
275
- 426: "Upgrade Required",
276
- 206: "Partial Content",
277
- 408: "Request Timeout",
278
- 411: "Length Required",
279
- 501: "Not Implemented",
280
- 504: "Gateway Timeout",
281
- 406: "Not Acceptable",
282
- 205: "Reset Content",
283
- 508: "Loop Detected",
284
- 207: "Multi-Status",
285
- 304: "Not Modified",
286
- 401: "Unauthorized",
287
- 414: "URI Too Long",
288
- 418: "I'm a Teapot",
289
- 510: "Not Extended",
290
- 103: "Early Hints",
291
- 400: "Bad Request",
292
- 502: "Bad Gateway",
293
- 102: "Processing",
294
- 204: "No Content",
295
- 303: "See Other",
296
- 305: "Use Proxy",
297
- 403: "Forbidden",
298
- 404: "Not Found",
299
- 425: "Too Early",
300
- 100: "Continue",
301
- 202: "Accepted",
302
- 226: "I'm Used",
303
- 409: "Conflict",
304
- 201: "Created",
305
- 423: "Locked",
306
- 302: "Found",
307
- 410: "Gone",
308
- 200: "OK"
309
- };
310
-
311
- // src/utils/errors/application.error.ts
312
- var ApplicationError = class extends Error {
313
- constructor({
314
- code = HttpStatusMessage["500"],
315
- isOperational = false,
316
- status = 500,
317
- metadata,
318
- message,
319
- cause
320
- }) {
321
- super(message);
322
- this.name = new.target.name;
323
- this.code = code;
324
- this.status = status;
325
- this.isOperational = isOperational;
326
- this.metadata = metadata;
327
- this.cause = cause;
328
- Error.captureStackTrace(this, new.target);
329
- }
330
- };
331
-
332
- // src/utils/unwrap-vo.util.ts
333
- function unwrapValueObject(input, seen = /* @__PURE__ */ new WeakSet()) {
334
- if (input === null || input === void 0) {
335
- return input;
336
- }
337
- if (typeof input !== "object") {
338
- return input;
339
- }
340
- if (seen.has(input)) {
341
- throw new Error("Circular reference detected in ValueObject unwrap");
342
- }
343
- seen.add(input);
344
- if (Array.isArray(input)) {
345
- const result2 = input.map((item) => unwrapValueObject(item, seen));
346
- seen.delete(input);
347
- return result2;
348
- }
349
- if (input instanceof ValueObject) {
350
- const result2 = unwrapValueObject(input.value, seen);
351
- seen.delete(input);
352
- return result2;
353
- }
354
- if (input instanceof Date) {
355
- seen.delete(input);
356
- return input.toISOString();
357
- }
358
- if (input instanceof Map) {
359
- const result2 = /* @__PURE__ */ new Map();
360
- input.forEach((value, key) => {
361
- result2.set(key, unwrapValueObject(value, seen));
362
- });
363
- seen.delete(input);
364
- return result2;
365
- }
366
- if (input instanceof Set) {
367
- const result2 = new Set(
368
- Array.from(input.values()).map((v) => unwrapValueObject(v, seen))
369
- );
370
- seen.delete(input);
371
- return result2;
372
- }
373
- const result = {};
374
- for (const key in input) {
375
- if (Object.hasOwn(input, key)) {
376
- result[key] = unwrapValueObject(input[key], seen);
377
- }
378
- }
379
- seen.delete(input);
380
- return result;
381
- }
382
- function ensureObject(input) {
383
- if (input === null || input === void 0) {
384
- return {};
385
- }
386
- if (typeof input === "object") {
387
- return input;
388
- }
389
- return { value: input };
390
- }
391
- export {
392
- AggregateId,
393
- ApplicationError,
394
- DomainError,
395
- EntityValidationError,
396
- HttpStatus,
397
- HttpStatusMessage,
398
- InvalidValueObjectError,
399
- ValueObject,
400
- deepFreeze,
401
- ensureObject,
402
- unwrapValueObject
403
- };
1
+ var I=Object.defineProperty;var l=Object.getOwnPropertySymbols;var _=Object.prototype.hasOwnProperty,m=Object.prototype.propertyIsEnumerable;var O=(e,t,r)=>t in e?I(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,u=(e,t)=>{for(var r in t||(t={}))_.call(t,r)&&O(e,r,t[r]);if(l)for(var r of l(t))m.call(t,r)&&O(e,r,t[r]);return e};var S=e=>e instanceof Error?{cause:{message:e.message,stack:e.stack,name:e.name}}:e?{cause:e}:{},n=class extends Error{constructor(t,r,a={}){super(t,u({},S(a.cause))),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name,this.code=r,this.metadata=Object.freeze(u({},a))}};import U from"fast-deep-equal/es6";function E(e,t=new WeakSet){if(e==null||typeof e!="object"&&!Array.isArray(e)||Object.isFrozen(e)||t.has(e))return e;if(t.add(e),Array.isArray(e))e.forEach(r=>E(r,t));else for(let r in e)Object.hasOwn(e,r)&&E(e[r],t);return Object.freeze(e)}var s=class e{get value(){return this.props}constructor(t){this.validate(t),this.props=E(t)}static is(t){return t instanceof e}equals(t){return!t||!(t instanceof this.constructor)?!1:U(this.props,t.props)}};var p=class extends n{constructor(t,r){super(t,"ENTITY_VALIDATION_ERROR",{cause:r})}};var T=class extends n{constructor(t){super(t,"INVALID_VALUE_OBJECT")}};import{v4 as D}from"uuid";import g from"zod";var i=class i extends s{get uuid(){return this.value}static create(t){return new i(t)}static generate(){return new i(D())}isEmpty(){return!this.value}toString(){return this.value}validate(t){let r=i.schema.safeParse(t);if(!r.success)throw new T(`Invalid AggregateId: ${r.error.message}`)}};i.schema=g.uuid();var R=i;var Y=Object.freeze({REQUEST_HEADER_FIELDS_TOO_LARGE:431,NETWORK_AUTHENTICATION_REQUIRED:511,NON_AUTHORITATIVE_INFORMATION:203,PROXY_AUTHENTICATION_REQUIRED:407,UNAVAILABLE_FOR_LEGAL_REASONS:451,HTTP_VERSION_NOT_SUPPORTED:505,BANDWIDTH_LIMIT_EXCEEDED:509,VARIANT_ALSO_NEGOTIATES:506,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,PRECONDITION_REQUIRED:428,INTERNAL_SERVER_ERROR:500,UNPROCESSABLE_ENTITY:422,INSUFFICIENT_STORAGE:507,SWITCHING_PROTOCOLS:101,PRECONDITION_FAILED:412,MISDIRECTED_REQUEST:421,SERVICE_UNAVAILABLE:503,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,METHOD_NOT_ALLOWED:405,EXPECTATION_FAILED:417,MOVED_PERMANENTLY:301,PAYLOAD_TOO_LARGE:413,FAILED_DEPENDENCY:424,TOO_MANY_REQUESTS:429,ALREADY_REPORTED:208,MULTIPLE_CHOICES:300,PAYMENT_REQUIRED:402,UPGRADE_REQUIRED:426,PARTIAL_CONTENT:206,REQUEST_TIMEOUT:408,LENGTH_REQUIRED:411,NOT_IMPLEMENTED:501,GATEWAY_TIMEOUT:504,NOT_ACCEPTABLE:406,RESET_CONTENT:205,LOOP_DETECTED:508,MULTI_STATUS:207,NOT_MODIFIED:304,UNAUTHORIZED:401,URI_TOO_LONG:414,NOT_EXTENDED:510,EARLY_HINTS:103,BAD_REQUEST:400,IM_A_TEAPOT:418,BAD_GATEWAY:502,PROCESSING:102,NO_CONTENT:204,SEE_OTHER:303,USE_PROXY:305,FORBIDDEN:403,NOT_FOUND:404,TOO_EARLY:425,CONTINUE:100,ACCEPTED:202,CONFLICT:409,CREATED:201,IM_USED:226,LOCKED:423,FOUND:302,GONE:410,OK:200}),f={431:"Request Header Fields Too Large",511:"Network Authentication Required",203:"Non-Authoritative Information",407:"Proxy Authentication Required",451:"Unavailable For Legal Reasons",505:"HTTP Version Not Supported",509:"Bandwidth Limit Exceeded",506:"Variant Also Negotiates",415:"Unsupported Media Type",416:"Range Not Satisfiable",428:"Precondition Required",500:"Internal Server Error",422:"Unprocessable Entity",507:"Insufficient Storage",101:"Switching Protocols",412:"Precondition Failed",421:"Misdirected Request",503:"Service Unavailable",307:"Temporary Redirect",308:"Permanent Redirect",405:"Method Not Allowed",417:"Expectation Failed",301:"Moved Permanently",413:"Payload Too Large",424:"Failed Dependency",429:"Too Many Requests",208:"Already Reported",300:"Multiple Choices",402:"Payment Required",426:"Upgrade Required",206:"Partial Content",408:"Request Timeout",411:"Length Required",501:"Not Implemented",504:"Gateway Timeout",406:"Not Acceptable",205:"Reset Content",508:"Loop Detected",207:"Multi-Status",304:"Not Modified",401:"Unauthorized",414:"URI Too Long",418:"I'm a Teapot",510:"Not Extended",103:"Early Hints",400:"Bad Request",502:"Bad Gateway",102:"Processing",204:"No Content",303:"See Other",305:"Use Proxy",403:"Forbidden",404:"Not Found",425:"Too Early",100:"Continue",202:"Accepted",226:"I'm Used",409:"Conflict",201:"Created",423:"Locked",302:"Found",410:"Gone",200:"OK"};var A=class extends Error{constructor({code:t=f[500],isOperational:r=!1,status:a=500,metadata:o,message:d,cause:N}){super(d),this.name=new.target.name,this.code=t,this.status=a,this.isOperational=r,this.metadata=o,this.cause=N,Error.captureStackTrace(this,new.target)}};function c(e,t=new WeakSet){if(e==null||typeof e!="object")return e;if(t.has(e))throw new Error("Circular reference detected in ValueObject unwrap");if(t.add(e),Array.isArray(e)){let a=e.map(o=>c(o,t));return t.delete(e),a}if(e instanceof s){let a=c(e.value,t);return t.delete(e),a}if(e instanceof Date)return t.delete(e),e.toISOString();if(e instanceof Map){let a=new Map;return e.forEach((o,d)=>{a.set(d,c(o,t))}),t.delete(e),a}if(e instanceof Set){let a=new Set(Array.from(e.values()).map(o=>c(o,t)));return t.delete(e),a}let r={};for(let a in e)Object.hasOwn(e,a)&&(r[a]=c(e[a],t));return t.delete(e),r}function W(e){return e==null?{}:typeof e=="object"?e:{value:e}}export{R as AggregateId,A as ApplicationError,n as DomainError,p as EntityValidationError,Y as HttpStatus,f as HttpStatusMessage,T as InvalidValueObjectError,s as ValueObject,E as deepFreeze,W as ensureObject,c as unwrapValueObject};
404
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/domain/base/domain.error.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (\n !other ||\n !(other instanceof (this.constructor as typeof ValueObject))\n ) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as any)[key], seen); // Use 'any' here as T[key] might not be assignable to T for deepFreeze's input\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { ValueObject } from '../base/vo';\n\n/**\n * AggregateId is a ValueObject that represents a unique identifier for an aggregate.\n */\nexport class AggregateId extends ValueObject<string> {\n /**\n * The schema for the AggregateId\n */\n private static readonly schema = z.uuid();\n\n /**\n * Get the UUID of the AggregateId\n * @returns The UUID of the AggregateId\n */\n public get uuid(): string {\n return this.value;\n }\n\n /**\n * Create a new AggregateId\n * @param value The value to create the AggregateId from\n * @returns The new AggregateId\n */\n public static create(value: string): AggregateId {\n return new AggregateId(value);\n }\n\n /**\n * Create a new AggregateId with a random UUID v4\n */\n public static generate(): AggregateId {\n return new AggregateId(v4());\n }\n\n /**\n * Check if the AggregateId is empty\n * @returns True if the AggregateId is empty, false otherwise\n */\n public isEmpty(): boolean {\n return !this.value;\n }\n\n /**\n * Convert the AggregateId to a string\n * @returns The string representation of the AggregateId\n */\n public toString(): string {\n return this.value;\n }\n\n /**\n * Validate the AggregateId\n * @param value The value to validate\n * @throws InvalidValueObjectException if the value is invalid\n */\n protected validate(value: string): void {\n const result = AggregateId.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid AggregateId: ${result.error.message}`,\n );\n }\n }\n}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../src/domain/base/domain.error.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (\n !other ||\n !(other instanceof (this.constructor as typeof ValueObject))\n ) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.\n *\n * @param obj - The object to be deeply frozen.\n * @param seen - A WeakSet to track already processed objects (for circular references).\n * @returns A deeply frozen version of the input object.\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { ValueObject } from '../base/vo';\n\n/**\n * AggregateId is a ValueObject that represents a unique identifier for an aggregate.\n */\nexport class AggregateId extends ValueObject<string> {\n /**\n * The schema for the AggregateId\n */\n private static readonly schema = z.uuid();\n\n /**\n * Get the UUID of the AggregateId\n * @returns The UUID of the AggregateId\n */\n public get uuid(): string {\n return this.value;\n }\n\n /**\n * Create a new AggregateId\n * @param value The value to create the AggregateId from\n * @returns The new AggregateId\n */\n public static create(value: string): AggregateId {\n return new AggregateId(value);\n }\n\n /**\n * Create a new AggregateId with a random UUID v4\n */\n public static generate(): AggregateId {\n return new AggregateId(v4());\n }\n\n /**\n * Check if the AggregateId is empty\n * @returns True if the AggregateId is empty, false otherwise\n */\n public isEmpty(): boolean {\n return !this.value;\n }\n\n /**\n * Convert the AggregateId to a string\n * @returns The string representation of the AggregateId\n */\n public toString(): string {\n return this.value;\n }\n\n /**\n * Validate the AggregateId\n * @param value The value to validate\n * @throws InvalidValueObjectException if the value is invalid\n */\n protected validate(value: string): void {\n const result = AggregateId.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid AggregateId: ${result.error.message}`,\n );\n }\n }\n}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n * Usage:\n * ```ts\n * import { HttpStatus } from 'path-to-this-file';\n *\n * function handleRequest() {\n * return {\n * statusCode: HttpStatus.OK,\n * body: 'Success',\n * };\n * }\n * ```\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":"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","names":["getCauseInfo","cause","DomainError","message","code","metadata","__spreadValues","deepEqual","deepFreeze","obj","seen","item","key","ValueObject","_ValueObject","props","deepFreeze","vo","other","deepEqual","EntityValidationError","DomainError","message","cause","InvalidValueObjectError","DomainError","message","v4","z","_AggregateId","ValueObject","value","v4","result","InvalidValueObjectError","z","AggregateId","HttpStatus","HttpStatusMessage","ApplicationError","code","HttpStatusMessage","isOperational","status","metadata","message","cause","unwrapValueObject","input","seen","result","item","ValueObject","value","key","v","ensureObject"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rineex/ddd",
3
- "version": "0.0.0",
3
+ "version": "1.0.0",
4
4
  "description": "Domain Driven Design package for Rineex core modules",
5
5
  "author": "Rineex Team",
6
6
  "main": "./dist/index.js",
@@ -9,6 +9,7 @@
9
9
  "files": [
10
10
  "dist/**"
11
11
  ],
12
+ "sideEffects": false,
12
13
  "devDependencies": {
13
14
  "@changesets/cli": "2.29.8",
14
15
  "@types/node": "24.10.4",
@@ -29,12 +30,11 @@
29
30
  "keywords": [
30
31
  "rineex",
31
32
  "ddd",
32
- "domain-driven-design",
33
- "typescript",
34
- "package"
33
+ "domain-driven-design"
35
34
  ],
36
35
  "license": "Apache-2.0",
37
36
  "publishConfig": {
37
+ "provenance": true,
38
38
  "access": "public",
39
39
  "registry": "https://registry.npmjs.org"
40
40
  },
@@ -43,7 +43,7 @@
43
43
  "url": "https://github.com/rineex/core.git",
44
44
  "directory": "packages/ddd"
45
45
  },
46
- "peerDependencies": {
46
+ "dependencies": {
47
47
  "fast-deep-equal": "3.1.3",
48
48
  "isbot": "5.1.32",
49
49
  "ua-parser-js": "2.0.7",
@@ -54,6 +54,6 @@
54
54
  "test": "vitest run",
55
55
  "lint": "eslint 'src/**/*.ts'",
56
56
  "check-types": "tsc --noEmit",
57
- "build": "tsup --format cjs,esm --dts --tsconfig ./tsconfig.build.json"
57
+ "build": "tsup"
58
58
  }
59
59
  }