c2-mongoose 2.1.13 → 2.1.17

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.
@@ -1,238 +1,238 @@
1
- import moment from "moment"
2
- import mongoose from "mongoose"
3
- import { dbCollation } from "../configuration/Environment"
4
- import { Pagination, SearchResponse } from "../types/SearchResponse"
5
- import { isEmpty, isNotEmpty } from "../utils/Utils"
6
-
7
- abstract class SearchFlow {
8
- searchText: string
9
- order: string
10
- orderBy: string
11
- page: number
12
- limit: number
13
- select: string
14
- populate: any
15
- filters: any
16
-
17
- constructor(params: any) {
18
- this.searchText = params.searchText || ""
19
- this.order = params.order || "asc"
20
- this.orderBy = params.orderBy || "_id"
21
- this.select = params.select
22
- this.populate = params.populate
23
- this.page = params.page || undefined
24
- this.limit = params.limit || 25
25
- this.buildPopulate()
26
- }
27
-
28
- public buildPopulate(): any {
29
- if (isEmpty(this.populate)) {
30
- return
31
- }
32
-
33
- var propertiesArray = this.populate.toString().split(',')
34
- var populates = [] as any
35
- for (var property of propertiesArray) {
36
- let [first, ...rest] = property.split('.')
37
- let nested = rest.join('.')
38
- populates.push(this.buildPath(first, nested))
39
- }
40
-
41
- this.populate = populates
42
- }
43
-
44
- public buildPath(target: string, nested: string = "") {
45
- var populate = {} as any
46
- populate.path = target
47
- if (isNotEmpty(nested)) {
48
- let [first, ...rest] = nested.split('.')
49
- let nested2 = rest.join('.')
50
- populate.populate = this.buildPath(first, nested2)
51
- }
52
- return populate
53
- }
54
-
55
- public buildOrdenation() {
56
- let order = {} as any
57
- this.orderBy = this.orderBy || "_id"
58
- order[this.orderBy] = this.order === "desc" ? -1 : 1
59
- return order
60
- }
61
-
62
- private isPageable = () => {
63
- if (isEmpty(this.page)) {
64
- this.page = 1
65
- }
66
-
67
- if (this.page >= 0) {
68
- return true
69
- }
70
-
71
- return false
72
- }
73
-
74
- public diacriticSensitiveRegex(string: string = ""): string {
75
- return string
76
- .replace(/[a|á|à|ä|â|A|Á|Â|Ã|Ä]/g, '[a,á,à,ä,â,A,Á,Â,Ã,Ä]')
77
- .replace(/[e|é|ë|è|E|É|Ë|È]/g, '[e,é,ë,è,E,É,Ë,È]')
78
- .replace(/[i|í|ï|ì|I|Í|Ï|Ì]/g, '[i,í,ï,ì,I,Í,Ï,Ì]')
79
- .replace(/[o|ó|ö|ò|õ|O|Ó|Ö|Ô|Õ]/g, '[o,ó,ö,ò,õ,O,Ó,Ö,Ô,Õ]')
80
- .replace(/[u|ü|ú|ù|U|Ú|Ü|Ù]/g, '[u,ü,ú,ù,U,Ú,Ü,Ù]')
81
- .replace(/[ç|Ç|c|C]/g, '[c,C,ç,Ç]')
82
- }
83
-
84
- public async search(model: mongoose.Model<any>): Promise<SearchResponse<any>> {
85
- if (this.isPageable()) {
86
- return await this.searchPageable(model)
87
- }
88
-
89
- return await this.searchNoPageable(model)
90
- }
91
-
92
- private searchPageable = async (model: mongoose.Model<any>): Promise<SearchResponse<any>> => {
93
- const sort = this.buildOrdenation()
94
- var items = await model
95
- .find(this.filters, this.select)
96
- .populate(this.populate)
97
- .skip((this.page - 1) * this.limit)
98
- .limit(this.limit)
99
- .sort(sort)
100
- .collation({
101
- locale: dbCollation || "pt"
102
- }) as []
103
-
104
- return this.result(model, items)
105
- }
106
-
107
- private async searchNoPageable(model: mongoose.Model<any>): Promise<SearchResponse<any>> {
108
- const sort = this.buildOrdenation()
109
- var items = await model
110
- .find(this.filters, this.select)
111
- .populate(this.populate)
112
- .sort(sort)
113
- .collation({
114
- locale: dbCollation || "pt"
115
- }) as []
116
-
117
- return this.result(model, items)
118
- }
119
-
120
- private async result(model: mongoose.Model<any>, items: []): Promise<SearchResponse<any>> {
121
- var total = await this.count(model)
122
-
123
- var paging: Pagination = {}
124
- paging.total = total
125
- paging.page = this.page
126
- paging.limit = this.limit
127
-
128
- var searchResponse: SearchResponse<any> = {}
129
- searchResponse.items = items
130
- searchResponse.paging = paging
131
-
132
- return searchResponse
133
- }
134
-
135
- public async count(model: mongoose.Model<any>): Promise<number> {
136
- return await model.countDocuments(this.filters).exec()
137
- }
138
-
139
- public async findOne(repository: mongoose.Model<any>, model: any, params: any = {}) {
140
- return await repository.findOne(model)
141
- .sort(params.sort)
142
- .select(params.select)
143
- .populate(params.populate)
144
- }
145
-
146
- public async sumBy(model: mongoose.Model<any>, _sum: any, _by: any): Promise<any[]> {
147
- const ret = await model.aggregate(
148
- [
149
- {
150
- '$match': this.filters
151
- },
152
- {
153
- $group: {
154
- _id: _by,
155
- totalValue: { "$sum": _sum },
156
- count: { "$sum": 1 }
157
- }
158
- }
159
- ]
160
- )
161
- return ret
162
- }
163
-
164
- public buildDefaultFilters(objectSearch: any) {
165
- let filters = { $and: [] } as any
166
- Object.entries(objectSearch.model).forEach(([key, value]) => {
167
- if (isNotEmpty(value)) {
168
- let condition = {} as any
169
- if (['order', 'orderBy', 'properties', 'populate', 'page', 'limit', 'model', 'select', 'searchText', 'isPageable', 'searchPageable'].includes(key)) {
170
- return
171
- }
172
-
173
- if (key.endsWith('DateRange') || key.endsWith('DateTimeRange') ) {
174
- var fieldName = key.replace('Range', '')
175
- var values = value as any
176
- if (isNotEmpty(values[0])) {
177
- var momentValue = moment(values[0])
178
- condition[fieldName] = {
179
- ...condition[fieldName],
180
- $gte: momentValue.toDate()
181
- }
182
- }
183
-
184
- if (isNotEmpty(values[1])) {
185
- var momentValue = moment(values[1])
186
- condition[fieldName] = {
187
- ...condition[fieldName],
188
- $lte: momentValue.toDate()
189
- }
190
- }
191
- filters.$and.push(condition)
192
- } else if (key.endsWith('Like')) {
193
- var fieldName = key.replace('Like', '')
194
- condition[fieldName] = { $regex: value as any, $options: 'i' }
195
- filters.$and.push(condition)
196
- } else {
197
- if (!Array.isArray(value)) {
198
- condition[key] = value
199
- } else {
200
- condition[key] = { $in: value }
201
- }
202
- filters.$and.push(condition)
203
- }
204
- }
205
- })
206
-
207
-
208
- // if (isNotEmpty(objectSearch.model)) {
209
- // this.addFilterModel(objectSearch.model, filters)
210
- // }
211
-
212
- if (filters.$and.length === 0)
213
- delete filters['$and']
214
-
215
- return filters
216
- }
217
-
218
- public addFilterModel(model: any, filters: any) {
219
- Object.entries(model).forEach(([key, value]) => {
220
- if (key.endsWith('DateRange')) {
221
- return
222
- }
223
- if (key.endsWith('Like')) {
224
- return
225
- }
226
- if (['order', 'orderBy', 'properties', 'populate', 'page', 'limit', 'model', 'select', 'searchText', 'isPageable', 'searchPageable'].includes(key)) {
227
- return
228
- }
229
- if (isNotEmpty(value)) {
230
- let condition = {} as any
231
- condition[key] = value
232
- filters.$and.push(condition)
233
- }
234
- })
235
- }
236
- }
237
-
1
+ import moment from "moment"
2
+ import mongoose from "mongoose"
3
+ import { dbCollation } from "../configuration/Environment"
4
+ import { Pagination, SearchResponse } from "../types/SearchResponse"
5
+ import { isEmpty, isNotEmpty } from "../utils/Utils"
6
+
7
+ abstract class SearchFlow {
8
+ searchText: string
9
+ order: string
10
+ orderBy: string
11
+ page: number
12
+ limit: number
13
+ select: string
14
+ populate: any
15
+ filters: any
16
+
17
+ constructor(params: any) {
18
+ this.searchText = params.searchText || ""
19
+ this.order = params.order || "asc"
20
+ this.orderBy = params.orderBy || "_id"
21
+ this.select = params.select
22
+ this.populate = params.populate
23
+ this.page = params.page || undefined
24
+ this.limit = params.limit || 25
25
+ this.buildPopulate()
26
+ }
27
+
28
+ public buildPopulate(): any {
29
+ if (isEmpty(this.populate)) {
30
+ return
31
+ }
32
+
33
+ var propertiesArray = this.populate.toString().split(',')
34
+ var populates = [] as any
35
+ for (var property of propertiesArray) {
36
+ let [first, ...rest] = property.split('.')
37
+ let nested = rest.join('.')
38
+ populates.push(this.buildPath(first, nested))
39
+ }
40
+
41
+ this.populate = populates
42
+ }
43
+
44
+ public buildPath(target: string, nested: string = "") {
45
+ var populate = {} as any
46
+ populate.path = target
47
+ if (isNotEmpty(nested)) {
48
+ let [first, ...rest] = nested.split('.')
49
+ let nested2 = rest.join('.')
50
+ populate.populate = this.buildPath(first, nested2)
51
+ }
52
+ return populate
53
+ }
54
+
55
+ public buildOrdenation() {
56
+ let order = {} as any
57
+ this.orderBy = this.orderBy || "_id"
58
+ order[this.orderBy] = this.order === "desc" ? -1 : 1
59
+ return order
60
+ }
61
+
62
+ private isPageable = () => {
63
+ if (isEmpty(this.page)) {
64
+ this.page = 1
65
+ }
66
+
67
+ if (this.page >= 0) {
68
+ return true
69
+ }
70
+
71
+ return false
72
+ }
73
+
74
+ public diacriticSensitiveRegex(string: string = ""): string {
75
+ return string
76
+ .replace(/[a|á|à|ä|â|A|Á|Â|Ã|Ä]/g, '[a,á,à,ä,â,A,Á,Â,Ã,Ä]')
77
+ .replace(/[e|é|ë|è|E|É|Ë|È]/g, '[e,é,ë,è,E,É,Ë,È]')
78
+ .replace(/[i|í|ï|ì|I|Í|Ï|Ì]/g, '[i,í,ï,ì,I,Í,Ï,Ì]')
79
+ .replace(/[o|ó|ö|ò|õ|O|Ó|Ö|Ô|Õ]/g, '[o,ó,ö,ò,õ,O,Ó,Ö,Ô,Õ]')
80
+ .replace(/[u|ü|ú|ù|U|Ú|Ü|Ù]/g, '[u,ü,ú,ù,U,Ú,Ü,Ù]')
81
+ .replace(/[ç|Ç|c|C]/g, '[c,C,ç,Ç]')
82
+ }
83
+
84
+ public async search(model: mongoose.Model<any>): Promise<SearchResponse<any>> {
85
+ if (this.isPageable()) {
86
+ return await this.searchPageable(model)
87
+ }
88
+
89
+ return await this.searchNoPageable(model)
90
+ }
91
+
92
+ private searchPageable = async (model: mongoose.Model<any>): Promise<SearchResponse<any>> => {
93
+ const sort = this.buildOrdenation()
94
+ var items = await model
95
+ .find(this.filters, this.select)
96
+ .populate(this.populate)
97
+ .skip((this.page - 1) * this.limit)
98
+ .limit(this.limit)
99
+ .sort(sort)
100
+ .collation({
101
+ locale: dbCollation || "pt"
102
+ }) as []
103
+
104
+ return this.result(model, items)
105
+ }
106
+
107
+ private async searchNoPageable(model: mongoose.Model<any>): Promise<SearchResponse<any>> {
108
+ const sort = this.buildOrdenation()
109
+ var items = await model
110
+ .find(this.filters, this.select)
111
+ .populate(this.populate)
112
+ .sort(sort)
113
+ .collation({
114
+ locale: dbCollation || "pt"
115
+ }) as []
116
+
117
+ return this.result(model, items)
118
+ }
119
+
120
+ private async result(model: mongoose.Model<any>, items: []): Promise<SearchResponse<any>> {
121
+ var total = await this.count(model)
122
+
123
+ var paging: Pagination = {}
124
+ paging.total = total
125
+ paging.page = this.page
126
+ paging.limit = this.limit
127
+
128
+ var searchResponse: SearchResponse<any> = {}
129
+ searchResponse.items = items
130
+ searchResponse.paging = paging
131
+
132
+ return searchResponse
133
+ }
134
+
135
+ public async count(model: mongoose.Model<any>): Promise<number> {
136
+ return await model.countDocuments(this.filters).exec()
137
+ }
138
+
139
+ public async findOne(repository: mongoose.Model<any>, model: any, params: any = {}) {
140
+ return await repository.findOne(model)
141
+ .sort(params.sort)
142
+ .select(params.select)
143
+ .populate(params.populate)
144
+ }
145
+
146
+ public async sumBy(model: mongoose.Model<any>, _sum: any, _by: any): Promise<any[]> {
147
+ const ret = await model.aggregate(
148
+ [
149
+ {
150
+ '$match': this.filters
151
+ },
152
+ {
153
+ $group: {
154
+ _id: _by,
155
+ totalValue: { "$sum": _sum },
156
+ count: { "$sum": 1 }
157
+ }
158
+ }
159
+ ]
160
+ )
161
+ return ret
162
+ }
163
+
164
+ public buildDefaultFilters(objectSearch: any) {
165
+ let filters = { $and: [] } as any
166
+ Object.entries(objectSearch.model).forEach(([key, value]) => {
167
+ if (isNotEmpty(value)) {
168
+ let condition = {} as any
169
+ if (['order', 'orderBy', 'properties', 'populate', 'page', 'limit', 'model', 'select', 'searchText', 'isPageable', 'searchPageable'].includes(key)) {
170
+ return
171
+ }
172
+
173
+ if (key.endsWith('DateRange') || key.endsWith('DateTimeRange')) {
174
+ var fieldName = key.replace('Range', '')
175
+ var values = value as any
176
+ if (isNotEmpty(values[0])) {
177
+ var momentValue = moment(values[0])
178
+ condition[fieldName] = {
179
+ ...condition[fieldName],
180
+ $gte: momentValue.toDate()
181
+ }
182
+ }
183
+
184
+ if (isNotEmpty(values[1])) {
185
+ var momentValue = moment(values[1])
186
+ condition[fieldName] = {
187
+ ...condition[fieldName],
188
+ $lte: momentValue.toDate().setHours(23, 59, 59)
189
+ }
190
+ }
191
+ filters.$and.push(condition)
192
+ } else if (key.endsWith('Like')) {
193
+ var fieldName = key.replace('Like', '')
194
+ condition[fieldName] = { $regex: value as any, $options: 'i' }
195
+ filters.$and.push(condition)
196
+ } else {
197
+ if (!Array.isArray(value)) {
198
+ condition[key] = value
199
+ } else {
200
+ condition[key] = { $in: value }
201
+ }
202
+ filters.$and.push(condition)
203
+ }
204
+ }
205
+ })
206
+
207
+
208
+ // if (isNotEmpty(objectSearch.model)) {
209
+ // this.addFilterModel(objectSearch.model, filters)
210
+ // }
211
+
212
+ if (filters.$and.length === 0)
213
+ delete filters['$and']
214
+
215
+ return filters
216
+ }
217
+
218
+ public addFilterModel(model: any, filters: any) {
219
+ Object.entries(model).forEach(([key, value]) => {
220
+ if (key.endsWith('DateRange')) {
221
+ return
222
+ }
223
+ if (key.endsWith('Like')) {
224
+ return
225
+ }
226
+ if (['order', 'orderBy', 'properties', 'populate', 'page', 'limit', 'model', 'select', 'searchText', 'isPageable', 'searchPageable'].includes(key)) {
227
+ return
228
+ }
229
+ if (isNotEmpty(value)) {
230
+ let condition = {} as any
231
+ condition[key] = value
232
+ filters.$and.push(condition)
233
+ }
234
+ })
235
+ }
236
+ }
237
+
238
238
  export default SearchFlow
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- import CrudFlow from "./flow/CrudFlow"
2
- import SearchFlow from "./flow/SearchFlow"
3
- import { Pagination, SearchResponse } from "./types/SearchResponse"
4
-
5
- export { CrudFlow, SearchFlow, SearchResponse, Pagination }
1
+ import CrudFlow from "./flow/CrudFlow"
2
+ import SearchFlow from "./flow/SearchFlow"
3
+ import { Pagination, SearchResponse } from "./types/SearchResponse"
4
+
5
+ export { CrudFlow, SearchFlow, SearchResponse, Pagination }
@@ -1,10 +1,10 @@
1
- export declare interface SearchResponse<T> {
2
- paging?: Pagination,
3
- items?: T[]
4
- }
5
-
6
- export declare interface Pagination {
7
- total?: number,
8
- page?: number,
9
- limit?: number
1
+ export declare interface SearchResponse<T> {
2
+ paging?: Pagination,
3
+ items?: T[]
4
+ }
5
+
6
+ export declare interface Pagination {
7
+ total?: number,
8
+ page?: number,
9
+ limit?: number
10
10
  }
@@ -1,57 +1,57 @@
1
- export const isNotEmpty = (obj: any) => {
2
- return !isEmpty(obj)
3
- }
4
-
5
- export const isEmpty = (obj: any) => {
6
- if (!obj) {
7
- return true
8
- }
9
-
10
- if (Array.isArray(obj)) {
11
- if (obj.length == 0) {
12
- return true
13
- }
14
- }
15
-
16
- if (obj === "") {
17
- return true
18
- }
19
-
20
- return false
21
- }
22
-
23
- export const isIterable = (input: any) => {
24
- if (input === null || input === undefined) {
25
- return false
26
- }
27
-
28
- if ('string' === typeof input) {
29
- return false
30
- }
31
-
32
- return typeof input[Symbol.iterator] === 'function'
33
- }
34
-
35
- export const isNotIterable = (input: any) => {
36
- return !isIterable(input)
37
- }
38
-
39
- export const compareAsc = (a: any, b: any) => {
40
- if (a._id < b._id) {
41
- return -1;
42
- }
43
- if (a._id > b._id) {
44
- return 1;
45
- }
46
- return 0;
47
- }
48
-
49
- export const compareDesc = (a: any, b: any) => {
50
- if (a._id > b._id) {
51
- return -1;
52
- }
53
- if (a._id < b._id) {
54
- return 1;
55
- }
56
- return 0;
1
+ export const isNotEmpty = (obj: any) => {
2
+ return !isEmpty(obj)
3
+ }
4
+
5
+ export const isEmpty = (obj: any) => {
6
+ if (!obj) {
7
+ return true
8
+ }
9
+
10
+ if (Array.isArray(obj)) {
11
+ if (obj.length == 0) {
12
+ return true
13
+ }
14
+ }
15
+
16
+ if (obj === "") {
17
+ return true
18
+ }
19
+
20
+ return false
21
+ }
22
+
23
+ export const isIterable = (input: any) => {
24
+ if (input === null || input === undefined) {
25
+ return false
26
+ }
27
+
28
+ if ('string' === typeof input) {
29
+ return false
30
+ }
31
+
32
+ return typeof input[Symbol.iterator] === 'function'
33
+ }
34
+
35
+ export const isNotIterable = (input: any) => {
36
+ return !isIterable(input)
37
+ }
38
+
39
+ export const compareAsc = (a: any, b: any) => {
40
+ if (a._id < b._id) {
41
+ return -1;
42
+ }
43
+ if (a._id > b._id) {
44
+ return 1;
45
+ }
46
+ return 0;
47
+ }
48
+
49
+ export const compareDesc = (a: any, b: any) => {
50
+ if (a._id > b._id) {
51
+ return -1;
52
+ }
53
+ if (a._id < b._id) {
54
+ return 1;
55
+ }
56
+ return 0;
57
57
  }
package/tsconfig.json CHANGED
@@ -1,12 +1,12 @@
1
- {
2
- "compilerOptions": {
3
- "declaration": true,
4
- "declarationDir": "./dist",
5
- "outDir": "./dist",
6
- "target": "es5",
7
- "module": "commonjs",
8
- "strict": true,
9
- "esModuleInterop": true
10
- },
11
- "include": ["src/**/*"]
12
- }
1
+ {
2
+ "compilerOptions": {
3
+ "declaration": true,
4
+ "declarationDir": "./dist",
5
+ "outDir": "./dist",
6
+ "target": "es5",
7
+ "module": "commonjs",
8
+ "strict": true,
9
+ "esModuleInterop": true
10
+ },
11
+ "include": ["src/**/*"]
12
+ }
@@ -1,26 +0,0 @@
1
- import mongoose from "mongoose";
2
- declare abstract class Search {
3
- searchText: string;
4
- order: string;
5
- orderBy: string;
6
- page: number;
7
- limit: number;
8
- select: string;
9
- populate: string | [] | any;
10
- filters: any;
11
- constructor(params: any);
12
- buildPopulate: () => any;
13
- buildPath: (target: string, nested?: string) => any;
14
- buildOrdenation: () => any;
15
- private isPageable;
16
- diacriticSensitiveRegex: (string?: string) => string;
17
- search: (model: mongoose.Model<any>) => Promise<SearchResponse<any>>;
18
- private searchPageable;
19
- private searchNoPageable;
20
- private result;
21
- count: (model: mongoose.Model<any>) => Promise<number>;
22
- sumBy: (model: mongoose.Model<any>, _sum: any, _by: any) => Promise<any[]>;
23
- buildDefaultFilters: (objectSearch: any) => any;
24
- addFilterModel: (model: any, filters: any) => void;
25
- }
26
- export default Search;