@globalart/ddd 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.mjs ADDED
@@ -0,0 +1,902 @@
1
+ import { v4 } from "uuid";
2
+ import { z } from "zod";
3
+ import { isEmpty, isNil, isNumber } from "lodash";
4
+ import { None, Ok, Some } from "oxide.ts";
5
+ import { match } from "ts-pattern";
6
+ import { dequal } from "dequal";
7
+ import { isAfter, isBefore, isEqual, isToday, isTomorrow, isWithinInterval, isYesterday } from "date-fns";
8
+ import { customAlphabet } from "nanoid";
9
+
10
+ //#region src/aggregate-root.ts
11
+ var AggregateRoot = class {
12
+ #domainEvents = [];
13
+ get domainEvents() {
14
+ return this.#domainEvents;
15
+ }
16
+ set domainEvents(events) {
17
+ this.#domainEvents = events;
18
+ }
19
+ addDomainEvent(event) {
20
+ this.#domainEvents.push(event);
21
+ }
22
+ removeEvents(events) {
23
+ this.#domainEvents = this.#domainEvents.filter((event) => !events.includes(event));
24
+ }
25
+ };
26
+
27
+ //#endregion
28
+ //#region src/command.ts
29
+ var Command = class {
30
+ commandId;
31
+ correlationId;
32
+ causationId;
33
+ constructor(props) {
34
+ this.correlationId = props.correlationId ?? v4();
35
+ this.commandId = props.commandId ?? v4();
36
+ }
37
+ };
38
+
39
+ //#endregion
40
+ //#region src/event.ts
41
+ const eventSchema = (name, payload, meta) => z.object({
42
+ id: z.string().uuid(),
43
+ name: z.literal(name),
44
+ operatorId: z.string().optional(),
45
+ payload,
46
+ timestamp: z.coerce.date(),
47
+ meta
48
+ });
49
+ var BaseEvent = class {
50
+ constructor(payload, operatorId, meta, id = v4(), timestamp = /* @__PURE__ */ new Date()) {
51
+ this.payload = payload;
52
+ this.operatorId = operatorId;
53
+ this.meta = meta;
54
+ this.id = id;
55
+ this.timestamp = timestamp;
56
+ }
57
+ toJSON() {
58
+ return {
59
+ id: this.id,
60
+ name: this.name,
61
+ operatorId: this.operatorId,
62
+ timestamp: this.timestamp.toISOString(),
63
+ payload: this.payload,
64
+ meta: this.meta
65
+ };
66
+ }
67
+ };
68
+
69
+ //#endregion
70
+ //#region src/exception.base.ts
71
+ var ExceptionBase = class extends Error {
72
+ correlationId;
73
+ /**
74
+ *
75
+ * @param message
76
+ * @param correlationId
77
+ * @param cause
78
+ * @param metadata
79
+ */
80
+ constructor(message, correlationId, cause, metadata) {
81
+ super(message);
82
+ this.message = message;
83
+ this.cause = cause;
84
+ this.metadata = metadata;
85
+ Error.captureStackTrace(this, this.constructor);
86
+ this.correlationId = correlationId;
87
+ }
88
+ toJSON() {
89
+ return {
90
+ message: this.message,
91
+ code: this.code,
92
+ stack: this.stack,
93
+ correlationId: this.correlationId,
94
+ cause: JSON.stringify(this.cause),
95
+ metadata: this.metadata
96
+ };
97
+ }
98
+ };
99
+
100
+ //#endregion
101
+ //#region src/filter/base.filter.ts
102
+ const baseFilter = z.object({
103
+ field: z.string().min(1),
104
+ relation: z.string().min(1).optional()
105
+ });
106
+
107
+ //#endregion
108
+ //#region src/filter/conjunction.ts
109
+ const $and = z.literal("$and");
110
+ const $or = z.literal("$or");
111
+ const $not = z.literal("$not");
112
+ const conjunctions = z.union([
113
+ $and,
114
+ $or,
115
+ $not
116
+ ]);
117
+
118
+ //#endregion
119
+ //#region src/utils.ts
120
+ function convertPropsToObject(props) {
121
+ const propsCopy = { ...props };
122
+ for (const prop in propsCopy) {
123
+ if (Array.isArray(propsCopy[prop])) propsCopy[prop] = propsCopy[prop].map((item) => {
124
+ return convertToPlainObject(item);
125
+ });
126
+ propsCopy[prop] = convertToPlainObject(propsCopy[prop]);
127
+ }
128
+ return propsCopy;
129
+ }
130
+ function convertToPlainObject(item) {
131
+ if (ValueObject.isValueObject(item)) return item.unpack();
132
+ return item;
133
+ }
134
+
135
+ //#endregion
136
+ //#region src/value-objects/value-object.ts
137
+ var ValueObject = class ValueObject {
138
+ constructor(props) {
139
+ this.props = props;
140
+ }
141
+ equals(vo) {
142
+ if (vo === null || vo === void 0) return false;
143
+ return dequal(vo, this);
144
+ }
145
+ static isValueObject(obj) {
146
+ return obj instanceof ValueObject;
147
+ }
148
+ unpack() {
149
+ if (this.isDomainPrimitive(this.props)) return this.props.value;
150
+ const propsCopy = convertPropsToObject(this.props);
151
+ return Object.freeze(propsCopy);
152
+ }
153
+ isDomainPrimitive(obj) {
154
+ if (Object.prototype.hasOwnProperty.call(obj, "value")) return true;
155
+ return false;
156
+ }
157
+ };
158
+
159
+ //#endregion
160
+ //#region src/filter/fields/field-value.base.ts
161
+ var FieldValueBase = class extends ValueObject {};
162
+
163
+ //#endregion
164
+ //#region src/filter/fields/date/date-field-value.ts
165
+ var DateFieldValue = class extends FieldValueBase {
166
+ constructor(value) {
167
+ super({ value });
168
+ }
169
+ accept(visitor) {
170
+ visitor.date(this);
171
+ }
172
+ static fromNullableString(str) {
173
+ if (!str) return new this(null);
174
+ return new this(new Date(str));
175
+ }
176
+ };
177
+
178
+ //#endregion
179
+ //#region src/filter/operators.ts
180
+ const $eq = z.literal("$eq");
181
+ const $neq = z.literal("$neq");
182
+ const $contains = z.literal("$contains");
183
+ const $not_contains = z.literal("$not_contains");
184
+ const $starts_with = z.literal("$starts_with");
185
+ const $ends_with = z.literal("$ends_with");
186
+ const $regex = z.literal("$regex");
187
+ const $is_true = z.literal("$is_true");
188
+ const $is_false = z.literal("$is_false");
189
+ const $in = z.literal("$in");
190
+ const $nin = z.literal("$nin");
191
+ const $gt = z.literal("$gt");
192
+ const $lt = z.literal("$lt");
193
+ const $gte = z.literal("$gte");
194
+ const $lte = z.literal("$lte");
195
+ const $start_eq = z.literal("$start_eq");
196
+ const $start_neq = z.literal("$start_neq");
197
+ const $start_gt = z.literal("$start_gt");
198
+ const $start_lt = z.literal("$start_lt");
199
+ const $start_gte = z.literal("$start_gte");
200
+ const $start_lte = z.literal("$start_lte");
201
+ const $end_eq = z.literal("$end_eq");
202
+ const $end_neq = z.literal("$end_neq");
203
+ const $end_gt = z.literal("$end_gt");
204
+ const $end_lt = z.literal("$end_lt");
205
+ const $end_gte = z.literal("$end_gte");
206
+ const $end_lte = z.literal("$end_lte");
207
+ const $is_empty = z.literal("$is_empty");
208
+ const $is_not_empty = z.literal("$is_not_empty");
209
+ const $is_today = z.literal("$is_today");
210
+ const $is_not_today = z.literal("$is_not_today");
211
+ const $is_tomorrow = z.literal("$is_tomorrow");
212
+ const $is_yesterday = z.literal("$is_yesterday");
213
+ const $between = z.literal("$between");
214
+ const $has_file_type = z.literal("$has_file_type");
215
+ const $has_file_extension = z.literal("$has_file_extension");
216
+ const $is_root = z.literal("$is_root");
217
+ const $is_me = z.literal("$is_me");
218
+ const $is_not_me = z.literal("$is_not_me");
219
+ const operatorsWihtoutValue = z.union([
220
+ $is_empty,
221
+ $is_not_empty,
222
+ $is_today,
223
+ $is_not_today,
224
+ $is_tomorrow,
225
+ $is_yesterday,
226
+ $is_root,
227
+ $is_me,
228
+ $is_not_me
229
+ ]);
230
+ const isOperatorWithoutValue = (value) => operatorsWihtoutValue.safeParse(value).success;
231
+
232
+ //#endregion
233
+ //#region src/filter/fields/date/date.filter.ts
234
+ const dateFilterOperators = z.union([
235
+ $eq,
236
+ $neq,
237
+ $gt,
238
+ $gte,
239
+ $lt,
240
+ $lte,
241
+ $between,
242
+ $is_today,
243
+ $is_tomorrow,
244
+ $is_yesterday,
245
+ $is_not_today
246
+ ]);
247
+ const dateFilterValue = z.string().nullable().or(z.tuple([z.string(), z.string()]));
248
+ const dateFilter = z.object({
249
+ type: z.literal("date"),
250
+ operator: dateFilterOperators,
251
+ value: dateFilterValue
252
+ }).merge(baseFilter);
253
+
254
+ //#endregion
255
+ //#region src/filter/fields/number/number-field-value.ts
256
+ var NumberFieldValue = class extends FieldValueBase {
257
+ constructor(value) {
258
+ super({ value });
259
+ }
260
+ accept(visitor) {
261
+ visitor.number(this);
262
+ }
263
+ };
264
+
265
+ //#endregion
266
+ //#region src/filter/fields/number/number.filter.ts
267
+ const numberFilterOperators = z.union([
268
+ $eq,
269
+ $neq,
270
+ $gt,
271
+ $gte,
272
+ $lt,
273
+ $lte,
274
+ $is_empty,
275
+ $is_not_empty
276
+ ]);
277
+ const numberFilterValue = z.number().nullable();
278
+ const numberFilter = z.object({
279
+ type: z.literal("number"),
280
+ operator: numberFilterOperators,
281
+ value: numberFilterValue
282
+ }).merge(baseFilter);
283
+
284
+ //#endregion
285
+ //#region src/filter/fields/string/string-field-value.ts
286
+ var StringFieldValue = class extends FieldValueBase {
287
+ constructor(value) {
288
+ super({ value });
289
+ }
290
+ accept(visitor) {
291
+ visitor.string(this);
292
+ }
293
+ };
294
+
295
+ //#endregion
296
+ //#region src/filter/fields/string/string.filter.ts
297
+ const stringFilterOperators = z.union([
298
+ $eq,
299
+ $neq,
300
+ $contains,
301
+ $not_contains,
302
+ $starts_with,
303
+ $ends_with,
304
+ $regex,
305
+ $is_empty,
306
+ $is_not_empty
307
+ ]);
308
+ const stringFilterValue = z.string().nullable();
309
+ const stringFilter = z.object({
310
+ type: z.literal("string"),
311
+ operator: stringFilterOperators,
312
+ value: stringFilterValue
313
+ }).merge(baseFilter);
314
+
315
+ //#endregion
316
+ //#region src/specification.ts
317
+ var CompositeSpecification = class {
318
+ and(s) {
319
+ return new And(this, s);
320
+ }
321
+ or(s) {
322
+ return new Or(this, s);
323
+ }
324
+ not() {
325
+ return new Not(this);
326
+ }
327
+ };
328
+ var And = class extends CompositeSpecification {
329
+ constructor(left, right) {
330
+ super();
331
+ this.left = left;
332
+ this.right = right;
333
+ }
334
+ isSatisfiedBy(t) {
335
+ return this.left.isSatisfiedBy(t) && this.right.isSatisfiedBy(t);
336
+ }
337
+ mutate(t) {
338
+ return this.left.mutate(t).and(this.right.mutate(t));
339
+ }
340
+ accept(v) {
341
+ return this.left.accept(v).and(this.right.accept(v));
342
+ }
343
+ };
344
+ var Or = class extends CompositeSpecification {
345
+ constructor(left, right) {
346
+ super();
347
+ this.left = left;
348
+ this.right = right;
349
+ }
350
+ isSatisfiedBy(t) {
351
+ return this.left.isSatisfiedBy(t) || this.right.isSatisfiedBy(t);
352
+ }
353
+ mutate(t) {
354
+ return this.left.mutate(t).orElse(() => this.right.mutate(t));
355
+ }
356
+ accept(v) {
357
+ v.or(this.left, this.right);
358
+ return Ok(void 0);
359
+ }
360
+ };
361
+ var Not = class extends CompositeSpecification {
362
+ constructor(spec) {
363
+ super();
364
+ this.spec = spec;
365
+ }
366
+ isSatisfiedBy(t) {
367
+ return !this.spec.isSatisfiedBy(t);
368
+ }
369
+ mutate() {
370
+ throw new Error("[Not.mutate] Method not implemented.");
371
+ }
372
+ accept(v) {
373
+ return this.spec.accept(v.not());
374
+ }
375
+ };
376
+ const and = (...specs) => {
377
+ if (!specs.length) return None;
378
+ let s = specs[0];
379
+ for (const spec of specs.slice(1)) s = s.and(spec);
380
+ return Some(s);
381
+ };
382
+ const andOptions = (...specs) => {
383
+ return and(...specs.filter((spec) => spec.isSome()).map((spec) => spec.unwrap()));
384
+ };
385
+ const or = (...specs) => {
386
+ if (!specs.length) return None;
387
+ let s = specs[0];
388
+ for (const spec of specs.slice(1)) s = s.or(spec);
389
+ return Some(s);
390
+ };
391
+
392
+ //#endregion
393
+ //#region src/filter/filter-specification.base.ts
394
+ var BaseFilterSpecification = class extends CompositeSpecification {
395
+ constructor(field, value, relation) {
396
+ super();
397
+ this.field = field;
398
+ this.value = value;
399
+ this.relation = relation;
400
+ }
401
+ mutate(t) {
402
+ throw new Error("Method not implemented.");
403
+ }
404
+ };
405
+
406
+ //#endregion
407
+ //#region src/filter/specifications/date.specification.ts
408
+ var DateEqual = class extends BaseFilterSpecification {
409
+ isSatisfiedBy(value) {
410
+ return value instanceof DateFieldValue && value.equals(this.value);
411
+ }
412
+ accept(v) {
413
+ v.dateEqual(this);
414
+ return Ok(void 0);
415
+ }
416
+ };
417
+ var DateGreaterThan = class extends BaseFilterSpecification {
418
+ isSatisfiedBy(value) {
419
+ if (!(value instanceof DateFieldValue)) return false;
420
+ const d1 = value.unpack();
421
+ const d2 = this.value.unpack();
422
+ return !!d1 && !!d2 && isAfter(d1, d2);
423
+ }
424
+ accept(v) {
425
+ v.dateGreaterThan(this);
426
+ return Ok(void 0);
427
+ }
428
+ };
429
+ var DateLessThan = class extends BaseFilterSpecification {
430
+ isSatisfiedBy(value) {
431
+ if (!(value instanceof DateFieldValue)) return false;
432
+ const d1 = value.unpack();
433
+ const d2 = this.value.unpack();
434
+ return !!d1 && !!d2 && isBefore(d1, d2);
435
+ }
436
+ accept(v) {
437
+ v.dateLessThan(this);
438
+ return Ok(void 0);
439
+ }
440
+ };
441
+ var DateGreaterThanOrEqual = class extends BaseFilterSpecification {
442
+ isSatisfiedBy(value) {
443
+ if (!(value instanceof DateFieldValue)) return false;
444
+ const d1 = value.unpack();
445
+ const d2 = this.value.unpack();
446
+ return !!d1 && !!d2 && (isEqual(d1, d2) || isAfter(d1, d2));
447
+ }
448
+ accept(v) {
449
+ v.dateGreaterThanOrEqual(this);
450
+ return Ok(void 0);
451
+ }
452
+ };
453
+ var DateLessThanOrEqual = class extends BaseFilterSpecification {
454
+ isSatisfiedBy(value) {
455
+ if (!(value instanceof DateFieldValue)) return false;
456
+ const d1 = value.unpack();
457
+ const d2 = this.value.unpack();
458
+ return !!d1 && !!d2 && (isEqual(d1, d2) || isBefore(d1, d2));
459
+ }
460
+ accept(v) {
461
+ v.dateLessThanOrEqual(this);
462
+ return Ok(void 0);
463
+ }
464
+ };
465
+ var DateIsToday = class extends BaseFilterSpecification {
466
+ isSatisfiedBy(value) {
467
+ if (!(value instanceof DateFieldValue)) return false;
468
+ const date = value.unpack();
469
+ return !!date && isToday(date);
470
+ }
471
+ accept(v) {
472
+ v.dateIsToday(this);
473
+ return Ok(void 0);
474
+ }
475
+ };
476
+ var DateIsTomorrow = class extends BaseFilterSpecification {
477
+ isSatisfiedBy(value) {
478
+ if (!(value instanceof DateFieldValue)) return false;
479
+ const date = value.unpack();
480
+ return !!date && isTomorrow(date);
481
+ }
482
+ accept(v) {
483
+ v.dateIsTomorrow(this);
484
+ return Ok(void 0);
485
+ }
486
+ };
487
+ var DateIsYesterday = class extends BaseFilterSpecification {
488
+ isSatisfiedBy(value) {
489
+ if (!(value instanceof DateFieldValue)) return false;
490
+ const date = value.unpack();
491
+ return !!date && isYesterday(date);
492
+ }
493
+ accept(v) {
494
+ v.dateIsYesterday(this);
495
+ return Ok(void 0);
496
+ }
497
+ };
498
+ var DateBetween = class extends BaseFilterSpecification {
499
+ constructor(field, dateStart, dateEnd, relation) {
500
+ super(field, null, relation);
501
+ this.field = field;
502
+ this.dateStart = dateStart;
503
+ this.dateEnd = dateEnd;
504
+ this.relation = relation;
505
+ }
506
+ isSatisfiedBy(value) {
507
+ if (!(value instanceof DateFieldValue)) return false;
508
+ const date = value.unpack();
509
+ return !!date && isWithinInterval(date, {
510
+ start: this.dateStart,
511
+ end: this.dateEnd
512
+ });
513
+ }
514
+ accept(v) {
515
+ v.dateBetween(this);
516
+ return Ok(void 0);
517
+ }
518
+ };
519
+
520
+ //#endregion
521
+ //#region src/filter/specifications/number.specification.ts
522
+ var NumberEqual = class extends BaseFilterSpecification {
523
+ isSatisfiedBy(value) {
524
+ return value instanceof NumberFieldValue && value.equals(this.value);
525
+ }
526
+ accept(v) {
527
+ v.numberEqual(this);
528
+ return Ok(void 0);
529
+ }
530
+ };
531
+ var NumberGreaterThan = class extends BaseFilterSpecification {
532
+ isSatisfiedBy(value) {
533
+ if (!(value instanceof NumberFieldValue)) return false;
534
+ const n1 = value.unpack();
535
+ const n2 = this.value.unpack();
536
+ if (n1 === null && isNumber(n2)) return true;
537
+ return n1 !== null && n2 !== null && n1 > n2;
538
+ }
539
+ accept(v) {
540
+ v.numberGreaterThan(this);
541
+ return Ok(void 0);
542
+ }
543
+ };
544
+ var NumberLessThan = class extends BaseFilterSpecification {
545
+ isSatisfiedBy(value) {
546
+ if (!(value instanceof NumberFieldValue)) return false;
547
+ const n1 = value.unpack();
548
+ const n2 = this.value.unpack();
549
+ return n1 !== null && n2 !== null && n1 < n2;
550
+ }
551
+ accept(v) {
552
+ v.numberLessThan(this);
553
+ return Ok(void 0);
554
+ }
555
+ };
556
+ var NumberGreaterThanOrEqual = class extends BaseFilterSpecification {
557
+ isSatisfiedBy(value) {
558
+ if (!(value instanceof NumberFieldValue)) return false;
559
+ const n1 = value.unpack();
560
+ const n2 = this.value.unpack();
561
+ if (n1 === null && isNumber(n2)) return true;
562
+ return n1 !== null && n2 !== null && n1 >= n2;
563
+ }
564
+ accept(v) {
565
+ v.numberGreaterThanOrEqual(this);
566
+ return Ok(void 0);
567
+ }
568
+ };
569
+ var NumberLessThanOrEqual = class extends BaseFilterSpecification {
570
+ isSatisfiedBy(value) {
571
+ if (!(value instanceof NumberFieldValue)) return false;
572
+ const n1 = value.unpack();
573
+ const n2 = this.value.unpack();
574
+ return n1 !== null && n2 !== null && n1 <= n2;
575
+ }
576
+ accept(v) {
577
+ v.numberLessThanOrEqual(this);
578
+ return Ok(void 0);
579
+ }
580
+ };
581
+ var NumberEmpty = class extends BaseFilterSpecification {
582
+ constructor(field) {
583
+ super(field, new NumberFieldValue(null));
584
+ this.field = field;
585
+ }
586
+ isSatisfiedBy(value) {
587
+ return value instanceof NumberFieldValue && isNil(value.unpack());
588
+ }
589
+ accept(v) {
590
+ v.numberEmpty(this);
591
+ return Ok(void 0);
592
+ }
593
+ };
594
+
595
+ //#endregion
596
+ //#region src/filter/specifications/string.specification.ts
597
+ var StringEqual = class extends BaseFilterSpecification {
598
+ isSatisfiedBy(value) {
599
+ return value instanceof StringFieldValue && this.value.equals(value);
600
+ }
601
+ accept(v) {
602
+ v.stringEqual(this);
603
+ return Ok(void 0);
604
+ }
605
+ };
606
+ var StringNotEqual = class extends BaseFilterSpecification {
607
+ isSatisfiedBy(value) {
608
+ return value instanceof StringFieldValue && this.value.equals(value);
609
+ }
610
+ accept(v) {
611
+ v.stringNotEqual(this);
612
+ return Ok(void 0);
613
+ }
614
+ };
615
+ var StringContain = class extends BaseFilterSpecification {
616
+ isSatisfiedBy(value) {
617
+ if (!(value instanceof StringFieldValue)) return false;
618
+ const s1 = value.unpack();
619
+ const s2 = this.value.unpack();
620
+ return !!s1 && !!s2 && s1.includes(s2);
621
+ }
622
+ accept(v) {
623
+ v.stringContain(this);
624
+ return Ok(void 0);
625
+ }
626
+ };
627
+ var StringStartsWith = class extends BaseFilterSpecification {
628
+ isSatisfiedBy(value) {
629
+ if (!(value instanceof StringFieldValue)) return false;
630
+ const s1 = value.unpack();
631
+ const s2 = this.value.unpack();
632
+ return !!s1 && !!s2 && s1.startsWith(s2);
633
+ }
634
+ accept(v) {
635
+ v.stringStartsWith(this);
636
+ return Ok(void 0);
637
+ }
638
+ };
639
+ var StringEndsWith = class extends BaseFilterSpecification {
640
+ isSatisfiedBy(value) {
641
+ if (!(value instanceof StringFieldValue)) return false;
642
+ const s1 = value.unpack();
643
+ const s2 = this.value.unpack();
644
+ return !!s1 && !!s2 && s1.endsWith(s2);
645
+ }
646
+ accept(v) {
647
+ v.stringEndsWith(this);
648
+ return Ok(void 0);
649
+ }
650
+ };
651
+ var StringRegex = class extends BaseFilterSpecification {
652
+ isSatisfiedBy(value) {
653
+ if (!(value instanceof StringFieldValue)) return false;
654
+ const s1 = value.unpack();
655
+ const s2 = this.value.unpack();
656
+ return !!s1 && !!s2 && new RegExp(s2).test(s1);
657
+ }
658
+ accept(v) {
659
+ v.stringRegex(this);
660
+ return Ok(void 0);
661
+ }
662
+ };
663
+ var StringEmpty = class extends BaseFilterSpecification {
664
+ constructor(field) {
665
+ super(field, new StringFieldValue(null));
666
+ }
667
+ isSatisfiedBy(value) {
668
+ if (value instanceof StringFieldValue) return !value.unpack();
669
+ return !value;
670
+ }
671
+ accept(v) {
672
+ v.stringEmpty(this);
673
+ return Ok(void 0);
674
+ }
675
+ };
676
+
677
+ //#endregion
678
+ //#region src/filter/filter.ts
679
+ const filterRoorFilter = (filters) => {
680
+ const filterTuple = [filters[0], ...filters.slice(1)];
681
+ const filter$1 = z.union(filterTuple);
682
+ const group$1 = z.lazy(() => z.object({
683
+ conjunction: conjunctions,
684
+ children: z.union([group$1, filter$1]).array().nonempty().optional()
685
+ }));
686
+ const filterOrGroup$1 = filter$1.or(group$1);
687
+ const filterOrGroupList$1 = filterOrGroup$1.array();
688
+ return group$1.or(filterOrGroupList$1);
689
+ };
690
+ const filter = z.discriminatedUnion("type", [
691
+ numberFilter,
692
+ stringFilter,
693
+ dateFilter
694
+ ]);
695
+ const group = z.lazy(() => z.object({
696
+ conjunction: conjunctions,
697
+ children: z.union([group, filter]).array().nonempty().optional()
698
+ }));
699
+ const filterOrGroup = filter.or(group);
700
+ const filterOrGroupList = filterOrGroup.array();
701
+ const rootFilter = filterOrGroup.or(filterOrGroupList);
702
+ const isGroup = (filterOrGroup$1) => {
703
+ return Reflect.has(filterOrGroup$1, "conjunction");
704
+ };
705
+ const isFilter = (filterOrGroup$1) => {
706
+ return Reflect.has(filterOrGroup$1, "type") && Reflect.has(filterOrGroup$1, "operator");
707
+ };
708
+ const operators = z.union([numberFilterOperators, stringFilterOperators]);
709
+ const operatorsMap = { number: numberFilterOperators.options.map((v) => v.value) };
710
+ const convertStringFilter = (filter$1) => {
711
+ if (filter$1.value === void 0) return None;
712
+ switch (filter$1.operator) {
713
+ case "$eq": return Some(new StringEqual(filter$1.field, new StringFieldValue(filter$1.value), filter$1.relation));
714
+ case "$neq": return Some(new StringNotEqual(filter$1.field, new StringFieldValue(filter$1.value), filter$1.relation));
715
+ case "$contains": return Some(new StringContain(filter$1.field, new StringFieldValue(filter$1.value)));
716
+ case "$not_contains": return Some(new StringContain(filter$1.field, new StringFieldValue(filter$1.value)).not());
717
+ case "$starts_with": return Some(new StringStartsWith(filter$1.field, new StringFieldValue(filter$1.value)));
718
+ case "$ends_with": return Some(new StringEndsWith(filter$1.field, new StringFieldValue(filter$1.value)));
719
+ case "$regex": return Some(new StringRegex(filter$1.field, new StringFieldValue(filter$1.value)));
720
+ case "$is_empty": return Some(new StringEmpty(filter$1.field));
721
+ case "$is_not_empty": return Some(new StringEmpty(filter$1.field).not());
722
+ default: return None;
723
+ }
724
+ };
725
+ const convertNumberFilter = (filter$1) => {
726
+ if (filter$1 === void 0) return None;
727
+ switch (filter$1.operator) {
728
+ case "$eq": return Some(new NumberEqual(filter$1.field, new NumberFieldValue(filter$1.value)));
729
+ case "$neq": return Some(new NumberEqual(filter$1.field, new NumberFieldValue(filter$1.value)).not());
730
+ case "$gt": return Some(new NumberGreaterThan(filter$1.field, new NumberFieldValue(filter$1.value)));
731
+ case "$gte": return Some(new NumberGreaterThanOrEqual(filter$1.field, new NumberFieldValue(filter$1.value)));
732
+ case "$lt": return Some(new NumberLessThan(filter$1.field, new NumberFieldValue(filter$1.value)));
733
+ case "$lte": return Some(new NumberLessThanOrEqual(filter$1.field, new NumberFieldValue(filter$1.value)));
734
+ case "$is_empty": return Some(new NumberEmpty(filter$1.field));
735
+ case "$is_not_empty": return Some(new NumberEmpty(filter$1.field).not());
736
+ default: return None;
737
+ }
738
+ };
739
+ const convertDateFilter = (filter$1) => {
740
+ if (filter$1 === void 0) return None;
741
+ switch (filter$1.operator) {
742
+ case "$eq": return Some(new DateEqual(filter$1.field, DateFieldValue.fromNullableString(filter$1.value), filter$1.relation));
743
+ case "$between": return Some(new DateBetween(filter$1.field, new Date(filter$1.value[0]), new Date(filter$1.value[1])));
744
+ }
745
+ };
746
+ const convertFilter = (filter$1) => {
747
+ return match(filter$1).returnType().with({ type: "number" }, (f) => convertNumberFilter(f)).with({ type: "string" }, (f) => convertStringFilter(f)).with({ type: "date" }, (f) => convertDateFilter(f)).otherwise(() => None);
748
+ };
749
+ const convertFilterOrGroup = (filterOrGroup$1) => {
750
+ if (isGroup(filterOrGroup$1)) return convertFilterOrGroupList(filterOrGroup$1.children, filterOrGroup$1.conjunction);
751
+ else if (isFilter(filterOrGroup$1)) return convertFilter(filterOrGroup$1);
752
+ return None;
753
+ };
754
+ const convertFilterOrGroupList = (filterOrGroupList$1 = [], conjunction = "$and") => {
755
+ let spec = None;
756
+ for (const filter$1 of filterOrGroupList$1) if (spec.isNone()) {
757
+ spec = convertFilterOrGroup(filter$1);
758
+ if (conjunction === "$not") return spec.map((s) => s.not());
759
+ } else if (isFilter(filter$1)) spec = spec.map((left) => {
760
+ const right = convertFilterOrGroup(filter$1);
761
+ if (right.isSome()) {
762
+ if (conjunction === "$and") return left.and(right.unwrap());
763
+ else if (conjunction === "$or") return left.or(right.unwrap());
764
+ return left.and(right.unwrap().not());
765
+ }
766
+ return left;
767
+ });
768
+ else if (isGroup(filter$1)) spec = convertFilterOrGroupList(filter$1.children, filter$1.conjunction);
769
+ return spec;
770
+ };
771
+ const convertFilterSpec = (filter$1) => {
772
+ if (Array.isArray(filter$1)) return convertFilterOrGroupList(filter$1);
773
+ return convertFilterOrGroup(filter$1);
774
+ };
775
+ const isEmptyFilter = (filter$1) => isEmpty(filter$1);
776
+
777
+ //#endregion
778
+ //#region src/filter/fields/date/date-field.type.ts
779
+ const dateFieldValue = z.date().nullable();
780
+
781
+ //#endregion
782
+ //#region src/filter/fields/number/number-field.type.ts
783
+ const numberFieldValue = z.number().or(z.null());
784
+
785
+ //#endregion
786
+ //#region src/filter/fields/string/string-field.type.ts
787
+ const stringFieldValue = z.string().nullable();
788
+
789
+ //#endregion
790
+ //#region src/filter/root-filter.ts
791
+ var RootFilter = class extends ValueObject {
792
+ get value() {
793
+ return this.props;
794
+ }
795
+ get group() {
796
+ if (Array.isArray(this.value)) return {
797
+ conjunction: "$and",
798
+ children: this.value
799
+ };
800
+ if (isGroup(this.value)) return this.value;
801
+ return {
802
+ conjunction: "$and",
803
+ children: [this.value]
804
+ };
805
+ }
806
+ getSpec() {
807
+ return convertFilterSpec(this.value);
808
+ }
809
+ toJSON() {
810
+ return this.props;
811
+ }
812
+ };
813
+
814
+ //#endregion
815
+ //#region src/pagination.ts
816
+ const paginationSchema = z.object({
817
+ limit: z.coerce.number().positive().int().optional(),
818
+ offset: z.coerce.number().nonnegative().int().optional()
819
+ });
820
+ const paginatedResponseSchema = paginationSchema.extend({ total: z.number().nonnegative().int() });
821
+
822
+ //#endregion
823
+ //#region src/query.ts
824
+ var Query = class {};
825
+
826
+ //#endregion
827
+ //#region src/sort.ts
828
+ const sortingSchema = z.record(z.string(), z.enum(["ASC", "DESC"]));
829
+
830
+ //#endregion
831
+ //#region src/value-objects/boolean.vo.ts
832
+ var BoolVO = class BoolVO extends ValueObject {
833
+ constructor(value) {
834
+ super({ value });
835
+ }
836
+ get value() {
837
+ return this.props.value;
838
+ }
839
+ static True() {
840
+ return new BoolVO(true);
841
+ }
842
+ static False() {
843
+ return new BoolVO(false);
844
+ }
845
+ };
846
+
847
+ //#endregion
848
+ //#region src/value-objects/date.vo.ts
849
+ var DateVO = class DateVO extends ValueObject {
850
+ constructor(value) {
851
+ const date = new Date(value);
852
+ super({ value: date });
853
+ }
854
+ get value() {
855
+ return this.props.value;
856
+ }
857
+ static now() {
858
+ return new DateVO(Date.now());
859
+ }
860
+ };
861
+
862
+ //#endregion
863
+ //#region src/value-objects/id.vo.ts
864
+ var ID = class extends ValueObject {
865
+ constructor(value) {
866
+ super({ value });
867
+ }
868
+ get value() {
869
+ return this.props.value;
870
+ }
871
+ };
872
+
873
+ //#endregion
874
+ //#region src/value-objects/nanoid.vo.ts
875
+ var NanoID = class NanoID extends ID {
876
+ static ALPHABETS = "0123456789abcdefghijklmnopqrstuvwxyz";
877
+ static createId(prefix = "", size = 5) {
878
+ const id = customAlphabet(NanoID.ALPHABETS, size)();
879
+ return prefix + id;
880
+ }
881
+ get value() {
882
+ return this.props.value;
883
+ }
884
+ };
885
+
886
+ //#endregion
887
+ //#region src/value-objects/string.vo.ts
888
+ var StringVO = class StringVO extends ValueObject {
889
+ constructor(value) {
890
+ super({ value });
891
+ }
892
+ get value() {
893
+ return this.props.value;
894
+ }
895
+ static empty() {
896
+ return new StringVO("");
897
+ }
898
+ };
899
+
900
+ //#endregion
901
+ export { $between, $contains, $end_eq, $end_gt, $end_gte, $end_lt, $end_lte, $end_neq, $ends_with, $eq, $gt, $gte, $has_file_extension, $has_file_type, $in, $is_empty, $is_false, $is_me, $is_not_empty, $is_not_me, $is_not_today, $is_root, $is_today, $is_tomorrow, $is_true, $is_yesterday, $lt, $lte, $neq, $nin, $not_contains, $regex, $start_eq, $start_gt, $start_gte, $start_lt, $start_lte, $start_neq, $starts_with, AggregateRoot, BaseEvent, BaseFilterSpecification, BoolVO, Command, CompositeSpecification, DateBetween, DateEqual, DateFieldValue, DateGreaterThan, DateGreaterThanOrEqual, DateIsToday, DateIsTomorrow, DateIsYesterday, DateLessThan, DateLessThanOrEqual, DateVO, ExceptionBase, FieldValueBase, ID, NanoID, NumberEmpty, NumberEqual, NumberFieldValue, NumberGreaterThan, NumberGreaterThanOrEqual, NumberLessThan, NumberLessThanOrEqual, Query, RootFilter, StringContain, StringEmpty, StringEndsWith, StringEqual, StringFieldValue, StringNotEqual, StringRegex, StringStartsWith, StringVO, ValueObject, and, andOptions, baseFilter, conjunctions, convertFilterSpec, convertPropsToObject, dateFieldValue, dateFilter, dateFilterOperators, dateFilterValue, eventSchema, filterOrGroupList, filterRoorFilter, isEmptyFilter, isFilter, isGroup, isOperatorWithoutValue, numberFieldValue, numberFilter, numberFilterOperators, numberFilterValue, operators, operatorsMap, operatorsWihtoutValue, or, paginatedResponseSchema, paginationSchema, rootFilter, sortingSchema, stringFieldValue, stringFilter, stringFilterOperators, stringFilterValue };
902
+ //# sourceMappingURL=index.mjs.map