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.
- package/dist/flow/SearcherFlow.js +2 -2
- package/dist/flow/searcher/SearcherV2Flow.d.ts +10 -0
- package/dist/flow/searcher/SearcherV2Flow.js +100 -0
- package/dist/flow/searcher/item/BuildConditionFlowItem.d.ts +6 -0
- package/dist/flow/searcher/item/BuildConditionFlowItem.js +130 -0
- package/dist/flow/searcher/item/BuildPaginationDataFlowItem.d.ts +5 -0
- package/dist/flow/searcher/item/BuildPaginationDataFlowItem.js +35 -0
- package/dist/flow/searcher/item/BuildRegexFlowItem.d.ts +5 -0
- package/dist/flow/searcher/item/BuildRegexFlowItem.js +24 -0
- package/dist/flow/searcher/item/ExtractFieldsOfTypeFlowItem.d.ts +6 -0
- package/dist/flow/searcher/item/ExtractFieldsOfTypeFlowItem.js +32 -0
- package/dist/flow/searcher/item/GetTypeOfFieldInModelFlowItem.d.ts +6 -0
- package/dist/flow/searcher/item/GetTypeOfFieldInModelFlowItem.js +12 -0
- package/dist/flow/searcher/item/GroupFlowItem.d.ts +6 -0
- package/dist/flow/searcher/item/GroupFlowItem.js +80 -0
- package/dist/flow/searcher/item/IsValidObjectIdFlowItem.d.ts +5 -0
- package/dist/flow/searcher/item/IsValidObjectIdFlowItem.js +12 -0
- package/dist/flow/searcher/item/MatchFlowItem.d.ts +6 -0
- package/dist/flow/searcher/item/MatchFlowItem.js +132 -0
- package/dist/flow/searcher/item/NormalizeValueFlowItem.d.ts +5 -0
- package/dist/flow/searcher/item/NormalizeValueFlowItem.js +25 -0
- package/dist/flow/searcher/item/PopulateFlowItem.d.ts +6 -0
- package/dist/flow/searcher/item/PopulateFlowItem.js +101 -0
- package/dist/flow/searcher/item/ProjectFlowItem.d.ts +5 -0
- package/dist/flow/searcher/item/ProjectFlowItem.js +42 -0
- package/dist/flow/searcher/item/SortFlowItem.d.ts +5 -0
- package/dist/flow/searcher/item/SortFlowItem.js +13 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/package.json +1 -1
- package/src/flow/SearcherFlow.ts +2 -2
- package/src/flow/searcher/SearcherV2Flow.ts +65 -0
- package/src/flow/searcher/item/BuildConditionFlowItem.ts +126 -0
- package/src/flow/searcher/item/BuildPaginationDataFlowItem.ts +31 -0
- package/src/flow/searcher/item/BuildRegexFlowItem.ts +20 -0
- package/src/flow/searcher/item/ExtractFieldsOfTypeFlowItem.ts +20 -0
- package/src/flow/searcher/item/GetTypeOfFieldInModelFlowItem.ts +10 -0
- package/src/flow/searcher/item/GroupFlowItem.ts +86 -0
- package/src/flow/searcher/item/IsValidObjectIdFlowItem.ts +8 -0
- package/src/flow/searcher/item/MatchFlowItem.ts +113 -0
- package/src/flow/searcher/item/NormalizeValueFlowItem.ts +22 -0
- package/src/flow/searcher/item/PopulateFlowItem.ts +99 -0
- package/src/flow/searcher/item/ProjectFlowItem.ts +34 -0
- package/src/flow/searcher/item/SortFlowItem.ts +9 -0
- 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,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,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,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
package/src/flow/SearcherFlow.ts
CHANGED
|
@@ -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
|