@recursyve/nestjs-data-filter 11.4.0 → 11.5.0
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/lib/filter/controllers/dynamic-filter.controller.js +1 -1
- package/lib/filter/controllers/filter.controller.js +1 -1
- package/lib/filter/filter.service.d.ts +2 -1
- package/lib/filter/filter.service.js +17 -14
- package/lib/filter/filters/filter.d.ts +9 -4
- package/lib/filter/filters/filter.js +1 -1
- package/lib/filter/filters/options.filter.d.ts +1 -1
- package/lib/filter/filters/options.filter.js +8 -5
- package/package.json +5 -2
|
@@ -33,7 +33,7 @@ class DynamicFilterController {
|
|
|
33
33
|
async filterCount(query, request) {
|
|
34
34
|
query = this.transformQuery(query, request);
|
|
35
35
|
const user = await this.getUser(request);
|
|
36
|
-
return this.filterService.count({ options: query, user });
|
|
36
|
+
return this.filterService.count({ options: query, request, user });
|
|
37
37
|
}
|
|
38
38
|
async downloadData(query, type, request) {
|
|
39
39
|
query = this.transformQuery(query, request);
|
|
@@ -31,7 +31,7 @@ class FilterController {
|
|
|
31
31
|
}
|
|
32
32
|
async filterCount(query, request) {
|
|
33
33
|
const user = await this.getUser(request);
|
|
34
|
-
return this.filterService.count({ options: query, user });
|
|
34
|
+
return this.filterService.count({ options: query, request, user });
|
|
35
35
|
}
|
|
36
36
|
async downloadData(query, type, request) {
|
|
37
37
|
const user = await this.getUser(request);
|
|
@@ -15,6 +15,7 @@ import { FilterConfigurationModel } from "./models/filter-configuration.model";
|
|
|
15
15
|
import { FilterResourceValueModel } from "./models/filter-resource-value.model";
|
|
16
16
|
interface CountParams<Users extends DataFilterUserModel> {
|
|
17
17
|
options: FilterQueryModel;
|
|
18
|
+
request: Request;
|
|
18
19
|
user?: Users | null;
|
|
19
20
|
}
|
|
20
21
|
interface DownloadDataParams<Users extends DataFilterUserModel, Request> {
|
|
@@ -49,7 +50,7 @@ export declare class FilterService<Data> {
|
|
|
49
50
|
count<Users extends DataFilterUserModel>(params: CountParams<Users>): Promise<number>;
|
|
50
51
|
filter<Request, Users extends DataFilterUserModel>(params: FilterParams<DataFilterUserModel, Request>): Promise<FilterResultModel<Data>>;
|
|
51
52
|
downloadData<Request>(params: DownloadDataParams<DataFilterUserModel, Request>): Promise<Buffer | string>;
|
|
52
|
-
getFindOptions(model: typeof M, query: QueryModel | undefined, data?: object): Promise<FindOptions>;
|
|
53
|
+
getFindOptions<Request>(model: typeof M, query: QueryModel | undefined, request: Request, user: DataFilterUserModel | null, data?: object): Promise<FindOptions>;
|
|
53
54
|
private convertNumber;
|
|
54
55
|
private init;
|
|
55
56
|
private getInclude;
|
|
@@ -90,7 +90,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
90
90
|
var _a, _b;
|
|
91
91
|
const { options } = params;
|
|
92
92
|
const user = (_a = params.user) !== null && _a !== void 0 ? _a : null;
|
|
93
|
-
const countOptions = await this.getFindOptions(this.repository.model, options.query);
|
|
93
|
+
const countOptions = await this.getFindOptions(this.repository.model, options.query, params.request, user);
|
|
94
94
|
if (options.search) {
|
|
95
95
|
this.addSearchCondition(options.search, countOptions, (_b = user === null || user === void 0 ? void 0 : user.language) !== null && _b !== void 0 ? _b : null);
|
|
96
96
|
}
|
|
@@ -103,7 +103,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
103
103
|
if (options.order) {
|
|
104
104
|
options.order = this.normalizeOrder(options.order);
|
|
105
105
|
}
|
|
106
|
-
const countOptions = await this.getFindOptions(this.repository.model, options.query, options.data);
|
|
106
|
+
const countOptions = await this.getFindOptions(this.repository.model, options.query, request, user, options.data);
|
|
107
107
|
if (options.search) {
|
|
108
108
|
this.addSearchCondition(options.search, countOptions, (_b = user === null || user === void 0 ? void 0 : user.language) !== null && _b !== void 0 ? _b : null);
|
|
109
109
|
}
|
|
@@ -124,7 +124,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
124
124
|
async downloadData(params) {
|
|
125
125
|
var _a, _b, _c;
|
|
126
126
|
const { exportOptions, options, request, type, user } = params;
|
|
127
|
-
const findOptions = await this.getFindOptions(this.exportRepository.model, options.query);
|
|
127
|
+
const findOptions = await this.getFindOptions(this.exportRepository.model, options.query, request, user);
|
|
128
128
|
if (options.order) {
|
|
129
129
|
options.order = this.normalizeOrder(options.order);
|
|
130
130
|
}
|
|
@@ -151,7 +151,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
151
151
|
return await this.repository.downloadData(values, type, (_c = user === null || user === void 0 ? void 0 : user.language) !== null && _c !== void 0 ? _c : "fr", exportOptions);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
-
async getFindOptions(model, query, data) {
|
|
154
|
+
async getFindOptions(model, query, request, user, data) {
|
|
155
155
|
/**
|
|
156
156
|
* Reset Geo localization filter state
|
|
157
157
|
*/
|
|
@@ -163,7 +163,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
163
163
|
const havingConditions = [];
|
|
164
164
|
option = {
|
|
165
165
|
...option,
|
|
166
|
-
include: await this.getInclude(model, query, data),
|
|
166
|
+
include: await this.getInclude(model, query, request, user, data),
|
|
167
167
|
where: query.condition === "and" ? { [sequelize_1.Op.and]: whereConditions } : { [sequelize_1.Op.or]: whereConditions },
|
|
168
168
|
having: query.condition === "and" ? { [sequelize_1.Op.and]: havingConditions } : { [sequelize_1.Op.or]: havingConditions }
|
|
169
169
|
};
|
|
@@ -203,7 +203,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
203
203
|
this.definitions[key] = this.model[key];
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
|
-
async getInclude(model, query, data) {
|
|
206
|
+
async getInclude(model, query, request, user, data) {
|
|
207
207
|
if (!query.rules) {
|
|
208
208
|
return [];
|
|
209
209
|
}
|
|
@@ -211,7 +211,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
211
211
|
for (const rule of query.rules) {
|
|
212
212
|
const m = rule;
|
|
213
213
|
if (m.condition) {
|
|
214
|
-
includes.push(await this.getInclude(model, m, data));
|
|
214
|
+
includes.push(await this.getInclude(model, m, request, user, data));
|
|
215
215
|
continue;
|
|
216
216
|
}
|
|
217
217
|
const r = rule;
|
|
@@ -221,19 +221,19 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
221
221
|
const filter = this.definitions[r.id];
|
|
222
222
|
if (filter.rootFilter) {
|
|
223
223
|
const f = filter;
|
|
224
|
-
includes.push(...this.getFilterInclude(model, f.rootFilter, r, data));
|
|
224
|
+
includes.push(...this.getFilterInclude(model, f.rootFilter, r, request, user, data));
|
|
225
225
|
if (!f.lazyLoading) {
|
|
226
226
|
if (f.valueFilter) {
|
|
227
|
-
includes.push(...this.getFilterInclude(model, f.valueFilter, r, data));
|
|
227
|
+
includes.push(...this.getFilterInclude(model, f.valueFilter, r, request, user, data));
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
else if (f.getValueFilter && Array.isArray(r.value)) {
|
|
231
231
|
const valueFiler = await f.getValueFilter(r.value[0]);
|
|
232
|
-
includes.push(...this.getFilterInclude(model, valueFiler, r, data));
|
|
232
|
+
includes.push(...this.getFilterInclude(model, valueFiler, r, request, user, data));
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
else {
|
|
236
|
-
includes.push(...this.getFilterInclude(model, filter, r, data));
|
|
236
|
+
includes.push(...this.getFilterInclude(model, filter, r, request, user, data));
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
return sequelize_utils_1.SequelizeUtils.reduceIncludes(includes, true);
|
|
@@ -386,7 +386,7 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
386
386
|
const customAttributes = filter.order ? this.getOrderCustomAttribute(filter.order, filter.data) : [];
|
|
387
387
|
const values = await repository.model.findAll({
|
|
388
388
|
...options,
|
|
389
|
-
attributes: [[sequelize_typescript_1.Sequelize.literal(`DISTINCT \`${this.repository.model.name}\`.\`id\``), "
|
|
389
|
+
attributes: [[sequelize_typescript_1.Sequelize.literal(`DISTINCT \`${this.repository.model.name}\`.\`id\``), "id"], ...customAttributes],
|
|
390
390
|
limit: (_d = filter.page) === null || _d === void 0 ? void 0 : _d.size,
|
|
391
391
|
offset: filter.page ? filter.page.number * filter.page.size + ((_e = filter.page.offset) !== null && _e !== void 0 ? _e : 0) : undefined,
|
|
392
392
|
subQuery: false,
|
|
@@ -428,9 +428,9 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
428
428
|
}
|
|
429
429
|
return where;
|
|
430
430
|
}
|
|
431
|
-
getFilterInclude(model, filter, rule, data) {
|
|
431
|
+
getFilterInclude(model, filter, rule, request, user, data) {
|
|
432
432
|
const includes = [];
|
|
433
|
-
const paths = filter.getIncludePaths(rule, data);
|
|
433
|
+
const paths = filter.getIncludePaths(rule, request, user, data);
|
|
434
434
|
for (const path of paths) {
|
|
435
435
|
includes.push(this.sequelizeModelScanner.getIncludes(model, path, [], [], true));
|
|
436
436
|
}
|
|
@@ -440,6 +440,9 @@ let FilterService = FilterService_1 = class FilterService {
|
|
|
440
440
|
}
|
|
441
441
|
return includes;
|
|
442
442
|
}
|
|
443
|
+
if (typeof filter.where === "function") {
|
|
444
|
+
filter.where = filter.where({ request, user });
|
|
445
|
+
}
|
|
443
446
|
return [
|
|
444
447
|
...includes,
|
|
445
448
|
this.sequelizeModelScanner.getIncludes(model, {
|
|
@@ -14,8 +14,13 @@ export interface FilterConditionRule {
|
|
|
14
14
|
path?: string;
|
|
15
15
|
operation: FilterOperators;
|
|
16
16
|
value?: (unknown | unknown[]) | ((value: unknown | unknown[]) => unknown | unknown[]);
|
|
17
|
-
where?: IncludeWhereModel;
|
|
17
|
+
where?: IncludeWhereModel | IncludeWhereModalCallback;
|
|
18
18
|
}
|
|
19
|
+
export interface IncludeWhereModelContext<Request = unknown> {
|
|
20
|
+
request: Request;
|
|
21
|
+
user: DataFilterUserModel | null;
|
|
22
|
+
}
|
|
23
|
+
type IncludeWhereModalCallback = (context: IncludeWhereModelContext) => IncludeWhereModel;
|
|
19
24
|
export interface FilterCondition {
|
|
20
25
|
condition: Condition;
|
|
21
26
|
rules: (FilterConditionRule | FilterCondition)[];
|
|
@@ -39,7 +44,7 @@ export interface BaseFilterDefinition {
|
|
|
39
44
|
paranoid?: boolean;
|
|
40
45
|
condition?: FilterCondition;
|
|
41
46
|
group?: string;
|
|
42
|
-
where?: IncludeWhereModel;
|
|
47
|
+
where?: IncludeWhereModel | IncludeWhereModalCallback;
|
|
43
48
|
pathCondition?: PathCondition;
|
|
44
49
|
json?: JsonConfig;
|
|
45
50
|
enabled?: ({ user, request }: EnabledConfig) => Promise<boolean>;
|
|
@@ -52,7 +57,7 @@ export interface FilterDefinition extends BaseFilterDefinition, IRule {
|
|
|
52
57
|
type: FilterType;
|
|
53
58
|
operators: (FilterOperatorTypes | CustomOperator)[];
|
|
54
59
|
getConfig<Request>(key: string, req: Request, user?: DataFilterUserModel): Promise<FilterBaseConfigurationModel | null>;
|
|
55
|
-
getIncludePaths(rule: QueryRuleModel, data?: object): PathModel[];
|
|
60
|
+
getIncludePaths<Request>(rule: QueryRuleModel, request: Request, user: DataFilterUserModel | null, data?: object): PathModel[];
|
|
56
61
|
getWhereOptions(rule: QueryRuleModel): Promise<WhereOptions | undefined>;
|
|
57
62
|
getHavingOptions(rule: QueryRuleModel): Promise<WhereOptions | undefined>;
|
|
58
63
|
usePathCondition(query: QueryModel): boolean;
|
|
@@ -79,7 +84,7 @@ export declare abstract class Filter implements FilterDefinition {
|
|
|
79
84
|
removeOperators(...operator: (FilterOperatorTypes | CustomOperator)[]): Filter;
|
|
80
85
|
setOperators(...operator: (FilterOperatorTypes | CustomOperator)[]): Filter;
|
|
81
86
|
getConfig<Request = any>(key: string, request: Request, user?: DataFilterUserModel): Promise<FilterBaseConfigurationModel | null>;
|
|
82
|
-
getIncludePaths(rule: QueryRuleModel, data?: object): PathModel[];
|
|
87
|
+
getIncludePaths<Request>(rule: QueryRuleModel, request: Request, user: DataFilterUserModel | null, data?: object): PathModel[];
|
|
83
88
|
getWhereOptions(rule: QueryRuleModel, name?: string): Promise<WhereOptions | undefined>;
|
|
84
89
|
getHavingOptions(rule: QueryRuleModel): Promise<WhereOptions | undefined>;
|
|
85
90
|
usePathCondition(query: QueryModel): boolean;
|
|
@@ -33,7 +33,7 @@ export declare class OptionsFilter extends Filter implements OptionsFilterDefini
|
|
|
33
33
|
options: OptionsFilterOption[];
|
|
34
34
|
constructor(definition: BaseFilterDefinition & OptionsFilterDefinition);
|
|
35
35
|
getConfig<Request>(key: string, request: Request, user?: DataFilterUserModel): Promise<OptionsFilterConfigurationModel | null>;
|
|
36
|
-
getIncludePaths(rule: QueryRuleModel, data?: object): PathModel[];
|
|
36
|
+
getIncludePaths<Request>(rule: QueryRuleModel, request: Request, user: DataFilterUserModel | null, data?: object): PathModel[];
|
|
37
37
|
getWhereOptions(rule: QueryRuleModel): Promise<WhereOptions | undefined>;
|
|
38
38
|
getHavingOptions(rule: QueryRuleModel): Promise<WhereOptions | undefined>;
|
|
39
39
|
private getRulePaths;
|
|
@@ -51,13 +51,13 @@ class OptionsFilter extends filter_1.Filter {
|
|
|
51
51
|
}))
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
getIncludePaths(rule, data) {
|
|
54
|
+
getIncludePaths(rule, request, user, data) {
|
|
55
55
|
const option = this.options.find(x => x.key === rule.value);
|
|
56
56
|
const condition = option === null || option === void 0 ? void 0 : option.condition;
|
|
57
57
|
if (!condition) {
|
|
58
|
-
return super.getIncludePaths(rule);
|
|
58
|
+
return super.getIncludePaths(rule, request, user);
|
|
59
59
|
}
|
|
60
|
-
return this.getRulePaths(condition.rules, data);
|
|
60
|
+
return this.getRulePaths(condition.rules, request, user, data);
|
|
61
61
|
}
|
|
62
62
|
async getWhereOptions(rule) {
|
|
63
63
|
const option = this.options.find(x => x.key === rule.value);
|
|
@@ -93,11 +93,11 @@ class OptionsFilter extends filter_1.Filter {
|
|
|
93
93
|
operation: (_a = option.operator) !== null && _a !== void 0 ? _a : rule.operation
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
|
-
getRulePaths(rules, data) {
|
|
96
|
+
getRulePaths(rules, request, user, data) {
|
|
97
97
|
const paths = [];
|
|
98
98
|
for (const rule of rules) {
|
|
99
99
|
if (rule.rules) {
|
|
100
|
-
paths.push(...this.getRulePaths(rule.rules, data));
|
|
100
|
+
paths.push(...this.getRulePaths(rule.rules, request, user, data));
|
|
101
101
|
}
|
|
102
102
|
else if (rule.path) {
|
|
103
103
|
if (paths.every((path) => path.path !== rule.path)) {
|
|
@@ -105,6 +105,9 @@ class OptionsFilter extends filter_1.Filter {
|
|
|
105
105
|
if (!r.path) {
|
|
106
106
|
continue;
|
|
107
107
|
}
|
|
108
|
+
if (typeof r.where === "function") {
|
|
109
|
+
r.where = r.where({ request, user });
|
|
110
|
+
}
|
|
108
111
|
paths.push({
|
|
109
112
|
path: r.path,
|
|
110
113
|
where: filter_utils_1.FilterUtils.generateWhereConditions(r.where, data)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@recursyve/nestjs-data-filter",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.5.0",
|
|
4
4
|
"description": "NestJs DataFilter library",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
"pack:lib": "npm run build:lib && cd dist && npm pack",
|
|
11
11
|
"publish-package": "npm run build:lib && npm run copy:lib && npm publish ./dist --access public",
|
|
12
12
|
"publish-package:beta": "npm run publish-package -- --tag beta --access public",
|
|
13
|
-
"publish-package:dry-run": "npm run publish-package -- --dry-run"
|
|
13
|
+
"publish-package:dry-run": "npm run publish-package -- --dry-run",
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"test:watch": "jest --watch",
|
|
16
|
+
"test:coverage": "jest --coverage"
|
|
14
17
|
},
|
|
15
18
|
"repository": {
|
|
16
19
|
"type": "git",
|