module.exports = function(Self) { Self.installMethod = function(methodName, filterCb, filterResult) { this.remoteMethod(methodName, { description: 'List items using a filter', accessType: 'READ', accepts: [ { arg: 'filter', type: 'object', required: true, description: 'Filter defining where', http: function(ctx) { return ctx.req.query; } } ], returns: { arg: 'data', type: [this.modelName], root: true }, http: { verb: 'get', path: `/${methodName}` } }); this[methodName] = (params, cb) => { let filter = removeEmpty(filterCb(params)); var response = {}; function returnValues() { if (response.instances !== undefined && response.count !== undefined) { if (filterResult) cb(null, filterResult(response)); else cb(null, response); } } function error() { cb(null, response); } this.find(filter, function(err, instances) { if (err) { error(); } else { response.instances = instances; returnValues(); } }); this.count(filter.where, function(err, totalCount) { if (err) { error(); } else { response.count = totalCount; returnValues(); } }); }; }; }; function removeEmpty(o) { if (Array.isArray(o)) { let array = []; for (let item of o) { let i = removeEmpty(item); if (!isEmpty(i)) array.push(i); } if (array.length > 0) return array; } else if (typeof o === 'object') { let object = {}; for (let key in o) { let i = removeEmpty(o[key]); if (!isEmpty(i)) object[key] = i; } if (Object.keys(object).length > 0) return object; } else if (!isEmpty(o)) return o; return undefined; } function isEmpty(value) { return value === undefined || value === ''; }