/** * Passes a loopback fields filter to an object. * * @param {Object} fields The fields object or array * @return {Object} The fields as object */ function fieldsToObject(fields) { let fieldsObj = {}; if (Array.isArray(fields)) { for (let field of fields) fieldsObj[field] = true; } else if (typeof fields == 'object') { for (let field in fields) { if (fields[field]) fieldsObj[field] = true; } } return fieldsObj; } /** * Merges two loopback fields filters. * * @param {Object|Array} src The source fields * @param {Object|Array} dst The destination fields * @return {Array} The merged fields as an array */ function mergeFields(src, dst) { let fields = {}; Object.assign(fields, fieldsToObject(src), fieldsToObject(dst) ); return Object.keys(fields); } /** * Merges two loopback where filters. * * @param {Object|Array} src The source where * @param {Object|Array} dst The destination where * @return {Array} The merged wheres */ function mergeWhere(src, dst) { let and = []; if (src) and.push(src); if (dst) and.push(dst); return simplifyOperation(and, 'and'); } /** * Merges two loopback filters returning the merged filter. * * @param {Object} src The source filter * @param {Object} dst The destination filter * @return {Object} The result filter */ function mergeFilters(src, dst) { let res = Object.assign({}, dst); if (!src) return res; if (src.fields) res.fields = mergeFields(src.fields, res.fields); if (src.where) res.where = mergeWhere(res.where, src.where); if (src.include) res.include = src.include; if (src.order) res.order = src.order; if (src.limit) res.limit = src.limit; if (src.offset) res.offset = src.offset; if (src.skip) res.skip = src.skip; return res; } function simplifyOperation(operation, operator) { switch (operation.length) { case 0: return undefined; case 1: return operation[0]; default: return {[operator]: operation}; } } function buildFilter(params, builderFunc) { let and = []; for (let param in params) { let value = params[param]; if (value == null) continue; let expr = builderFunc(param, value); if (expr) and.push(expr); } return simplifyOperation(and, 'and'); } module.exports = { fieldsToObject: fieldsToObject, mergeFields: mergeFields, mergeWhere: mergeWhere, mergeFilters: mergeFilters, buildFilter: buildFilter };