UNPKG

@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
"use strict"; 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