You've already forked Epicnabbo-Catalogus-Updated-Daily
98 lines
2.5 KiB
JavaScript
98 lines
2.5 KiB
JavaScript
'use strict';
|
|
|
|
const promisify = require('./promisify');
|
|
const skipMap = {
|
|
constructor: true,
|
|
arity: true,
|
|
length: true,
|
|
name: true,
|
|
arguments: true,
|
|
caller: true,
|
|
callee: true,
|
|
prototype: true,
|
|
__isPromisified__: true
|
|
};
|
|
|
|
module.exports = promisifyAll;
|
|
|
|
/**
|
|
* @param {Object} target
|
|
* @param {Object} [opts]
|
|
* @param {String} [opts.suffix=Async]
|
|
* @param {Function} [opts.filter]
|
|
* @param {Integer} [opts.depth=2]
|
|
* @example
|
|
* const redis = require('redis');
|
|
* Aigle.promisifyAll(redis);
|
|
* const client = redis.createClient();
|
|
*
|
|
* const key = 'test';
|
|
* redis.hsetAsync(key, 1)
|
|
* .then(() => redis.hgetAsync(key))
|
|
* .then(value => console.log(value)); // 1
|
|
*/
|
|
function promisifyAll(target, opts) {
|
|
const { suffix = 'Async', filter = defaultFilter, depth = 2 } = opts || {};
|
|
_promisifyAll(suffix, filter, target, undefined, undefined, depth);
|
|
return target;
|
|
}
|
|
|
|
function defaultFilter(name) {
|
|
return /^(?!_).*/.test(name);
|
|
}
|
|
|
|
function _promisifyAll(suffix, filter, obj, key, target, depth) {
|
|
const memo = {};
|
|
switch (typeof obj) {
|
|
case 'function':
|
|
if (target) {
|
|
if (obj.__isPromisified__) {
|
|
return;
|
|
}
|
|
const _key = `${key}${suffix}`;
|
|
if (target[_key]) {
|
|
if (!target[_key].__isPromisified__) {
|
|
throw new TypeError(
|
|
`Cannot promisify an API that has normal methods with '${suffix}'-suffix`
|
|
);
|
|
}
|
|
} else {
|
|
target[_key] = promisify(obj);
|
|
}
|
|
}
|
|
iterate(suffix, filter, obj, obj, depth, memo);
|
|
iterate(suffix, filter, obj.prototype, obj.prototype, depth, memo);
|
|
break;
|
|
case 'object':
|
|
if (!obj) {
|
|
break;
|
|
}
|
|
iterate(suffix, filter, obj, obj, depth, memo);
|
|
iterate(suffix, filter, Object.getPrototypeOf(obj), obj, depth, memo);
|
|
}
|
|
}
|
|
|
|
const fp = Function.prototype;
|
|
const op = Object.prototype;
|
|
const ap = Array.prototype;
|
|
|
|
function iterate(suffix, filter, obj, target, depth, memo) {
|
|
if (depth-- === 0 || !obj || fp === obj || op === obj || ap === obj || Object.isFrozen(obj)) {
|
|
return;
|
|
}
|
|
const keys = Object.getOwnPropertyNames(obj);
|
|
let l = keys.length;
|
|
while (l--) {
|
|
const key = keys[l];
|
|
if (skipMap[key] === true || memo[key] === true || !filter(key)) {
|
|
continue;
|
|
}
|
|
const desc = Object.getOwnPropertyDescriptor(obj, key);
|
|
if (!desc || desc.set || desc.get) {
|
|
continue;
|
|
}
|
|
memo[key] = true;
|
|
_promisifyAll(suffix, filter, obj[key], key, target, depth);
|
|
}
|
|
}
|