You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.8 KiB

2 years ago
'use strict';
var isES5 = typeof Object.defineProperty === 'function'
&& typeof Object.defineProperties === 'function';
var hasProto = [].__proto__ === Array.prototype; // eslint-disable-line no-proto
if (!isES5 || !hasProto) {
throw new TypeError('util.promisify requires a true ES5 environment, that also supports `__proto__`');
}
var getOwnPropertyDescriptors = require('object.getownpropertydescriptors');
if (typeof Promise !== 'function') {
throw new TypeError('`Promise` must be globally available for util.promisify to work.');
}
var callBound = require('es-abstract/helpers/callBound');
var $slice = callBound('Array.prototype.slice');
var $concat = callBound('Array.prototype.concat');
var $forEach = callBound('Array.prototype.forEach');
var hasSymbols = require('has-symbols')();
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]);
}
}));
});
};
promisified.__proto__ = orig.__proto__; // eslint-disable-line no-proto
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;