@brozeph/mongoose-middleware
Version:
Middleware for mongoose that makes filtering, sorting, pagination and projection chainable and simple to apply
254 lines (208 loc) • 7.87 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-int"));
var _parseFloat2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-float"));
var _default = function _default(mongoose) {
function analyzeWhereSpec(val) {
if (typeof val === 'string') {
switch (val.toLowerCase()) {
case 'null':
return null;
case 'true':
return true;
case 'false':
return false;
default:
// use a regex to validate if val is a real parse-able number
// javascript isNaN() treats a string such as '100000329e97' as
// a legitimate number, which is not a desirable result
// e.g. both Number('100000329e97'), parseInt('100000329e97')
// yield a number 100000329, and isNaN('100000329e97') === false
if (/^[-+]?[0-9]*\.?[0-9]+$/.test(val)) {
// val is a number
if (val.indexOf('.') > -1) {
// val is a float
return (0, _parseFloat2["default"])(val);
} else {
return (0, _parseInt2["default"])(val, 10);
}
}
}
}
return val;
}
function applyEquals(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).equals(analyzeWhereSpec(spec[key]));
});
}
function applyExists(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).exists(analyzeWhereSpec(spec[key]));
});
}
function applyGreaterThan(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).gt(spec[key]);
});
}
function applyGreaterThanEqual(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).gte(spec[key]);
});
}
function applyIn(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key)["in"](spec[key]);
});
}
function applyLesserThan(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).lt(spec[key]);
});
}
function applyLesserThanEqual(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).lte(spec[key]);
});
}
function applyNotIn(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).nin(spec[key]);
});
}
function applyNotEqual(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _keys["default"])(spec).forEach(function (key) {
query.where(key).ne(analyzeWhereSpec(spec[key]));
});
}
function applyRegex(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var buildRegex = arguments.length > 2 ? arguments[2] : undefined;
(0, _keys["default"])(spec).forEach(function (key) {
var val = buildRegex(spec[key]);
if ((0, _isArray["default"])(val)) {
val.forEach(function (term) {
query.where(key, term);
});
} else {
query.where(key, val);
}
});
}
function applyRegexAsOptional(query) {
var spec = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var buildRegex = arguments.length > 2 ? arguments[2] : undefined;
var orOptions = [],
orOptionsNode = {};
(0, _keys["default"])(spec).forEach(function (key) {
var val = buildRegex(spec[key]);
if ((0, _isArray["default"])(val)) {
orOptions = orOptions.concat(function () {
var node = {},
nodeOptions = [];
val.forEach(function (term) {
node = {};
node[key] = term;
nodeOptions.push(node);
});
return nodeOptions;
}());
} else {
orOptionsNode = {};
orOptionsNode[key] = val;
orOptions.push(orOptionsNode);
}
});
if (orOptions.length > 0) {
query.or(orOptions);
}
}
function regexContains(val) {
if ((0, _isArray["default"])(val) && val.length) {
return val.map(function (term) {
return regexContains(term);
});
}
if (typeof val === 'string') {
return new RegExp(sanitize(val), 'i');
}
return val;
}
function regexEndsWith(val) {
if ((0, _isArray["default"])(val) && val.length) {
return val.map(function (term) {
return regexEndsWith(term);
});
}
return new RegExp(sanitize(val) + '$', 'i');
}
function regexExact(val) {
if ((0, _isArray["default"])(val) && val.length) {
return val.map(function (term) {
return regexExact(term);
});
}
val = analyzeWhereSpec(val);
if (typeof val === 'string') {
return new RegExp('^' + sanitize(val) + '$', 'i');
}
return val;
}
function regexStartsWith(val) {
if ((0, _isArray["default"])(val) && val.length) {
return val.map(function (term) {
return regexStartsWith(term);
});
}
return new RegExp('^' + sanitize(val), 'i');
}
function sanitize(str) {
// sanitizes regex escapes
return str.replace(/[\W\s]/ig, '\\$&');
}
mongoose.Query.prototype.filter = function (options) {
if (!options || !options.filters) {
return this;
}
var mandatory = options.filters.mandatory || {},
optional = options.filters.optional || {},
query = this; // MANDATORY
applyRegex(query, mandatory.contains, regexContains);
applyRegex(query, mandatory.endsWith, regexEndsWith);
applyRegex(query, mandatory.startsWith, regexStartsWith);
applyRegex(query, mandatory.exact, regexExact);
applyEquals(query, mandatory.equals || {});
applyExists(query, mandatory.exists || {});
applyGreaterThan(query, mandatory.greaterThan || mandatory.gt || {});
applyGreaterThanEqual(query, mandatory.greaterThanEqual || mandatory.gte || {});
applyIn(query, mandatory["in"] || {});
applyLesserThan(query, mandatory.lessThan || mandatory.lt || {});
applyLesserThanEqual(query, mandatory.lessThanEqual || mandatory.lte || {});
applyNotIn(query, mandatory.notIn || mandatory.nin || {});
applyNotEqual(query, mandatory.notEqual || mandatory.notEqualTo || mandatory.ne || {}); // OPTIONAL
applyRegexAsOptional(query, optional.contains, regexContains);
applyRegexAsOptional(query, optional.endsWith, regexEndsWith);
applyRegexAsOptional(query, optional.startsWith, regexStartsWith);
applyRegexAsOptional(query, optional.exact, regexExact);
return query;
};
};
exports["default"] = _default;
//# sourceMappingURL=filter.js.map
;