UNPKG

promise-useful-utils

Version:
385 lines (325 loc) 9.74 kB
'use strict'; var _toConsumableArray = require('babel-runtime/helpers/to-consumable-array')['default']; var _Symbol = require('babel-runtime/core-js/symbol')['default']; var _getIterator = require('babel-runtime/core-js/get-iterator')['default']; var _Object$getOwnPropertyNames = require('babel-runtime/core-js/object/get-own-property-names')['default']; var _Object$getOwnPropertyDescriptor = require('babel-runtime/core-js/object/get-own-property-descriptor')['default']; var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; var _Promise = require('babel-runtime/core-js/promise')['default']; Object.defineProperty(exports, '__esModule', { value: true }); exports.promisify = promisify; exports.promisifyAll = promisifyAll; exports.fromNode = fromNode; exports.asCallback = asCallback; var THIS = _Symbol(); var rident = /^[a-z$_][a-z$_0-9]*$/i; var excludedPrototypes = [Array.prototype, Object.prototype, Function.prototype]; var defaultSuffix = 'Async'; var defaultFilter = function defaultFilter(name) { return isIdentifier(name) && name.charAt(0) !== '_' && name !== 'constructor'; }; /** * @param {string} str * @return {boolean} */ function isIdentifier(str) { return rident.test(str); } /** * @param {*} obj * @return {boolean} */ function isExcludedProto(obj) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = _getIterator(excludedPrototypes), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var excludedProto = _step.value; if (obj === excludedProto) { return true; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return false; } /** * @param {Object} obj * @return {string[]} */ function inheritedDataKeys(obj) { var keys = {}; while (obj !== null && !isExcludedProto(obj)) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = _getIterator(_Object$getOwnPropertyNames(obj)), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var key = _step2.value; if (keys[key] === undefined) { var desc = _Object$getOwnPropertyDescriptor(obj, key); if (desc !== null && desc.get === undefined && desc.set === undefined) { keys[key] = true; } } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2['return']) { _iterator2['return'](); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } obj = Object.getPrototypeOf(obj); } return _Object$keys(keys); } /** * @param {*} obj * @return {boolean} */ function isPromisified(obj) { try { return obj.__isPromisified__ === true; } catch (err) { return false; } } /** * @param {Object} object * @param {string} key * @param {string} suffix * @return {boolean} */ function hasPromisified(object, key, suffix) { var desc = _Object$getOwnPropertyNames(object, key + suffix); if (desc === null) { return false; } if (desc.get === undefined && desc.set === undefined) { return isPromisified(desc.value); } return true; } /** * @param {*} * @return {boolean} */ function isClass(fn) { try { if (typeof fn !== 'function') { return false; } var names = _Object$getOwnPropertyNames(fn.prototype); return names.length > 1 || names.length > 0 && !(names.length === 1 && names[0] === 'constructor') || /this\s*\.\s*\S+\s*=/.test(fn + '') && _Object$getOwnPropertyNames(fn).length > 0; } catch (err) { return false; } } /** * @param {(function|string)} method * @param {Object} [receiver] * @return {function} */ function makeNodePromisifier(method, receiver) { function promisified() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var _receiver = receiver === THIS ? this : receiver; var _method = typeof method === 'string' ? _receiver[method] : method; return fromNode(function (cb) { _method.apply(_receiver, args.concat(cb)); }); } Object.defineProperty(promisified, '__isPromisified__', { value: true, configurable: true, enumerable: false, writable: true }); return promisified; } /** * @param {Object} target * @param {string} suffix * @param {function} filter * @param {function} promisifier * @return {Object} */ function plainPromisifyAll(target, suffix, filter, promisifier) { var suffixRegexp = new RegExp(suffix.replace(/([$])/, '\\$') + '$'); var methods = {}; var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = _getIterator(inheritedDataKeys(target)), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var key = _step3.value; var value = target[key]; if (key === 'constructor' || typeof value !== 'function' || isPromisified(value) || hasPromisified(target, key, suffix) || !filter(key, value, target, defaultFilter(key, value, target))) { continue; } if (isClass(value) && value !== target) { plainPromisifyAll(value, suffix, filter, promisifier); plainPromisifyAll(value.prototype, suffix, filter, promisifier); continue; } if (suffixRegexp.test(key)) { var keyWithoutSuffix = key.replace(suffixRegexp, ''); if (methods[keyWithoutSuffix] !== undefined) { throw new TypeError('Cannot promisify an API that has normal methods with ' + suffix + '-suffix'); } } methods[key] = value; } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3['return']) { _iterator3['return'](); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = _getIterator(_Object$keys(methods)), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var key = _step4.value; if (promisifier === makeNodePromisifier) { target[key + suffix] = makeNodePromisifier(methods[key], THIS); } else { target[key + suffix] = promisifier(methods[key], function (fn) { return makeNodePromisifier(fn, THIS); }); } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4['return']) { _iterator4['return'](); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } return target; } /** * @param {function} nodeFunction * @param {*} [receiver] * @return {Promise} */ function promisify(nodeFunction) { var receiver = arguments.length <= 1 || arguments[1] === undefined ? THIS : arguments[1]; if (isPromisified(nodeFunction)) { return nodeFunction; } return makeNodePromisifier(nodeFunction, receiver); } /** * @param {Object} target * @param {Object} [opts] * @param {string} [opts.suffix='Async'] * @param {function} [opts.filter] * @param {function} [opts.promisifier] */ function promisifyAll(target, opts) { opts = Object(opts); var suffix = opts.suffix; if (typeof suffix !== 'string') { suffix = defaultSuffix; } var filter = opts.filter; if (typeof filter !== 'function') { filter = defaultFilter; } var promisifier = opts.promisifier; if (typeof promisifier !== 'function') { promisifier = makeNodePromisifier; } if (!isIdentifier(suffix)) { throw new RangeError('suffix must be a valid identifier'); } if (isClass(target)) { plainPromisifyAll(target.prototype, suffix, filter, promisifier); } return plainPromisifyAll(target, suffix, filter, promisifier); } /** * @param {function} resolver * @return {Promise} */ function fromNode(resolver) { return new _Promise(function (resolve, reject) { resolver(function (err) { for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } if (err) { reject(err); return; } if (args.length === 1) { args = args[0]; } resolve(args); }); }); } /** * @param {Promise} promise * @param {function} nodeback * @param {Object} [opts] * @param {boolean} [opts.spread=false] * @return {Promise} */ function asCallback(promise, nodeback, options) { if (typeof nodeback === 'function') { promise.then(function (value) { if (Object(options).spread) { var args = [null].concat(value); nodeback.apply(undefined, _toConsumableArray(args)); return; } nodeback(null, value); }, function (err) { nodeback(err); }); } return promise; }