UNPKG

dambreaker-mongo

Version:
94 lines (78 loc) 3.06 kB
/*! * dambreaker-mongo * Copyright(c) 2018 Benoît Claveau <benoit.claveau@gmail.com> / CABASI * Inspire by https://github.com/nswbmw/qs-mongodb * MIT Licensed */ const { Error, UndefinedError } = require("oups"); const qs = require('qs'); const logicalOperators = { '&&': '$and', '||': '$or', //'^' : '$nor' }; /** * price>5 => { price: { $gt: 5 }} * skip=5 => { skip: 5 } * sort[name]=1 => { sort: { name: 1 }} */ class MongoQueryString { constructor(json) { this.json = json; } parse(querystring) { if (!querystring) return querystring; querystring = this.cancelNullable(querystring); querystring = this.formatComparisonOperators(querystring); let pathReg; while (pathReg = querystring.match(/\(([^\(]+?)\)/)) { querystring = querystring.replace(pathReg[0], this.formatLogicalOperators(pathReg[1])); } querystring = this.formatLogicalOperators(querystring); querystring = this.formatCommaOperators(querystring); const query = qs.parse(querystring); const { skip, limit, sort, project, ...filter } = this.json.typed(query); return { filter, skip, limit, sort, project }; } cancelNullable(str) { str = str.replace(/([^&=><!]+)[=><!]=?(&|$)/g, ""); //empty regexp ex field=, field>, field<, field>=, field<=, field!= str = str.replace(/([^&=]+)=\/\^?\$?\/([ig]*)(&|$)/g, ""); //empty regexp field=//, ..., field=//ig, field=/^/, field=/$/, ... return str; } formatComparisonOperators(str) { str = str.replace(/(=?!)(?!=)/g, '[$not]='); //special str = str.replace(/=?>=/g, '[$gte]='); str = str.replace(/=?<=/g, '[$lte]='); str = str.replace(/=?(!=|<>)/g, '[$ne]='); str = str.replace(/=?>/g, '[$gt]='); str = str.replace(/=?</g, '[$lt]='); //regexp with options str = str.replace(/([^&=]+)=\/([^&=]+)\/([ig]*)(&|$)/g, `$1[$regex]=$2&$1[$options]=$3$4`); //str = str.replace(/([^&|]+)=\/([^&|]+)\/(\w*)[$|&]/g, `$1[$regex]=$2&$1[$options]=$3`); return str; } formatLogicalOperators(str) { for (let operator in logicalOperators) { if (~str.indexOf(operator)) { str = str.split(operator).map((item, index) => { return item.split('&').map(item => { return logicalOperators[operator] + '[' + index + ']' + item.replace(/^([^\[=]+)/, '[$1]'); }).join('&'); }).join('&'); break; } }; return str; } formatCommaOperators(str) { if (!str.match(/,/)) return str; return str.split('&').map(item => { return item.replace(/(.+)=((.+)(,(.+))+)/g, (querystring, p1, p2) => { return p2.split(',').map((item) => { return p1 + '[$in]=' + item; }).join('&'); }); }).join('&'); } } exports = module.exports = MongoQueryString;