var Promise = require('any-promise') var assert = require('assert') module.exports = thenify /** * Turn async functions into promises * * @param {Function} $$__fn__$$ * @return {Function} * @api public */ function thenify($$__fn__$$, options) { assert(typeof $$__fn__$$ === 'function') return eval(createWrapper($$__fn__$$.name, options)) } /** * Turn async functions into promises and backward compatible with callback * * @param {Function} $$__fn__$$ * @return {Function} * @api public */ thenify.withCallback = function ($$__fn__$$, options) { assert(typeof $$__fn__$$ === 'function') options = options || {} options.withCallback = true if (options.multiArgs === undefined) options.multiArgs = true return eval(createWrapper($$__fn__$$.name, options)) } function createCallback(resolve, reject, multiArgs) { return function(err, value) { if (err) return reject(err) var length = arguments.length if (length <= 2 || !multiArgs) return resolve(value) if (Array.isArray(multiArgs)) { var values = {} for (var i = 1; i < length; i++) values[multiArgs[i - 1]] = arguments[i] return resolve(values) } var values = new Array(length - 1) for (var i = 1; i < length; ++i) values[i - 1] = arguments[i] resolve(values) } } function createWrapper(name, options) { name = (name || '').replace(/\s|bound(?!$)/g, '') options = options || {} // default to true var multiArgs = options.multiArgs !== undefined ? options.multiArgs : true multiArgs = 'var multiArgs = ' + JSON.stringify(multiArgs) + '\n' var withCallback = options.withCallback ? 'var lastType = typeof arguments[len - 1]\n' + 'if (lastType === "function") return $$__fn__$$.apply(self, arguments)\n' : '' return '(function ' + name + '() {\n' + 'var self = this\n' + 'var len = arguments.length\n' + multiArgs + withCallback + 'var args = new Array(len + 1)\n' + 'for (var i = 0; i < len; ++i) args[i] = arguments[i]\n' + 'var lastIndex = i\n' + 'return new Promise(function (resolve, reject) {\n' + 'args[lastIndex] = createCallback(resolve, reject, multiArgs)\n' + '$$__fn__$$.apply(self, args)\n' + '})\n' + '})' }