-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathindex.js
102 lines (93 loc) · 3.46 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
90
91
92
93
94
95
96
97
98
99
100
101
102
'use strict';
let Promise = require('bluebird');
/**
* Wraps static and instance methods whose name ends with Async, or are
* GeneratorFunctions. Any GeneratorFunction is wrapped with
* bluebird.coroutine(), and others with bluebird.method(). Accepts an optional
* array of method names, wrapping only those found in the array, and disabling
* the Async suffix check. Returns the class.
*
* @param {function} klass The class to wrap
* @param {string[]} [methodNames] Optional array of method names
* @returns {function} The supplied class
* @throws {Error} If methodNames is provided, but is not an array
*/
function wrap(klass, methodNames) {
validateMethodNames(methodNames);
wrapStaticMethods(klass, methodNames);
wrapInstanceMethods(klass, methodNames);
return klass;
}
/**
* Wraps static methods whose name ends with Async or are GeneratorFunctions.
* Any GeneratorFunction is wrapped with bluebird.coroutine(), and others with
* bluebird.method(). Accepts an optional array of method names, wrapping only
* those found in the array, and disabling the Async suffix check. Returns the
* class.
*
* @param {function} klass The class to wrap
* @param {string[]} [methodNames] Optional array of method names
* @returns {function} The supplied class
* @throws {Error} If methodNames is provided, but is not an array
*/
function wrapStaticMethods(klass, methodNames) {
validateMethodNames(methodNames);
wrapFunctions(klass, methodNames);
return klass;
}
/**
* Wraps instance methods whose name ends with Async, or are GeneratorFunctions.
* Any GeneratorFunction is wrapped with bluebird.coroutine(), and others with
* bluebird.method(). Accepts an optional array of method names, wrapping only
* those found in the array, and disabling the Async suffix check. Returns the
* class.
*
* @param {function} klass The class to wrap
* @param {string[]} [methodNames] Optional array of method names
* @returns {function} The supplied class
* @throws {Error} If methodNames is provided, but is not an array
*/
function wrapInstanceMethods(klass, methodNames) {
validateMethodNames(methodNames);
wrapFunctions(klass.prototype, methodNames);
return klass;
}
/**
* Helper function that validates the methodNames parameter.
*
* @param {string[]} [methodNames] Optional array of method names
* @throws {Error} If methodNames is provided, but is not an array
*/
function validateMethodNames(methodNames) {
if (methodNames && !(methodNames instanceof Array)) {
throw new Error('Optional methodNames should be an array if provided');
}
}
function wrapFunctions(target, methodNames) {
_actualMethodKeys(target).forEach(function(key) {
let constructor = target[key].constructor.name;
if (methodNames) {
if (methodNames.indexOf(key) === -1) return;
} else if (!key.endsWith('Async') && constructor !== 'GeneratorFunction') {
return;
}
if (target[key].constructor.name === 'GeneratorFunction') {
target[key] = Promise.coroutine(target[key]);
} else {
target[key] = Promise.method(target[key]);
}
});
}
function _actualMethodKeys(target) {
return Object.getOwnPropertyNames(target)
.filter(key => {
var propertyDescriptor = Object.getOwnPropertyDescriptor(target, key);
return !propertyDescriptor.get && !propertyDescriptor.set;
})
.filter(key => typeof target[key] === 'function');
}
module.exports = {
wrap,
wrapStaticMethods,
wrapInstanceMethods
};