@woltz/rich-domain 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/.github/workflows/ci.yml +40 -0
  2. package/.husky/commit-msg +1 -0
  3. package/.husky/pre-commit +1 -0
  4. package/.versionrc.json +21 -0
  5. package/.vscode/settings.json +3 -0
  6. package/CHANGELOG.md +81 -0
  7. package/LICENSE +21 -0
  8. package/README.md +712 -0
  9. package/commitlint.config.js +23 -0
  10. package/dist/base-entity.d.ts +67 -0
  11. package/dist/base-entity.d.ts.map +1 -0
  12. package/dist/base-entity.js +309 -0
  13. package/dist/base-entity.js.map +1 -0
  14. package/dist/constants.d.ts +3 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +6 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/criteria.d.ts +60 -0
  19. package/dist/criteria.d.ts.map +1 -0
  20. package/dist/criteria.js +214 -0
  21. package/dist/criteria.js.map +1 -0
  22. package/dist/deep-proxy.d.ts +34 -0
  23. package/dist/deep-proxy.d.ts.map +1 -0
  24. package/dist/deep-proxy.js +297 -0
  25. package/dist/deep-proxy.js.map +1 -0
  26. package/dist/domain-event-bus.d.ts +57 -0
  27. package/dist/domain-event-bus.d.ts.map +1 -0
  28. package/dist/domain-event-bus.js +112 -0
  29. package/dist/domain-event-bus.js.map +1 -0
  30. package/dist/domain-event.d.ts +55 -0
  31. package/dist/domain-event.d.ts.map +1 -0
  32. package/dist/domain-event.js +42 -0
  33. package/dist/domain-event.js.map +1 -0
  34. package/dist/entity.d.ts +13 -0
  35. package/dist/entity.d.ts.map +1 -0
  36. package/dist/entity.js +15 -0
  37. package/dist/entity.js.map +1 -0
  38. package/dist/filtering.d.ts +107 -0
  39. package/dist/filtering.d.ts.map +1 -0
  40. package/dist/filtering.js +202 -0
  41. package/dist/filtering.js.map +1 -0
  42. package/dist/id.d.ts +51 -0
  43. package/dist/id.d.ts.map +1 -0
  44. package/dist/id.js +84 -0
  45. package/dist/id.js.map +1 -0
  46. package/dist/index.d.ts +15 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +25 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/ordering.d.ts +93 -0
  51. package/dist/ordering.d.ts.map +1 -0
  52. package/dist/ordering.js +154 -0
  53. package/dist/ordering.js.map +1 -0
  54. package/dist/paginated-result.d.ts +62 -0
  55. package/dist/paginated-result.d.ts.map +1 -0
  56. package/dist/paginated-result.js +201 -0
  57. package/dist/paginated-result.js.map +1 -0
  58. package/dist/pagination.d.ts +218 -0
  59. package/dist/pagination.d.ts.map +1 -0
  60. package/dist/pagination.js +281 -0
  61. package/dist/pagination.js.map +1 -0
  62. package/dist/repository/base-repository.d.ts +77 -0
  63. package/dist/repository/base-repository.d.ts.map +1 -0
  64. package/dist/repository/base-repository.js +80 -0
  65. package/dist/repository/base-repository.js.map +1 -0
  66. package/dist/repository/in-memory-repository.d.ts +46 -0
  67. package/dist/repository/in-memory-repository.d.ts.map +1 -0
  68. package/dist/repository/in-memory-repository.js +85 -0
  69. package/dist/repository/in-memory-repository.js.map +1 -0
  70. package/dist/repository/index.d.ts +42 -0
  71. package/dist/repository/index.d.ts.map +1 -0
  72. package/dist/repository/index.js +47 -0
  73. package/dist/repository/index.js.map +1 -0
  74. package/dist/repository/mapper.d.ts +56 -0
  75. package/dist/repository/mapper.d.ts.map +1 -0
  76. package/dist/repository/mapper.js +15 -0
  77. package/dist/repository/mapper.js.map +1 -0
  78. package/dist/repository/types.d.ts +87 -0
  79. package/dist/repository/types.d.ts.map +1 -0
  80. package/dist/repository/types.js +6 -0
  81. package/dist/repository/types.js.map +1 -0
  82. package/dist/repository/unit-of-work.d.ts +70 -0
  83. package/dist/repository/unit-of-work.d.ts.map +1 -0
  84. package/dist/repository/unit-of-work.js +122 -0
  85. package/dist/repository/unit-of-work.js.map +1 -0
  86. package/dist/repository.d.ts +2 -0
  87. package/dist/repository.d.ts.map +1 -0
  88. package/dist/repository.js +21 -0
  89. package/dist/repository.js.map +1 -0
  90. package/dist/specification.d.ts +102 -0
  91. package/dist/specification.d.ts.map +1 -0
  92. package/dist/specification.js +187 -0
  93. package/dist/specification.js.map +1 -0
  94. package/dist/types/criteria.d.ts +35 -0
  95. package/dist/types/criteria.d.ts.map +1 -0
  96. package/dist/types/criteria.js +17 -0
  97. package/dist/types/criteria.js.map +1 -0
  98. package/dist/types/domain.d.ts +30 -0
  99. package/dist/types/domain.d.ts.map +1 -0
  100. package/dist/types/domain.js +2 -0
  101. package/dist/types/domain.js.map +1 -0
  102. package/dist/types/history-tracker.d.ts +36 -0
  103. package/dist/types/history-tracker.d.ts.map +1 -0
  104. package/dist/types/history-tracker.js +2 -0
  105. package/dist/types/history-tracker.js.map +1 -0
  106. package/dist/types/index.d.ts +8 -0
  107. package/dist/types/index.d.ts.map +1 -0
  108. package/dist/types/index.js +8 -0
  109. package/dist/types/index.js.map +1 -0
  110. package/dist/types/repository.d.ts +43 -0
  111. package/dist/types/repository.d.ts.map +1 -0
  112. package/dist/types/repository.js +2 -0
  113. package/dist/types/repository.js.map +1 -0
  114. package/dist/types/standard-schema.d.ts +15 -0
  115. package/dist/types/standard-schema.d.ts.map +1 -0
  116. package/dist/types/standard-schema.js +2 -0
  117. package/dist/types/standard-schema.js.map +1 -0
  118. package/dist/types/unit-of-work.d.ts +39 -0
  119. package/dist/types/unit-of-work.d.ts.map +1 -0
  120. package/dist/types/unit-of-work.js +2 -0
  121. package/dist/types/unit-of-work.js.map +1 -0
  122. package/dist/types/utils.d.ts +14 -0
  123. package/dist/types/utils.d.ts.map +1 -0
  124. package/dist/types/utils.js +2 -0
  125. package/dist/types/utils.js.map +1 -0
  126. package/dist/types.d.ts +88 -0
  127. package/dist/types.d.ts.map +1 -0
  128. package/dist/types.js +12 -0
  129. package/dist/types.js.map +1 -0
  130. package/dist/validation-error.d.ts +42 -0
  131. package/dist/validation-error.d.ts.map +1 -0
  132. package/dist/validation-error.js +73 -0
  133. package/dist/validation-error.js.map +1 -0
  134. package/dist/value-object.d.ts +47 -0
  135. package/dist/value-object.d.ts.map +1 -0
  136. package/dist/value-object.js +136 -0
  137. package/dist/value-object.js.map +1 -0
  138. package/eslint.config.js +51 -0
  139. package/jest.config.js +21 -0
  140. package/package.json +58 -0
  141. package/src/base-entity.ts +401 -0
  142. package/src/constants.ts +7 -0
  143. package/src/criteria.ts +291 -0
  144. package/src/deep-proxy.ts +339 -0
  145. package/src/domain-event-bus.ts +166 -0
  146. package/src/domain-event.ts +90 -0
  147. package/src/entity.ts +16 -0
  148. package/src/id.ts +94 -0
  149. package/src/index.ts +33 -0
  150. package/src/paginated-result.ts +274 -0
  151. package/src/repository/base-repository.ts +152 -0
  152. package/src/repository/in-memory-repository.ts +104 -0
  153. package/src/repository/index.ts +55 -0
  154. package/src/repository/mapper.ts +74 -0
  155. package/src/repository/unit-of-work.ts +148 -0
  156. package/src/types/criteria.ts +79 -0
  157. package/src/types/domain.ts +37 -0
  158. package/src/types/history-tracker.ts +45 -0
  159. package/src/types/index.ts +7 -0
  160. package/src/types/repository.ts +51 -0
  161. package/src/types/standard-schema.ts +19 -0
  162. package/src/types/unit-of-work.ts +46 -0
  163. package/src/types/utils.ts +29 -0
  164. package/src/validation-error.ts +97 -0
  165. package/src/value-object.ts +187 -0
  166. package/tests/criteria.test.ts +432 -0
  167. package/tests/domain-events.test.ts +445 -0
  168. package/tests/entity-equality.test.ts +487 -0
  169. package/tests/entity-validation.test.ts +339 -0
  170. package/tests/entity.test.ts +33 -0
  171. package/tests/history-tracker.spec.ts +667 -0
  172. package/tests/id.test.ts +341 -0
  173. package/tests/repository.test.ts +641 -0
  174. package/tests/to-json.test.ts +91 -0
  175. package/tests/utils.ts +151 -0
  176. package/tests/value-object-validation.test.ts +228 -0
  177. package/tests/value-objects.test.ts +52 -0
  178. package/tsconfig.json +31 -0
@@ -0,0 +1,112 @@
1
+ // ============================================================================
2
+ // Domain Event Bus - Pub/Sub for Domain Events
3
+ // ============================================================================
4
+ /**
5
+ * Domain Event Bus - Singleton pattern for event pub/sub
6
+ */
7
+ export class DomainEventBus {
8
+ constructor() {
9
+ this.handlers = new Map();
10
+ this.wildcardHandlers = new Set();
11
+ }
12
+ /**
13
+ * Get the singleton instance
14
+ */
15
+ static getInstance() {
16
+ if (!DomainEventBus.instance) {
17
+ DomainEventBus.instance = new DomainEventBus();
18
+ }
19
+ return DomainEventBus.instance;
20
+ }
21
+ /**
22
+ * Subscribe to a specific event type
23
+ */
24
+ subscribe(eventType, handler) {
25
+ const eventName = typeof eventType === "string" ? eventType : eventType.name;
26
+ if (!this.handlers.has(eventName)) {
27
+ this.handlers.set(eventName, new Set());
28
+ }
29
+ this.handlers.get(eventName).add(handler);
30
+ }
31
+ /**
32
+ * Subscribe to all events (wildcard)
33
+ */
34
+ subscribeAll(handler) {
35
+ this.wildcardHandlers.add(handler);
36
+ }
37
+ /**
38
+ * Unsubscribe from a specific event type
39
+ */
40
+ unsubscribe(eventType, handler) {
41
+ const eventName = typeof eventType === "string" ? eventType : eventType.name;
42
+ const handlers = this.handlers.get(eventName);
43
+ if (handlers) {
44
+ handlers.delete(handler);
45
+ if (handlers.size === 0) {
46
+ this.handlers.delete(eventName);
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Unsubscribe from all events
52
+ */
53
+ unsubscribeAll(handler) {
54
+ this.wildcardHandlers.delete(handler);
55
+ }
56
+ /**
57
+ * Publish a single event
58
+ */
59
+ async publish(event) {
60
+ const eventName = event.eventName;
61
+ const handlers = this.handlers.get(eventName) || new Set();
62
+ // Execute specific handlers
63
+ const specificPromises = Array.from(handlers).map((handler) => this.executeHandler(handler, event));
64
+ // Execute wildcard handlers
65
+ const wildcardPromises = Array.from(this.wildcardHandlers).map((handler) => this.executeHandler(handler, event));
66
+ await Promise.all([...specificPromises, ...wildcardPromises]);
67
+ }
68
+ /**
69
+ * Publish multiple events
70
+ */
71
+ async publishAll(events) {
72
+ await Promise.all(events.map((event) => this.publish(event)));
73
+ }
74
+ /**
75
+ * Clear all handlers (useful for testing)
76
+ */
77
+ clearAllHandlers() {
78
+ this.handlers.clear();
79
+ this.wildcardHandlers.clear();
80
+ }
81
+ /**
82
+ * Get count of handlers for an event type
83
+ */
84
+ getHandlerCount(eventType) {
85
+ const eventName = typeof eventType === "string" ? eventType : eventType.name;
86
+ return this.handlers.get(eventName)?.size || 0;
87
+ }
88
+ /**
89
+ * Execute a handler (function or class)
90
+ */
91
+ async executeHandler(handler, event) {
92
+ try {
93
+ if (typeof handler === "function") {
94
+ await handler(event);
95
+ }
96
+ else {
97
+ await handler.handle(event);
98
+ }
99
+ }
100
+ catch (error) {
101
+ console.error(`Error handling event ${event.eventName}:`, error);
102
+ // Don't throw - we don't want one handler failure to break others
103
+ }
104
+ }
105
+ }
106
+ /**
107
+ * Convenience function to get the event bus instance
108
+ */
109
+ export function getEventBus() {
110
+ return DomainEventBus.getInstance();
111
+ }
112
+ //# sourceMappingURL=domain-event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-event-bus.js","sourceRoot":"","sources":["../src/domain-event-bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { Id } from "./id";
2
+ /**
3
+ * Interface for all domain events
4
+ */
5
+ export interface IDomainEvent {
6
+ /**
7
+ * Unique identifier for this event occurrence
8
+ */
9
+ readonly eventId: string;
10
+ /**
11
+ * When the event occurred
12
+ */
13
+ readonly occurredOn: Date;
14
+ /**
15
+ * Name/type of the event (e.g., "UserCreated", "OrderPlaced")
16
+ */
17
+ readonly eventName: string;
18
+ /**
19
+ * ID of the aggregate that raised this event
20
+ */
21
+ readonly aggregateId: string;
22
+ }
23
+ /**
24
+ * Base class for domain events
25
+ */
26
+ export declare abstract class DomainEvent implements IDomainEvent {
27
+ readonly eventId: string;
28
+ readonly occurredOn: Date;
29
+ readonly aggregateId: string;
30
+ constructor(aggregateId: Id | string);
31
+ /**
32
+ * Get the event name (defaults to class name)
33
+ */
34
+ get eventName(): string;
35
+ private generateEventId;
36
+ /**
37
+ * Convert event to JSON
38
+ */
39
+ toJSON(): Record<string, any>;
40
+ /**
41
+ * Override this to provide event-specific data
42
+ */
43
+ protected getPayload(): Record<string, any>;
44
+ }
45
+ /**
46
+ * Event handler function type
47
+ */
48
+ export type DomainEventHandler<T extends IDomainEvent = IDomainEvent> = (event: T) => void | Promise<void>;
49
+ /**
50
+ * Event handler class type
51
+ */
52
+ export interface IDomainEventHandler<T extends IDomainEvent = IDomainEvent> {
53
+ handle(event: T): void | Promise<void>;
54
+ }
55
+ //# sourceMappingURL=domain-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-event.d.ts","sourceRoot":"","sources":["../src/domain-event.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,8BAAsB,WAAY,YAAW,YAAY;IACvD,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,SAAgB,UAAU,EAAE,IAAI,CAAC;IACjC,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAExB,WAAW,EAAE,EAAE,GAAG,MAAM;IAMpC;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAU7B;;OAEG;IACH,SAAS,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAG5C;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,IAAI,CACtE,KAAK,EAAE,CAAC,KACL,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY;IACxE,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC"}
@@ -0,0 +1,42 @@
1
+ // ============================================================================
2
+ // Domain Events - Event-Driven Architecture Support
3
+ // ============================================================================
4
+ import { Id } from "./id";
5
+ /**
6
+ * Base class for domain events
7
+ */
8
+ export class DomainEvent {
9
+ constructor(aggregateId) {
10
+ this.eventId = this.generateEventId();
11
+ this.occurredOn = new Date();
12
+ this.aggregateId = aggregateId instanceof Id ? aggregateId.value : aggregateId;
13
+ }
14
+ /**
15
+ * Get the event name (defaults to class name)
16
+ */
17
+ get eventName() {
18
+ return this.constructor.name;
19
+ }
20
+ generateEventId() {
21
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
22
+ }
23
+ /**
24
+ * Convert event to JSON
25
+ */
26
+ toJSON() {
27
+ return {
28
+ eventId: this.eventId,
29
+ eventName: this.eventName,
30
+ occurredOn: this.occurredOn.toISOString(),
31
+ aggregateId: this.aggregateId,
32
+ ...this.getPayload(),
33
+ };
34
+ }
35
+ /**
36
+ * Override this to provide event-specific data
37
+ */
38
+ getPayload() {
39
+ return {};
40
+ }
41
+ }
42
+ //# sourceMappingURL=domain-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-event.js","sourceRoot":"","sources":["../src/domain-event.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,oDAAoD;AACpD,+EAA+E;AAE/E,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AA2B1B;;GAEG;AACH,MAAM,OAAgB,WAAW;IAK/B,YAAY,WAAwB;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,YAAY,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;IACjF,CAAC;IAED;;OAEG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAEO,eAAe;QACrB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACpE,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE;YACzC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,GAAG,IAAI,CAAC,UAAU,EAAE;SACrB,CAAC;IACJ,CAAC;IAED;;OAEG;IACO,UAAU;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import { BaseEntity } from './base-entity';
2
+ import { BaseProps } from './types';
3
+ /**
4
+ * Entity - Has identity and lifecycle, but is not an aggregate root
5
+ */
6
+ export declare class Entity<T extends BaseProps> extends BaseEntity<T> {
7
+ }
8
+ /**
9
+ * Aggregate - Aggregate root that manages a consistency boundary
10
+ */
11
+ export declare class Aggregate<T extends BaseProps> extends BaseEntity<T> {
12
+ }
13
+ //# sourceMappingURL=entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC;;GAEG;AACH,qBAAa,MAAM,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;CAAG;AAEjE;;GAEG;AACH,qBAAa,SAAS,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;CAAG"}
package/dist/entity.js ADDED
@@ -0,0 +1,15 @@
1
+ // ============================================================================
2
+ // Entity & Aggregate Classes
3
+ // ============================================================================
4
+ import { BaseEntity } from './base-entity';
5
+ /**
6
+ * Entity - Has identity and lifecycle, but is not an aggregate root
7
+ */
8
+ export class Entity extends BaseEntity {
9
+ }
10
+ /**
11
+ * Aggregate - Aggregate root that manages a consistency boundary
12
+ */
13
+ export class Aggregate extends BaseEntity {
14
+ }
15
+ //# sourceMappingURL=entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C;;GAEG;AACH,MAAM,OAAO,MAA4B,SAAQ,UAAa;CAAG;AAEjE;;GAEG;AACH,MAAM,OAAO,SAA+B,SAAQ,UAAa;CAAG"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Supported filter operators
3
+ */
4
+ export type FilterOperator = "equals" | "notEquals" | "greaterThan" | "greaterThanOrEquals" | "lessThan" | "lessThanOrEquals" | "in" | "notIn" | "contains" | "startsWith" | "endsWith" | "isNull" | "isNotNull";
5
+ /**
6
+ * Configuration for a single filter
7
+ */
8
+ export interface FilterConfig<T> {
9
+ field: keyof T | string;
10
+ operator: FilterOperator;
11
+ value?: any;
12
+ }
13
+ /**
14
+ * Represents a single filter condition
15
+ * Can be used for in-memory filtering or converted to database-specific queries
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const filter = new Filter('age', 'greaterThan', 18);
20
+ * const adults = users.filter(filter.predicateFn());
21
+ * ```
22
+ */
23
+ export declare class Filter<T> {
24
+ private readonly _field;
25
+ private readonly _operator;
26
+ private readonly _value?;
27
+ constructor(field: keyof T | string, operator: FilterOperator, value?: any);
28
+ /**
29
+ * Gets the field to filter
30
+ */
31
+ get field(): keyof T | string;
32
+ /**
33
+ * Gets the filter operator
34
+ */
35
+ get operator(): FilterOperator;
36
+ /**
37
+ * Gets the filter value
38
+ */
39
+ get value(): any;
40
+ /**
41
+ * Returns configuration object for serialization
42
+ */
43
+ toConfig(): FilterConfig<T>;
44
+ /**
45
+ * Checks if the operator requires a value
46
+ * @private
47
+ */
48
+ private requiresValue;
49
+ /**
50
+ * Creates a predicate function for in-memory filtering
51
+ * Handles nested properties using dot notation (e.g., "address.city")
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const filter = new Filter<User>('age', 'greaterThan', 18);
56
+ * const adults = users.filter(filter.predicateFn());
57
+ * ```
58
+ */
59
+ predicateFn(): (item: T) => boolean;
60
+ /**
61
+ * Gets nested property value using dot notation
62
+ * @private
63
+ */
64
+ private getNestedValue;
65
+ }
66
+ /**
67
+ * Logical operator for combining filters
68
+ */
69
+ export type LogicalOperator = "and" | "or";
70
+ /**
71
+ * Represents a composite filter that combines multiple filters with AND/OR logic
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const composite = new CompositeFilter<User>('and', [
76
+ * new Filter('age', 'greaterThan', 18),
77
+ * new Filter('status', 'equals', 'active')
78
+ * ]);
79
+ * const filtered = users.filter(composite.predicateFn());
80
+ * ```
81
+ */
82
+ export declare class CompositeFilter<T> {
83
+ private readonly _operator;
84
+ private readonly _filters;
85
+ constructor(operator: LogicalOperator, filters: (Filter<T> | CompositeFilter<T>)[]);
86
+ /**
87
+ * Gets the logical operator
88
+ */
89
+ get operator(): LogicalOperator;
90
+ /**
91
+ * Gets all filters
92
+ */
93
+ get filters(): readonly (Filter<T> | CompositeFilter<T>)[];
94
+ /**
95
+ * Creates a predicate function that applies the logical operator
96
+ */
97
+ predicateFn(): (item: T) => boolean;
98
+ /**
99
+ * Adds another filter with AND logic
100
+ */
101
+ and(filter: Filter<T> | CompositeFilter<T>): CompositeFilter<T>;
102
+ /**
103
+ * Adds another filter with OR logic
104
+ */
105
+ or(filter: Filter<T> | CompositeFilter<T>): CompositeFilter<T>;
106
+ }
107
+ //# sourceMappingURL=filtering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../src/filtering.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,WAAW,GACX,aAAa,GACb,qBAAqB,GACrB,UAAU,GACV,kBAAkB,GAClB,IAAI,GACJ,OAAO,GACP,UAAU,GACV,YAAY,GACZ,UAAU,GACV,QAAQ,GACR,WAAW,CAAC;AAEhB;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAMD;;;;;;;;;GASG;AACH,qBAAa,MAAM,CAAC,CAAC;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAM;gBAElB,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,GAAG;IAW1E;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAAC,GAAG,MAAM,CAE5B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,cAAc,CAE7B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,GAAG,CAEf;IAED;;OAEG;IACH,QAAQ,IAAI,YAAY,CAAC,CAAC,CAAC;IAQ3B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAIrB;;;;;;;;;OASG;IACH,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO;IA+DnC;;;OAGG;IACH,OAAO,CAAC,cAAc;CAGvB;AAMD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,IAAI,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,qBAAa,eAAe,CAAC,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;gBAElD,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE;IAQlF;;OAEG;IACH,IAAI,QAAQ,IAAI,eAAe,CAE9B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAEzD;IAED;;OAEG;IACH,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO;IAWnC;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAU/D;;OAEG;IACH,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;CAS/D"}
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Filtering System
4
+ // ============================================================================
5
+ // Provides filtering/where clause capabilities for queries and in-memory collections
6
+ // Supports common comparison operators and can be extended for custom operators
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.CompositeFilter = exports.Filter = void 0;
9
+ // ============================================================================
10
+ // Filter Class
11
+ // ============================================================================
12
+ /**
13
+ * Represents a single filter condition
14
+ * Can be used for in-memory filtering or converted to database-specific queries
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const filter = new Filter('age', 'greaterThan', 18);
19
+ * const adults = users.filter(filter.predicateFn());
20
+ * ```
21
+ */
22
+ class Filter {
23
+ constructor(field, operator, value) {
24
+ this._field = field;
25
+ this._operator = operator;
26
+ this._value = value;
27
+ // Validate that value is provided when required
28
+ if (this.requiresValue() && value === undefined) {
29
+ throw new Error(`Filter operator '${operator}' requires a value`);
30
+ }
31
+ }
32
+ /**
33
+ * Gets the field to filter
34
+ */
35
+ get field() {
36
+ return this._field;
37
+ }
38
+ /**
39
+ * Gets the filter operator
40
+ */
41
+ get operator() {
42
+ return this._operator;
43
+ }
44
+ /**
45
+ * Gets the filter value
46
+ */
47
+ get value() {
48
+ return this._value;
49
+ }
50
+ /**
51
+ * Returns configuration object for serialization
52
+ */
53
+ toConfig() {
54
+ return {
55
+ field: this._field,
56
+ operator: this._operator,
57
+ value: this._value,
58
+ };
59
+ }
60
+ /**
61
+ * Checks if the operator requires a value
62
+ * @private
63
+ */
64
+ requiresValue() {
65
+ return this._operator !== "isNull" && this._operator !== "isNotNull";
66
+ }
67
+ /**
68
+ * Creates a predicate function for in-memory filtering
69
+ * Handles nested properties using dot notation (e.g., "address.city")
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * const filter = new Filter<User>('age', 'greaterThan', 18);
74
+ * const adults = users.filter(filter.predicateFn());
75
+ * ```
76
+ */
77
+ predicateFn() {
78
+ return (item) => {
79
+ const fieldValue = this.getNestedValue(item, this._field);
80
+ switch (this._operator) {
81
+ case "equals":
82
+ return fieldValue === this._value;
83
+ case "notEquals":
84
+ return fieldValue !== this._value;
85
+ case "greaterThan":
86
+ return fieldValue > this._value;
87
+ case "greaterThanOrEquals":
88
+ return fieldValue >= this._value;
89
+ case "lessThan":
90
+ return fieldValue < this._value;
91
+ case "lessThanOrEquals":
92
+ return fieldValue <= this._value;
93
+ case "in":
94
+ return Array.isArray(this._value) && this._value.includes(fieldValue);
95
+ case "notIn":
96
+ return Array.isArray(this._value) && !this._value.includes(fieldValue);
97
+ case "contains":
98
+ return (typeof fieldValue === "string" &&
99
+ typeof this._value === "string" &&
100
+ fieldValue.includes(this._value));
101
+ case "startsWith":
102
+ return (typeof fieldValue === "string" &&
103
+ typeof this._value === "string" &&
104
+ fieldValue.startsWith(this._value));
105
+ case "endsWith":
106
+ return (typeof fieldValue === "string" &&
107
+ typeof this._value === "string" &&
108
+ fieldValue.endsWith(this._value));
109
+ case "isNull":
110
+ return fieldValue === null || fieldValue === undefined;
111
+ case "isNotNull":
112
+ return fieldValue !== null && fieldValue !== undefined;
113
+ default:
114
+ // This should never happen with proper typing
115
+ throw new Error(`Unknown filter operator: ${this._operator}`);
116
+ }
117
+ };
118
+ }
119
+ /**
120
+ * Gets nested property value using dot notation
121
+ * @private
122
+ */
123
+ getNestedValue(obj, path) {
124
+ return path.split(".").reduce((current, prop) => current?.[prop], obj);
125
+ }
126
+ }
127
+ exports.Filter = Filter;
128
+ /**
129
+ * Represents a composite filter that combines multiple filters with AND/OR logic
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const composite = new CompositeFilter<User>('and', [
134
+ * new Filter('age', 'greaterThan', 18),
135
+ * new Filter('status', 'equals', 'active')
136
+ * ]);
137
+ * const filtered = users.filter(composite.predicateFn());
138
+ * ```
139
+ */
140
+ class CompositeFilter {
141
+ constructor(operator, filters) {
142
+ if (filters.length === 0) {
143
+ throw new Error("At least one filter is required");
144
+ }
145
+ this._operator = operator;
146
+ this._filters = filters;
147
+ }
148
+ /**
149
+ * Gets the logical operator
150
+ */
151
+ get operator() {
152
+ return this._operator;
153
+ }
154
+ /**
155
+ * Gets all filters
156
+ */
157
+ get filters() {
158
+ return this._filters;
159
+ }
160
+ /**
161
+ * Creates a predicate function that applies the logical operator
162
+ */
163
+ predicateFn() {
164
+ return (item) => {
165
+ if (this._operator === "and") {
166
+ return this._filters.every((filter) => filter.predicateFn()(item));
167
+ }
168
+ else {
169
+ // OR
170
+ return this._filters.some((filter) => filter.predicateFn()(item));
171
+ }
172
+ };
173
+ }
174
+ /**
175
+ * Adds another filter with AND logic
176
+ */
177
+ and(filter) {
178
+ if (this._operator === "and") {
179
+ // Flatten if already AND
180
+ return new CompositeFilter("and", [...this._filters, filter]);
181
+ }
182
+ else {
183
+ // Wrap in new AND
184
+ return new CompositeFilter("and", [this, filter]);
185
+ }
186
+ }
187
+ /**
188
+ * Adds another filter with OR logic
189
+ */
190
+ or(filter) {
191
+ if (this._operator === "or") {
192
+ // Flatten if already OR
193
+ return new CompositeFilter("or", [...this._filters, filter]);
194
+ }
195
+ else {
196
+ // Wrap in new OR
197
+ return new CompositeFilter("or", [this, filter]);
198
+ }
199
+ }
200
+ }
201
+ exports.CompositeFilter = CompositeFilter;
202
+ //# sourceMappingURL=filtering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filtering.js","sourceRoot":"","sources":["../src/filtering.ts"],"names":[],"mappings":"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"}
package/dist/id.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ export declare class Id {
2
+ private readonly _value;
3
+ private readonly _isNew;
4
+ /**
5
+ * Create a new Id
6
+ * @param value - Optional existing ID value. If not provided, generates a new UUID.
7
+ *
8
+ * @example
9
+ * // New entity (generates UUID)
10
+ * const newId = new Id();
11
+ * newId.isNew // true
12
+ *
13
+ * // Existing entity (uses provided ID)
14
+ * const existingId = new Id("550e8400-e29b-41d4-a716-446655440000");
15
+ * existingId.isNew // false
16
+ */
17
+ constructor(value?: string);
18
+ /**
19
+ * Get the string value of the ID
20
+ */
21
+ get value(): string;
22
+ /**
23
+ * Check if this ID represents a new entity
24
+ */
25
+ get isNew(): boolean;
26
+ /**
27
+ * Convert to string (for JSON serialization and comparisons)
28
+ */
29
+ toString(): string;
30
+ /**
31
+ * Convert to JSON (returns the string value)
32
+ */
33
+ toJSON(): string;
34
+ /**
35
+ * Check equality with another Id or string
36
+ */
37
+ equals(other: Id | string): boolean;
38
+ /**
39
+ * Generate a UUID v4
40
+ */
41
+ private generateUUID;
42
+ /**
43
+ * Create a new Id (convenience static method)
44
+ */
45
+ static create(): Id;
46
+ /**
47
+ * Create an Id from an existing value
48
+ */
49
+ static from(value: string): Id;
50
+ }
51
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAKA,qBAAa,EAAE;IACb,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IAEjC;;;;;;;;;;;;OAYG;gBACS,KAAK,CAAC,EAAE,MAAM;IAY1B;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,MAAM,IAAI,MAAM;IAIhB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,EAAE,GAAG,MAAM,GAAG,OAAO;IAOnC;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,EAAE;IAInB;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE;CAG/B"}