-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
89 lines (78 loc) · 2.28 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
const util = require('util');
module.exports = new Proxy({}, {
get: (cache, module) => {
if (!(module in cache)) {
let original = require(module);
let promisified = Object.assign(Object.create(null), original);
try {
let methods = require(`./lib/${module}`);
handleModule(original, promisified, methods);
} catch (e) {
return original;
}
cache[module] = promisified;
}
return cache[module];
}
});
function handleModule(original, promisified, methods) {
// All the standardly promisifyable module methods
methods.default && methods.default.forEach(name => {
let orig = original[name];
promisified[name] = promiseNoCallback(orig, defaultExecutor);
});
// Methods that report errors (only?) in events
methods.event && methods.event.forEach(name => {
let orig = original[name];
promisified[name] = promiseNoCallback(orig, eventErrorExecutor);
});
// Methods that always resolve
methods.resolve && methods.resolve.forEach(name => {
let orig = original[name];
promisified[name] = promiseNoCallback(orig, alwaysResolveExecutor);
});
// Methods that have different argument order or values
// These require a custom executorFactory (see fs.exists)
for (name in methods.custom) {
let orig = original[name];
promisified[name] = promiseNoCallback(orig, methods.custom[name]);
}
// Classes, may have several levels, therefore recursive
for (c in methods.classes) {
handleModule(original[c].prototype,
promisified[c].prototype,
methods.classes[c]);
}
}
function promiseNoCallback(func, executorFactory) {
return function() {
if (typeof arguments[arguments.length - 1] == 'function') {
return func.apply(this, arguments);
}
return new Promise(executorFactory.call(this, func, ...arguments));
};
}
function defaultExecutor(func, ...args) {
return (resolve, reject) => {
args.push((err, ...args2) => {
if (err) reject(err);
else resolve(...args2);
});
func.apply(this, args);
};
}
function eventErrorExecutor(func, ...args) {
return (resolve, reject) => {
args.push((err, ...args2) => {
if (err) reject(err);
else resolve(...args2);
});
func.apply(this, args).on('error', reject);
};
}
function alwaysResolveExecutor(func, ...args) {
return resolve => {
args.push(resolve);
func.apply(this, args);
};
}