module.exports = function(self) { self.setup = function() { self.super_.setup.call(this); let disableMethods = { create: true, replaceOrCreate: true, patchOrCreate: true, upsert: true, updateOrCreate: true, exists: true, find: true, findOne: true, findById: true, deleteById: true, replaceById: true, updateAttributes: false, createChangeStream: true, updateAll: true, upsertWithWhere: true, count: true }; for (let method in disableMethods) { // this.disableRemoteMethod(method, disableMethods[method]); } }; self.defineScope = function(serverFilter) { this.remoteMethodCtx('list', { accepts: [ { arg: 'filter', type: 'object', description: 'Filter defining where' } ], returns: { type: [this.modelName], root: true }, http: { verb: 'get', path: '/list' } }); this.list = function(ctx, clientFilter, cb) { var clientFields = (clientFilter && clientFilter.fields) ? clientFilter.fields : []; var serverFields = (serverFilter && serverFilter.fields) ? serverFilter.fields : []; var fields = clientFields.filter(itemC => { return serverFields.some(itemS => itemS === itemC); }); var and = []; (clientFilter && clientFilter.where) && and.push(clientFilter.where); (serverFilter && serverFilter.where) && and.push(serverFilter.where); var order; var limit; if (clientFilter && clientFilter.order) order = clientFilter.order; else if (serverFilter && serverFilter.order) order = serverFilter.order; if (serverFilter && serverFilter.limit) limit = serverFilter.limit; else if (clientFilter && clientFilter.limit) limit = clientFilter.limit; var filter = {order: order, limit: limit}; filter.where = (and.length > 0) && {and: and}; filter.fields = fields; this.find(filter, function(err, states) { (err) ? cb(err, null) : cb(null, states); }); }; }; self.rawSql = function(query, params, cb) { var connector = this.dataSource.connector; return new Promise(function(resolve, reject) { connector.execute(query, params, function(error, response) { if (error && !reject) cb(error, null); else if (error && reject) reject(error); else resolve(response); }); }); }; self.remoteMethodCtx = function(methodName, args) { var ctx = { arg: 'context', type: 'object', http: function(ctx) { return ctx; } }; if (args.accepts === undefined) args.accepts = []; else if (!Array.isArray(args.accepts)) args.accepts = [args.accepts]; args.accepts.unshift(ctx); this.remoteMethod(methodName, args); }; self.connectToService = function(ctx, dataSource) { this.app.dataSources[dataSource].connector.remotes.auth = { bearer: new Buffer(ctx.req.accessToken.id).toString('base64'), sendImmediately: true }; }; self.disconnectFromService = function(dataSource) { this.app.dataSources[dataSource].connector.remotes.auth = { bearer: new Buffer("").toString('base64'), sendImmediately: true }; }; self.installMethod = function(methodName, filterCb) { 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) 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(); } }); }; }; self.validateBinded = function(propertyName, validatorFn, options) { var customValidator = function(err) { if (!validatorFn(this[propertyName])) err(); }; options.isExportable = true; options.bindedFunction = validatorFn; this.validate(propertyName, customValidator, options); }; }; function removeEmpty(o) { if (Array.isArray(o)) { let array = []; for (let item of o) { let i = removeEmpty(item); if (!isEmpty(item)) array.push(item); } 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 === ""; }