c2-mongoose 2.1.319 → 2.1.321

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 (45) hide show
  1. package/dist/flow/SearcherFlow.js +2 -2
  2. package/dist/flow/searcher/SearcherV2Flow.d.ts +10 -0
  3. package/dist/flow/searcher/SearcherV2Flow.js +100 -0
  4. package/dist/flow/searcher/item/BuildConditionFlowItem.d.ts +6 -0
  5. package/dist/flow/searcher/item/BuildConditionFlowItem.js +130 -0
  6. package/dist/flow/searcher/item/BuildPaginationDataFlowItem.d.ts +5 -0
  7. package/dist/flow/searcher/item/BuildPaginationDataFlowItem.js +35 -0
  8. package/dist/flow/searcher/item/BuildRegexFlowItem.d.ts +5 -0
  9. package/dist/flow/searcher/item/BuildRegexFlowItem.js +24 -0
  10. package/dist/flow/searcher/item/ExtractFieldsOfTypeFlowItem.d.ts +6 -0
  11. package/dist/flow/searcher/item/ExtractFieldsOfTypeFlowItem.js +32 -0
  12. package/dist/flow/searcher/item/GetTypeOfFieldInModelFlowItem.d.ts +6 -0
  13. package/dist/flow/searcher/item/GetTypeOfFieldInModelFlowItem.js +12 -0
  14. package/dist/flow/searcher/item/GroupFlowItem.d.ts +6 -0
  15. package/dist/flow/searcher/item/GroupFlowItem.js +80 -0
  16. package/dist/flow/searcher/item/IsValidObjectIdFlowItem.d.ts +5 -0
  17. package/dist/flow/searcher/item/IsValidObjectIdFlowItem.js +12 -0
  18. package/dist/flow/searcher/item/MatchFlowItem.d.ts +6 -0
  19. package/dist/flow/searcher/item/MatchFlowItem.js +132 -0
  20. package/dist/flow/searcher/item/NormalizeValueFlowItem.d.ts +5 -0
  21. package/dist/flow/searcher/item/NormalizeValueFlowItem.js +25 -0
  22. package/dist/flow/searcher/item/PopulateFlowItem.d.ts +6 -0
  23. package/dist/flow/searcher/item/PopulateFlowItem.js +101 -0
  24. package/dist/flow/searcher/item/ProjectFlowItem.d.ts +5 -0
  25. package/dist/flow/searcher/item/ProjectFlowItem.js +42 -0
  26. package/dist/flow/searcher/item/SortFlowItem.d.ts +5 -0
  27. package/dist/flow/searcher/item/SortFlowItem.js +13 -0
  28. package/dist/index.d.ts +2 -1
  29. package/dist/index.js +3 -1
  30. package/package.json +1 -1
  31. package/src/flow/SearcherFlow.ts +2 -2
  32. package/src/flow/searcher/SearcherV2Flow.ts +65 -0
  33. package/src/flow/searcher/item/BuildConditionFlowItem.ts +126 -0
  34. package/src/flow/searcher/item/BuildPaginationDataFlowItem.ts +31 -0
  35. package/src/flow/searcher/item/BuildRegexFlowItem.ts +20 -0
  36. package/src/flow/searcher/item/ExtractFieldsOfTypeFlowItem.ts +20 -0
  37. package/src/flow/searcher/item/GetTypeOfFieldInModelFlowItem.ts +10 -0
  38. package/src/flow/searcher/item/GroupFlowItem.ts +86 -0
  39. package/src/flow/searcher/item/IsValidObjectIdFlowItem.ts +8 -0
  40. package/src/flow/searcher/item/MatchFlowItem.ts +113 -0
  41. package/src/flow/searcher/item/NormalizeValueFlowItem.ts +22 -0
  42. package/src/flow/searcher/item/PopulateFlowItem.ts +99 -0
  43. package/src/flow/searcher/item/ProjectFlowItem.ts +34 -0
  44. package/src/flow/searcher/item/SortFlowItem.ts +9 -0
  45. package/src/index.ts +2 -1
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var mongoose_1 = require("mongoose");
7
+ var IsValidObjectIdFlowItem_1 = __importDefault(require("./IsValidObjectIdFlowItem"));
8
+ var NormalizeValueFlowItem = /** @class */ (function () {
9
+ function NormalizeValueFlowItem() {
10
+ }
11
+ NormalizeValueFlowItem.prototype.exec = function (key, value) {
12
+ if (typeof value === 'string' && IsValidObjectIdFlowItem_1.default.exec(value) && key !== 'owner') {
13
+ value = new mongoose_1.Types.ObjectId(value);
14
+ }
15
+ if (value === 'true') {
16
+ value = true;
17
+ }
18
+ if (value === 'false') {
19
+ value = false;
20
+ }
21
+ return value;
22
+ };
23
+ return NormalizeValueFlowItem;
24
+ }());
25
+ exports.default = new NormalizeValueFlowItem;
@@ -0,0 +1,6 @@
1
+ import mongoose from "mongoose";
2
+ declare class PopulateFlowItem {
3
+ exec(populate: never[] | undefined, modelRoot: mongoose.Model<any>): any[];
4
+ }
5
+ declare const _default: PopulateFlowItem;
6
+ export default _default;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ var mongoose_1 = __importDefault(require("mongoose"));
16
+ var PopulateFlowItem = /** @class */ (function () {
17
+ function PopulateFlowItem() {
18
+ }
19
+ PopulateFlowItem.prototype.exec = function (populate, modelRoot) {
20
+ if (populate === void 0) { populate = []; }
21
+ var populateClauses = [];
22
+ populate.forEach(function (populateField) {
23
+ var _a, _b;
24
+ var _c = populateField.split('.'), first = _c[0], rest = _c.slice(1);
25
+ var fieldDefinition = modelRoot.schema.path(first);
26
+ var typeFirst = fieldDefinition.instance;
27
+ if (typeFirst === 'Array') {
28
+ if (rest === null || rest === void 0 ? void 0 : rest.length) {
29
+ first = [first, rest[0]].join(".");
30
+ rest.splice(0, 1);
31
+ fieldDefinition = modelRoot.schema.path(first);
32
+ }
33
+ }
34
+ if (!fieldDefinition || !fieldDefinition.options || !fieldDefinition.options.ref) {
35
+ throw new Error("[1]No reference found for populate field: ".concat(populateField));
36
+ }
37
+ var modelName = fieldDefinition.options.ref;
38
+ var refModel = mongoose_1.default.model(modelName);
39
+ var collectionName = refModel.collection.name;
40
+ if (!populateClauses.some(function (populateClause) { var _a; return ((_a = populateClause === null || populateClause === void 0 ? void 0 : populateClause.$lookup) === null || _a === void 0 ? void 0 : _a.localField) === first; })) {
41
+ var populateClauseLookup = [
42
+ {
43
+ $lookup: {
44
+ from: collectionName,
45
+ localField: first,
46
+ foreignField: "_id",
47
+ as: first
48
+ }
49
+ },
50
+ ];
51
+ if (typeFirst !== 'Array') {
52
+ populateClauseLookup.push({
53
+ $addFields: (_a = {},
54
+ _a["".concat(first)] = { $ifNull: [{ $arrayElemAt: ["$".concat(first), 0] }, undefined] },
55
+ _a)
56
+ });
57
+ }
58
+ populateClauses = __spreadArray(__spreadArray([], populateClauses, true), populateClauseLookup, true);
59
+ }
60
+ if ((rest === null || rest === void 0 ? void 0 : rest.length) > 0) {
61
+ var pathRelativeCurrent_1 = first;
62
+ for (var _i = 0, rest_1 = rest; _i < rest_1.length; _i++) {
63
+ var nextField = rest_1[_i];
64
+ pathRelativeCurrent_1 += ".".concat(nextField);
65
+ if (populateClauses.some(function (populateClause) { var _a; return (_a = populateClause === null || populateClause === void 0 ? void 0 : populateClause.$lookup) === null || _a === void 0 ? void 0 : _a.localField.startsWith(pathRelativeCurrent_1); })) {
66
+ break;
67
+ }
68
+ fieldDefinition = refModel.schema.path(nextField);
69
+ if (!fieldDefinition || !fieldDefinition.options || !fieldDefinition.options.ref) {
70
+ throw new Error("[1]No reference found for populate field: ".concat(populateField));
71
+ }
72
+ modelName = fieldDefinition.options.ref;
73
+ refModel = mongoose_1.default.model(modelName);
74
+ collectionName = refModel.collection.name;
75
+ var populateClauseLookup = [
76
+ {
77
+ $lookup: {
78
+ from: collectionName,
79
+ localField: pathRelativeCurrent_1,
80
+ foreignField: "_id",
81
+ as: pathRelativeCurrent_1
82
+ }
83
+ }
84
+ ];
85
+ if (typeFirst !== 'Array') {
86
+ populateClauseLookup.push({
87
+ $addFields: (_b = {},
88
+ _b["".concat(pathRelativeCurrent_1)] = { $ifNull: [{ $arrayElemAt: ["$".concat(pathRelativeCurrent_1), 0] }, undefined] },
89
+ _b)
90
+ });
91
+ }
92
+ populateClauses = __spreadArray(__spreadArray([], populateClauses, true), populateClauseLookup, true);
93
+ }
94
+ return;
95
+ }
96
+ });
97
+ return populateClauses;
98
+ };
99
+ return PopulateFlowItem;
100
+ }());
101
+ exports.default = new PopulateFlowItem;
@@ -0,0 +1,5 @@
1
+ declare class ProjectFlowItem {
2
+ exec(select?: any[]): any;
3
+ }
4
+ declare const _default: ProjectFlowItem;
5
+ export default _default;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ var ProjectFlowItem = /** @class */ (function () {
15
+ function ProjectFlowItem() {
16
+ }
17
+ ProjectFlowItem.prototype.exec = function (select) {
18
+ if (select === void 0) { select = []; }
19
+ var nested = function (projectCurrent, field, include) {
20
+ var _a = field.split('.'), first = _a[0], rest = _a.slice(1);
21
+ if (rest.length === 0) {
22
+ projectCurrent[first] = include ? 1 : 0;
23
+ return projectCurrent;
24
+ }
25
+ projectCurrent[first] = __assign(__assign({}, projectCurrent[first]), nested(projectCurrent[first] || {}, rest.join("."), include));
26
+ return projectCurrent;
27
+ };
28
+ if (!(select === null || select === void 0 ? void 0 : select.length))
29
+ return [];
30
+ var selectClauses = {
31
+ $project: {}
32
+ };
33
+ select.forEach(function (selectField) {
34
+ var include = selectField.startsWith("-") ? false : true;
35
+ selectField = selectField.replace("-", "");
36
+ selectClauses.$project = nested(selectClauses.$project, selectField, include);
37
+ });
38
+ return [selectClauses];
39
+ };
40
+ return ProjectFlowItem;
41
+ }());
42
+ exports.default = new ProjectFlowItem;
@@ -0,0 +1,5 @@
1
+ declare class SortFlowItem {
2
+ exec(orderBy: string, orderSense: string): any[];
3
+ }
4
+ declare const _default: SortFlowItem;
5
+ export default _default;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var SortFlowItem = /** @class */ (function () {
4
+ function SortFlowItem() {
5
+ }
6
+ SortFlowItem.prototype.exec = function (orderBy, orderSense) {
7
+ var sort = {};
8
+ sort[orderBy] = orderSense === "desc" ? -1 : 1;
9
+ return [{ $sort: sort }];
10
+ };
11
+ return SortFlowItem;
12
+ }());
13
+ exports.default = new SortFlowItem;
package/dist/index.d.ts CHANGED
@@ -9,9 +9,10 @@ import BuildPipelineToJoinFlowItem from "./flow/item/BuildPipelineToJoinFlowItem
9
9
  import BuildPopulateSingleFlowItem from "./flow/item/BuildPopulateSingleFlowItem";
10
10
  import BuildSelectSingleFlowItem from "./flow/item/BuildSelectSingleFlowItem";
11
11
  import ConvertToSearchResponseFlowItem from "./flow/item/ConvertToSearchResponseFlowItem";
12
+ import SearcherV2Flow from "./flow/searcher/SearcherV2Flow";
12
13
  import { IFacet } from "./model/Facet";
13
14
  import { ILogger, LoggerModel, LoggerSearch, TypeOfOperation } from "./model/Logger";
14
15
  import { Options } from "./types/Options";
15
16
  import { Pagination, SearchResponse } from "./types/SearchResponse";
16
17
  import { initialize } from "./utils/Utils";
17
- export { AddStagePaginationFlowItem, AddStageSortFlowItem, BuildPipelineToCountJoinFlowItem, BuildPipelineToJoinFlowItem, BuildPopulateSingleFlowItem, BuildSelectSingleFlowItem, C2Flow, ConvertToSearchResponseFlowItem, CrudFlow, IFacet, ILogger, LoggerModel, LoggerSearch, Options, Pagination, SearchFlow, SearchResponse, SearcherFlow, TypeOfOperation, initialize };
18
+ export { AddStagePaginationFlowItem, AddStageSortFlowItem, BuildPipelineToCountJoinFlowItem, BuildPipelineToJoinFlowItem, BuildPopulateSingleFlowItem, BuildSelectSingleFlowItem, C2Flow, ConvertToSearchResponseFlowItem, CrudFlow, IFacet, ILogger, LoggerModel, LoggerSearch, Options, Pagination, SearchFlow, SearchResponse, SearcherFlow, TypeOfOperation, initialize, SearcherV2Flow };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.initialize = exports.TypeOfOperation = exports.SearcherFlow = exports.SearchFlow = exports.LoggerSearch = exports.LoggerModel = exports.CrudFlow = exports.ConvertToSearchResponseFlowItem = exports.C2Flow = exports.BuildSelectSingleFlowItem = exports.BuildPopulateSingleFlowItem = exports.BuildPipelineToJoinFlowItem = exports.BuildPipelineToCountJoinFlowItem = exports.AddStageSortFlowItem = exports.AddStagePaginationFlowItem = void 0;
6
+ exports.SearcherV2Flow = exports.initialize = exports.TypeOfOperation = exports.SearcherFlow = exports.SearchFlow = exports.LoggerSearch = exports.LoggerModel = exports.CrudFlow = exports.ConvertToSearchResponseFlowItem = exports.C2Flow = exports.BuildSelectSingleFlowItem = exports.BuildPopulateSingleFlowItem = exports.BuildPipelineToJoinFlowItem = exports.BuildPipelineToCountJoinFlowItem = exports.AddStageSortFlowItem = exports.AddStagePaginationFlowItem = void 0;
7
7
  var C2Flow_1 = __importDefault(require("./flow/C2Flow"));
8
8
  exports.C2Flow = C2Flow_1.default;
9
9
  var CrudFlow_1 = __importDefault(require("./flow/CrudFlow"));
@@ -26,6 +26,8 @@ var BuildSelectSingleFlowItem_1 = __importDefault(require("./flow/item/BuildSele
26
26
  exports.BuildSelectSingleFlowItem = BuildSelectSingleFlowItem_1.default;
27
27
  var ConvertToSearchResponseFlowItem_1 = __importDefault(require("./flow/item/ConvertToSearchResponseFlowItem"));
28
28
  exports.ConvertToSearchResponseFlowItem = ConvertToSearchResponseFlowItem_1.default;
29
+ var SearcherV2Flow_1 = __importDefault(require("./flow/searcher/SearcherV2Flow"));
30
+ exports.SearcherV2Flow = SearcherV2Flow_1.default;
29
31
  var Logger_1 = require("./model/Logger");
30
32
  Object.defineProperty(exports, "LoggerModel", { enumerable: true, get: function () { return Logger_1.LoggerModel; } });
31
33
  Object.defineProperty(exports, "LoggerSearch", { enumerable: true, get: function () { return Logger_1.LoggerSearch; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c2-mongoose",
3
- "version": "2.1.319",
3
+ "version": "2.1.321",
4
4
  "description": "Lib to make any search in database mongoose and use as basic crud",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -219,14 +219,14 @@ class SearcherFlow<D> {
219
219
  if (isNotEmpty(values[0])) {
220
220
  condition[fieldName] = {
221
221
  ...condition[fieldName],
222
- $gte: values[0]
222
+ $gte: Number(values[0])
223
223
  }
224
224
  }
225
225
 
226
226
  if (isNotEmpty(values[1])) {
227
227
  condition[fieldName] = {
228
228
  ...condition[fieldName],
229
- $lte: values[1]
229
+ $lte: Number(values[1])
230
230
  }
231
231
  }
232
232
  } else if (key.endsWith('Like')) {
@@ -0,0 +1,65 @@
1
+ import mongoose from "mongoose"
2
+ import GroupFlowItem from "./item/GroupFlowItem"
3
+ import PopulateFlowItem from "./item/PopulateFlowItem"
4
+ import SortFlowItem from "./item/SortFlowItem"
5
+ import ProjectFlowItem from "./item/ProjectFlowItem"
6
+ import MatchFlowItem from "./item/MatchFlowItem"
7
+ import BuildPaginationDataFlowItem from "./item/BuildPaginationDataFlowItem"
8
+
9
+ export interface IParams {
10
+ [key: string]: any
11
+ mainFilter: any
12
+ }
13
+
14
+ class SearcherV2Flow {
15
+
16
+ async exec(params: IParams, model: mongoose.Model<any>) {
17
+ const facet: any = {}
18
+ let pipelineFacetPaging: any[] = []
19
+ let pipelineFacetItems: any[] = [
20
+ ...GroupFlowItem.exec(params.groupBy, params.sumFields, params.groupDetailed, model),
21
+ ...PopulateFlowItem.exec(params.populate, model),
22
+ ...MatchFlowItem.exec(params, model),
23
+ ...SortFlowItem.exec(params.orderBy, params.orderSense),
24
+ ...ProjectFlowItem.exec(params.select),
25
+ ]
26
+
27
+
28
+ if (params.pageable) {
29
+ pipelineFacetItems = [
30
+ ...pipelineFacetItems,
31
+ { $skip: ((params.page - 1) * params.limit) },
32
+ { $limit: params.limit }
33
+ ]
34
+
35
+ pipelineFacetPaging = [
36
+ ...GroupFlowItem.exec(params.groupBy, params.sumFields, params.groupDetailed, model),
37
+ ...PopulateFlowItem.exec(params.populate, model),
38
+ ...MatchFlowItem.exec(params, model),
39
+ ...BuildPaginationDataFlowItem.exec(params.page, params.limit),
40
+ ]
41
+ facet.paging = pipelineFacetPaging
42
+ }
43
+ facet.items = pipelineFacetItems
44
+
45
+ let result = await model.aggregate([
46
+ {
47
+ $match: MatchFlowItem.exec(params.mainFilter, model)
48
+ },
49
+ {
50
+ $facet: facet
51
+ }
52
+ ])
53
+
54
+ const ret: any = {}
55
+ ret.items = result[0].items
56
+
57
+ if (params.pageable) {
58
+ ret.paging = result[0].paging[0]
59
+ }
60
+
61
+ return ret
62
+ }
63
+ }
64
+
65
+ export default new SearcherV2Flow
@@ -0,0 +1,126 @@
1
+ import moment from "moment"
2
+ import mongoose, { Types } from "mongoose"
3
+ import BuildRegexFlowItem from "./BuildRegexFlowItem"
4
+ import IsValidObjectIdFlowItem from "./IsValidObjectIdFlowItem"
5
+
6
+ class BuildConditionFlowItem {
7
+ exec(key: string, value: any, model: mongoose.Model<any>) {
8
+ let condition = {} as any
9
+ if (key.endsWith('DateRange')) {
10
+ var fieldName = key.replace('Range', '')
11
+ var values = value as any
12
+ if (values[0]) {
13
+ var momentValue = moment(values[0])
14
+ momentValue.hour(0)
15
+ momentValue.minute(0)
16
+ momentValue.second(0)
17
+ condition[fieldName] = {
18
+ ...condition[fieldName],
19
+ $gte: momentValue.tz('America/Sao_Paulo', false).toDate()
20
+ }
21
+ }
22
+
23
+ if (values[1]) {
24
+ var momentValue = moment(values[1])
25
+ momentValue.hour(23)
26
+ momentValue.minute(59)
27
+ momentValue.second(59)
28
+ condition[fieldName] = {
29
+ ...condition[fieldName],
30
+ $lte: momentValue.tz('America/Sao_Paulo', false).toDate()
31
+ }
32
+ }
33
+ } else if (key.endsWith('DateTimeRange')) {
34
+ var fieldName = key.replace('Range', '')
35
+ var values = value as any
36
+ if (values[0]) {
37
+ var momentValue = moment(values[0])
38
+ condition[fieldName] = {
39
+ ...condition[fieldName],
40
+ $gte: momentValue.tz('America/Sao_Paulo', false).toDate()
41
+ }
42
+ }
43
+
44
+ if (values[1]) {
45
+ var momentValue = moment(values[1])
46
+ condition[fieldName] = {
47
+ ...condition[fieldName],
48
+ $lte: momentValue.tz('America/Sao_Paulo', false).toDate()
49
+ }
50
+ }
51
+ } else if (key.endsWith('Range')) {
52
+ var fieldName = key.replace('Range', '')
53
+ var values = value as any
54
+ if (values[0]) {
55
+ condition[fieldName] = {
56
+ ...condition[fieldName],
57
+ $gte: Number(values[0])
58
+ }
59
+ }
60
+
61
+ if (values[1]) {
62
+ condition[fieldName] = {
63
+ ...condition[fieldName],
64
+ $lte: Number(values[1])
65
+ }
66
+ }
67
+ } else if (key.endsWith('Like')) {
68
+ var fieldName = key.replace('Like', '')
69
+ condition[fieldName] = BuildRegexFlowItem.exec(value as string) //{ $regex: value as any, $options: 'i' }
70
+ } else if (key.endsWith("AtLeastOneExists")) {
71
+ key = key.replace("AtLeastOneExists", "");
72
+
73
+ const fields = key.split('.')
74
+ if (!fields) return condition;
75
+
76
+ condition[fields[0]] = { $elemMatch: { [fields[1]]: { $exists: value as boolean } } }
77
+ } else if (key.endsWith('Exists')) {
78
+ var fieldName = key.replace('Exists', '')
79
+ condition[fieldName] = { $exists: value as boolean }
80
+ } else if (key.endsWith("IsEmpty")) {
81
+ key = key.replace("IsEmpty", "");
82
+ condition[key] = value ? { $size: 0 } : { $not: { $size: 0 } };
83
+ } else {
84
+ if (model?.schema?.paths[key]?.instance === 'Array') {
85
+ if (!Array.isArray(value)) {
86
+ value = [value]
87
+ }
88
+
89
+ (value as [])?.forEach((v: any) => {
90
+ if (typeof v === 'string' && IsValidObjectIdFlowItem.exec(v)) {
91
+ v = new Types.ObjectId(v);
92
+ }
93
+ })
94
+
95
+ if (key.endsWith("NotIn")) {
96
+ key = key.replace("NotIn", "");
97
+ condition[key] = { $nin: value };
98
+ } else {
99
+ condition[key] = { $in: value };
100
+ }
101
+ } else if (Array.isArray(value)) {
102
+ var arr = [];
103
+ for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
104
+ var val = value_1[_i];
105
+ if (typeof val === 'string' && IsValidObjectIdFlowItem.exec(val)) {
106
+ val = new Types.ObjectId(val);
107
+ }
108
+ arr.push(val);
109
+ }
110
+ if (key.endsWith("NotIn")) {
111
+ key = key.replace("NotIn", "");
112
+ condition[key] = { $nin: arr };
113
+ } else {
114
+ condition[key] = { $in: arr };
115
+ }
116
+ } else {
117
+ condition[key] = value;
118
+ }
119
+ }
120
+
121
+ return condition
122
+
123
+ }
124
+ }
125
+
126
+ export default new BuildConditionFlowItem
@@ -0,0 +1,31 @@
1
+ class BuildPaginationDataFlowItem {
2
+ exec(page: number, limit: number): any[] {
3
+ return [
4
+ { $count: "total" },
5
+ {
6
+ $addFields: {
7
+ page: page,
8
+ limit: limit,
9
+ total: "$total",
10
+ totalPages: {
11
+ $cond: {
12
+ if: { $eq: ['$total', 0] },
13
+ then: 0,
14
+ else: { $ceil: { $divide: ['$total', limit] } }
15
+ }
16
+ },
17
+ startIndex: { $subtract: [{ $multiply: [page, limit] }, limit - 1] },
18
+ endIndex: {
19
+ $cond: {
20
+ if: { $gt: [{ $multiply: [page, limit] }, "$total"] },
21
+ then: "$total",
22
+ else: { $multiply: [page, limit] }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ]
28
+ }
29
+ }
30
+
31
+ export default new BuildPaginationDataFlowItem
@@ -0,0 +1,20 @@
1
+ class BuildRegexFlowItem {
2
+ exec(searchText: string): RegExp {
3
+ const regexExpression = searchText
4
+ .replace(/[+?^${}()|[\]\\]/g, '\\$&') //Tratar os caracteres que podem ser chaves, escape os demais q podem ser regex
5
+ .replace(/^"/, '^').replace(/"$/, '$') //Replace aspas duplas para busca exata
6
+ .replace(/^%22/, '^').replace(/%22$/, '$') //Replace aspas duplas para busca exata
7
+ .replace(/%20/, ' ') //Replace espaço em branco para nao quebrar o proximo replace
8
+ .replace(/\*/g, '.*?') //Replace % para o padrão regex (% é muito utilizado como o .*? e é mais simples para o usuario digitar)
9
+ .replace(/%/g, '.*?') //Replace % para o padrão regex (% é muito utilizado como o .*? e é mais simples para o usuario digitar)
10
+ .replace(/[ç|Ç|c|C]/g, '[c,C,ç,Ç]')
11
+ .replace(/[a|á|à|ä|â|A|Á|Â|Ã|Ä]/g, '[a,á,à,ä,â,A,Á,Â,Ã,Ä]')
12
+ .replace(/[e|é|ë|è|E|É|Ë|È]/g, '[e,é,ë,è,E,É,Ë,È]')
13
+ .replace(/[i|í|ï|ì|I|Í|Ï|Ì]/g, '[i,í,ï,ì,I,Í,Ï,Ì]')
14
+ .replace(/[o|ó|ö|ò|õ|O|Ó|Ö|Ô|Õ]/g, '[o,ó,ö,ò,õ,O,Ó,Ö,Ô,Õ]')
15
+ .replace(/[u|ü|ú|ù|U|Ú|Ü|Ù]/g, '[u,ü,ú,ù,U,Ú,Ü,Ù]')
16
+ return new RegExp(`${regexExpression}`, 'i');
17
+ }
18
+ }
19
+
20
+ export default new BuildRegexFlowItem
@@ -0,0 +1,20 @@
1
+ import { Schema } from "mongoose"
2
+
3
+ class ExtractFieldsOfTypeFlowItem {
4
+
5
+ exec(schema: Schema, typing = 'String', parent = ''): string[] {
6
+ let fieldsTyped: string[] = []
7
+ Object.keys(schema.paths).forEach((field: string) => {
8
+ if (schema.paths[field].instance === typing) {
9
+ fieldsTyped.push(`${parent !== '' ? `${parent}.` : ''}${field}`)
10
+ } else if (schema.paths[field].instance === 'Embedded') {
11
+ fieldsTyped = [...fieldsTyped, ...this.exec(schema.paths[field].schema, typing, field)]
12
+ }
13
+ })
14
+
15
+ return fieldsTyped
16
+ }
17
+
18
+ }
19
+
20
+ export default new ExtractFieldsOfTypeFlowItem
@@ -0,0 +1,10 @@
1
+ import mongoose from "mongoose"
2
+
3
+ class GetTypeOfFieldInModelFlowItem {
4
+ exec(fieldToGroup: string, modelRoot: mongoose.Model<any, {}, {}, {}, any, any>): string {
5
+ let fieldDefinition = modelRoot.schema.path(fieldToGroup)
6
+ return fieldDefinition.instance
7
+ }
8
+ }
9
+
10
+ export default new GetTypeOfFieldInModelFlowItem
@@ -0,0 +1,86 @@
1
+ import mongoose from "mongoose";
2
+ import GetTypeOfFieldInModelFlowItem from "./GetTypeOfFieldInModelFlowItem";
3
+
4
+ class GroupFlowItem {
5
+ exec(fieldToGroup: string, sumFields: string, detailed: boolean, modelRoot: mongoose.Model<any>): any[] {
6
+ if (!fieldToGroup) return []
7
+
8
+ const sumField = sumFields ? sumFields[0] : undefined
9
+
10
+ const groupsClauses = []
11
+
12
+ let [first] = fieldToGroup.split('.')
13
+ const typeOfFieldToGroup = GetTypeOfFieldInModelFlowItem.exec(first, modelRoot)
14
+ if (typeOfFieldToGroup === "Array") {
15
+ groupsClauses.push({
16
+ $unwind: {
17
+ path: `$${first}`,
18
+ preserveNullAndEmptyArrays: true,
19
+ }
20
+ })
21
+ }
22
+
23
+ let groupField: any = `$${fieldToGroup}`
24
+ // Check if the field ends with "Date" and add day precision
25
+ if (fieldToGroup.endsWith("Date") || fieldToGroup.endsWith("DateTime")) {
26
+ groupField = {
27
+ $dateToString: {
28
+ format: "%Y-%m-%d",
29
+ date: `$${fieldToGroup}`
30
+ }
31
+ }
32
+ }
33
+
34
+ const groupClause: any = {
35
+ $group: {
36
+ _id: groupField,
37
+ count: { $sum: 1 }
38
+ }
39
+ }
40
+
41
+ if (detailed) {
42
+ groupClause.$group.docs = { $push: "$$ROOT" }
43
+ }
44
+
45
+
46
+ if (sumField) {
47
+ const tempFieldName = sumField.replace(/\./g, '_')
48
+
49
+ let [firstSumField] = sumField.split('.')
50
+ const typeOfFieldToSum = GetTypeOfFieldInModelFlowItem.exec(firstSumField, modelRoot)
51
+
52
+ if (typeOfFieldToSum === "Array") {
53
+ groupClause.$group[tempFieldName] = { $sum: { $sum: { '$ifNull': [`$${sumField}`, 0] } } }
54
+ } else {
55
+ groupClause.$group[tempFieldName] = { $sum: { $ifNull: [`$${sumField}`, 0] } }
56
+ }
57
+ groupsClauses.push(groupClause)
58
+ } else {
59
+ groupsClauses.push(groupClause)
60
+ }
61
+
62
+
63
+ const projectClause: any = {
64
+ $project: {
65
+ _id: 1,
66
+ [fieldToGroup]: "$_id",
67
+ count: 1
68
+ }
69
+ }
70
+
71
+ if (detailed) {
72
+ projectClause.$project.docs = 1
73
+ }
74
+
75
+ if (sumField) {
76
+ const tempFieldName = sumField.replace(/\./g, '_')
77
+ projectClause.$project[`${sumField}Total`] = `$${tempFieldName}`
78
+ }
79
+
80
+ groupsClauses.push(projectClause)
81
+
82
+ return groupsClauses
83
+ }
84
+ }
85
+
86
+ export default new GroupFlowItem
@@ -0,0 +1,8 @@
1
+ class IsValidObjectIdFlowItem {
2
+ exec(value: string): boolean {
3
+ const objectIdPattern = /^[0-9a-fA-F]{24}$/;
4
+ return objectIdPattern.test(value);
5
+ }
6
+ }
7
+
8
+ export default new IsValidObjectIdFlowItem