| 'use strict'; | 
|   | 
| const processFn = (fn, options) => function (...args) { | 
|     const P = options.promiseModule; | 
|   | 
|     return new P((resolve, reject) => { | 
|         if (options.multiArgs) { | 
|             args.push((...result) => { | 
|                 if (options.errorFirst) { | 
|                     if (result[0]) { | 
|                         reject(result); | 
|                     } else { | 
|                         result.shift(); | 
|                         resolve(result); | 
|                     } | 
|                 } else { | 
|                     resolve(result); | 
|                 } | 
|             }); | 
|         } else if (options.errorFirst) { | 
|             args.push((error, result) => { | 
|                 if (error) { | 
|                     reject(error); | 
|                 } else { | 
|                     resolve(result); | 
|                 } | 
|             }); | 
|         } else { | 
|             args.push(resolve); | 
|         } | 
|   | 
|         fn.apply(this, args); | 
|     }); | 
| }; | 
|   | 
| module.exports = (input, options) => { | 
|     options = Object.assign({ | 
|         exclude: [/.+(Sync|Stream)$/], | 
|         errorFirst: true, | 
|         promiseModule: Promise | 
|     }, options); | 
|   | 
|     const objType = typeof input; | 
|     if (!(input !== null && (objType === 'object' || objType === 'function'))) { | 
|         throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? 'null' : objType}\``); | 
|     } | 
|   | 
|     const filter = key => { | 
|         const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); | 
|         return options.include ? options.include.some(match) : !options.exclude.some(match); | 
|     }; | 
|   | 
|     let ret; | 
|     if (objType === 'function') { | 
|         ret = function (...args) { | 
|             return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); | 
|         }; | 
|     } else { | 
|         ret = Object.create(Object.getPrototypeOf(input)); | 
|     } | 
|   | 
|     for (const key in input) { // eslint-disable-line guard-for-in | 
|         const property = input[key]; | 
|         ret[key] = typeof property === 'function' && filter(key) ? processFn(property, options) : property; | 
|     } | 
|   | 
|     return ret; | 
| }; |