@abejarano/ts-mongodb-criteria 1.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 (46) hide show
  1. package/README.md +329 -0
  2. package/dist/AggregateRoot.d.ts +4 -0
  3. package/dist/AggregateRoot.js +6 -0
  4. package/dist/criteria/Criteria.d.ts +11 -0
  5. package/dist/criteria/Criteria.js +19 -0
  6. package/dist/criteria/Filter.d.ts +10 -0
  7. package/dist/criteria/Filter.js +24 -0
  8. package/dist/criteria/FilterField.d.ts +4 -0
  9. package/dist/criteria/FilterField.js +10 -0
  10. package/dist/criteria/FilterOperator.d.ts +18 -0
  11. package/dist/criteria/FilterOperator.js +36 -0
  12. package/dist/criteria/FilterValue.d.ts +30 -0
  13. package/dist/criteria/FilterValue.js +74 -0
  14. package/dist/criteria/Filters.d.ts +8 -0
  15. package/dist/criteria/Filters.js +16 -0
  16. package/dist/criteria/Order.d.ts +12 -0
  17. package/dist/criteria/Order.js +30 -0
  18. package/dist/criteria/OrderBy.d.ts +7 -0
  19. package/dist/criteria/OrderBy.js +17 -0
  20. package/dist/criteria/OrderType.d.ts +13 -0
  21. package/dist/criteria/OrderType.js +34 -0
  22. package/dist/criteria/Paginate.d.ts +5 -0
  23. package/dist/criteria/Paginate.js +2 -0
  24. package/dist/criteria/index.d.ts +10 -0
  25. package/dist/criteria/index.js +26 -0
  26. package/dist/exceptions/InvalidArgumentError.exception.d.ts +2 -0
  27. package/dist/exceptions/InvalidArgumentError.exception.js +6 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.js +19 -0
  30. package/dist/mongo/MongoClientFactory.d.ts +17 -0
  31. package/dist/mongo/MongoClientFactory.js +49 -0
  32. package/dist/mongo/MongoCriteriaConverter.d.ts +43 -0
  33. package/dist/mongo/MongoCriteriaConverter.js +115 -0
  34. package/dist/mongo/MongoRepository.d.ts +15 -0
  35. package/dist/mongo/MongoRepository.js +95 -0
  36. package/dist/mongo/index.d.ts +3 -0
  37. package/dist/mongo/index.js +19 -0
  38. package/dist/valueObject/EnumValueObject.d.ts +7 -0
  39. package/dist/valueObject/EnumValueObject.js +16 -0
  40. package/dist/valueObject/StringValueObject.d.ts +8 -0
  41. package/dist/valueObject/StringValueObject.js +24 -0
  42. package/dist/valueObject/ValueObject.d.ts +8 -0
  43. package/dist/valueObject/ValueObject.js +23 -0
  44. package/dist/valueObject/index.d.ts +3 -0
  45. package/dist/valueObject/index.js +19 -0
  46. package/package.json +62 -0
package/README.md ADDED
@@ -0,0 +1,329 @@
1
+ # ๐Ÿ” TypeScript MongoDB Criteria Pattern
2
+
3
+ [![npm version](https://badge.fury.io/js/@abejarano%2Fts-mongodb-criteria.svg)](https://www.npmjs.com/package/@abejarano/ts-mongodb-criteria)
4
+ [![GitHub Package](https://img.shields.io/badge/GitHub-Package-blue.svg)](https://github.com/abejarano/ts-mongo-criteria/packages)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9+-blue.svg)](https://www.typescriptlang.org/)
6
+ [![MongoDB](https://img.shields.io/badge/MongoDB-6.0+-green.svg)](https://www.mongodb.com/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-20+-green.svg)](https://nodejs.org/)
9
+ [![Tests](https://img.shields.io/badge/Tests-30%2F30%20passing-brightgreen.svg)](#testing)
10
+
11
+ > A robust, type-safe implementation of the **Criteria Pattern** for MongoDB queries in TypeScript. Build complex database queries dynamically with a fluent, composable API designed following Domain-Driven Design (DDD) and Clean Architecture principles.
12
+
13
+ ## ๐Ÿ“š Table of Contents
14
+
15
+ - [๐ŸŽฏ Overview](#-overview)
16
+ - [โœจ Key Features](#-key-features)
17
+ - [๐Ÿ“ฆ Installation](#-installation)
18
+ - [๐Ÿš€ Quick Start](#-quick-start)
19
+ - [๐Ÿ“– Documentation](#-documentation)
20
+ - [๐Ÿงช Testing](#-testing)
21
+ - [๐Ÿค Contributing](#-contributing)
22
+ - [๐Ÿ“„ License](#-license)
23
+
24
+ ## ๐ŸŽฏ Overview
25
+
26
+ The **Criteria Pattern** is a powerful design pattern that enables dynamic query construction without writing raw database queries. This library provides a type-safe, MongoDB-specific implementation that helps you:
27
+
28
+ - **Build queries dynamically** based on runtime conditions
29
+ - **Maintain type safety** throughout your query construction
30
+ - **Compose and reuse** query components across your application
31
+ - **Separate concerns** between query logic and data models
32
+ - **Test queries easily** with a mockable interface
33
+
34
+ ### What is the Criteria Pattern?
35
+
36
+ The Criteria pattern encapsulates query logic in a structured, object-oriented way. Instead of building query strings or objects directly, you compose `Criteria` objects that represent your search intentions. This approach provides flexibility, reusability, testability, and type safety.
37
+
38
+ ## โœจ Key Features
39
+
40
+ ### ๐Ÿ”’ **Type Safety First**
41
+
42
+ - Full TypeScript support with strict typing
43
+ - Compile-time validation of query structure
44
+ - IntelliSense support for all operations
45
+
46
+ ### ๐Ÿงฉ **Flexible Query Building**
47
+
48
+ - Support for all common MongoDB operators (EQUAL, NOT_EQUAL, GT, GTE, LT, LTE, CONTAINS, NOT_CONTAINS)
49
+ - **NEW**: OR operator for complex logical combinations
50
+ - Composable filters that can be combined and reused
51
+ - Dynamic query construction based on runtime conditions
52
+
53
+ ### ๐Ÿ“Š **Advanced Querying**
54
+
55
+ ```typescript
56
+ // Simple equality
57
+ { status: { $eq: "active" } }
58
+
59
+ // Complex OR conditions
60
+ { $or: [
61
+ { name: { $regex: "john" } },
62
+ { email: { $regex: "john" } }
63
+ ]}
64
+
65
+ // Range queries
66
+ { age: { $gte: 18 }, price: { $lte: 999.99 } }
67
+ ```
68
+
69
+ ### ๐ŸŽฏ **MongoDB Optimized**
70
+
71
+ - Native MongoDB 6.0+ support
72
+ - Efficient query generation
73
+ - Automatic index-friendly query structure
74
+
75
+ ### ๐Ÿ“ฆ **Zero Dependencies**
76
+
77
+ - Only peer dependencies (MongoDB driver)
78
+ - Lightweight bundle size
79
+
80
+ ### ๐Ÿ—๏ธ **Clean Architecture**
81
+
82
+ - Repository pattern implementation
83
+ - Domain-driven design principles
84
+ - Separation of concerns
85
+
86
+ ## ๐Ÿ“ฆ Installation
87
+
88
+ ```bash
89
+ # Using npm
90
+ npm install @abejarano/ts-mongodb-criteria
91
+
92
+ # Using yarn
93
+ yarn add @abejarano/ts-mongodb-criteria
94
+
95
+ # Using pnpm
96
+ pnpm add @abejarano/ts-mongodb-criteria
97
+ ```
98
+
99
+ ### Peer Dependencies
100
+
101
+ ```bash
102
+ # MongoDB driver (required)
103
+ npm install mongodb@^6.0.0
104
+
105
+ # TypeScript (for development)
106
+ npm install -D typescript@^5.0.0
107
+ ```
108
+
109
+ ### System Requirements
110
+
111
+ - **Node.js**: 20.0.0 or higher
112
+ - **TypeScript**: 5.0.0 or higher (for development)
113
+ - **MongoDB**: 6.0.0 or higher
114
+
115
+ ## ๐Ÿš€ Quick Start
116
+
117
+ ```typescript
118
+ import {
119
+ Criteria,
120
+ Filters,
121
+ Order,
122
+ Operator,
123
+ MongoRepository,
124
+ } from "@abejarano/ts-mongodb-criteria"
125
+
126
+ // 1. Create filters using a simple Map-based syntax
127
+ const filters = [
128
+ new Map([
129
+ ["field", "status"],
130
+ ["operator", Operator.EQUAL],
131
+ ["value", "active"],
132
+ ]),
133
+ new Map([
134
+ ["field", "age"],
135
+ ["operator", Operator.GTE],
136
+ ["value", "18"],
137
+ ]),
138
+ ]
139
+
140
+ // 2. Build criteria with filters, sorting, and pagination
141
+ const criteria = new Criteria(
142
+ Filters.fromValues(filters),
143
+ Order.desc("createdAt"),
144
+ 20, // limit
145
+ 1 // page
146
+ )
147
+
148
+ // 3. Use with your MongoDB repository
149
+ class UserRepository extends MongoRepository<User> {
150
+ collectionName(): string {
151
+ return "users"
152
+ }
153
+ }
154
+
155
+ const userRepo = new UserRepository()
156
+ const users = await userRepo.searchByCriteria(criteria)
157
+ ```
158
+
159
+ **Your First Query in 30 Seconds:**
160
+
161
+ ```typescript
162
+ // Find active users over 18, sorted by creation date
163
+ const activeAdultUsers = new Criteria(
164
+ Filters.fromValues([
165
+ new Map([
166
+ ["field", "status"],
167
+ ["operator", Operator.EQUAL],
168
+ ["value", "active"],
169
+ ]),
170
+ new Map([
171
+ ["field", "age"],
172
+ ["operator", Operator.GTE],
173
+ ["value", "18"],
174
+ ]),
175
+ ]),
176
+ Order.desc("createdAt"),
177
+ 10, // Get 10 results
178
+ 1 // First page
179
+ )
180
+
181
+ const results = await repository.searchByCriteria(activeAdultUsers)
182
+ ```
183
+
184
+ ## ๐Ÿ“– Documentation
185
+
186
+ ### ๐Ÿ“– Complete Documentation
187
+
188
+ - **[๐Ÿ“˜ Quick Start Guide](./docs/quick-start.md)** - Get up and running in minutes
189
+ - **[๐Ÿ—๏ธ Criteria Pattern Guide](./docs/criteria-pattern.md)** - Deep dive into the pattern, architecture, and theory
190
+ - **[๐Ÿ”ง Operators Reference](./docs/operators.md)** - Complete guide to all available operators and their usage
191
+ - **[โšก Performance Guide](./docs/performance.md)** - Optimization strategies and best practices
192
+ - **[๐Ÿ”„ Migration Guide](./docs/migration.md)** - Migrate from other query systems to Criteria pattern
193
+
194
+ ### ๐ŸŽฏ Key Concepts
195
+
196
+ #### 1. **Criteria** - The main query builder
197
+
198
+ ```typescript
199
+ const criteria = new Criteria(filters, order, limit?, page?)
200
+ ```
201
+
202
+ #### 2. **Filters** - Collection of filter conditions
203
+
204
+ ```typescript
205
+ const filters = Filters.fromValues([...filterMaps])
206
+ ```
207
+
208
+ #### 3. **Order** - Sorting specification
209
+
210
+ ```typescript
211
+ const order = Order.desc("createdAt") // or Order.asc("name")
212
+ ```
213
+
214
+ #### 4. **Operators** - Available filter operations
215
+
216
+ - `EQUAL`, `NOT_EQUAL` - Exact matching
217
+ - `GT`, `GTE`, `LT`, `LTE` - Range operations
218
+ - `BETWEEN` - Inclusive range with lower and upper bounds
219
+ - `CONTAINS`, `NOT_CONTAINS` - Text search
220
+ - `OR` - Logical OR combinations
221
+
222
+ ### ๐Ÿ†• OR Operator Example
223
+
224
+ ```typescript
225
+ import { OrCondition } from "@abejarano/ts-mongodb-criteria"
226
+
227
+ // Search across multiple fields
228
+ const searchConditions: OrCondition[] = [
229
+ { field: "name", operator: Operator.CONTAINS, value: "john" },
230
+ { field: "email", operator: Operator.CONTAINS, value: "john" },
231
+ ]
232
+
233
+ const filters = [
234
+ new Map([
235
+ ["field", "search"],
236
+ ["operator", Operator.OR],
237
+ ["value", searchConditions],
238
+ ]),
239
+ ]
240
+
241
+ // Generates: { $or: [
242
+ // { name: { $regex: "john" } },
243
+ // { email: { $regex: "john" } }
244
+ // ]}
245
+ ```
246
+
247
+ ### โฑ๏ธ BETWEEN Operator Example
248
+
249
+ ```typescript
250
+ // Filter users created between two dates
251
+ const filters = [
252
+ new Map([
253
+ ["field", "createdAt"],
254
+ ["operator", Operator.BETWEEN],
255
+ ["value", { start: new Date("2024-01-01"), end: new Date("2024-01-31") }],
256
+ ]),
257
+ ]
258
+
259
+ const criteria = new Criteria(Filters.fromValues(filters), Order.none())
260
+
261
+ // Generates: { createdAt: { $gte: 2024-01-01, $lte: 2024-01-31 } }
262
+ ```
263
+
264
+ ## ๐Ÿงช Testing
265
+
266
+ The library includes comprehensive test coverage (30/30 tests passing).
267
+
268
+ ```bash
269
+ # Run all tests
270
+ npm test
271
+
272
+ # Run tests in watch mode
273
+ npm run test:watch
274
+
275
+ # Run tests with coverage
276
+ npm run test:coverage
277
+ ```
278
+
279
+ ## ๐Ÿค Contributing
280
+
281
+ We welcome contributions! Please follow these guidelines:
282
+
283
+ ### Development Setup
284
+
285
+ ```bash
286
+ # Clone the repository
287
+ git clone https://github.com/abejarano/ts-mongo-criteria.git
288
+ cd ts-mongo-criteria
289
+
290
+ # Install dependencies
291
+ yarn install
292
+
293
+ # Run tests
294
+ yarn test
295
+
296
+ # Build the project
297
+ yarn build
298
+ ```
299
+
300
+ ### Contribution Process
301
+
302
+ 1. **Fork** the repository
303
+ 2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
304
+ 3. **Write** tests for your changes
305
+ 4. **Ensure** all tests pass (`yarn test`)
306
+ 5. **Commit** using conventional commits (`git commit -m 'feat: add amazing feature'`)
307
+ 6. **Push** to your branch (`git push origin feature/amazing-feature`)
308
+ 7. **Open** a Pull Request
309
+
310
+ ## ๐Ÿ“„ License
311
+
312
+ This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
313
+
314
+ ---
315
+
316
+ ## ๐Ÿ‘จโ€๐Ÿ’ป Author
317
+
318
+ **รngel Bejarano**
319
+ ๐Ÿ“ง [angel.bejarano@jaspesoft.com](mailto:angel.bejarano@jaspesoft.com)
320
+ ๐Ÿ™ [GitHub](https://github.com/abejarano)
321
+ ๐Ÿข [Jaspesoft](https://jaspesoft.com)
322
+
323
+ ---
324
+
325
+ โญ๏ธ **If this project helps you, please give it a star on GitHub!**
326
+
327
+ ๐Ÿค **Questions or suggestions?** Open an issue or start a discussion.
328
+
329
+ ๐Ÿ“ข **Follow us** for updates and new features!
@@ -0,0 +1,4 @@
1
+ export declare abstract class AggregateRoot {
2
+ abstract getId(): string;
3
+ abstract toPrimitives(): any;
4
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AggregateRoot = void 0;
4
+ class AggregateRoot {
5
+ }
6
+ exports.AggregateRoot = AggregateRoot;
@@ -0,0 +1,11 @@
1
+ import { Filters } from "./Filters";
2
+ import { Order } from "./Order";
3
+ export declare class Criteria {
4
+ readonly filters: Filters;
5
+ readonly order: Order;
6
+ readonly limit?: number;
7
+ readonly offset?: number;
8
+ readonly currentPage?: number;
9
+ constructor(filters: Filters, order: Order, limit?: number, offset?: number);
10
+ hasFilters(): boolean;
11
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Criteria = void 0;
4
+ class Criteria {
5
+ constructor(filters, order, limit, offset) {
6
+ this.filters = filters;
7
+ this.order = order;
8
+ this.limit = limit;
9
+ this.currentPage = offset;
10
+ this.offset =
11
+ offset !== undefined && limit !== undefined
12
+ ? (offset - 1) * limit
13
+ : undefined;
14
+ }
15
+ hasFilters() {
16
+ return this.filters.filters.length > 0;
17
+ }
18
+ }
19
+ exports.Criteria = Criteria;
@@ -0,0 +1,10 @@
1
+ import { FilterField } from "./FilterField";
2
+ import { FilterOperator } from "./FilterOperator";
3
+ import { FilterInputValue, FilterValue } from "./FilterValue";
4
+ export declare class Filter {
5
+ readonly field: FilterField;
6
+ readonly operator: FilterOperator;
7
+ readonly value: FilterValue;
8
+ constructor(field: FilterField, operator: FilterOperator, value: FilterValue);
9
+ static fromValues(values: Map<string, FilterInputValue>): Filter;
10
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Filter = void 0;
4
+ const FilterField_1 = require("./FilterField");
5
+ const FilterOperator_1 = require("./FilterOperator");
6
+ const FilterValue_1 = require("./FilterValue");
7
+ const InvalidArgumentError_exception_1 = require("../exceptions/InvalidArgumentError.exception");
8
+ class Filter {
9
+ constructor(field, operator, value) {
10
+ this.field = field;
11
+ this.operator = operator;
12
+ this.value = value;
13
+ }
14
+ static fromValues(values) {
15
+ const field = values.get("field");
16
+ const operator = values.get("operator");
17
+ const value = values.get("value");
18
+ if (!field || !operator || value === undefined) {
19
+ throw new InvalidArgumentError_exception_1.InvalidArgumentError(`The filter is invalid`);
20
+ }
21
+ return new Filter(new FilterField_1.FilterField(field), FilterOperator_1.FilterOperator.fromValue(operator), new FilterValue_1.FilterValue(value));
22
+ }
23
+ }
24
+ exports.Filter = Filter;
@@ -0,0 +1,4 @@
1
+ import { StringValueObject } from "../valueObject";
2
+ export declare class FilterField extends StringValueObject {
3
+ constructor(value: string);
4
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilterField = void 0;
4
+ const valueObject_1 = require("../valueObject");
5
+ class FilterField extends valueObject_1.StringValueObject {
6
+ constructor(value) {
7
+ super(value);
8
+ }
9
+ }
10
+ exports.FilterField = FilterField;
@@ -0,0 +1,18 @@
1
+ export declare enum Operator {
2
+ EQUAL = "=",
3
+ NOT_EQUAL = "!=",
4
+ GT = ">",
5
+ LT = "<",
6
+ CONTAINS = "CONTAINS",
7
+ NOT_CONTAINS = "NOT_CONTAINS",
8
+ GTE = ">=",
9
+ LTE = "<=",
10
+ BETWEEN = "BETWEEN",
11
+ OR = "OR"
12
+ }
13
+ export declare class FilterOperator {
14
+ value: Operator;
15
+ constructor(value: Operator);
16
+ static fromValue(value: string): FilterOperator;
17
+ protected throwErrorForInvalidValue(value: Operator): void;
18
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilterOperator = exports.Operator = void 0;
4
+ const InvalidArgumentError_exception_1 = require("../exceptions/InvalidArgumentError.exception");
5
+ var Operator;
6
+ (function (Operator) {
7
+ Operator["EQUAL"] = "=";
8
+ Operator["NOT_EQUAL"] = "!=";
9
+ Operator["GT"] = ">";
10
+ Operator["LT"] = "<";
11
+ Operator["CONTAINS"] = "CONTAINS";
12
+ Operator["NOT_CONTAINS"] = "NOT_CONTAINS";
13
+ Operator["GTE"] = ">=";
14
+ Operator["LTE"] = "<=";
15
+ Operator["BETWEEN"] = "BETWEEN";
16
+ Operator["OR"] = "OR";
17
+ })(Operator || (exports.Operator = Operator = {}));
18
+ //export class FilterOperator extends EnumValueObject<Operator> {
19
+ class FilterOperator {
20
+ constructor(value) {
21
+ this.value = value;
22
+ //super(value, Object.values(Operator));
23
+ }
24
+ static fromValue(value) {
25
+ for (const operatorValue of Object.values(Operator)) {
26
+ if (value === operatorValue.toString()) {
27
+ return new FilterOperator(operatorValue);
28
+ }
29
+ }
30
+ throw new InvalidArgumentError_exception_1.InvalidArgumentError(`The filter operator ${value} is invalid`);
31
+ }
32
+ throwErrorForInvalidValue(value) {
33
+ throw new InvalidArgumentError_exception_1.InvalidArgumentError(`The filter operator ${value} is invalid`);
34
+ }
35
+ }
36
+ exports.FilterOperator = FilterOperator;
@@ -0,0 +1,30 @@
1
+ import { StringValueObject } from "../valueObject";
2
+ import { Operator } from "./FilterOperator";
3
+ export interface OrCondition {
4
+ field: string;
5
+ operator: Operator;
6
+ value: string;
7
+ }
8
+ export type FilterPrimitive = string | number | boolean | Date;
9
+ export type BetweenValue = {
10
+ start: FilterPrimitive;
11
+ end: FilterPrimitive;
12
+ } | {
13
+ startDate: FilterPrimitive;
14
+ endDate: FilterPrimitive;
15
+ } | {
16
+ from: FilterPrimitive;
17
+ to: FilterPrimitive;
18
+ };
19
+ export type FilterInputValue = FilterPrimitive | FilterPrimitive[] | OrCondition[] | BetweenValue;
20
+ export declare class FilterValue extends StringValueObject {
21
+ private readonly _originalValue;
22
+ constructor(value: FilterInputValue);
23
+ get isOrConditions(): boolean;
24
+ get asOrConditions(): OrCondition[];
25
+ get isBetween(): boolean;
26
+ get asBetween(): {
27
+ start: FilterPrimitive;
28
+ end: FilterPrimitive;
29
+ };
30
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilterValue = void 0;
4
+ const valueObject_1 = require("../valueObject");
5
+ const isOrConditionArray = (value) => {
6
+ if (!Array.isArray(value) || value.length === 0) {
7
+ return false;
8
+ }
9
+ const candidate = value[0];
10
+ return (typeof candidate === "object" &&
11
+ candidate !== null &&
12
+ "field" in candidate &&
13
+ "operator" in candidate &&
14
+ "value" in candidate);
15
+ };
16
+ const isBetweenObject = (value) => {
17
+ if (value === null || typeof value !== "object") {
18
+ return false;
19
+ }
20
+ const candidate = value;
21
+ const hasStartEnd = "start" in candidate && "end" in candidate;
22
+ const hasStartDateEndDate = "startDate" in candidate && "endDate" in candidate;
23
+ const hasFromTo = "from" in candidate && "to" in candidate;
24
+ return hasStartEnd || hasStartDateEndDate || hasFromTo;
25
+ };
26
+ const normalizeBetweenValue = (value) => {
27
+ if ("start" in value && "end" in value) {
28
+ return { start: value.start, end: value.end };
29
+ }
30
+ if ("startDate" in value && "endDate" in value) {
31
+ return { start: value.startDate, end: value.endDate };
32
+ }
33
+ return { start: value.from, end: value.to };
34
+ };
35
+ class FilterValue extends valueObject_1.StringValueObject {
36
+ constructor(value) {
37
+ if (Array.isArray(value) && isOrConditionArray(value)) {
38
+ // Handle OrCondition[]
39
+ super(JSON.stringify(value));
40
+ }
41
+ else if (Array.isArray(value)) {
42
+ // Handle primitive arrays (kept for backward compatibility)
43
+ super(value.join(","));
44
+ }
45
+ else if (isBetweenObject(value)) {
46
+ // Store serialized version but keep original reference
47
+ super(JSON.stringify(value));
48
+ }
49
+ else {
50
+ // Handle primitive values (string, number, boolean, Date)
51
+ super(value);
52
+ }
53
+ this._originalValue = value;
54
+ }
55
+ get isOrConditions() {
56
+ return isOrConditionArray(this._originalValue);
57
+ }
58
+ get asOrConditions() {
59
+ if (this.isOrConditions) {
60
+ return this._originalValue;
61
+ }
62
+ throw new Error("Value is not an OrCondition array");
63
+ }
64
+ get isBetween() {
65
+ return isBetweenObject(this._originalValue);
66
+ }
67
+ get asBetween() {
68
+ if (this.isBetween) {
69
+ return normalizeBetweenValue(this._originalValue);
70
+ }
71
+ throw new Error("Value is not a BETWEEN structure");
72
+ }
73
+ }
74
+ exports.FilterValue = FilterValue;
@@ -0,0 +1,8 @@
1
+ import { Filter } from "./Filter";
2
+ import { FilterInputValue } from "./FilterValue";
3
+ export declare class Filters {
4
+ readonly filters: Filter[];
5
+ constructor(filters: Filter[]);
6
+ static fromValues(filters: Array<Map<string, FilterInputValue>>): Filters;
7
+ static none(): Filters;
8
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Filters = void 0;
4
+ const Filter_1 = require("./Filter");
5
+ class Filters {
6
+ constructor(filters) {
7
+ this.filters = filters;
8
+ }
9
+ static fromValues(filters) {
10
+ return new Filters(filters.map((values) => Filter_1.Filter.fromValues(values)));
11
+ }
12
+ static none() {
13
+ return new Filters([]);
14
+ }
15
+ }
16
+ exports.Filters = Filters;
@@ -0,0 +1,12 @@
1
+ import { OrderBy } from "./OrderBy";
2
+ import { OrderType } from "./OrderType";
3
+ export declare class Order {
4
+ readonly orderBy: OrderBy;
5
+ readonly orderType: OrderType;
6
+ constructor(orderBy: OrderBy, orderType: OrderType);
7
+ static fromValues(orderBy?: string, orderType?: string): Order;
8
+ static none(): Order;
9
+ static desc(orderBy: string): Order;
10
+ static asc(orderBy: string): Order;
11
+ hasOrder(): boolean;
12
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Order = void 0;
4
+ const OrderBy_1 = require("./OrderBy");
5
+ const OrderType_1 = require("./OrderType");
6
+ class Order {
7
+ constructor(orderBy, orderType) {
8
+ this.orderBy = orderBy;
9
+ this.orderType = orderType;
10
+ }
11
+ static fromValues(orderBy, orderType) {
12
+ if (!orderBy) {
13
+ return Order.none();
14
+ }
15
+ return new Order(new OrderBy_1.OrderBy(orderBy), OrderType_1.OrderType.fromValue(orderType || OrderType_1.OrderTypes.ASC));
16
+ }
17
+ static none() {
18
+ return new Order(new OrderBy_1.OrderBy(""), new OrderType_1.OrderType(OrderType_1.OrderTypes.NONE));
19
+ }
20
+ static desc(orderBy) {
21
+ return new Order(new OrderBy_1.OrderBy(orderBy), new OrderType_1.OrderType(OrderType_1.OrderTypes.DESC));
22
+ }
23
+ static asc(orderBy) {
24
+ return new Order(new OrderBy_1.OrderBy(orderBy), new OrderType_1.OrderType(OrderType_1.OrderTypes.ASC));
25
+ }
26
+ hasOrder() {
27
+ return !this.orderType.isNone();
28
+ }
29
+ }
30
+ exports.Order = Order;
@@ -0,0 +1,7 @@
1
+ import { ValueObject } from "../valueObject/ValueObject";
2
+ export declare class OrderBy extends ValueObject<string> {
3
+ readonly value: string;
4
+ constructor(value: string);
5
+ static create(value: string): OrderBy;
6
+ getValue(): string;
7
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OrderBy = void 0;
4
+ const ValueObject_1 = require("../valueObject/ValueObject");
5
+ class OrderBy extends ValueObject_1.ValueObject {
6
+ constructor(value) {
7
+ super(value);
8
+ this.value = value;
9
+ }
10
+ static create(value) {
11
+ return new OrderBy(value);
12
+ }
13
+ getValue() {
14
+ return this.value;
15
+ }
16
+ }
17
+ exports.OrderBy = OrderBy;