@builder6/query-mongodb 0.6.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/LICENSE +201 -0
- package/README.md +37 -0
- package/dist/index.js +272 -0
- package/dist/index.test.js +1941 -0
- package/dist/options.js +420 -0
- package/dist/options.test.js +960 -0
- package/dist/pipelines.js +751 -0
- package/dist/pipelines.test.js +782 -0
- package/dist/utils.js +45 -0
- package/dist/utils.test.js +36 -0
- package/index.js +1 -0
- package/options.js +1 -0
- package/package.json +60 -0
- package/src/index.js +497 -0
- package/src/index.test.js +2333 -0
- package/src/options.js +573 -0
- package/src/options.test.js +1112 -0
- package/src/pipelines.js +760 -0
- package/src/pipelines.test.js +1300 -0
- package/src/utils.js +33 -0
- package/src/utils.test.js +40 -0
package/dist/options.js
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
4
|
+
|
|
5
|
+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
6
|
+
|
|
7
|
+
var yup = require('yup');
|
|
8
|
+
|
|
9
|
+
var regexBool = /(true|false)/i;
|
|
10
|
+
|
|
11
|
+
function OptionError() {
|
|
12
|
+
var message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
13
|
+
|
|
14
|
+
this.name = 'OptionError';
|
|
15
|
+
this.message = message;
|
|
16
|
+
}
|
|
17
|
+
OptionError.prototype = Error.prototype;
|
|
18
|
+
|
|
19
|
+
var asBool = function asBool(v) {
|
|
20
|
+
var match = void 0;
|
|
21
|
+
if (typeof v === 'string' && (match = v.match(regexBool))) {
|
|
22
|
+
return {
|
|
23
|
+
true: true,
|
|
24
|
+
false: false
|
|
25
|
+
}[match[0].toLowerCase()];
|
|
26
|
+
} else return !!v;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function fixFilterAndSearch(schema) {
|
|
30
|
+
|
|
31
|
+
var operators = ['=', '<>', '>', '>=', '<', '<='];
|
|
32
|
+
|
|
33
|
+
function fixValue(type, value) {
|
|
34
|
+
return {
|
|
35
|
+
int: parseInt,
|
|
36
|
+
float: parseFloat,
|
|
37
|
+
datetime: function datetime(v) {
|
|
38
|
+
return new Date(v);
|
|
39
|
+
},
|
|
40
|
+
bool: asBool
|
|
41
|
+
}[type](value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function fixFilter(f) {
|
|
45
|
+
if (!f || !Array.isArray(f)) return f;
|
|
46
|
+
if (f.length === 3 && typeof f[2] === 'string' && schema[f[0]] && operators.includes(f[1])) return [f[0], f[1], fixValue(schema[f[0]], f[2])];else return f.map(function (e) {
|
|
47
|
+
return fixFilter(e);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function fixSearch(se, so, sv) {
|
|
52
|
+
if (!se || !so || !sv || typeof sv !== 'string') return sv;
|
|
53
|
+
var fieldName = typeof se === 'string' ? schema[se] : Array.isArray(se) ? se.find(function (e) {
|
|
54
|
+
return schema[e] ? e : null;
|
|
55
|
+
}) : null;
|
|
56
|
+
return fieldName ? fixValue(schema[fieldName], sv) : sv;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return function (qry) {
|
|
60
|
+
if (!qry) return qry;
|
|
61
|
+
var fixedFilter = fixFilter(parse(qry.filter));
|
|
62
|
+
var fixedSearchValue = fixSearch(qry.searchExpr, qry.searchOperation, qry.searchValue);
|
|
63
|
+
|
|
64
|
+
return Object.assign({}, qry, fixedFilter ? {
|
|
65
|
+
filter: fixedFilter
|
|
66
|
+
} : {}, fixedSearchValue ? {
|
|
67
|
+
searchValue: fixedSearchValue
|
|
68
|
+
} : {});
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
var wrapYupChecker = function wrapYupChecker(yupChecker) {
|
|
73
|
+
return {
|
|
74
|
+
validate: function validate(o) {
|
|
75
|
+
try {
|
|
76
|
+
yupChecker.validateSync(o, { strict: true });
|
|
77
|
+
return null;
|
|
78
|
+
} catch (e) {
|
|
79
|
+
return e;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
var sortOptionsCheckerYup = yup.object().shape({
|
|
86
|
+
desc: yup.bool().required(),
|
|
87
|
+
selector: yup.string().required(),
|
|
88
|
+
|
|
89
|
+
isExpanded: yup.mixed()
|
|
90
|
+
}).noUnknown();
|
|
91
|
+
|
|
92
|
+
var sortOptionsChecker = wrapYupChecker(sortOptionsCheckerYup);
|
|
93
|
+
|
|
94
|
+
yup.addMethod(yup.mixed, 'or', function (schemas, msg) {
|
|
95
|
+
return this.test({
|
|
96
|
+
name: 'or',
|
|
97
|
+
message: "Can't find valid schema" || msg,
|
|
98
|
+
test: function test(value) {
|
|
99
|
+
if (!Array.isArray(schemas)) throw new OptionError('"or" requires schema array');
|
|
100
|
+
|
|
101
|
+
var results = schemas.map(function (schema) {
|
|
102
|
+
return schema.isValidSync(value, { strict: true });
|
|
103
|
+
});
|
|
104
|
+
return results.some(function (res) {
|
|
105
|
+
return !!res;
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
exclusive: false
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
var groupOptionsCheckerYup = yup.object().shape({
|
|
113
|
+
selector: yup.string().required(),
|
|
114
|
+
desc: yup.bool(),
|
|
115
|
+
isExpanded: yup.bool(),
|
|
116
|
+
groupInterval: yup.mixed().or([yup.number().integer(), yup.mixed().oneOf(['year', 'quarter', 'month', 'day', 'dayOfWeek', 'hour', 'minute', 'second'])])
|
|
117
|
+
}).noUnknown();
|
|
118
|
+
|
|
119
|
+
var groupOptionsChecker = wrapYupChecker(groupOptionsCheckerYup);
|
|
120
|
+
|
|
121
|
+
var summaryOptionsCheckerYup = yup.object().shape({
|
|
122
|
+
summaryType: yup.mixed().oneOf(['sum', 'avg', 'min', 'max', 'count']).required(),
|
|
123
|
+
selector: yup.string()
|
|
124
|
+
}).noUnknown();
|
|
125
|
+
|
|
126
|
+
var summaryOptionsChecker = wrapYupChecker(summaryOptionsCheckerYup);
|
|
127
|
+
|
|
128
|
+
function validateAll(list, checker) {
|
|
129
|
+
var short = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
130
|
+
|
|
131
|
+
return list.reduce(function (r, v) {
|
|
132
|
+
if (short && !r.valid) return r;
|
|
133
|
+
var newr = checker.validate(v);
|
|
134
|
+
if (newr) {
|
|
135
|
+
r.errors.push(newr);
|
|
136
|
+
r.valid = false;
|
|
137
|
+
}
|
|
138
|
+
return r;
|
|
139
|
+
}, { valid: true, errors: [] });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function parse(arg) {
|
|
143
|
+
var canBeString = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
144
|
+
|
|
145
|
+
var ob = arg;
|
|
146
|
+
if (typeof arg === 'string') {
|
|
147
|
+
try {
|
|
148
|
+
ob = JSON.parse(arg);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
if (!canBeString) throw new OptionError(e.message);
|
|
151
|
+
return arg;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return ob;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function representsTrue(val) {
|
|
158
|
+
return val === true || val === 'true';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function wrapLoadOptions(lo) {
|
|
162
|
+
return {
|
|
163
|
+
loadOptions: lo
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function wrapProcessingOptions(po) {
|
|
168
|
+
return {
|
|
169
|
+
processingOptions: po
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function check(qry, onames, checker) {
|
|
174
|
+
var converter = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function (v) {
|
|
175
|
+
return v;
|
|
176
|
+
};
|
|
177
|
+
var defaultValue = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
|
|
178
|
+
var wrapper = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : wrapLoadOptions;
|
|
179
|
+
|
|
180
|
+
var options = typeof onames === 'string' ? [onames] : onames;
|
|
181
|
+
var allFound = qry && options.reduce(function (r, v) {
|
|
182
|
+
return r && !!qry[v];
|
|
183
|
+
}, true);
|
|
184
|
+
|
|
185
|
+
if (!allFound) return defaultValue;
|
|
186
|
+
try {
|
|
187
|
+
var vals = options.map(function (o) {
|
|
188
|
+
return converter(qry[o], o);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
var checkResult = checker.apply(undefined, _toConsumableArray(vals));
|
|
192
|
+
|
|
193
|
+
return checkResult ? wrapper(checkResult) : {
|
|
194
|
+
errors: options.map(function (o) {
|
|
195
|
+
return 'Invalid \'' + o + '\': ' + qry[o];
|
|
196
|
+
})
|
|
197
|
+
};
|
|
198
|
+
} catch (err) {
|
|
199
|
+
return {
|
|
200
|
+
errors: [err]
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function takeOptions(qry) {
|
|
206
|
+
return check(qry, 'take', function (take) {
|
|
207
|
+
return take >= 0 ? {
|
|
208
|
+
take: take
|
|
209
|
+
} : null;
|
|
210
|
+
}, function (take) {
|
|
211
|
+
return parseInt(take);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function skipOptions(qry) {
|
|
216
|
+
return check(qry, 'skip', function (skip) {
|
|
217
|
+
return skip >= 0 ? {
|
|
218
|
+
skip: skip
|
|
219
|
+
} : null;
|
|
220
|
+
}, function (skip) {
|
|
221
|
+
return parseInt(skip);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function totalCountOptions(qry) {
|
|
226
|
+
return check(qry, 'requireTotalCount', function (requireTotalCount) {
|
|
227
|
+
return {
|
|
228
|
+
requireTotalCount: requireTotalCount
|
|
229
|
+
};
|
|
230
|
+
}, function (requireTotalCount) {
|
|
231
|
+
return representsTrue(requireTotalCount);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function sortOptions(qry) {
|
|
236
|
+
return check(qry, 'sort', function (sort) {
|
|
237
|
+
var sortOptions = parse(sort);
|
|
238
|
+
if (Array.isArray(sortOptions) && sortOptions.length > 0) {
|
|
239
|
+
var vr = validateAll(sortOptions, sortOptionsChecker);
|
|
240
|
+
if (vr.valid) return {
|
|
241
|
+
sort: sortOptions
|
|
242
|
+
};else {
|
|
243
|
+
throw new OptionError('Sort parameter validation errors: ' + JSON.stringify(vr.errors));
|
|
244
|
+
}
|
|
245
|
+
} else return null;
|
|
246
|
+
}, function (sort) {
|
|
247
|
+
var sortOptions = parse(sort);
|
|
248
|
+
if (Array.isArray(sortOptions)) {
|
|
249
|
+
return sortOptions.map(function (s) {
|
|
250
|
+
return _extends({}, s, { desc: representsTrue(s.desc) });
|
|
251
|
+
});
|
|
252
|
+
} else return sort;
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function groupOptions(qry) {
|
|
257
|
+
return check(qry, 'group', function (group) {
|
|
258
|
+
var groupOptions = parse(group);
|
|
259
|
+
if (Array.isArray(groupOptions)) {
|
|
260
|
+
if (groupOptions.length > 0) {
|
|
261
|
+
var vr = validateAll(groupOptions, groupOptionsChecker);
|
|
262
|
+
if (vr.valid) return mergeResults([wrapLoadOptions({
|
|
263
|
+
group: groupOptions
|
|
264
|
+
}), check(qry, 'requireGroupCount', function (requireGroupCount) {
|
|
265
|
+
return {
|
|
266
|
+
requireGroupCount: requireGroupCount
|
|
267
|
+
};
|
|
268
|
+
}, function (requireGroupCount) {
|
|
269
|
+
return representsTrue(requireGroupCount);
|
|
270
|
+
}), check(qry, 'groupSummary', function (groupSummary) {
|
|
271
|
+
var gsOptions = parse(groupSummary);
|
|
272
|
+
if (Array.isArray(gsOptions)) {
|
|
273
|
+
if (gsOptions.length > 0) {
|
|
274
|
+
var _vr = validateAll(gsOptions, summaryOptionsChecker);
|
|
275
|
+
if (_vr.valid) return {
|
|
276
|
+
groupSummary: gsOptions
|
|
277
|
+
};else throw new OptionError('Group summary parameter validation errors: ' + JSON.stringify(_vr.errors));
|
|
278
|
+
} else return {};
|
|
279
|
+
} else return null;
|
|
280
|
+
})]);else throw new OptionError('Group parameter validation errors: ' + JSON.stringify(vr.errors));
|
|
281
|
+
} else return {};
|
|
282
|
+
} else return null;
|
|
283
|
+
}, function (group) {
|
|
284
|
+
var groupOptions = parse(group);
|
|
285
|
+
if (Array.isArray(groupOptions)) {
|
|
286
|
+
return groupOptions.map(function (g) {
|
|
287
|
+
return _extends({}, g, {
|
|
288
|
+
isExpanded: representsTrue(g.isExpanded)
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
} else return group;
|
|
292
|
+
}, undefined, function (o) {
|
|
293
|
+
return o;
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function totalSummaryOptions(qry) {
|
|
298
|
+
return check(qry, 'totalSummary', function (totalSummary) {
|
|
299
|
+
var tsOptions = parse(totalSummary);
|
|
300
|
+
if (Array.isArray(tsOptions)) {
|
|
301
|
+
if (tsOptions.length > 0) {
|
|
302
|
+
var vr = validateAll(tsOptions, summaryOptionsChecker);
|
|
303
|
+
if (vr.valid) return {
|
|
304
|
+
totalSummary: tsOptions
|
|
305
|
+
};else throw new OptionError('Total summary parameter validation errors: ' + JSON.stringify(vr.errors));
|
|
306
|
+
} else return {};
|
|
307
|
+
} else return null;
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function filterOptions(qry) {
|
|
312
|
+
return check(qry, 'filter', function (filter) {
|
|
313
|
+
var filterOptions = parse(filter, true);
|
|
314
|
+
if (typeof filterOptions === 'string' || Array.isArray(filterOptions)) return {
|
|
315
|
+
filter: filterOptions
|
|
316
|
+
};else return null;
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function searchOptions(qry) {
|
|
321
|
+
return check(qry, ['searchExpr', 'searchOperation', 'searchValue'], function (se, so, sv) {
|
|
322
|
+
if (typeof se === 'string' || Array.isArray(se)) return {
|
|
323
|
+
searchExpr: se,
|
|
324
|
+
searchOperation: so,
|
|
325
|
+
searchValue: sv
|
|
326
|
+
};else return null;
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function selectOptions(qry) {
|
|
331
|
+
return check(qry, 'select', function (select) {
|
|
332
|
+
var selectOptions = parse(select, true);
|
|
333
|
+
if (typeof selectOptions === 'string') return {
|
|
334
|
+
select: [selectOptions]
|
|
335
|
+
};else if (Array.isArray(selectOptions)) {
|
|
336
|
+
if (selectOptions.length > 0) {
|
|
337
|
+
if (selectOptions.reduce(function (r, v) {
|
|
338
|
+
return r && typeof v === 'string';
|
|
339
|
+
})) return {
|
|
340
|
+
select: selectOptions
|
|
341
|
+
};else throw new OptionError('Select array parameter has invalid content: ' + JSON.stringify(selectOptions));
|
|
342
|
+
} else return {};
|
|
343
|
+
} else return null;
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function timezoneOptions(qry) {
|
|
348
|
+
return check(qry, 'tzOffset', function (tzOffset) {
|
|
349
|
+
return {
|
|
350
|
+
timezoneOffset: parseInt(tzOffset) || 0
|
|
351
|
+
};
|
|
352
|
+
}, function (v) {
|
|
353
|
+
return v;
|
|
354
|
+
}, {
|
|
355
|
+
timezoneOffset: 0
|
|
356
|
+
}, wrapProcessingOptions);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function caseInsensitiveRegexOptions(qry) {
|
|
360
|
+
return check(qry, 'caseInsensitiveRegex', function (caseInsensitiveRegex) {
|
|
361
|
+
return {
|
|
362
|
+
caseInsensitiveRegex: caseInsensitiveRegex
|
|
363
|
+
};
|
|
364
|
+
}, function (caseInsensitiveRegex) {
|
|
365
|
+
return representsTrue(caseInsensitiveRegex);
|
|
366
|
+
}, { caseInsensitiveRegex: true }, wrapProcessingOptions);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function summaryQueryLimitOptions(qry) {
|
|
370
|
+
return check(qry, 'summaryQueryLimit', function (sql) {
|
|
371
|
+
return sql >= 0 ? {
|
|
372
|
+
summaryQueryLimit: sql
|
|
373
|
+
} : {};
|
|
374
|
+
}, function (sql) {
|
|
375
|
+
return parseInt(sql);
|
|
376
|
+
}, {}, wrapProcessingOptions);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function mergeResults(results) {
|
|
380
|
+
return results.reduce(function (r, v) {
|
|
381
|
+
return {
|
|
382
|
+
loadOptions: _extends({}, r.loadOptions || {}, v.loadOptions || {}),
|
|
383
|
+
processingOptions: _extends({}, r.processingOptions || {}, v.processingOptions || {}),
|
|
384
|
+
errors: [].concat(_toConsumableArray(r.errors || []), _toConsumableArray(v.errors || []))
|
|
385
|
+
};
|
|
386
|
+
}, {});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function getOptions(qry, schema) {
|
|
390
|
+
if (!qry) return undefined;
|
|
391
|
+
|
|
392
|
+
var fixedQry = schema ? fixFilterAndSearch(schema)(qry) : qry;
|
|
393
|
+
|
|
394
|
+
return mergeResults([takeOptions, skipOptions, totalCountOptions, sortOptions, groupOptions, totalSummaryOptions, filterOptions, searchOptions, selectOptions, timezoneOptions, summaryQueryLimitOptions, caseInsensitiveRegexOptions].map(function (f) {
|
|
395
|
+
return f(fixedQry);
|
|
396
|
+
}));
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
module.exports = {
|
|
400
|
+
getOptions: getOptions,
|
|
401
|
+
private: {
|
|
402
|
+
fixFilterAndSearch: fixFilterAndSearch,
|
|
403
|
+
validateAll: validateAll,
|
|
404
|
+
check: check,
|
|
405
|
+
takeOptions: takeOptions,
|
|
406
|
+
skipOptions: skipOptions,
|
|
407
|
+
totalCountOptions: totalCountOptions,
|
|
408
|
+
sortOptions: sortOptions,
|
|
409
|
+
groupOptions: groupOptions,
|
|
410
|
+
totalSummaryOptions: totalSummaryOptions,
|
|
411
|
+
filterOptions: filterOptions,
|
|
412
|
+
searchOptions: searchOptions,
|
|
413
|
+
selectOptions: selectOptions,
|
|
414
|
+
sortOptionsChecker: sortOptionsChecker,
|
|
415
|
+
groupOptionsChecker: groupOptionsChecker,
|
|
416
|
+
summaryOptionsChecker: summaryOptionsChecker,
|
|
417
|
+
asBool: asBool,
|
|
418
|
+
parse: parse
|
|
419
|
+
}
|
|
420
|
+
};
|