@archi-code/criteria 1.0.0-alpha.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 (87) hide show
  1. package/dist/cjs/composite-filter.dto.d.ts +8 -0
  2. package/dist/cjs/composite-filter.dto.js +23 -0
  3. package/dist/cjs/composite-filter.dto.js.map +1 -0
  4. package/dist/cjs/converter/mongo-db/mongo-criteria-converter.d.ts +10 -0
  5. package/dist/cjs/converter/mongo-db/mongo-criteria-converter.js +90 -0
  6. package/dist/cjs/converter/mongo-db/mongo-criteria-converter.js.map +1 -0
  7. package/dist/cjs/converter/mongo-db/mongo-query.d.ts +13 -0
  8. package/dist/cjs/converter/mongo-db/mongo-query.js +3 -0
  9. package/dist/cjs/converter/mongo-db/mongo-query.js.map +1 -0
  10. package/dist/cjs/filter-operator.d.ts +14 -0
  11. package/dist/cjs/filter-operator.js +19 -0
  12. package/dist/cjs/filter-operator.js.map +1 -0
  13. package/dist/cjs/index.d.ts +13 -0
  14. package/dist/cjs/index.js +30 -0
  15. package/dist/cjs/index.js.map +1 -0
  16. package/dist/cjs/logical-operator.d.ts +1 -0
  17. package/dist/cjs/logical-operator.js +3 -0
  18. package/dist/cjs/logical-operator.js.map +1 -0
  19. package/dist/cjs/search-criteria.dto.d.ts +11 -0
  20. package/dist/cjs/search-criteria.dto.js +13 -0
  21. package/dist/cjs/search-criteria.dto.js.map +1 -0
  22. package/dist/cjs/search-filter.dto.d.ts +3 -0
  23. package/dist/cjs/search-filter.dto.js +3 -0
  24. package/dist/cjs/search-filter.dto.js.map +1 -0
  25. package/dist/cjs/search-group-by.dto.d.ts +4 -0
  26. package/dist/cjs/search-group-by.dto.js +24 -0
  27. package/dist/cjs/search-group-by.dto.js.map +1 -0
  28. package/dist/cjs/search-order-item.dto.d.ts +4 -0
  29. package/dist/cjs/search-order-item.dto.js +3 -0
  30. package/dist/cjs/search-order-item.dto.js.map +1 -0
  31. package/dist/cjs/search-order.dto.d.ts +5 -0
  32. package/dist/cjs/search-order.dto.js +21 -0
  33. package/dist/cjs/search-order.dto.js.map +1 -0
  34. package/dist/cjs/search-paginator.dto.d.ts +6 -0
  35. package/dist/cjs/search-paginator.dto.js +20 -0
  36. package/dist/cjs/search-paginator.dto.js.map +1 -0
  37. package/dist/cjs/search-query-serializer.d.ts +7 -0
  38. package/dist/cjs/search-query-serializer.js +74 -0
  39. package/dist/cjs/search-query-serializer.js.map +1 -0
  40. package/dist/cjs/simple-filter.dto.d.ts +8 -0
  41. package/dist/cjs/simple-filter.dto.js +52 -0
  42. package/dist/cjs/simple-filter.dto.js.map +1 -0
  43. package/dist/esm/composite-filter.dto.d.ts +8 -0
  44. package/dist/esm/composite-filter.dto.js +19 -0
  45. package/dist/esm/composite-filter.dto.js.map +1 -0
  46. package/dist/esm/converter/mongo-db/mongo-criteria-converter.d.ts +10 -0
  47. package/dist/esm/converter/mongo-db/mongo-criteria-converter.js +86 -0
  48. package/dist/esm/converter/mongo-db/mongo-criteria-converter.js.map +1 -0
  49. package/dist/esm/converter/mongo-db/mongo-query.d.ts +13 -0
  50. package/dist/esm/converter/mongo-db/mongo-query.js +2 -0
  51. package/dist/esm/converter/mongo-db/mongo-query.js.map +1 -0
  52. package/dist/esm/filter-operator.d.ts +14 -0
  53. package/dist/esm/filter-operator.js +16 -0
  54. package/dist/esm/filter-operator.js.map +1 -0
  55. package/dist/esm/index.d.ts +13 -0
  56. package/dist/esm/index.js +14 -0
  57. package/dist/esm/index.js.map +1 -0
  58. package/dist/esm/logical-operator.d.ts +1 -0
  59. package/dist/esm/logical-operator.js +2 -0
  60. package/dist/esm/logical-operator.js.map +1 -0
  61. package/dist/esm/search-criteria.dto.d.ts +11 -0
  62. package/dist/esm/search-criteria.dto.js +9 -0
  63. package/dist/esm/search-criteria.dto.js.map +1 -0
  64. package/dist/esm/search-filter.dto.d.ts +3 -0
  65. package/dist/esm/search-filter.dto.js +2 -0
  66. package/dist/esm/search-filter.dto.js.map +1 -0
  67. package/dist/esm/search-group-by.dto.d.ts +4 -0
  68. package/dist/esm/search-group-by.dto.js +20 -0
  69. package/dist/esm/search-group-by.dto.js.map +1 -0
  70. package/dist/esm/search-order-item.dto.d.ts +4 -0
  71. package/dist/esm/search-order-item.dto.js +2 -0
  72. package/dist/esm/search-order-item.dto.js.map +1 -0
  73. package/dist/esm/search-order.dto.d.ts +5 -0
  74. package/dist/esm/search-order.dto.js +17 -0
  75. package/dist/esm/search-order.dto.js.map +1 -0
  76. package/dist/esm/search-paginator.dto.d.ts +6 -0
  77. package/dist/esm/search-paginator.dto.js +16 -0
  78. package/dist/esm/search-paginator.dto.js.map +1 -0
  79. package/dist/esm/search-query-serializer.d.ts +7 -0
  80. package/dist/esm/search-query-serializer.js +70 -0
  81. package/dist/esm/search-query-serializer.js.map +1 -0
  82. package/dist/esm/simple-filter.dto.d.ts +8 -0
  83. package/dist/esm/simple-filter.dto.js +48 -0
  84. package/dist/esm/simple-filter.dto.js.map +1 -0
  85. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  86. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  87. package/package.json +73 -0
@@ -0,0 +1,10 @@
1
+ import { SearchCriteriaDto } from '../../search-criteria.dto';
2
+ import { MongoQuery } from './mongo-query';
3
+ export declare class MongoCriteriaConverter {
4
+ private operatorMap;
5
+ convert(criteria: SearchCriteriaDto): MongoQuery;
6
+ private generateFilter;
7
+ private generateSimpleFilter;
8
+ private generateSort;
9
+ private generatePagination;
10
+ }
@@ -0,0 +1,86 @@
1
+ import { FilterOperator } from '../../filter-operator';
2
+ import { SimpleFilterDto } from '../../simple-filter.dto';
3
+ import { CompositeFilterDto } from '../../composite-filter.dto';
4
+ export class MongoCriteriaConverter {
5
+ constructor() {
6
+ this.operatorMap = {
7
+ [FilterOperator.EQ]: '$eq',
8
+ [FilterOperator.NE]: '$ne',
9
+ [FilterOperator.GT]: '$gt',
10
+ [FilterOperator.GTE]: '$gte',
11
+ [FilterOperator.LT]: '$lt',
12
+ [FilterOperator.LTE]: '$lte',
13
+ [FilterOperator.LIKE]: '$regex',
14
+ [FilterOperator.ILIKE]: '$regex',
15
+ };
16
+ }
17
+ convert(criteria) {
18
+ const filter = criteria.filters ? this.generateFilter(criteria.filters) : {};
19
+ const sort = criteria.orders ? this.generateSort(criteria.orders) : {};
20
+ const { skip, limit } = this.generatePagination(criteria.paginator);
21
+ return { filter, sort, skip, limit };
22
+ }
23
+ generateFilter(filterDto) {
24
+ if (filterDto instanceof SimpleFilterDto) {
25
+ return this.generateSimpleFilter(filterDto);
26
+ }
27
+ else if (filterDto instanceof CompositeFilterDto) {
28
+ const nestedFilters = filterDto.filters.map((f) => this.generateFilter(f));
29
+ if (filterDto.logicalOperator === 'or') {
30
+ return { $or: nestedFilters };
31
+ }
32
+ else {
33
+ return { $and: nestedFilters };
34
+ }
35
+ }
36
+ throw new Error('Unsupported filter type');
37
+ }
38
+ generateSimpleFilter(filter) {
39
+ const field = filter.field;
40
+ const value = filter.value;
41
+ if (filter.operator === FilterOperator.EQ) {
42
+ return { [field]: value };
43
+ }
44
+ const op = this.operatorMap[filter.operator];
45
+ if (filter.operator === FilterOperator.IN) {
46
+ return { [field]: { $in: Array.isArray(value) ? value : [value] } };
47
+ }
48
+ if (filter.operator === FilterOperator.NIN) {
49
+ return { [field]: { $nin: Array.isArray(value) ? value : [value] } };
50
+ }
51
+ if (filter.operator === FilterOperator.BETWEEN) {
52
+ if (!Array.isArray(value) || value.length !== 2) {
53
+ throw new Error(`BETWEEN operator requires an array of two values for field ${field}`);
54
+ }
55
+ return { [field]: { $gte: value[0], $lte: value[1] } };
56
+ }
57
+ if (filter.operator === FilterOperator.LIKE || filter.operator === FilterOperator.ILIKE) {
58
+ const regexOptions = filter.operator === FilterOperator.ILIKE ? 'i' : '';
59
+ const regexFilter = regexOptions
60
+ ? { $regex: value, $options: regexOptions }
61
+ : { $regex: value };
62
+ return { [field]: regexFilter };
63
+ }
64
+ if (op) {
65
+ return { [field]: { [op]: value } };
66
+ }
67
+ throw new Error(`Operator ${filter.operator} is not supported for Mongo conversion`);
68
+ }
69
+ generateSort(orders) {
70
+ const sort = {};
71
+ orders.orders.forEach((orderItem) => {
72
+ const field = orderItem.field === 'id' ? '_id' : orderItem.field;
73
+ sort[field] = orderItem.direction === 'asc' ? 1 : -1;
74
+ });
75
+ return sort;
76
+ }
77
+ generatePagination(paginator) {
78
+ if (!paginator) {
79
+ return { skip: 0, limit: 0 };
80
+ }
81
+ const skip = (paginator.page - 1) * paginator.perPage;
82
+ const limit = paginator.perPage;
83
+ return { skip, limit };
84
+ }
85
+ }
86
+ //# sourceMappingURL=mongo-criteria-converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo-criteria-converter.js","sourceRoot":"","sources":["../../../../src/converter/mongo-db/mongo-criteria-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAKhE,MAAM,OAAO,sBAAsB;IAAnC;QAEU,gBAAW,GAAyD;YAC1E,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,KAAK;YAC1B,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,KAAK;YAC1B,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,KAAK;YAC1B,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM;YAC5B,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,KAAK;YAC1B,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM;YAC5B,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,QAAQ;YAC/B,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,QAAQ;SAEjC,CAAC;IAkFJ,CAAC;IAhFQ,OAAO,CAAC,QAA2B;QACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAGpE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACvC,CAAC;IAEO,cAAc,CAAC,SAA0B;QAC/C,IAAI,SAAS,YAAY,eAAe,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,SAAS,YAAY,kBAAkB,EAAE,CAAC;YAEnD,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YAE3E,IAAI,SAAS,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;gBACvC,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;YACjC,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAEO,oBAAoB,CAAC,MAAuB;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAG3B,IAAI,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,EAAE,EAAE,CAAC;YAC1C,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAA4B,CAAC;QACtD,CAAC;QAED,MAAM,EAAE,GAAoC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAG9E,IAAI,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,EAAE,EAAE,CAAC;YAC1C,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACtE,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,GAAG,EAAE,CAAC;YAC3C,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACvE,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,OAAO,EAAE,CAAC;YAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChD,MAAM,IAAI,KAAK,CAAC,8DAA8D,KAAK,EAAE,CAAC,CAAC;YACzF,CAAC;YACD,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACzD,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,KAAK,EAAE,CAAC;YACxF,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,MAAM,WAAW,GAAG,YAAY;gBAC9B,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE;gBAC3C,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,WAAW,EAA4B,CAAC;QAC5D,CAAC;QACD,IAAI,EAAE,EAAE,CAAC;YACP,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACtC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,YAAY,MAAM,CAAC,QAAQ,wCAAwC,CAAC,CAAC;IACvF,CAAC;IAEO,YAAY,CAAC,MAAsB;QACzC,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAElC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;YACjE,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,kBAAkB,CAAC,SAA8B;QACvD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC;QAChC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ export type MongoFilterOperator = '$eq' | '$ne' | '$gt' | '$gte' | '$lt' | '$lte' | '$regex' | '$in' | '$nin';
2
+ export type MongoFilter = Record<string, Partial<Record<MongoFilterOperator, any>>> | {
3
+ $or: MongoFilter[];
4
+ } | {
5
+ $and: MongoFilter[];
6
+ };
7
+ export type MongoSort = Record<string, 1 | -1>;
8
+ export interface MongoQuery {
9
+ filter: MongoFilter;
10
+ sort: MongoSort;
11
+ skip: number;
12
+ limit: number;
13
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mongo-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo-query.js","sourceRoot":"","sources":["../../../../src/converter/mongo-db/mongo-query.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ export declare enum FilterOperator {
2
+ EQ = "eq",
3
+ NE = "ne",
4
+ LT = "lt",
5
+ LTE = "lte",
6
+ GT = "gt",
7
+ GTE = "gte",
8
+ IN = "in",
9
+ NIN = "nin",
10
+ BETWEEN = "between",
11
+ LIKE = "like",
12
+ ILIKE = "ilike",
13
+ INARRAY = "inarray"
14
+ }
@@ -0,0 +1,16 @@
1
+ export var FilterOperator;
2
+ (function (FilterOperator) {
3
+ FilterOperator["EQ"] = "eq";
4
+ FilterOperator["NE"] = "ne";
5
+ FilterOperator["LT"] = "lt";
6
+ FilterOperator["LTE"] = "lte";
7
+ FilterOperator["GT"] = "gt";
8
+ FilterOperator["GTE"] = "gte";
9
+ FilterOperator["IN"] = "in";
10
+ FilterOperator["NIN"] = "nin";
11
+ FilterOperator["BETWEEN"] = "between";
12
+ FilterOperator["LIKE"] = "like";
13
+ FilterOperator["ILIKE"] = "ilike";
14
+ FilterOperator["INARRAY"] = "inarray";
15
+ })(FilterOperator || (FilterOperator = {}));
16
+ //# sourceMappingURL=filter-operator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-operator.js","sourceRoot":"","sources":["../../src/filter-operator.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,cAaX;AAbD,WAAY,cAAc;IACxB,2BAAS,CAAA;IACT,2BAAS,CAAA;IACT,2BAAS,CAAA;IACT,6BAAW,CAAA;IACX,2BAAS,CAAA;IACT,6BAAW,CAAA;IACX,2BAAS,CAAA;IACT,6BAAW,CAAA;IACX,qCAAmB,CAAA;IACnB,+BAAa,CAAA;IACb,iCAAe,CAAA;IACf,qCAAmB,CAAA;AACrB,CAAC,EAbW,cAAc,KAAd,cAAc,QAazB"}
@@ -0,0 +1,13 @@
1
+ export * from './converter/mongo-db/mongo-query';
2
+ export * from './converter/mongo-db/mongo-criteria-converter';
3
+ export * from './composite-filter.dto';
4
+ export * from './filter-operator';
5
+ export * from './logical-operator';
6
+ export * from './search-criteria.dto';
7
+ export * from './search-filter.dto';
8
+ export * from './search-group-by.dto';
9
+ export * from './search-order.dto';
10
+ export * from './search-order-item.dto';
11
+ export * from './search-paginator.dto';
12
+ export * from './simple-filter.dto';
13
+ export * from './search-query-serializer';
@@ -0,0 +1,14 @@
1
+ export * from './converter/mongo-db/mongo-query';
2
+ export * from './converter/mongo-db/mongo-criteria-converter';
3
+ export * from './composite-filter.dto';
4
+ export * from './filter-operator';
5
+ export * from './logical-operator';
6
+ export * from './search-criteria.dto';
7
+ export * from './search-filter.dto';
8
+ export * from './search-group-by.dto';
9
+ export * from './search-order.dto';
10
+ export * from './search-order-item.dto';
11
+ export * from './search-paginator.dto';
12
+ export * from './simple-filter.dto';
13
+ export * from './search-query-serializer';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1 @@
1
+ export type LogicalOperator = 'and' | 'or';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logical-operator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logical-operator.js","sourceRoot":"","sources":["../../src/logical-operator.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { SearchFilterDto } from './search-filter.dto';
2
+ import { SearchOrderDto } from './search-order.dto';
3
+ import { SearchPaginatorDto } from './search-paginator.dto';
4
+ import { SearchGroupByDto } from './search-group-by.dto';
5
+ export declare class SearchCriteriaDto {
6
+ readonly filters?: SearchFilterDto | undefined;
7
+ readonly orders?: SearchOrderDto | undefined;
8
+ readonly paginator?: SearchPaginatorDto | undefined;
9
+ readonly groupBy?: SearchGroupByDto | undefined;
10
+ constructor(filters?: SearchFilterDto | undefined, orders?: SearchOrderDto | undefined, paginator?: SearchPaginatorDto | undefined, groupBy?: SearchGroupByDto | undefined);
11
+ }
@@ -0,0 +1,9 @@
1
+ export class SearchCriteriaDto {
2
+ constructor(filters, orders, paginator, groupBy) {
3
+ this.filters = filters;
4
+ this.orders = orders;
5
+ this.paginator = paginator;
6
+ this.groupBy = groupBy;
7
+ }
8
+ }
9
+ //# sourceMappingURL=search-criteria.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-criteria.dto.js","sourceRoot":"","sources":["../../src/search-criteria.dto.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,iBAAiB;IAC5B,YACkB,OAAyB,EACzB,MAAuB,EACvB,SAA8B,EAC9B,OAA0B;QAH1B,YAAO,GAAP,OAAO,CAAkB;QACzB,WAAM,GAAN,MAAM,CAAiB;QACvB,cAAS,GAAT,SAAS,CAAqB;QAC9B,YAAO,GAAP,OAAO,CAAmB;IACzC,CAAC;CACL"}
@@ -0,0 +1,3 @@
1
+ import { SimpleFilterDto } from './simple-filter.dto';
2
+ import { CompositeFilterDto } from './composite-filter.dto';
3
+ export type SearchFilterDto = SimpleFilterDto | CompositeFilterDto;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-filter.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-filter.dto.js","sourceRoot":"","sources":["../../src/search-filter.dto.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export declare class SearchGroupByDto {
2
+ readonly fields: string[];
3
+ constructor(groupBy: string | string[]);
4
+ }
@@ -0,0 +1,20 @@
1
+ export class SearchGroupByDto {
2
+ constructor(groupBy) {
3
+ if (groupBy == null) {
4
+ throw new Error('SearchGroupByDto: groupBy value cannot be null or undefined');
5
+ }
6
+ else if (typeof groupBy === 'string') {
7
+ this.fields = [groupBy];
8
+ }
9
+ else if (Array.isArray(groupBy)) {
10
+ if (!groupBy.every((item) => typeof item === 'string')) {
11
+ throw new Error('SearchGroupByDto: All groupBy fields must be strings');
12
+ }
13
+ this.fields = groupBy;
14
+ }
15
+ else {
16
+ throw new Error('SearchGroupByDto: groupBy must be a string or an array of strings');
17
+ }
18
+ }
19
+ }
20
+ //# sourceMappingURL=search-group-by.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-group-by.dto.js","sourceRoot":"","sources":["../../src/search-group-by.dto.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAgB;IAG3B,YAAY,OAA0B;QACpC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QACjF,CAAC;aAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export interface SearchOrderItemDto {
2
+ field: string;
3
+ direction: 'asc' | 'desc';
4
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-order-item.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-order-item.dto.js","sourceRoot":"","sources":["../../src/search-order-item.dto.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { SearchOrderItemDto } from './search-order-item.dto';
2
+ export declare class SearchOrderDto {
3
+ readonly orders: SearchOrderItemDto[];
4
+ constructor(orders: SearchOrderItemDto[]);
5
+ }
@@ -0,0 +1,17 @@
1
+ export class SearchOrderDto {
2
+ constructor(orders) {
3
+ if (!Array.isArray(orders)) {
4
+ throw new Error('SearchOrderDto: orders must be an array');
5
+ }
6
+ orders.forEach((o) => {
7
+ if (!o.field || typeof o.field !== 'string') {
8
+ throw new Error('SearchOrderDto: Each order must have a non-empty string as field');
9
+ }
10
+ if (o.direction !== 'asc' && o.direction !== 'desc') {
11
+ throw new Error('SearchOrderDto: Each order must have direction "asc" or "desc"');
12
+ }
13
+ });
14
+ this.orders = orders;
15
+ }
16
+ }
17
+ //# sourceMappingURL=search-order.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-order.dto.js","sourceRoot":"","sources":["../../src/search-order.dto.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,cAAc;IAGzB,YAAY,MAA4B;QACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACnB,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5C,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;YACtF,CAAC;YACD,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,IAAI,CAAC,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;gBACpD,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ export declare class SearchPaginatorDto {
2
+ readonly page: number;
3
+ readonly perPage: number;
4
+ constructor(page: number, perPage: number);
5
+ validate(): void;
6
+ }
@@ -0,0 +1,16 @@
1
+ export class SearchPaginatorDto {
2
+ constructor(page, perPage) {
3
+ this.page = typeof page === 'string' ? Number(page) : page;
4
+ this.perPage = typeof perPage === 'string' ? Number(perPage) : perPage;
5
+ this.validate();
6
+ }
7
+ validate() {
8
+ if (!Number.isInteger(this.page) || !Number.isInteger(this.perPage)) {
9
+ throw new Error('SearchPaginatorDto: "page" and "perPage" must be integers');
10
+ }
11
+ if (this.page < 1 || this.perPage < 1) {
12
+ throw new Error('SearchPaginatorDto: "page" and "perPage" must be positive integers');
13
+ }
14
+ }
15
+ }
16
+ //# sourceMappingURL=search-paginator.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-paginator.dto.js","sourceRoot":"","sources":["../../src/search-paginator.dto.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,kBAAkB;IAI7B,YAAY,IAAY,EAAE,OAAe;QAEvC,IAAI,CAAC,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3D,IAAI,CAAC,OAAO,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACvE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { SearchCriteriaDto } from './search-criteria.dto';
2
+ export declare class SearchQuerySerializer {
3
+ static serialize(query: SearchCriteriaDto): string;
4
+ static deserialize(serialized: string): SearchCriteriaDto;
5
+ private static serializeFilter;
6
+ private static deserializeFilter;
7
+ }
@@ -0,0 +1,70 @@
1
+ import { SearchCriteriaDto } from './search-criteria.dto';
2
+ import { SearchOrderDto } from './search-order.dto';
3
+ import { SearchPaginatorDto } from './search-paginator.dto';
4
+ import { CompositeFilterDto } from './composite-filter.dto';
5
+ import { SimpleFilterDto } from './simple-filter.dto';
6
+ import { SearchGroupByDto } from './search-group-by.dto';
7
+ export class SearchQuerySerializer {
8
+ static serialize(query) {
9
+ const obj = {};
10
+ obj.filters = query.filters ? this.serializeFilter(query.filters) : null;
11
+ obj.orders = query.orders
12
+ ? query.orders.orders.map((o) => ({
13
+ field: o.field,
14
+ direction: o.direction,
15
+ }))
16
+ : null;
17
+ obj.paginator = query.paginator
18
+ ? { page: query.paginator.page, perPage: query.paginator.perPage }
19
+ : null;
20
+ obj.groupBy = query.groupBy ? query.groupBy.fields : null;
21
+ return JSON.stringify(obj);
22
+ }
23
+ static deserialize(serialized) {
24
+ let obj;
25
+ try {
26
+ obj = JSON.parse(serialized);
27
+ }
28
+ catch {
29
+ throw new Error('Invalid JSON string');
30
+ }
31
+ const filters = obj.filters ? this.deserializeFilter(obj.filters) : undefined;
32
+ const orders = obj.orders ? new SearchOrderDto(obj.orders) : undefined;
33
+ const paginator = obj.paginator
34
+ ? new SearchPaginatorDto(obj.paginator.page, obj.paginator.perPage)
35
+ : undefined;
36
+ const groupBy = obj.groupBy ? new SearchGroupByDto(obj.groupBy) : undefined;
37
+ return new SearchCriteriaDto(filters, orders, paginator, groupBy);
38
+ }
39
+ static serializeFilter(filter) {
40
+ if (filter instanceof SimpleFilterDto) {
41
+ return {
42
+ type: 'simple',
43
+ field: filter.field,
44
+ operator: filter.operator,
45
+ value: filter.value,
46
+ };
47
+ }
48
+ else if (filter instanceof CompositeFilterDto) {
49
+ return {
50
+ type: 'composite',
51
+ logicalOperator: filter.logicalOperator,
52
+ filters: filter.filters.map((f) => this.serializeFilter(f)),
53
+ };
54
+ }
55
+ throw new Error('Unknown filter type');
56
+ }
57
+ static deserializeFilter(obj) {
58
+ if (obj.type === 'simple') {
59
+ return new SimpleFilterDto(obj.field, obj.operator, obj.value);
60
+ }
61
+ else if (obj.type === 'composite') {
62
+ const subFilters = Array.isArray(obj.filters)
63
+ ? obj.filters.map((sub) => this.deserializeFilter(sub))
64
+ : [];
65
+ return new CompositeFilterDto(obj.logicalOperator, subFilters);
66
+ }
67
+ throw new Error('Unknown filter format');
68
+ }
69
+ }
70
+ //# sourceMappingURL=search-query-serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-query-serializer.js","sourceRoot":"","sources":["../../src/search-query-serializer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { FilterOperator } from './filter-operator';
2
+ export declare class SimpleFilterDto {
3
+ readonly field: string;
4
+ readonly operator: FilterOperator;
5
+ readonly value: string | number | (string | number)[];
6
+ constructor(field: string, operator: FilterOperator, value: string | number | (string | number)[]);
7
+ validate(): void;
8
+ }
@@ -0,0 +1,48 @@
1
+ import { FilterOperator } from './filter-operator';
2
+ export class SimpleFilterDto {
3
+ constructor(field, operator, value) {
4
+ this.field = field;
5
+ this.operator = operator;
6
+ const numericOperators = [
7
+ FilterOperator.LT,
8
+ FilterOperator.LTE,
9
+ FilterOperator.GT,
10
+ FilterOperator.GTE,
11
+ FilterOperator.BETWEEN,
12
+ ];
13
+ if (numericOperators.includes(operator)) {
14
+ if (Array.isArray(value)) {
15
+ this.value = value.map((v) => {
16
+ const num = Number(v);
17
+ if (isNaN(num)) {
18
+ throw new Error(`SimpleFilterDto: Value "${v}" must be a number`);
19
+ }
20
+ return num;
21
+ });
22
+ }
23
+ else {
24
+ const num = Number(value);
25
+ if (isNaN(num)) {
26
+ throw new Error(`SimpleFilterDto: Value "${value}" must be a number`);
27
+ }
28
+ this.value = num;
29
+ }
30
+ }
31
+ else {
32
+ this.value = value;
33
+ }
34
+ this.validate();
35
+ }
36
+ validate() {
37
+ if (!this.field || typeof this.field !== 'string') {
38
+ throw new Error('SimpleFilterDto: "field" must be a non-empty string');
39
+ }
40
+ if (!Object.values(FilterOperator).includes(this.operator)) {
41
+ throw new Error(`SimpleFilterDto: Invalid operator "${this.operator}"`);
42
+ }
43
+ if (this.value === undefined) {
44
+ throw new Error('SimpleFilterDto: "value" is required');
45
+ }
46
+ }
47
+ }
48
+ //# sourceMappingURL=simple-filter.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-filter.dto.js","sourceRoot":"","sources":["../../src/simple-filter.dto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,OAAO,eAAe;IAG1B,YACkB,KAAa,EACb,QAAwB,EACxC,KAA4C;QAF5B,UAAK,GAAL,KAAK,CAAQ;QACb,aAAQ,GAAR,QAAQ,CAAgB;QAIxC,MAAM,gBAAgB,GAAG;YACvB,cAAc,CAAC,EAAE;YACjB,cAAc,CAAC,GAAG;YAClB,cAAc,CAAC,EAAE;YACjB,cAAc,CAAC,GAAG;YAClB,cAAc,CAAC,OAAO;SACvB,CAAC;QACF,IAAI,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;oBACtB,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;wBACf,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,oBAAoB,CAAC,CAAC;oBACpE,CAAC;oBACD,OAAO,GAAG,CAAC;gBACb,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC1B,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,oBAAoB,CAAC,CAAC;gBACxE,CAAC;gBACD,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;YACnB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;CACF"}