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,113 @@
|
|
|
1
|
+
import mongoose, { Types } from "mongoose"
|
|
2
|
+
import ExtractFieldsOfTypeFlowItem from "./ExtractFieldsOfTypeFlowItem"
|
|
3
|
+
import IsValidObjectIdFlowItem from "./IsValidObjectIdFlowItem"
|
|
4
|
+
import BuildConditionFlowItem from "./BuildConditionFlowItem"
|
|
5
|
+
import BuildRegexFlowItem from "./BuildRegexFlowItem"
|
|
6
|
+
import NormalizeValueFlowItem from "./NormalizeValueFlowItem"
|
|
7
|
+
|
|
8
|
+
class MatchFlowItem {
|
|
9
|
+
exec(filters: any, model: mongoose.Model<any>) {
|
|
10
|
+
|
|
11
|
+
// Recuperar todos os campos do tipo String
|
|
12
|
+
const camposString = !filters.searchTextFields ? ExtractFieldsOfTypeFlowItem.exec(model.schema, 'String') : filters.searchTextFields
|
|
13
|
+
|
|
14
|
+
let andQueriesParam = {} as any
|
|
15
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
16
|
+
if (value !== undefined || value === null) {
|
|
17
|
+
if ([
|
|
18
|
+
'mainFilters',
|
|
19
|
+
'or',
|
|
20
|
+
'filters',
|
|
21
|
+
'withTotalizers',
|
|
22
|
+
'onlyMetadata',
|
|
23
|
+
'projection',
|
|
24
|
+
'pageable',
|
|
25
|
+
'orderSense',
|
|
26
|
+
'orderBy',
|
|
27
|
+
'groupBy',
|
|
28
|
+
'groupDetailed',
|
|
29
|
+
'sumFields',
|
|
30
|
+
'countFields',
|
|
31
|
+
'properties',
|
|
32
|
+
'populate',
|
|
33
|
+
'page',
|
|
34
|
+
'limit',
|
|
35
|
+
'model',
|
|
36
|
+
'select',
|
|
37
|
+
'searchText',
|
|
38
|
+
'searchTextFields',
|
|
39
|
+
'sort',
|
|
40
|
+
'isPageable',
|
|
41
|
+
'searchPageable'].includes(key)) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (typeof value === 'string' && IsValidObjectIdFlowItem.exec(value as string) && key !== 'owner' && key !== 'identifier') {
|
|
46
|
+
value = new Types.ObjectId(value as string)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (value === 'true') {
|
|
50
|
+
value = true
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (value === 'false') {
|
|
54
|
+
value = false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const condition = BuildConditionFlowItem.exec(key, value, model)
|
|
58
|
+
andQueriesParam = { ...andQueriesParam, ...condition }
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
if (filters.searchText && camposString) {
|
|
63
|
+
let regex = BuildRegexFlowItem.exec(filters.searchText)
|
|
64
|
+
let conditions = { $or: [] as any }
|
|
65
|
+
for (let fieldString of camposString) {
|
|
66
|
+
let conditionAux: { [key: string]: any } = {}
|
|
67
|
+
conditionAux[fieldString] = { $regex: regex }
|
|
68
|
+
|
|
69
|
+
conditions.$or.push(conditionAux)
|
|
70
|
+
}
|
|
71
|
+
andQueriesParam = { ...andQueriesParam, ...conditions }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const orPayload: any[] = []
|
|
75
|
+
if (filters?.or) {
|
|
76
|
+
for (const clauseOr of filters?.or) {
|
|
77
|
+
let and: any
|
|
78
|
+
let conditionsAnd: any
|
|
79
|
+
Object.entries(clauseOr).forEach(([key, value]) => {
|
|
80
|
+
if (!value) return
|
|
81
|
+
value = NormalizeValueFlowItem.exec(key, value)
|
|
82
|
+
const condition = BuildConditionFlowItem.exec(key, value, model)
|
|
83
|
+
|
|
84
|
+
if (!conditionsAnd) {
|
|
85
|
+
conditionsAnd = {}
|
|
86
|
+
}
|
|
87
|
+
conditionsAnd = { ...conditionsAnd, ...condition }
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
if (conditionsAnd) {
|
|
91
|
+
and = { $and: [conditionsAnd] }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (and) {
|
|
95
|
+
orPayload.push(and)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let filtersFinal = { ...andQueriesParam } as any
|
|
101
|
+
|
|
102
|
+
if (orPayload.length > 0) {
|
|
103
|
+
if (!filtersFinal.$or) filtersFinal.$or = []
|
|
104
|
+
filtersFinal.$or = [...filtersFinal.$or, ...orPayload]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
return filtersFinal
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export default new MatchFlowItem;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Types } from "mongoose"
|
|
2
|
+
import IsValidObjectIdFlowItem from "./IsValidObjectIdFlowItem"
|
|
3
|
+
|
|
4
|
+
class NormalizeValueFlowItem {
|
|
5
|
+
exec(key: string, value: any) {
|
|
6
|
+
if (typeof value === 'string' && IsValidObjectIdFlowItem.exec(value as string) && key !== 'owner') {
|
|
7
|
+
value = new Types.ObjectId(value as string)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (value === 'true') {
|
|
11
|
+
value = true
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (value === 'false') {
|
|
15
|
+
value = false
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return value
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default new NormalizeValueFlowItem
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
|
|
3
|
+
class PopulateFlowItem {
|
|
4
|
+
exec(populate = [], modelRoot: mongoose.Model<any>): any[] {
|
|
5
|
+
let populateClauses: any[] = []
|
|
6
|
+
populate.forEach((populateField: string) => {
|
|
7
|
+
let [first, ...rest] = populateField.split('.')
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
let fieldDefinition = modelRoot.schema.path(first);
|
|
11
|
+
let typeFirst = fieldDefinition.instance
|
|
12
|
+
|
|
13
|
+
if (typeFirst === 'Array') {
|
|
14
|
+
if (rest?.length) {
|
|
15
|
+
first = [first, rest[0]].join(".")
|
|
16
|
+
rest.splice(0, 1)
|
|
17
|
+
fieldDefinition = modelRoot.schema.path(first);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!fieldDefinition || !fieldDefinition.options || !fieldDefinition.options.ref) {
|
|
22
|
+
throw new Error(`[1]No reference found for populate field: ${populateField}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let modelName = fieldDefinition.options.ref;
|
|
26
|
+
let refModel = mongoose.model(modelName);
|
|
27
|
+
let collectionName = refModel.collection.name;
|
|
28
|
+
|
|
29
|
+
if (!populateClauses.some((populateClause: any) => populateClause?.$lookup?.localField === first)) {
|
|
30
|
+
const populateClauseLookup: any[] = [
|
|
31
|
+
{
|
|
32
|
+
$lookup: {
|
|
33
|
+
from: collectionName, // The collection where user data is stored
|
|
34
|
+
localField: first,
|
|
35
|
+
foreignField: "_id",
|
|
36
|
+
as: first
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
]
|
|
40
|
+
if (typeFirst !== 'Array') {
|
|
41
|
+
populateClauseLookup.push(
|
|
42
|
+
{
|
|
43
|
+
$addFields: {
|
|
44
|
+
[`${first}`]: { $ifNull: [{ $arrayElemAt: [`$${first}`, 0] }, undefined] },
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
populateClauses = [...populateClauses, ...populateClauseLookup]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (rest?.length > 0) {
|
|
54
|
+
let pathRelativeCurrent = first
|
|
55
|
+
for (const nextField of rest) {
|
|
56
|
+
pathRelativeCurrent += `.${nextField}`
|
|
57
|
+
if (populateClauses.some((populateClause: any) => populateClause?.$lookup?.localField.startsWith(pathRelativeCurrent))) {
|
|
58
|
+
break
|
|
59
|
+
}
|
|
60
|
+
fieldDefinition = refModel.schema.path(nextField);
|
|
61
|
+
|
|
62
|
+
if (!fieldDefinition || !fieldDefinition.options || !fieldDefinition.options.ref) {
|
|
63
|
+
throw new Error(`[1]No reference found for populate field: ${populateField}`);
|
|
64
|
+
}
|
|
65
|
+
modelName = fieldDefinition.options.ref;
|
|
66
|
+
refModel = mongoose.model(modelName);
|
|
67
|
+
collectionName = refModel.collection.name;
|
|
68
|
+
|
|
69
|
+
const populateClauseLookup: any = [
|
|
70
|
+
{
|
|
71
|
+
$lookup: {
|
|
72
|
+
from: collectionName,
|
|
73
|
+
localField: pathRelativeCurrent,
|
|
74
|
+
foreignField: "_id",
|
|
75
|
+
as: pathRelativeCurrent
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
if (typeFirst !== 'Array') {
|
|
80
|
+
populateClauseLookup.push(
|
|
81
|
+
{
|
|
82
|
+
$addFields: {
|
|
83
|
+
[`${pathRelativeCurrent}`]: { $ifNull: [{ $arrayElemAt: [`$${pathRelativeCurrent}`, 0] }, undefined] },
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
populateClauses = [...populateClauses, ...populateClauseLookup]
|
|
90
|
+
}
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
return populateClauses
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default new PopulateFlowItem
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class ProjectFlowItem {
|
|
2
|
+
exec(select: any[] = []): any {
|
|
3
|
+
const nested = (projectCurrent: any, field: string, include: boolean) => {
|
|
4
|
+
let [first, ...rest] = field.split('.')
|
|
5
|
+
|
|
6
|
+
if (rest.length === 0) {
|
|
7
|
+
projectCurrent[first] = include ? 1 : 0
|
|
8
|
+
return projectCurrent
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
projectCurrent[first] = {
|
|
12
|
+
...projectCurrent[first],
|
|
13
|
+
...nested(projectCurrent[first] || {}, rest.join("."), include)
|
|
14
|
+
}
|
|
15
|
+
return projectCurrent
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!select?.length) return []
|
|
19
|
+
|
|
20
|
+
let selectClauses = {
|
|
21
|
+
$project: {}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
select.forEach((selectField: string) => {
|
|
25
|
+
let include = selectField.startsWith("-") ? false : true
|
|
26
|
+
selectField = selectField.replace("-", "")
|
|
27
|
+
selectClauses.$project = nested(selectClauses.$project, selectField, include)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
return [selectClauses]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default new ProjectFlowItem
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ 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"
|
|
@@ -17,5 +18,5 @@ import { initialize } from "./utils/Utils"
|
|
|
17
18
|
|
|
18
19
|
(global as any).LoggerRepository = undefined
|
|
19
20
|
|
|
20
|
-
export { AddStagePaginationFlowItem, AddStageSortFlowItem, BuildPipelineToCountJoinFlowItem, BuildPipelineToJoinFlowItem, BuildPopulateSingleFlowItem, BuildSelectSingleFlowItem, C2Flow, ConvertToSearchResponseFlowItem, CrudFlow, IFacet, ILogger, LoggerModel, LoggerSearch, Options, Pagination, SearchFlow, SearchResponse, SearcherFlow, TypeOfOperation, initialize }
|
|
21
|
+
export { AddStagePaginationFlowItem, AddStageSortFlowItem, BuildPipelineToCountJoinFlowItem, BuildPipelineToJoinFlowItem, BuildPopulateSingleFlowItem, BuildSelectSingleFlowItem, C2Flow, ConvertToSearchResponseFlowItem, CrudFlow, IFacet, ILogger, LoggerModel, LoggerSearch, Options, Pagination, SearchFlow, SearchResponse, SearcherFlow, TypeOfOperation, initialize, SearcherV2Flow }
|
|
21
22
|
|