87 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			87 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | var isES5 = typeof Object.defineProperty === 'function' | ||
|  | 	&& typeof Object.defineProperties === 'function' | ||
|  | 	&& typeof Object.getPrototypeOf === 'function' | ||
|  | 	&& typeof Object.setPrototypeOf === 'function'; | ||
|  | 
 | ||
|  | if (!isES5) { | ||
|  | 	throw new TypeError('util.promisify requires a true ES5 environment'); | ||
|  | } | ||
|  | 
 | ||
|  | var getOwnPropertyDescriptors = require('object.getownpropertydescriptors'); | ||
|  | 
 | ||
|  | if (typeof Promise !== 'function') { | ||
|  | 	throw new TypeError('`Promise` must be globally available for util.promisify to work.'); | ||
|  | } | ||
|  | 
 | ||
|  | var slice = Function.call.bind(Array.prototype.slice); | ||
|  | var concat = Function.call.bind(Array.prototype.concat); | ||
|  | var forEach = Function.call.bind(Array.prototype.forEach); | ||
|  | 
 | ||
|  | var hasSymbols = typeof Symbol === 'function' && typeof Symbol('') === 'symbol'; | ||
|  | 
 | ||
|  | var kCustomPromisifiedSymbol = hasSymbols ? Symbol('util.promisify.custom') : null; | ||
|  | var kCustomPromisifyArgsSymbol = hasSymbols ? Symbol('customPromisifyArgs') : null; | ||
|  | 
 | ||
|  | module.exports = function promisify(orig) { | ||
|  | 	if (typeof orig !== 'function') { | ||
|  | 		var error = new TypeError('The "original" argument must be of type function'); | ||
|  | 		error.name = 'TypeError [ERR_INVALID_ARG_TYPE]'; | ||
|  | 		error.code = 'ERR_INVALID_ARG_TYPE'; | ||
|  | 		throw error; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (hasSymbols && orig[kCustomPromisifiedSymbol]) { | ||
|  | 		var customFunction = orig[kCustomPromisifiedSymbol]; | ||
|  | 		if (typeof customFunction !== 'function') { | ||
|  | 			throw new TypeError('The [util.promisify.custom] property must be a function'); | ||
|  | 		} | ||
|  | 		Object.defineProperty(customFunction, kCustomPromisifiedSymbol, { | ||
|  | 			configurable: true, | ||
|  | 			enumerable: false, | ||
|  | 			value: customFunction, | ||
|  | 			writable: false | ||
|  | 		}); | ||
|  | 		return customFunction; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Names to create an object from in case the callback receives multiple
 | ||
|  | 	// arguments, e.g. ['stdout', 'stderr'] for child_process.exec.
 | ||
|  | 	var argumentNames = orig[kCustomPromisifyArgsSymbol]; | ||
|  | 
 | ||
|  | 	var promisified = function fn() { | ||
|  | 		var args = slice(arguments); | ||
|  | 		var self = this; // eslint-disable-line no-invalid-this
 | ||
|  | 		return new Promise(function (resolve, reject) { | ||
|  | 			orig.apply(self, concat(args, function (err) { | ||
|  | 				var values = arguments.length > 1 ? slice(arguments, 1) : []; | ||
|  | 				if (err) { | ||
|  | 					reject(err); | ||
|  | 				} else if (typeof argumentNames !== 'undefined' && values.length > 1) { | ||
|  | 					var obj = {}; | ||
|  | 					forEach(argumentNames, function (name, index) { | ||
|  | 						obj[name] = values[index]; | ||
|  | 					}); | ||
|  | 					resolve(obj); | ||
|  | 				} else { | ||
|  | 					resolve(values[0]); | ||
|  | 				} | ||
|  | 			})); | ||
|  | 		}); | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	Object.setPrototypeOf(promisified, Object.getPrototypeOf(orig)); | ||
|  | 
 | ||
|  | 	Object.defineProperty(promisified, kCustomPromisifiedSymbol, { | ||
|  | 		configurable: true, | ||
|  | 		enumerable: false, | ||
|  | 		value: promisified, | ||
|  | 		writable: false | ||
|  | 	}); | ||
|  | 	return Object.defineProperties(promisified, getOwnPropertyDescriptors(orig)); | ||
|  | }; | ||
|  | 
 | ||
|  | module.exports.custom = kCustomPromisifiedSymbol; | ||
|  | module.exports.customPromisifyArgs = kCustomPromisifyArgsSymbol; |