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;
 |