index.js
5.46 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"use strict";
/* eslint-disable prefer-rest-params */
Object.defineProperty(exports, "__esModule", { value: true });
exports.callbackifyAll = exports.callbackify = exports.promisifyAll = exports.promisify = void 0;
/**
* Wraps a callback style function to conditionally return a promise.
*
* @param {function} originalMethod - The method to promisify.
* @param {object=} options - Promise options.
* @param {boolean} options.singular - Resolve the promise with single arg instead of an array.
* @return {function} wrapped
*/
function promisify(originalMethod, options) {
if (originalMethod.promisified_) {
return originalMethod;
}
options = options || {};
const slice = Array.prototype.slice;
// tslint:disable-next-line:no-any
const wrapper = function () {
let last;
for (last = arguments.length - 1; last >= 0; last--) {
const arg = arguments[last];
if (typeof arg === 'undefined') {
continue; // skip trailing undefined.
}
if (typeof arg !== 'function') {
break; // non-callback last argument found.
}
return originalMethod.apply(this, arguments);
}
// peel trailing undefined.
const args = slice.call(arguments, 0, last + 1);
// tslint:disable-next-line:variable-name
let PromiseCtor = Promise;
// Because dedupe will likely create a single install of
// @google-cloud/common to be shared amongst all modules, we need to
// localize it at the Service level.
if (this && this.Promise) {
PromiseCtor = this.Promise;
}
return new PromiseCtor((resolve, reject) => {
// tslint:disable-next-line:no-any
args.push((...args) => {
const callbackArgs = slice.call(args);
const err = callbackArgs.shift();
if (err) {
return reject(err);
}
if (options.singular && callbackArgs.length === 1) {
resolve(callbackArgs[0]);
}
else {
resolve(callbackArgs);
}
});
originalMethod.apply(this, args);
});
};
wrapper.promisified_ = true;
return wrapper;
}
exports.promisify = promisify;
/**
* Promisifies certain Class methods. This will not promisify private or
* streaming methods.
*
* @param {module:common/service} Class - Service class.
* @param {object=} options - Configuration object.
*/
// tslint:disable-next-line:variable-name
function promisifyAll(Class, options) {
const exclude = (options && options.exclude) || [];
const ownPropertyNames = Object.getOwnPropertyNames(Class.prototype);
const methods = ownPropertyNames.filter(methodName => {
// clang-format off
return (!exclude.includes(methodName) &&
typeof Class.prototype[methodName] === 'function' && // is it a function?
!/(^_|(Stream|_)|promise$)|^constructor$/.test(methodName) // is it promisable?
);
// clang-format on
});
methods.forEach(methodName => {
const originalMethod = Class.prototype[methodName];
if (!originalMethod.promisified_) {
Class.prototype[methodName] = exports.promisify(originalMethod, options);
}
});
}
exports.promisifyAll = promisifyAll;
/**
* Wraps a promisy type function to conditionally call a callback function.
*
* @param {function} originalMethod - The method to callbackify.
* @param {object=} options - Callback options.
* @param {boolean} options.singular - Pass to the callback a single arg instead of an array.
* @return {function} wrapped
*/
function callbackify(originalMethod) {
if (originalMethod.callbackified_) {
return originalMethod;
}
// tslint:disable-next-line:no-any
const wrapper = function () {
if (typeof arguments[arguments.length - 1] !== 'function') {
return originalMethod.apply(this, arguments);
}
const cb = Array.prototype.pop.call(arguments);
originalMethod.apply(this, arguments).then(
// tslint:disable-next-line:no-any
(res) => {
res = Array.isArray(res) ? res : [res];
cb(null, ...res);
}, (err) => cb(err));
};
wrapper.callbackified_ = true;
return wrapper;
}
exports.callbackify = callbackify;
/**
* Callbackifies certain Class methods. This will not callbackify private or
* streaming methods.
*
* @param {module:common/service} Class - Service class.
* @param {object=} options - Configuration object.
*/
function callbackifyAll(
// tslint:disable-next-line:variable-name
Class, options) {
const exclude = (options && options.exclude) || [];
const ownPropertyNames = Object.getOwnPropertyNames(Class.prototype);
const methods = ownPropertyNames.filter(methodName => {
// clang-format off
return (!exclude.includes(methodName) &&
typeof Class.prototype[methodName] === 'function' && // is it a function?
!/^_|(Stream|_)|^constructor$/.test(methodName) // is it callbackifyable?
);
// clang-format on
});
methods.forEach(methodName => {
const originalMethod = Class.prototype[methodName];
if (!originalMethod.callbackified_) {
Class.prototype[methodName] = exports.callbackify(originalMethod);
}
});
}
exports.callbackifyAll = callbackifyAll;
//# sourceMappingURL=index.js.map