diff --git a/src/plugins/hooks.js b/src/plugins/hooks.js index 95b5aec47a..d3dec5965d 100644 --- a/src/plugins/hooks.js +++ b/src/plugins/hooks.js @@ -1,6 +1,5 @@ 'use strict'; -const async = require('async'); const util = require('util'); const winston = require('winston'); const plugins = require('.'); @@ -116,37 +115,40 @@ async function fireFilterHook(hook, hookList, params) { if (!Array.isArray(hookList) || !hookList.length) { return params; } - return await async.reduce(hookList, params, (params, hookObj, next) => { + + async function fireMethod(hookObj, params) { if (typeof hookObj.method !== 'function') { if (global.env === 'development') { winston.warn(`[plugins] Expected method for hook '${hook}' in plugin '${hookObj.id}' not found, skipping.`); } - return next(null, params); + return params; } - const returned = hookObj.method(params, next); - if (utils.isPromise(returned)) { - returned.then( - payload => setImmediate(next, null, payload), - err => setImmediate(next, err) - ); + + if (hookObj.method.constructor && hookObj.method.constructor.name === 'AsyncFunction') { + return await hookObj.method(params); } - }); - // breaks plugins that use a non-async function ie emoji-one parse.raw - // for (const hookObj of hookList) { - // if (typeof hookObj.method !== 'function') { - // if (global.env === 'development') { - // winston.warn(`[plugins] Expected method for hook '${hook}' in plugin '${hookObj.id}' not found, skipping.`); - // } - // } else { - // let hookFn = hookObj.method; - // if (hookFn.constructor && hookFn.constructor.name !== 'AsyncFunction') { - // hookFn = util.promisify(hookFn); - // } - // // eslint-disable-next-line - // params = await hookFn(params); - // } - // } - // return params; + return new Promise((resolve, reject) => { + const returned = hookObj.method(params, (err, result) => { + if (err) reject(err); else resolve(result); + }); + + if (utils.isPromise(returned)) { + returned.then( + payload => resolve(payload), + err => reject(err) + ); + return; + } + if (returned) { + resolve(returned); + } + }); + } + for (const hookObj of hookList) { + // eslint-disable-next-line + params = await fireMethod(hookObj, params); + } + return params; } async function fireActionHook(hook, hookList, params) { diff --git a/test/plugins.js b/test/plugins.js index bf4a600ff8..b7b5575d28 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -47,7 +47,7 @@ describe('Plugins', () => { }); }); - it('should register and fire a filter hook having 2 methods, one returning a promise and the other calling the callback', (done) => { + it('should register and fire a filter hook having 3 methods, one returning a promise, one calling the callback and one just returning', async () => { function method1(data, callback) { data.foo += 1; callback(null, data); @@ -58,15 +58,17 @@ describe('Plugins', () => { resolve(data); }); } + function method3(data) { + data.foo += 1; + return data; + } plugins.hooks.register('test-plugin', { hook: 'filter:test.hook2', method: method1 }); plugins.hooks.register('test-plugin', { hook: 'filter:test.hook2', method: method2 }); + plugins.hooks.register('test-plugin', { hook: 'filter:test.hook2', method: method3 }); - plugins.hooks.fire('filter:test.hook2', { foo: 1 }, (err, data) => { - assert.ifError(err); - assert.equal(data.foo, 7); - done(); - }); + const data = await plugins.hooks.fire('filter:test.hook2', { foo: 1 }); + assert.strictEqual(data.foo, 8); }); it('should register and fire a filter hook that returns a promise that gets rejected', (done) => {