Skip to content

Commit 21f9669

Browse files
feat(filter): add "includes all" filter to array type
2 parents 9d1991a + d93abc6 commit 21f9669

12 files changed

+237
-66
lines changed

.babelrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
"@babel/plugin-proposal-optional-chaining",
1616
"@babel/plugin-transform-runtime",
1717
"@babel/plugin-transform-arrow-functions",
18+
"@babel/plugin-proposal-class-properties"
1819
]
1920
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"devDependencies": {
3737
"@babel/cli": "7.10.1",
3838
"@babel/core": "7.10.1",
39+
"@babel/plugin-proposal-class-properties": "7.13.0",
3940
"@babel/plugin-proposal-optional-chaining": "7.10.1",
4041
"@babel/plugin-transform-arrow-functions": "7.10.4",
4142
"@babel/plugin-transform-runtime": "7.10.1",

src/services/composite-keys-manager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function CompositeKeysManager(model, schema, record) {
1717
};
1818

1919
this.getRecordsConditions = function getRecordsConditions(recordsIds, options) {
20-
const { OR } = new Operators(options);
20+
const { OR } = Operators.getInstance(options);
2121
return { [OR]: recordsIds.map((recordId) => this.getRecordConditions(recordId)) };
2222
};
2323

src/services/filters-parser.js

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { NoMatchingOperatorError } from './errors';
55
const { getReferenceSchema, getReferenceField } = require('../utils/query');
66

77
function FiltersParser(modelSchema, timezone, options) {
8-
this.OPERATORS = new Operators(options);
8+
this.OPERATORS = Operators.getInstance(options);
99
this.operatorDateParser = new BaseOperatorDateParser({ operators: this.OPERATORS, timezone });
1010

1111
this.perform = async (filtersString) =>
@@ -59,58 +59,6 @@ function FiltersParser(modelSchema, timezone, options) {
5959
}
6060
};
6161

62-
this.formatOperator = (operator) => {
63-
switch (operator) {
64-
case 'not':
65-
return this.OPERATORS.NOT;
66-
case 'greater_than':
67-
case 'after':
68-
return this.OPERATORS.GT;
69-
case 'less_than':
70-
case 'before':
71-
return this.OPERATORS.LT;
72-
case 'contains':
73-
case 'starts_with':
74-
case 'ends_with':
75-
return this.OPERATORS.LIKE;
76-
case 'not_contains':
77-
return this.OPERATORS.NOT_LIKE;
78-
case 'present':
79-
case 'not_equal':
80-
return this.OPERATORS.NE;
81-
case 'blank':
82-
case 'equal':
83-
return this.OPERATORS.EQ;
84-
default:
85-
throw new NoMatchingOperatorError();
86-
}
87-
};
88-
89-
this.formatValue = (operator, value) => {
90-
switch (operator) {
91-
case 'not':
92-
case 'greater_than':
93-
case 'less_than':
94-
case 'not_equal':
95-
case 'equal':
96-
case 'before':
97-
case 'after':
98-
return value;
99-
case 'contains':
100-
case 'not_contains':
101-
return `%${value}%`;
102-
case 'starts_with':
103-
return `${value}%`;
104-
case 'ends_with':
105-
return `%${value}`;
106-
case 'present':
107-
case 'blank':
108-
return null;
109-
default:
110-
throw new NoMatchingOperatorError();
111-
}
112-
};
113-
11462
this.formatOperatorValue = (operator, value, isTextField = false) => {
11563
switch (operator) {
11664
case 'not':
@@ -143,6 +91,8 @@ function FiltersParser(modelSchema, timezone, options) {
14391
} : { [this.OPERATORS.EQ]: null };
14492
case 'equal':
14593
return { [this.OPERATORS.EQ]: value };
94+
case 'includes_all':
95+
return { [this.OPERATORS.CONTAINS]: value };
14696
default:
14797
throw new NoMatchingOperatorError();
14898
}

src/services/has-many-dissociator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const orm = require('../utils/orm');
44
const { ErrorHTTP422 } = require('./errors');
55

66
function HasManyDissociator(model, association, options, params, data) {
7-
const OPERATORS = new Operators(options);
7+
const OPERATORS = Operators.getInstance(options);
88
const isDelete = Boolean(params.delete);
99

1010
this.perform = () => {

src/services/resources-getter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function ResourcesGetter(model, options, params) {
1515
const queryBuilder = new QueryBuilder(model, options, params);
1616
let segmentScope;
1717
let segmentWhere;
18-
const OPERATORS = new Operators(options);
18+
const OPERATORS = Operators.getInstance(options);
1919
const primaryKey = _.keys(model.primaryKeys)[0];
2020
const filterParser = new FiltersParser(schema, params.timezone, options);
2121
let fieldNamesRequested;

src/services/search-builder.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function SearchBuilder(model, opts, params, fieldNamesRequested) {
1313
let associations = _.clone(model.associations);
1414
const hasSearchFields = schema.searchFields && _.isArray(schema.searchFields);
1515
let searchAssociationFields;
16-
const OPERATORS = new Operators(opts);
16+
const OPERATORS = Operators.getInstance(opts);
1717
const fieldsSearched = [];
1818
let hasExtendedConditions = false;
1919

src/services/value-stat-getter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import FiltersParser from './filters-parser';
55
import Orm from '../utils/orm';
66

77
function ValueStatGetter(model, params, options) {
8-
const OPERATORS = new Operators(options);
8+
const OPERATORS = Operators.getInstance(options);
99

1010
this.operatorDateParser = new BaseOperatorDateParser({
1111
operators: OPERATORS,

src/utils/operators.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
let instance = null;
1+
class Operators {
2+
static _instance = null;
23

3-
function Operators(options) {
4-
if (instance) return instance;
4+
static _isNewSequelizeOp(options) {
5+
return !!(options && options.Sequelize && options.Sequelize.Op);
6+
}
57

6-
if (options && options.Sequelize && options.Sequelize.Op) {
8+
_setupNewSequelizeOp(options) {
79
const { Op } = options.Sequelize;
810
this.AND = Op.and;
11+
this.CONTAINS = Op.contains;
912
this.EQ = Op.eq;
1013
this.GT = Op.gt;
1114
this.GTE = Op.gte;
@@ -17,8 +20,11 @@ function Operators(options) {
1720
this.NOT = Op.not;
1821
this.NOT_LIKE = Op.notLike;
1922
this.OR = Op.or;
20-
} else {
23+
}
24+
25+
_setupOldSequelizeOp() {
2126
this.AND = '$and';
27+
this.CONTAINS = '$contains';
2228
this.EQ = '$eq';
2329
this.GT = '$gt';
2430
this.GTE = '$gte';
@@ -32,8 +38,19 @@ function Operators(options) {
3238
this.OR = '$or';
3339
}
3440

35-
instance = this;
36-
return this;
41+
constructor(options) {
42+
if (Operators._isNewSequelizeOp(options)) {
43+
this._setupNewSequelizeOp(options);
44+
} else {
45+
this._setupOldSequelizeOp();
46+
}
47+
48+
Operators._instance = this;
49+
}
50+
51+
static getInstance(options) {
52+
return Operators._instance || new Operators(options);
53+
}
3754
}
3855

3956
module.exports = Operators;

test/services/filters-parser.test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ describe('services > filters-parser', () => {
1212
sequelize: Sequelize,
1313
};
1414
const timezone = 'Europe/Paris';
15-
const OPERATORS = new Operators(sequelizeOptions);
15+
const OPERATORS = Operators.getInstance(sequelizeOptions);
1616
const defaultFiltersParser = new FiltersParser(schema, timezone, sequelizeOptions);
1717

1818
const getExpectedCondition = (field, conditions) => {
@@ -120,6 +120,12 @@ describe('services > filters-parser', () => {
120120
expect(defaultFiltersParser.formatOperatorValue.bind('random', value)).toThrow(NoMatchingOperatorError);
121121
});
122122
});
123+
124+
it('should return the appropriate value (array)', () => {
125+
expect.assertions(1);
126+
127+
expect(defaultFiltersParser.formatOperatorValue('includes_all', [1, 2])).toStrictEqual({ [OPERATORS.CONTAINS]: [1, 2] });
128+
});
123129
});
124130

125131
describe('formatAggregatorOperator function', () => {

0 commit comments

Comments
 (0)