@recursyve/nestjs-data-filter 11.4.1 → 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.
@@ -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);
@@ -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;
@@ -63,7 +63,7 @@ class Filter {
63
63
  }
64
64
  return config;
65
65
  }
66
- getIncludePaths(rule, data) {
66
+ getIncludePaths(rule, request, user, data) {
67
67
  return [];
68
68
  }
69
69
  async getWhereOptions(rule, name) {
@@ -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.4.1",
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",