@wix/filter-builder 1.0.1
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/cjs/__tests__/filter.spec.js +378 -0
- package/dist/cjs/__tests__/filter.spec.js.map +1 -0
- package/dist/cjs/__tests__/query-optimizer.spec.js +152 -0
- package/dist/cjs/__tests__/query-optimizer.spec.js.map +1 -0
- package/dist/cjs/clone.js +27 -0
- package/dist/cjs/clone.js.map +1 -0
- package/dist/cjs/filter-builder.js +30 -0
- package/dist/cjs/filter-builder.js.map +1 -0
- package/dist/cjs/filter-mixin.js +299 -0
- package/dist/cjs/filter-mixin.js.map +1 -0
- package/dist/cjs/filter-validator.js +101 -0
- package/dist/cjs/filter-validator.js.map +1 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/query-optimiser.js +211 -0
- package/dist/cjs/query-optimiser.js.map +1 -0
- package/dist/cjs/type-utils.js +68 -0
- package/dist/cjs/type-utils.js.map +1 -0
- package/dist/cjs/validator.js +2 -0
- package/dist/cjs/validator.js.map +1 -0
- package/dist/esm/__tests__/filter.spec.js +211 -0
- package/dist/esm/__tests__/filter.spec.js.map +1 -0
- package/dist/esm/__tests__/query-optimizer.spec.js +39 -0
- package/dist/esm/__tests__/query-optimizer.spec.js.map +1 -0
- package/dist/esm/clone.js +18 -0
- package/dist/esm/clone.js.map +1 -0
- package/dist/esm/filter-builder.js +25 -0
- package/dist/esm/filter-builder.js.map +1 -0
- package/dist/esm/filter-mixin.js +298 -0
- package/dist/esm/filter-mixin.js.map +1 -0
- package/dist/esm/filter-validator.js +78 -0
- package/dist/esm/filter-validator.js.map +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/query-optimiser.js +171 -0
- package/dist/esm/query-optimiser.js.map +1 -0
- package/dist/esm/type-utils.js +40 -0
- package/dist/esm/type-utils.js.map +1 -0
- package/dist/esm/validator.js +2 -0
- package/dist/esm/validator.js.map +1 -0
- package/dist/statics/filter-builder.umd.js +453 -0
- package/dist/statics/filter-builder.umd.js.map +1 -0
- package/dist/statics/filter-builder.umd.min.js +2 -0
- package/dist/statics/filter-builder.umd.min.js.map +1 -0
- package/dist/statics/manifest.json +3 -0
- package/dist/statics/manifest.min.json +3 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/__tests__/filter.spec.d.ts +2 -0
- package/dist/types/__tests__/filter.spec.d.ts.map +1 -0
- package/dist/types/__tests__/query-optimizer.spec.d.ts +2 -0
- package/dist/types/__tests__/query-optimizer.spec.d.ts.map +1 -0
- package/dist/types/clone.d.ts +2 -0
- package/dist/types/clone.d.ts.map +1 -0
- package/dist/types/filter-builder.d.ts +46 -0
- package/dist/types/filter-builder.d.ts.map +1 -0
- package/dist/types/filter-mixin.d.ts +42 -0
- package/dist/types/filter-mixin.d.ts.map +1 -0
- package/dist/types/filter-validator.d.ts +27 -0
- package/dist/types/filter-validator.d.ts.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/query-optimiser.d.ts +2 -0
- package/dist/types/query-optimiser.d.ts.map +1 -0
- package/dist/types/type-utils.d.ts +11 -0
- package/dist/types/type-utils.d.ts.map +1 -0
- package/dist/types/validator.d.ts +14 -0
- package/dist/types/validator.d.ts.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/filter-builder.ts"],"names":["FilterBuilder","constructorName","_build","getFilterModel","filterBuilder"],"mappings":";;;;;;;;AAAA;;AAEO,MAAMA,aAAN,SAA4B,2BAA5B,CAA0C;AAC5B,MAAfC,eAAe,GAAG;AACpB,WAAO,eAAP;AACD;;AAEDC,EAAAA,MAAM,GAAG;AACP,WAAO,KAAKC,cAAL,EAAP;AACD;;AAP8C;;;;AAU1C,SAASC,aAAT,GAAyB;AAC9B,SAAO,IAAIJ,aAAJ,CAAkB,EAAlB,CAAP;AACD;;eAEcI,a","sourcesContent":["import filterMixin from './filter-mixin'\n\nexport class FilterBuilder extends filterMixin() {\n get constructorName() {\n return 'FilterBuilder'\n }\n\n _build() {\n return this.getFilterModel()\n }\n}\n\nexport function filterBuilder() {\n return new FilterBuilder({})\n}\n\nexport default filterBuilder\n"]}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
|
|
10
|
+
var _typeUtils = require("./type-utils");
|
|
11
|
+
|
|
12
|
+
var _clone = _interopRequireDefault(require("./clone"));
|
|
13
|
+
|
|
14
|
+
var _filterValidator = require("./filter-validator");
|
|
15
|
+
|
|
16
|
+
var _queryOptimiser = require("./query-optimiser");
|
|
17
|
+
|
|
18
|
+
const filterMixin = (Base = class {}) => class extends Base {
|
|
19
|
+
constructor(obj = {}) {
|
|
20
|
+
super(obj);
|
|
21
|
+
(0, _defineProperty2.default)(this, "filterTree", void 0);
|
|
22
|
+
(0, _defineProperty2.default)(this, "invalidArguments", void 0);
|
|
23
|
+
this.filterTree = obj.filterTree || {
|
|
24
|
+
$and: []
|
|
25
|
+
};
|
|
26
|
+
this.invalidArguments = obj.invalidArguments || [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
eq(...args) {
|
|
30
|
+
return this._binaryAnd('$eq', '.eq', args);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
ne(...args) {
|
|
34
|
+
return this._binaryAnd('$ne', '.ne', args);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ge(...args) {
|
|
38
|
+
return this._AndLogicalEquivalence('$gte', '.ge', args);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
gt(...args) {
|
|
42
|
+
return this._AndLogicalEquivalence('$gt', '.gt', args);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
le(...args) {
|
|
46
|
+
return this._AndLogicalEquivalence('$lte', '.le', args);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
lt(...args) {
|
|
50
|
+
return this._AndLogicalEquivalence('$lt', '.lt', args);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
isNotEmpty(field) {
|
|
54
|
+
const _this$_filterValidato = this._filterValidator('.isNotEmpty').arityIsOne(arguments).validFieldName(field).validateAndAggregate(),
|
|
55
|
+
newInvalidArguments = _this$_filterValidato[0],
|
|
56
|
+
valid = _this$_filterValidato[1];
|
|
57
|
+
|
|
58
|
+
if (valid) {
|
|
59
|
+
return this.ne(field, null);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return this._copy(this.filterTree, newInvalidArguments);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
isEmpty(field) {
|
|
66
|
+
const _this$_filterValidato2 = this._filterValidator('.isEmpty').arityIsOne(arguments).validFieldName(field).validateAndAggregate(),
|
|
67
|
+
newInvalidArguments = _this$_filterValidato2[0],
|
|
68
|
+
valid = _this$_filterValidato2[1];
|
|
69
|
+
|
|
70
|
+
if (valid) {
|
|
71
|
+
return this.eq(field, null);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return this._copy(this.filterTree, newInvalidArguments);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
startsWith(...args) {
|
|
78
|
+
return this._AndStringOperand('$startsWith', '.startsWith', args);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
endsWith(...args) {
|
|
82
|
+
return this._AndStringOperand('$endsWith', '.endsWith', args);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
contains(...args) {
|
|
86
|
+
return this._AndStringOperand('$contains', '.contains', args);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
hasSome(...args) {
|
|
90
|
+
return this._AndSetOperand('$hasSome', '.hasSome', args);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
hasAll(...args) {
|
|
94
|
+
return this._AndSetOperand('$hasAll', '.hasAll', args);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
or(orQuery) {
|
|
98
|
+
const _this$_filterValidato3 = this._filterValidator('.or').arityIsOne(arguments).isInstanceOfSameClass(orQuery).validateAndAggregate(),
|
|
99
|
+
newInvalidArguments = _this$_filterValidato3[0],
|
|
100
|
+
valid = _this$_filterValidato3[1];
|
|
101
|
+
|
|
102
|
+
if (valid) {
|
|
103
|
+
const prefix = isEmptyAnd(this.filterTree) ? [] : [this.filterTree];
|
|
104
|
+
return this._copy(inAnd({
|
|
105
|
+
$or: [...prefix, orQuery.filterTree]
|
|
106
|
+
}), newInvalidArguments.concat(orQuery.invalidArguments));
|
|
107
|
+
} else {
|
|
108
|
+
return this._copy(this.filterTree, newInvalidArguments);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
and(andQuery) {
|
|
113
|
+
const _this$_filterValidato4 = this._filterValidator('.and').arityIsOne(arguments).isInstanceOfSameClass(andQuery).validateAndAggregate(),
|
|
114
|
+
newInvalidArguments = _this$_filterValidato4[0],
|
|
115
|
+
valid = _this$_filterValidato4[1];
|
|
116
|
+
|
|
117
|
+
if (valid) {
|
|
118
|
+
const prefix = isEmptyAnd(this.filterTree) ? [] : [this.filterTree];
|
|
119
|
+
return this._copy(inAnd(...prefix, andQuery.filterTree), newInvalidArguments.concat(andQuery.invalidArguments));
|
|
120
|
+
} else {
|
|
121
|
+
return this._copy(this.filterTree, newInvalidArguments);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
not(notQuery) {
|
|
126
|
+
const _this$_filterValidato5 = this._filterValidator('.not').arityIsOne(arguments).isInstanceOfSameClass(notQuery).validateAndAggregate(),
|
|
127
|
+
newInvalidArguments = _this$_filterValidato5[0],
|
|
128
|
+
valid = _this$_filterValidato5[1];
|
|
129
|
+
|
|
130
|
+
if (valid) {
|
|
131
|
+
const newFilterTree = (0, _clone.default)(this.filterTree);
|
|
132
|
+
const notClause = {
|
|
133
|
+
$not: [notQuery.filterTree]
|
|
134
|
+
};
|
|
135
|
+
const resultingFilter = inAndOptimized(newFilterTree, notClause);
|
|
136
|
+
return this._copy(resultingFilter, newInvalidArguments.concat(notQuery.invalidArguments));
|
|
137
|
+
} else {
|
|
138
|
+
return this._copy(this.filterTree, newInvalidArguments);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
between(field, rangeStart, rangeEnd) {
|
|
143
|
+
const _this$_filterValidato6 = this._filterValidator('.between').arityIsThree(arguments).sameType(rangeStart, rangeEnd).typeIsStringNumberOrDate(rangeStart).typeIsStringNumberOrDate(rangeEnd).validateAndAggregate(),
|
|
144
|
+
newInvalidArguments = _this$_filterValidato6[0],
|
|
145
|
+
valid = _this$_filterValidato6[1];
|
|
146
|
+
|
|
147
|
+
if (valid) {
|
|
148
|
+
return this.ge(field, rangeStart).lt(field, rangeEnd);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return this._copy(this.filterTree, newInvalidArguments);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getFilterModel() {
|
|
155
|
+
if (this.invalidArguments.length > 0) {
|
|
156
|
+
throw new Error(this.invalidArguments.join(' '));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return (0, _queryOptimiser.optimisedQuery)(this.filterTree);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
setFilterModel(filterModel) {
|
|
163
|
+
return this._copy(filterModel, []);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
_binaryAnd(filterOperatorSymbol, operatorName, args) {
|
|
167
|
+
const _Array$prototype$slic = Array.prototype.slice.call(args),
|
|
168
|
+
field = _Array$prototype$slic[0],
|
|
169
|
+
operand = _Array$prototype$slic[1];
|
|
170
|
+
|
|
171
|
+
const _this$_filterValidato7 = this._filterValidator(operatorName).arityIsTwo(args).validFieldName(field).validateAndAggregate(),
|
|
172
|
+
newInvalidArguments = _this$_filterValidato7[0];
|
|
173
|
+
|
|
174
|
+
const newFilterTree = this._makeNewFilter(field, filterOperatorSymbol, operand);
|
|
175
|
+
|
|
176
|
+
return this._copy(newFilterTree, newInvalidArguments);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
_AndLogicalEquivalence(filterOperatorSymbol, operatorName, args) {
|
|
180
|
+
const _Array$prototype$slic2 = Array.prototype.slice.call(args),
|
|
181
|
+
field = _Array$prototype$slic2[0],
|
|
182
|
+
operand = _Array$prototype$slic2[1];
|
|
183
|
+
|
|
184
|
+
const _this$_filterValidato8 = this._filterValidator(operatorName).arityIsTwo(args).validFieldName(field).typeIsStringNumberOrDate(operand).validateAndAggregate(),
|
|
185
|
+
newInvalidArguments = _this$_filterValidato8[0];
|
|
186
|
+
|
|
187
|
+
const newFilterTree = this._makeNewFilter(field, filterOperatorSymbol, operand);
|
|
188
|
+
|
|
189
|
+
return this._copy(newFilterTree, newInvalidArguments);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
_AndStringOperand(filterOperatorName, operatorName, args) {
|
|
193
|
+
const _Array$prototype$slic3 = Array.prototype.slice.call(args),
|
|
194
|
+
field = _Array$prototype$slic3[0],
|
|
195
|
+
operand = _Array$prototype$slic3[1];
|
|
196
|
+
|
|
197
|
+
const _this$_filterValidato9 = this._filterValidator(operatorName).arityIsTwo(args).validFieldName(field).typeIsString(operand).validateAndAggregate(),
|
|
198
|
+
newInvalidArguments = _this$_filterValidato9[0];
|
|
199
|
+
|
|
200
|
+
const newFilterTree = this._makeNewFilter(field, filterOperatorName, operand);
|
|
201
|
+
|
|
202
|
+
return this._copy(newFilterTree, newInvalidArguments);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
_AndSetOperand(filterOperatorName, operatorName, args) {
|
|
206
|
+
const _Array$prototype$slic4 = Array.prototype.slice.call(args),
|
|
207
|
+
field = _Array$prototype$slic4[0],
|
|
208
|
+
rawOperands = _Array$prototype$slic4.slice(1);
|
|
209
|
+
|
|
210
|
+
const operands = (0, _typeUtils.isArray)(rawOperands[0]) ? rawOperands[0] : rawOperands;
|
|
211
|
+
|
|
212
|
+
const _this$_filterValidato10 = this._filterValidator(operatorName).arityIsAtLeastTwo(args).validFieldName(field).typeIsStringNumberOrDateForAll(operands).validateAndAggregate(),
|
|
213
|
+
newInvalidArguments = _this$_filterValidato10[0];
|
|
214
|
+
|
|
215
|
+
const newFilterTree = this._makeNewFilter(field, filterOperatorName, operands);
|
|
216
|
+
|
|
217
|
+
return this._copy(newFilterTree, newInvalidArguments);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
_makeNewFilter(field, filterOperatorName, operand) {
|
|
221
|
+
const newFilterTree = (0, _clone.default)(this.filterTree); // filters with 'undefined' value are lost during serialization,
|
|
222
|
+
// e.g. { val: { $ne: undefined } | translates to { val: {} }
|
|
223
|
+
// Replacing 'undefined' with 'null' retains the filter.
|
|
224
|
+
|
|
225
|
+
const serializableOperand = operand === undefined ? null : operand;
|
|
226
|
+
|
|
227
|
+
const newFilter = this._buildFilter(field, filterOperatorName, serializableOperand);
|
|
228
|
+
|
|
229
|
+
if ((0, _typeUtils.isArray)(newFilterTree.$and)) {
|
|
230
|
+
newFilterTree.$and.push(newFilter);
|
|
231
|
+
return newFilterTree;
|
|
232
|
+
} else {
|
|
233
|
+
const result = isEmptyObject(newFilterTree) ? inAnd(newFilter) : inAnd(newFilterTree, newFilter);
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
_buildFilter(field, filterOperatorName, operand) {
|
|
239
|
+
if (filterOperatorName !== '$eq') {
|
|
240
|
+
const newFilter = {};
|
|
241
|
+
newFilter[field] = {};
|
|
242
|
+
newFilter[field][filterOperatorName] = this._replaceRefs(operand);
|
|
243
|
+
return newFilter;
|
|
244
|
+
} else {
|
|
245
|
+
const newFilter = {};
|
|
246
|
+
newFilter[field] = this._replaceRefs(operand);
|
|
247
|
+
return newFilter;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
_replaceRefs(operand) {
|
|
252
|
+
if ((0, _typeUtils.isArray)(operand)) {
|
|
253
|
+
return operand.map(op => this._replaceRefs(op));
|
|
254
|
+
} else {
|
|
255
|
+
return operand;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
_copy(filterTree, invalidArguments) {
|
|
260
|
+
// @ts-ignore-next-line
|
|
261
|
+
return new this.constructor({ ...this,
|
|
262
|
+
filterTree,
|
|
263
|
+
invalidArguments
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
_filterValidator(filterOperatorName) {
|
|
268
|
+
return new _filterValidator.FilterValidator(filterOperatorName, this.invalidArguments, this.constructor);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
function isConjunctiveFormFilter(filterTree) {
|
|
274
|
+
return (0, _typeUtils.isArray)(filterTree.$and);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function isEmptyObject(obj) {
|
|
278
|
+
return Object.keys(obj).length === 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function inAnd(...args) {
|
|
282
|
+
return {
|
|
283
|
+
$and: args
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function inAndOptimized(...args) {
|
|
288
|
+
return {
|
|
289
|
+
$and: args.reduce((aggr, val) => isConjunctiveFormFilter(val) ? aggr.concat(val.$and) : aggr.concat([val]), [])
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function isEmptyAnd(node) {
|
|
294
|
+
return node && node.$and && node.$and.length === 0;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
var _default = filterMixin;
|
|
298
|
+
exports.default = _default;
|
|
299
|
+
//# sourceMappingURL=filter-mixin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/filter-mixin.ts"],"names":["filterMixin","Base","constructor","obj","filterTree","$and","invalidArguments","eq","args","_binaryAnd","ne","ge","_AndLogicalEquivalence","gt","le","lt","isNotEmpty","field","_filterValidator","arityIsOne","arguments","validFieldName","validateAndAggregate","newInvalidArguments","valid","_copy","isEmpty","startsWith","_AndStringOperand","endsWith","contains","hasSome","_AndSetOperand","hasAll","or","orQuery","isInstanceOfSameClass","prefix","isEmptyAnd","inAnd","$or","concat","and","andQuery","not","notQuery","newFilterTree","notClause","$not","resultingFilter","inAndOptimized","between","rangeStart","rangeEnd","arityIsThree","sameType","typeIsStringNumberOrDate","getFilterModel","length","Error","join","setFilterModel","filterModel","filterOperatorSymbol","operatorName","Array","prototype","slice","call","operand","arityIsTwo","_makeNewFilter","filterOperatorName","typeIsString","rawOperands","operands","arityIsAtLeastTwo","typeIsStringNumberOrDateForAll","serializableOperand","undefined","newFilter","_buildFilter","push","result","isEmptyObject","_replaceRefs","map","op","FilterValidator","isConjunctiveFormFilter","Object","keys","reduce","aggr","val","node"],"mappings":";;;;;;;;;AAAA;;AACA;;AACA;;AAEA;;AAEA,MAAMA,WAAW,GAAG,CAACC,IAAS,GAAG,MAAM,EAAnB,KAClB,cAAcA,IAAd,CAAmB;AAIjBC,EAAAA,WAAW,CAACC,GAAuC,GAAG,EAA3C,EAA+C;AACxD,UAAMA,GAAN;AADwD;AAAA;AAExD,SAAKC,UAAL,GAAkBD,GAAG,CAACC,UAAJ,IAAkB;AAAEC,MAAAA,IAAI,EAAE;AAAR,KAApC;AACA,SAAKC,gBAAL,GAAwBH,GAAG,CAACG,gBAAJ,IAAwB,EAAhD;AACD;;AAEDC,EAAAA,EAAE,CAAC,GAAGC,IAAJ,EAAU;AACV,WAAO,KAAKC,UAAL,CAAgB,KAAhB,EAAuB,KAAvB,EAA8BD,IAA9B,CAAP;AACD;;AAEDE,EAAAA,EAAE,CAAC,GAAGF,IAAJ,EAAU;AACV,WAAO,KAAKC,UAAL,CAAgB,KAAhB,EAAuB,KAAvB,EAA8BD,IAA9B,CAAP;AACD;;AAEDG,EAAAA,EAAE,CAAC,GAAGH,IAAJ,EAAU;AACV,WAAO,KAAKI,sBAAL,CAA4B,MAA5B,EAAoC,KAApC,EAA2CJ,IAA3C,CAAP;AACD;;AAEDK,EAAAA,EAAE,CAAC,GAAGL,IAAJ,EAAU;AACV,WAAO,KAAKI,sBAAL,CAA4B,KAA5B,EAAmC,KAAnC,EAA0CJ,IAA1C,CAAP;AACD;;AAEDM,EAAAA,EAAE,CAAC,GAAGN,IAAJ,EAAU;AACV,WAAO,KAAKI,sBAAL,CAA4B,MAA5B,EAAoC,KAApC,EAA2CJ,IAA3C,CAAP;AACD;;AAEDO,EAAAA,EAAE,CAAC,GAAGP,IAAJ,EAAU;AACV,WAAO,KAAKI,sBAAL,CAA4B,KAA5B,EAAmC,KAAnC,EAA0CJ,IAA1C,CAAP;AACD;;AAEDQ,EAAAA,UAAU,CAACC,KAAD,EAAQ;AAChB,kCAAqC,KAAKC,gBAAL,CAAsB,aAAtB,EAClCC,UADkC,CACvBC,SADuB,EAElCC,cAFkC,CAEnBJ,KAFmB,EAGlCK,oBAHkC,EAArC;AAAA,UAAOC,mBAAP;AAAA,UAA4BC,KAA5B;;AAKA,QAAIA,KAAJ,EAAW;AACT,aAAO,KAAKd,EAAL,CAAQO,KAAR,EAAe,IAAf,CAAP;AACD;;AAED,WAAO,KAAKQ,KAAL,CAAW,KAAKrB,UAAhB,EAA4BmB,mBAA5B,CAAP;AACD;;AAEDG,EAAAA,OAAO,CAACT,KAAD,EAAQ;AACb,mCAAqC,KAAKC,gBAAL,CAAsB,UAAtB,EAClCC,UADkC,CACvBC,SADuB,EAElCC,cAFkC,CAEnBJ,KAFmB,EAGlCK,oBAHkC,EAArC;AAAA,UAAOC,mBAAP;AAAA,UAA4BC,KAA5B;;AAKA,QAAIA,KAAJ,EAAW;AACT,aAAO,KAAKjB,EAAL,CAAQU,KAAR,EAAe,IAAf,CAAP;AACD;;AAED,WAAO,KAAKQ,KAAL,CAAW,KAAKrB,UAAhB,EAA4BmB,mBAA5B,CAAP;AACD;;AAEDI,EAAAA,UAAU,CAAC,GAAGnB,IAAJ,EAAU;AAClB,WAAO,KAAKoB,iBAAL,CAAuB,aAAvB,EAAsC,aAAtC,EAAqDpB,IAArD,CAAP;AACD;;AAEDqB,EAAAA,QAAQ,CAAC,GAAGrB,IAAJ,EAAU;AAChB,WAAO,KAAKoB,iBAAL,CAAuB,WAAvB,EAAoC,WAApC,EAAiDpB,IAAjD,CAAP;AACD;;AAEDsB,EAAAA,QAAQ,CAAC,GAAGtB,IAAJ,EAAU;AAChB,WAAO,KAAKoB,iBAAL,CAAuB,WAAvB,EAAoC,WAApC,EAAiDpB,IAAjD,CAAP;AACD;;AAEDuB,EAAAA,OAAO,CAAC,GAAGvB,IAAJ,EAAU;AACf,WAAO,KAAKwB,cAAL,CAAoB,UAApB,EAAgC,UAAhC,EAA4CxB,IAA5C,CAAP;AACD;;AAEDyB,EAAAA,MAAM,CAAC,GAAGzB,IAAJ,EAAU;AACd,WAAO,KAAKwB,cAAL,CAAoB,SAApB,EAA+B,SAA/B,EAA0CxB,IAA1C,CAAP;AACD;;AAED0B,EAAAA,EAAE,CAACC,OAAD,EAAU;AACV,mCAAqC,KAAKjB,gBAAL,CAAsB,KAAtB,EAClCC,UADkC,CACvBC,SADuB,EAElCgB,qBAFkC,CAEZD,OAFY,EAGlCb,oBAHkC,EAArC;AAAA,UAAOC,mBAAP;AAAA,UAA4BC,KAA5B;;AAKA,QAAIA,KAAJ,EAAW;AACT,YAAMa,MAAM,GAAGC,UAAU,CAAC,KAAKlC,UAAN,CAAV,GAA8B,EAA9B,GAAmC,CAAC,KAAKA,UAAN,CAAlD;AACA,aAAO,KAAKqB,KAAL,CACLc,KAAK,CAAC;AAAEC,QAAAA,GAAG,EAAE,CAAC,GAAGH,MAAJ,EAAYF,OAAO,CAAC/B,UAApB;AAAP,OAAD,CADA,EAELmB,mBAAmB,CAACkB,MAApB,CAA2BN,OAAO,CAAC7B,gBAAnC,CAFK,CAAP;AAID,KAND,MAMO;AACL,aAAO,KAAKmB,KAAL,CAAW,KAAKrB,UAAhB,EAA4BmB,mBAA5B,CAAP;AACD;AACF;;AAEDmB,EAAAA,GAAG,CAACC,QAAD,EAAW;AACZ,mCAAqC,KAAKzB,gBAAL,CAAsB,MAAtB,EAClCC,UADkC,CACvBC,SADuB,EAElCgB,qBAFkC,CAEZO,QAFY,EAGlCrB,oBAHkC,EAArC;AAAA,UAAOC,mBAAP;AAAA,UAA4BC,KAA5B;;AAKA,QAAIA,KAAJ,EAAW;AACT,YAAMa,MAAM,GAAGC,UAAU,CAAC,KAAKlC,UAAN,CAAV,GAA8B,EAA9B,GAAmC,CAAC,KAAKA,UAAN,CAAlD;AACA,aAAO,KAAKqB,KAAL,CACLc,KAAK,CAAC,GAAGF,MAAJ,EAAYM,QAAQ,CAACvC,UAArB,CADA,EAELmB,mBAAmB,CAACkB,MAApB,CAA2BE,QAAQ,CAACrC,gBAApC,CAFK,CAAP;AAID,KAND,MAMO;AACL,aAAO,KAAKmB,KAAL,CAAW,KAAKrB,UAAhB,EAA4BmB,mBAA5B,CAAP;AACD;AACF;;AAEDqB,EAAAA,GAAG,CAACC,QAAD,EAAW;AACZ,mCAAqC,KAAK3B,gBAAL,CAAsB,MAAtB,EAClCC,UADkC,CACvBC,SADuB,EAElCgB,qBAFkC,CAEZS,QAFY,EAGlCvB,oBAHkC,EAArC;AAAA,UAAOC,mBAAP;AAAA,UAA4BC,KAA5B;;AAKA,QAAIA,KAAJ,EAAW;AACT,YAAMsB,aAAa,GAAG,oBAAM,KAAK1C,UAAX,CAAtB;AACA,YAAM2C,SAAS,GAAG;AAAEC,QAAAA,IAAI,EAAE,CAACH,QAAQ,CAACzC,UAAV;AAAR,OAAlB;AACA,YAAM6C,eAAe,GAAGC,cAAc,CAACJ,aAAD,EAAgBC,SAAhB,CAAtC;AAEA,aAAO,KAAKtB,KAAL,CACLwB,eADK,EAEL1B,mBAAmB,CAACkB,MAApB,CAA2BI,QAAQ,CAACvC,gBAApC,CAFK,CAAP;AAID,KATD,MASO;AACL,aAAO,KAAKmB,KAAL,CAAW,KAAKrB,UAAhB,EAA4BmB,mBAA5B,CAAP;AACD;AACF;;AAED4B,EAAAA,OAAO,CAAClC,KAAD,EAAQmC,UAAR,EAAoBC,QAApB,EAA8B;AACnC,mCAAqC,KAAKnC,gBAAL,CAAsB,UAAtB,EAClCoC,YADkC,CACrBlC,SADqB,EAElCmC,QAFkC,CAEzBH,UAFyB,EAEbC,QAFa,EAGlCG,wBAHkC,CAGTJ,UAHS,EAIlCI,wBAJkC,CAITH,QAJS,EAKlC/B,oBALkC,EAArC;AAAA,UAAOC,mBAAP;AAAA,UAA4BC,KAA5B;;AAOA,QAAIA,KAAJ,EAAW;AACT,aAAO,KAAKb,EAAL,CAAQM,KAAR,EAAemC,UAAf,EAA2BrC,EAA3B,CAA8BE,KAA9B,EAAqCoC,QAArC,CAAP;AACD;;AAED,WAAO,KAAK5B,KAAL,CAAW,KAAKrB,UAAhB,EAA4BmB,mBAA5B,CAAP;AACD;;AAEDkC,EAAAA,cAAc,GAAG;AACf,QAAI,KAAKnD,gBAAL,CAAsBoD,MAAtB,GAA+B,CAAnC,EAAsC;AACpC,YAAM,IAAIC,KAAJ,CAAU,KAAKrD,gBAAL,CAAsBsD,IAAtB,CAA2B,GAA3B,CAAV,CAAN;AACD;;AACD,WAAO,oCAAe,KAAKxD,UAApB,CAAP;AACD;;AAEDyD,EAAAA,cAAc,CAACC,WAAD,EAAc;AAC1B,WAAO,KAAKrC,KAAL,CAAWqC,WAAX,EAAwB,EAAxB,CAAP;AACD;;AAEDrD,EAAAA,UAAU,CAACsD,oBAAD,EAAuBC,YAAvB,EAAqCxD,IAArC,EAA2C;AACnD,kCAAyByD,KAAK,CAACC,SAAN,CAAgBC,KAAhB,CAAsBC,IAAtB,CAA2B5D,IAA3B,CAAzB;AAAA,UAAOS,KAAP;AAAA,UAAcoD,OAAd;;AAEA,mCAA8B,KAAKnD,gBAAL,CAAsB8C,YAAtB,EAC3BM,UAD2B,CAChB9D,IADgB,EAE3Ba,cAF2B,CAEZJ,KAFY,EAG3BK,oBAH2B,EAA9B;AAAA,UAAOC,mBAAP;;AAKA,UAAMuB,aAAa,GAAG,KAAKyB,cAAL,CACpBtD,KADoB,EAEpB8C,oBAFoB,EAGpBM,OAHoB,CAAtB;;AAMA,WAAO,KAAK5C,KAAL,CAAWqB,aAAX,EAA0BvB,mBAA1B,CAAP;AACD;;AAEDX,EAAAA,sBAAsB,CAACmD,oBAAD,EAAuBC,YAAvB,EAAqCxD,IAArC,EAA2C;AAC/D,mCAAyByD,KAAK,CAACC,SAAN,CAAgBC,KAAhB,CAAsBC,IAAtB,CAA2B5D,IAA3B,CAAzB;AAAA,UAAOS,KAAP;AAAA,UAAcoD,OAAd;;AAEA,mCAA8B,KAAKnD,gBAAL,CAAsB8C,YAAtB,EAC3BM,UAD2B,CAChB9D,IADgB,EAE3Ba,cAF2B,CAEZJ,KAFY,EAG3BuC,wBAH2B,CAGFa,OAHE,EAI3B/C,oBAJ2B,EAA9B;AAAA,UAAOC,mBAAP;;AAMA,UAAMuB,aAAa,GAAG,KAAKyB,cAAL,CACpBtD,KADoB,EAEpB8C,oBAFoB,EAGpBM,OAHoB,CAAtB;;AAKA,WAAO,KAAK5C,KAAL,CAAWqB,aAAX,EAA0BvB,mBAA1B,CAAP;AACD;;AAEDK,EAAAA,iBAAiB,CAAC4C,kBAAD,EAAqBR,YAArB,EAAmCxD,IAAnC,EAAyC;AACxD,mCAAyByD,KAAK,CAACC,SAAN,CAAgBC,KAAhB,CAAsBC,IAAtB,CAA2B5D,IAA3B,CAAzB;AAAA,UAAOS,KAAP;AAAA,UAAcoD,OAAd;;AAEA,mCAA8B,KAAKnD,gBAAL,CAAsB8C,YAAtB,EAC3BM,UAD2B,CAChB9D,IADgB,EAE3Ba,cAF2B,CAEZJ,KAFY,EAG3BwD,YAH2B,CAGdJ,OAHc,EAI3B/C,oBAJ2B,EAA9B;AAAA,UAAOC,mBAAP;;AAMA,UAAMuB,aAAa,GAAG,KAAKyB,cAAL,CACpBtD,KADoB,EAEpBuD,kBAFoB,EAGpBH,OAHoB,CAAtB;;AAMA,WAAO,KAAK5C,KAAL,CAAWqB,aAAX,EAA0BvB,mBAA1B,CAAP;AACD;;AAEDS,EAAAA,cAAc,CAACwC,kBAAD,EAAqBR,YAArB,EAAmCxD,IAAnC,EAAyC;AACrD,mCAAgCyD,KAAK,CAACC,SAAN,CAAgBC,KAAhB,CAAsBC,IAAtB,CAA2B5D,IAA3B,CAAhC;AAAA,UAAOS,KAAP;AAAA,UAAiByD,WAAjB;;AACA,UAAMC,QAAQ,GAAG,wBAAQD,WAAW,CAAC,CAAD,CAAnB,IAA0BA,WAAW,CAAC,CAAD,CAArC,GAA2CA,WAA5D;;AAEA,oCAA8B,KAAKxD,gBAAL,CAAsB8C,YAAtB,EAC3BY,iBAD2B,CACTpE,IADS,EAE3Ba,cAF2B,CAEZJ,KAFY,EAG3B4D,8BAH2B,CAGIF,QAHJ,EAI3BrD,oBAJ2B,EAA9B;AAAA,UAAOC,mBAAP;;AAMA,UAAMuB,aAAa,GAAG,KAAKyB,cAAL,CACpBtD,KADoB,EAEpBuD,kBAFoB,EAGpBG,QAHoB,CAAtB;;AAKA,WAAO,KAAKlD,KAAL,CAAWqB,aAAX,EAA0BvB,mBAA1B,CAAP;AACD;;AAEDgD,EAAAA,cAAc,CAACtD,KAAD,EAAQuD,kBAAR,EAA4BH,OAA5B,EAAqC;AACjD,UAAMvB,aAAa,GAAG,oBAAM,KAAK1C,UAAX,CAAtB,CADiD,CAGjD;AACA;AACA;;AACA,UAAM0E,mBAAmB,GAAGT,OAAO,KAAKU,SAAZ,GAAwB,IAAxB,GAA+BV,OAA3D;;AACA,UAAMW,SAAS,GAAG,KAAKC,YAAL,CAChBhE,KADgB,EAEhBuD,kBAFgB,EAGhBM,mBAHgB,CAAlB;;AAMA,QAAI,wBAAQhC,aAAa,CAACzC,IAAtB,CAAJ,EAAiC;AAC/ByC,MAAAA,aAAa,CAACzC,IAAd,CAAmB6E,IAAnB,CAAwBF,SAAxB;AACA,aAAOlC,aAAP;AACD,KAHD,MAGO;AACL,YAAMqC,MAAM,GAAGC,aAAa,CAACtC,aAAD,CAAb,GACXP,KAAK,CAACyC,SAAD,CADM,GAEXzC,KAAK,CAACO,aAAD,EAAgBkC,SAAhB,CAFT;AAGA,aAAOG,MAAP;AACD;AACF;;AAEDF,EAAAA,YAAY,CAAChE,KAAD,EAAQuD,kBAAR,EAA4BH,OAA5B,EAAqC;AAC/C,QAAIG,kBAAkB,KAAK,KAA3B,EAAkC;AAChC,YAAMQ,SAAS,GAAG,EAAlB;AACAA,MAAAA,SAAS,CAAC/D,KAAD,CAAT,GAAmB,EAAnB;AACA+D,MAAAA,SAAS,CAAC/D,KAAD,CAAT,CAAiBuD,kBAAjB,IAAuC,KAAKa,YAAL,CAAkBhB,OAAlB,CAAvC;AACA,aAAOW,SAAP;AACD,KALD,MAKO;AACL,YAAMA,SAAS,GAAG,EAAlB;AACAA,MAAAA,SAAS,CAAC/D,KAAD,CAAT,GAAmB,KAAKoE,YAAL,CAAkBhB,OAAlB,CAAnB;AACA,aAAOW,SAAP;AACD;AACF;;AAEDK,EAAAA,YAAY,CAAChB,OAAD,EAAU;AACpB,QAAI,wBAAQA,OAAR,CAAJ,EAAsB;AACpB,aAAOA,OAAO,CAACiB,GAAR,CAAaC,EAAD,IAAQ,KAAKF,YAAL,CAAkBE,EAAlB,CAApB,CAAP;AACD,KAFD,MAEO;AACL,aAAOlB,OAAP;AACD;AACF;;AAED5C,EAAAA,KAAK,CAACrB,UAAD,EAAaE,gBAAb,EAA+B;AAClC;AACA,WAAO,IAAI,KAAKJ,WAAT,CAAqB,EAAE,GAAG,IAAL;AAAWE,MAAAA,UAAX;AAAuBE,MAAAA;AAAvB,KAArB,CAAP;AACD;;AAEDY,EAAAA,gBAAgB,CAACsD,kBAAD,EAAgC;AAC9C,WAAO,IAAIgB,gCAAJ,CACLhB,kBADK,EAEL,KAAKlE,gBAFA,EAGL,KAAKJ,WAHA,CAAP;AAKD;;AA9RgB,CADrB;;AAkSA,SAASuF,uBAAT,CAAiCrF,UAAjC,EAA6C;AAC3C,SAAO,wBAAQA,UAAU,CAACC,IAAnB,CAAP;AACD;;AAED,SAAS+E,aAAT,CAAuBjF,GAAvB,EAA4B;AAC1B,SAAOuF,MAAM,CAACC,IAAP,CAAYxF,GAAZ,EAAiBuD,MAAjB,KAA4B,CAAnC;AACD;;AAED,SAASnB,KAAT,CAAe,GAAG/B,IAAlB,EAAwB;AACtB,SAAO;AACLH,IAAAA,IAAI,EAAEG;AADD,GAAP;AAGD;;AAED,SAAS0C,cAAT,CAAwB,GAAG1C,IAA3B,EAAiC;AAC/B,SAAO;AACLH,IAAAA,IAAI,EAAEG,IAAI,CAACoF,MAAL,CACJ,CAACC,IAAD,EAAOC,GAAP,KACEL,uBAAuB,CAACK,GAAD,CAAvB,GACID,IAAI,CAACpD,MAAL,CAAYqD,GAAG,CAACzF,IAAhB,CADJ,GAEIwF,IAAI,CAACpD,MAAL,CAAY,CAACqD,GAAD,CAAZ,CAJF,EAKJ,EALI;AADD,GAAP;AASD;;AAED,SAASxD,UAAT,CAAoByD,IAApB,EAA0B;AACxB,SAAOA,IAAI,IAAIA,IAAI,CAAC1F,IAAb,IAAqB0F,IAAI,CAAC1F,IAAL,CAAUqD,MAAV,KAAqB,CAAjD;AACD;;eAEc1D,W","sourcesContent":["import { isArray } from './type-utils'\nimport clone from './clone'\nimport { FilterValidator } from './filter-validator'\nimport { Validator } from './validator'\nimport { optimisedQuery } from './query-optimiser'\n\nconst filterMixin = (Base: any = class {}) =>\n class extends Base {\n filterTree\n invalidArguments\n\n constructor(obj: { filterTree?; invalidArguments? } = {}) {\n super(obj)\n this.filterTree = obj.filterTree || { $and: [] }\n this.invalidArguments = obj.invalidArguments || []\n }\n\n eq(...args) {\n return this._binaryAnd('$eq', '.eq', args)\n }\n\n ne(...args) {\n return this._binaryAnd('$ne', '.ne', args)\n }\n\n ge(...args) {\n return this._AndLogicalEquivalence('$gte', '.ge', args)\n }\n\n gt(...args) {\n return this._AndLogicalEquivalence('$gt', '.gt', args)\n }\n\n le(...args) {\n return this._AndLogicalEquivalence('$lte', '.le', args)\n }\n\n lt(...args) {\n return this._AndLogicalEquivalence('$lt', '.lt', args)\n }\n\n isNotEmpty(field) {\n const [newInvalidArguments, valid] = this._filterValidator('.isNotEmpty')\n .arityIsOne(arguments)\n .validFieldName(field)\n .validateAndAggregate()\n\n if (valid) {\n return this.ne(field, null)\n }\n\n return this._copy(this.filterTree, newInvalidArguments)\n }\n\n isEmpty(field) {\n const [newInvalidArguments, valid] = this._filterValidator('.isEmpty')\n .arityIsOne(arguments)\n .validFieldName(field)\n .validateAndAggregate()\n\n if (valid) {\n return this.eq(field, null)\n }\n\n return this._copy(this.filterTree, newInvalidArguments)\n }\n\n startsWith(...args) {\n return this._AndStringOperand('$startsWith', '.startsWith', args)\n }\n\n endsWith(...args) {\n return this._AndStringOperand('$endsWith', '.endsWith', args)\n }\n\n contains(...args) {\n return this._AndStringOperand('$contains', '.contains', args)\n }\n\n hasSome(...args) {\n return this._AndSetOperand('$hasSome', '.hasSome', args)\n }\n\n hasAll(...args) {\n return this._AndSetOperand('$hasAll', '.hasAll', args)\n }\n\n or(orQuery) {\n const [newInvalidArguments, valid] = this._filterValidator('.or')\n .arityIsOne(arguments)\n .isInstanceOfSameClass(orQuery)\n .validateAndAggregate()\n\n if (valid) {\n const prefix = isEmptyAnd(this.filterTree) ? [] : [this.filterTree]\n return this._copy(\n inAnd({ $or: [...prefix, orQuery.filterTree] }),\n newInvalidArguments.concat(orQuery.invalidArguments)\n )\n } else {\n return this._copy(this.filterTree, newInvalidArguments)\n }\n }\n\n and(andQuery) {\n const [newInvalidArguments, valid] = this._filterValidator('.and')\n .arityIsOne(arguments)\n .isInstanceOfSameClass(andQuery)\n .validateAndAggregate()\n\n if (valid) {\n const prefix = isEmptyAnd(this.filterTree) ? [] : [this.filterTree]\n return this._copy(\n inAnd(...prefix, andQuery.filterTree),\n newInvalidArguments.concat(andQuery.invalidArguments)\n )\n } else {\n return this._copy(this.filterTree, newInvalidArguments)\n }\n }\n\n not(notQuery) {\n const [newInvalidArguments, valid] = this._filterValidator('.not')\n .arityIsOne(arguments)\n .isInstanceOfSameClass(notQuery)\n .validateAndAggregate()\n\n if (valid) {\n const newFilterTree = clone(this.filterTree)\n const notClause = { $not: [notQuery.filterTree] }\n const resultingFilter = inAndOptimized(newFilterTree, notClause)\n\n return this._copy(\n resultingFilter,\n newInvalidArguments.concat(notQuery.invalidArguments)\n )\n } else {\n return this._copy(this.filterTree, newInvalidArguments)\n }\n }\n\n between(field, rangeStart, rangeEnd) {\n const [newInvalidArguments, valid] = this._filterValidator('.between')\n .arityIsThree(arguments)\n .sameType(rangeStart, rangeEnd)\n .typeIsStringNumberOrDate(rangeStart)\n .typeIsStringNumberOrDate(rangeEnd)\n .validateAndAggregate()\n\n if (valid) {\n return this.ge(field, rangeStart).lt(field, rangeEnd)\n }\n\n return this._copy(this.filterTree, newInvalidArguments)\n }\n\n getFilterModel() {\n if (this.invalidArguments.length > 0) {\n throw new Error(this.invalidArguments.join(' '))\n }\n return optimisedQuery(this.filterTree)\n }\n\n setFilterModel(filterModel) {\n return this._copy(filterModel, [])\n }\n\n _binaryAnd(filterOperatorSymbol, operatorName, args) {\n const [field, operand] = Array.prototype.slice.call(args)\n\n const [newInvalidArguments] = this._filterValidator(operatorName)\n .arityIsTwo(args)\n .validFieldName(field)\n .validateAndAggregate()\n\n const newFilterTree = this._makeNewFilter(\n field,\n filterOperatorSymbol,\n operand\n )\n\n return this._copy(newFilterTree, newInvalidArguments)\n }\n\n _AndLogicalEquivalence(filterOperatorSymbol, operatorName, args) {\n const [field, operand] = Array.prototype.slice.call(args)\n\n const [newInvalidArguments] = this._filterValidator(operatorName)\n .arityIsTwo(args)\n .validFieldName(field)\n .typeIsStringNumberOrDate(operand)\n .validateAndAggregate()\n\n const newFilterTree = this._makeNewFilter(\n field,\n filterOperatorSymbol,\n operand\n )\n return this._copy(newFilterTree, newInvalidArguments)\n }\n\n _AndStringOperand(filterOperatorName, operatorName, args) {\n const [field, operand] = Array.prototype.slice.call(args)\n\n const [newInvalidArguments] = this._filterValidator(operatorName)\n .arityIsTwo(args)\n .validFieldName(field)\n .typeIsString(operand)\n .validateAndAggregate()\n\n const newFilterTree = this._makeNewFilter(\n field,\n filterOperatorName,\n operand\n )\n\n return this._copy(newFilterTree, newInvalidArguments)\n }\n\n _AndSetOperand(filterOperatorName, operatorName, args) {\n const [field, ...rawOperands] = Array.prototype.slice.call(args)\n const operands = isArray(rawOperands[0]) ? rawOperands[0] : rawOperands\n\n const [newInvalidArguments] = this._filterValidator(operatorName)\n .arityIsAtLeastTwo(args)\n .validFieldName(field)\n .typeIsStringNumberOrDateForAll(operands)\n .validateAndAggregate()\n\n const newFilterTree = this._makeNewFilter(\n field,\n filterOperatorName,\n operands\n )\n return this._copy(newFilterTree, newInvalidArguments)\n }\n\n _makeNewFilter(field, filterOperatorName, operand) {\n const newFilterTree = clone(this.filterTree)\n\n // filters with 'undefined' value are lost during serialization,\n // e.g. { val: { $ne: undefined } | translates to { val: {} }\n // Replacing 'undefined' with 'null' retains the filter.\n const serializableOperand = operand === undefined ? null : operand\n const newFilter = this._buildFilter(\n field,\n filterOperatorName,\n serializableOperand\n )\n\n if (isArray(newFilterTree.$and)) {\n newFilterTree.$and.push(newFilter)\n return newFilterTree\n } else {\n const result = isEmptyObject(newFilterTree)\n ? inAnd(newFilter)\n : inAnd(newFilterTree, newFilter)\n return result\n }\n }\n\n _buildFilter(field, filterOperatorName, operand) {\n if (filterOperatorName !== '$eq') {\n const newFilter = {}\n newFilter[field] = {}\n newFilter[field][filterOperatorName] = this._replaceRefs(operand)\n return newFilter\n } else {\n const newFilter = {}\n newFilter[field] = this._replaceRefs(operand)\n return newFilter\n }\n }\n\n _replaceRefs(operand) {\n if (isArray(operand)) {\n return operand.map((op) => this._replaceRefs(op))\n } else {\n return operand\n }\n }\n\n _copy(filterTree, invalidArguments) {\n // @ts-ignore-next-line\n return new this.constructor({ ...this, filterTree, invalidArguments })\n }\n\n _filterValidator(filterOperatorName): Validator {\n return new FilterValidator(\n filterOperatorName,\n this.invalidArguments,\n this.constructor\n )\n }\n }\n\nfunction isConjunctiveFormFilter(filterTree) {\n return isArray(filterTree.$and)\n}\n\nfunction isEmptyObject(obj) {\n return Object.keys(obj).length === 0\n}\n\nfunction inAnd(...args) {\n return {\n $and: args,\n }\n}\n\nfunction inAndOptimized(...args) {\n return {\n $and: args.reduce(\n (aggr, val) =>\n isConjunctiveFormFilter(val)\n ? aggr.concat(val.$and)\n : aggr.concat([val]),\n []\n ),\n }\n}\n\nfunction isEmptyAnd(node) {\n return node && node.$and && node.$and.length === 0\n}\n\nexport default filterMixin\n"]}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
exports.FilterValidator = void 0;
|
|
7
|
+
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
|
|
10
|
+
var _typeUtils = require("./type-utils");
|
|
11
|
+
|
|
12
|
+
var _clone = _interopRequireDefault(require("./clone"));
|
|
13
|
+
|
|
14
|
+
class FilterValidator {
|
|
15
|
+
constructor(operatorName, previousInvalidArguments, ctor) {
|
|
16
|
+
(0, _defineProperty2.default)(this, "ctor", void 0);
|
|
17
|
+
(0, _defineProperty2.default)(this, "_invalidArguments", void 0);
|
|
18
|
+
(0, _defineProperty2.default)(this, "_validations", void 0);
|
|
19
|
+
(0, _defineProperty2.default)(this, "operatorName", void 0);
|
|
20
|
+
this._validations = [];
|
|
21
|
+
this.operatorName = operatorName;
|
|
22
|
+
this.ctor = ctor;
|
|
23
|
+
this._invalidArguments = (0, _clone.default)(previousInvalidArguments);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
typeIsString(value) {
|
|
27
|
+
return this.addValidation(() => (0, _typeUtils.isString)(value), () => `Invalid ${this.operatorName} parameter value [${(0, _typeUtils.typeForDisplay)(value)}]. ${this.operatorName} parameter must be a String.`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
typeIsStringNumberOrDate(value) {
|
|
31
|
+
return this.addValidation(() => isDateStringOrNumber(value), () => `Invalid ${this.operatorName} parameter value [${(0, _typeUtils.typeForDisplay)(value)}]. Valid ${this.operatorName} parameter types are String, Number or Date.`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
sameType(first, second) {
|
|
35
|
+
return this.addValidation(() => (0, _typeUtils.typeForDisplay)(first) === (0, _typeUtils.typeForDisplay)(second), () => `Invalid ${this.operatorName} parameter values [${(0, _typeUtils.typeForDisplay)(first)}] and [${(0, _typeUtils.typeForDisplay)(second)}]. Both parameters must be of the same type.`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
typeIsStringNumberOrDateForAll(values) {
|
|
39
|
+
return this.addValidation(() => values.every(isDateStringOrNumber), () => `Invalid ${this.operatorName} usage. ${this.operatorName} supports only Number, String or Date items.`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
validFieldName(field) {
|
|
43
|
+
return this.addValidation(() => (0, _typeUtils.isString)(field), () => `Invalid ${this.operatorName} field value [${(0, _typeUtils.typeForDisplay)(field)}]. ${this.operatorName} field must be a String.`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
isInstanceOfSameClass(obj) {
|
|
47
|
+
return this.addValidation(() => obj instanceof this.ctor, () => `Invalid ${this.operatorName} parameter [${(0, _typeUtils.typeForDisplay)(obj)}]. ${this.operatorName} expects FilterBuilder only.`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
arityIsOne(args) {
|
|
51
|
+
return this.addValidation(() => args.length === 1, () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires one parameter.`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
arityIsTwo(args) {
|
|
55
|
+
return this.addValidation(() => args.length === 2, () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires two parameters.`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
arityIsThree(args) {
|
|
59
|
+
return this.addValidation(() => args.length === 3, () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires three parameters.`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
arityIsAtLeastTwo(args) {
|
|
63
|
+
return this.addValidation(() => args.length >= 2, () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires at least two parameters.`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
addValidation(predicateFn, messageFn) {
|
|
67
|
+
this._validations.push({
|
|
68
|
+
predicateFn,
|
|
69
|
+
messageFn
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
validateAndAggregate() {
|
|
76
|
+
const valid = this._validations.every(({
|
|
77
|
+
predicateFn,
|
|
78
|
+
messageFn
|
|
79
|
+
}) => this._appendIfInvalid(predicateFn(), messageFn()));
|
|
80
|
+
|
|
81
|
+
return [this._invalidArguments, valid];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
_appendIfInvalid(valid, message) {
|
|
85
|
+
if (!valid) {
|
|
86
|
+
this._invalidArguments.push(message);
|
|
87
|
+
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
exports.FilterValidator = FilterValidator;
|
|
97
|
+
|
|
98
|
+
function isDateStringOrNumber(value) {
|
|
99
|
+
return (0, _typeUtils.isString)(value) || (0, _typeUtils.isNumber)(value) || (0, _typeUtils.isDate)(value);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=filter-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/filter-validator.ts"],"names":["FilterValidator","constructor","operatorName","previousInvalidArguments","ctor","_validations","_invalidArguments","typeIsString","value","addValidation","typeIsStringNumberOrDate","isDateStringOrNumber","sameType","first","second","typeIsStringNumberOrDateForAll","values","every","validFieldName","field","isInstanceOfSameClass","obj","arityIsOne","args","length","arityIsTwo","arityIsThree","arityIsAtLeastTwo","predicateFn","messageFn","push","validateAndAggregate","valid","_appendIfInvalid","message"],"mappings":"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","sourcesContent":["import { typeForDisplay, isDate, isString, isNumber } from './type-utils'\nimport clone from './clone'\nimport { Validator } from './validator'\n\nexport class FilterValidator implements Validator {\n private ctor\n private _invalidArguments: string[]\n public _validations: Validation[]\n public operatorName?: string\n\n constructor(operatorName, previousInvalidArguments, ctor) {\n this._validations = []\n this.operatorName = operatorName\n this.ctor = ctor\n this._invalidArguments = clone(previousInvalidArguments)\n }\n\n typeIsString(value) {\n return this.addValidation(\n () => isString(value),\n () => `Invalid ${this.operatorName} parameter value [${typeForDisplay(value)}]. ${this.operatorName} parameter must be a String.`\n )\n }\n\n typeIsStringNumberOrDate(value) {\n return this.addValidation(\n () => isDateStringOrNumber(value),\n () => `Invalid ${this.operatorName} parameter value [${typeForDisplay(value)}]. Valid ${this.operatorName} parameter types are String, Number or Date.`\n )\n }\n\n sameType(first, second) {\n return this.addValidation(\n () => typeForDisplay(first) === typeForDisplay(second),\n () => `Invalid ${this.operatorName} parameter values [${typeForDisplay(first)}] and [${typeForDisplay(second)}]. Both parameters must be of the same type.`\n )\n }\n\n typeIsStringNumberOrDateForAll(values) {\n return this.addValidation(\n () => values.every(isDateStringOrNumber),\n () => `Invalid ${this.operatorName} usage. ${this.operatorName} supports only Number, String or Date items.`\n )\n }\n\n validFieldName(field) {\n return this.addValidation(\n () => isString(field),\n () => `Invalid ${this.operatorName} field value [${typeForDisplay(field)}]. ${this.operatorName} field must be a String.`\n )\n }\n\n isInstanceOfSameClass(obj) {\n return this.addValidation(\n () => obj instanceof this.ctor,\n () => `Invalid ${this.operatorName} parameter [${typeForDisplay(obj)}]. ${this.operatorName} expects FilterBuilder only.`\n )\n }\n\n arityIsOne(args) {\n return this.addValidation(\n () => args.length === 1,\n () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires one parameter.`\n )\n }\n\n arityIsTwo(args) {\n return this.addValidation(\n () => args.length === 2,\n () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires two parameters.`\n )\n }\n\n arityIsThree(args) {\n return this.addValidation(\n () => args.length === 3,\n () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires three parameters.`\n )\n }\n\n arityIsAtLeastTwo(args) {\n return this.addValidation(\n () => args.length >= 2,\n () => `Invalid ${this.operatorName} usage. ${this.operatorName} requires at least two parameters.`\n )\n }\n\n addValidation(predicateFn, messageFn) {\n this._validations.push({\n predicateFn,\n messageFn,\n })\n return this\n }\n\n validateAndAggregate(): [string[], boolean] {\n const valid = this._validations.every(({ predicateFn, messageFn }) =>\n this._appendIfInvalid(predicateFn(), messageFn())\n )\n return [this._invalidArguments, valid]\n }\n\n _appendIfInvalid(valid, message) {\n if (!valid) {\n this._invalidArguments.push(message)\n return false\n }\n return true\n }\n}\n\nfunction isDateStringOrNumber(value) {\n return isString(value) || isNumber(value) || isDate(value)\n}\n\ninterface Validation {\n predicateFn: Function\n messageFn: Function\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _filterBuilder = require("./filter-builder");
|
|
9
|
+
|
|
10
|
+
exports.filterBuilder = _filterBuilder.filterBuilder;
|
|
11
|
+
|
|
12
|
+
var _filterMixin = _interopRequireDefault(require("./filter-mixin"));
|
|
13
|
+
|
|
14
|
+
exports.filterMixin = _filterMixin.default;
|
|
15
|
+
|
|
16
|
+
var _queryOptimiser = require("./query-optimiser");
|
|
17
|
+
|
|
18
|
+
exports.optimiseQuery = _queryOptimiser.optimisedQuery;
|
|
19
|
+
|
|
20
|
+
var _validator = require("./validator");
|
|
21
|
+
|
|
22
|
+
exports.Validator = _validator.Validator;
|
|
23
|
+
var _default = _filterBuilder.filterBuilder;
|
|
24
|
+
exports.default = _default;
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"names":["filterBuilder"],"mappings":";;;;;;;AAAA;;;;AACA;;;;AACA;;;;AACA;;;eAIeA,4B","sourcesContent":["import { filterBuilder } from './filter-builder'\nimport filterMixin from './filter-mixin'\nimport { optimisedQuery as optimiseQuery } from './query-optimiser'\nimport { Validator } from './validator'\n\nexport { filterMixin, filterBuilder, optimiseQuery, Validator }\n\nexport default filterBuilder\n"]}
|