kareem 2.6.3 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nyc_output/fa57d6c4-9e78-4624-9229-f77b87a07481.json +1 -0
- package/.nyc_output/processinfo/fa57d6c4-9e78-4624-9229-f77b87a07481.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/CHANGELOG.md +12 -0
- package/README.md +171 -210
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +116 -0
- package/coverage/lcov-report/index.js.html +1603 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +423 -0
- package/index.d.ts +2 -0
- package/index.js +182 -331
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -24,127 +24,74 @@ Kareem.overwriteResult = function overwriteResult() {
|
|
|
24
24
|
this.args = [...arguments];
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
Kareem.overwriteArguments = function overwriteArguments() {
|
|
28
|
+
if (!(this instanceof Kareem.overwriteArguments)) {
|
|
29
|
+
return new Kareem.overwriteArguments(...arguments);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this.args = [...arguments];
|
|
33
|
+
};
|
|
34
|
+
|
|
27
35
|
/**
|
|
28
36
|
* Execute all "pre" hooks for "name"
|
|
29
37
|
* @param {String} name The hook name to execute
|
|
30
38
|
* @param {*} context Overwrite the "this" for the hook
|
|
31
|
-
* @param {Array
|
|
32
|
-
* @param {
|
|
33
|
-
* @
|
|
39
|
+
* @param {Array} args arguments passed to the pre hooks
|
|
40
|
+
* @param {Object} [options] Optional options
|
|
41
|
+
* @param {Function} [options.filter] Filter function to select which hooks to run
|
|
42
|
+
* @returns {Array} The potentially modified arguments
|
|
34
43
|
*/
|
|
35
|
-
Kareem.prototype.execPre = function(name, context, args,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
Kareem.prototype.execPre = async function execPre(name, context, args, options) {
|
|
45
|
+
let pres = this._pres.get(name) || [];
|
|
46
|
+
if (options?.filter) {
|
|
47
|
+
pres = pres.filter(options.filter);
|
|
39
48
|
}
|
|
40
|
-
const pres = this._pres.get(name) || [];
|
|
41
49
|
const numPres = pres.length;
|
|
42
|
-
|
|
43
|
-
let
|
|
44
|
-
let asyncPresLeft = numAsyncPres;
|
|
45
|
-
let done = false;
|
|
46
|
-
const $args = args;
|
|
47
|
-
let shouldSkipWrappedFunction = null;
|
|
50
|
+
let $args = args;
|
|
51
|
+
let skipWrappedFunction = null;
|
|
48
52
|
|
|
49
53
|
if (!numPres) {
|
|
50
|
-
return
|
|
51
|
-
callback(null);
|
|
52
|
-
});
|
|
54
|
+
return $args;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (pre.isAsync) {
|
|
62
|
-
const args = [
|
|
63
|
-
decorateNextFn(_next),
|
|
64
|
-
decorateNextFn(function(error) {
|
|
65
|
-
if (error) {
|
|
66
|
-
if (done) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (error instanceof Kareem.skipWrappedFunction) {
|
|
70
|
-
shouldSkipWrappedFunction = error;
|
|
71
|
-
} else {
|
|
72
|
-
done = true;
|
|
73
|
-
return callback(error);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (--asyncPresLeft === 0 && currentPre >= numPres) {
|
|
77
|
-
return callback(shouldSkipWrappedFunction);
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
callMiddlewareFunction(pre.fn, context, args, args[0]);
|
|
83
|
-
} else if (pre.fn.length > 0) {
|
|
84
|
-
const args = [decorateNextFn(_next)];
|
|
85
|
-
const _args = arguments.length >= 2 ? arguments : [null].concat($args);
|
|
86
|
-
for (let i = 1; i < _args.length; ++i) {
|
|
87
|
-
if (i === _args.length - 1 && typeof _args[i] === 'function') {
|
|
88
|
-
continue; // skip callbacks to avoid accidentally calling the callback from a hook
|
|
89
|
-
}
|
|
90
|
-
args.push(_args[i]);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
callMiddlewareFunction(pre.fn, context, args, args[0]);
|
|
94
|
-
} else {
|
|
95
|
-
let maybePromiseLike = null;
|
|
96
|
-
try {
|
|
97
|
-
maybePromiseLike = pre.fn.call(context);
|
|
98
|
-
} catch (err) {
|
|
99
|
-
if (err != null) {
|
|
100
|
-
return callback(err);
|
|
101
|
-
}
|
|
57
|
+
for (const pre of pres) {
|
|
58
|
+
const args = [];
|
|
59
|
+
const _args = [null].concat($args);
|
|
60
|
+
for (let i = 1; i < _args.length; ++i) {
|
|
61
|
+
if (i === _args.length - 1 && typeof _args[i] === 'function') {
|
|
62
|
+
continue; // skip callbacks to avoid accidentally calling the callback from a hook
|
|
102
63
|
}
|
|
64
|
+
args.push(_args[i]);
|
|
65
|
+
}
|
|
103
66
|
|
|
67
|
+
try {
|
|
68
|
+
const maybePromiseLike = pre.fn.apply(context, args);
|
|
104
69
|
if (isPromiseLike(maybePromiseLike)) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (asyncPresLeft > 0) {
|
|
109
|
-
// Leave parallel hooks to run
|
|
110
|
-
return;
|
|
111
|
-
} else {
|
|
112
|
-
return nextTick(function() {
|
|
113
|
-
callback(shouldSkipWrappedFunction);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
70
|
+
const result = await maybePromiseLike;
|
|
71
|
+
if (result instanceof Kareem.overwriteArguments) {
|
|
72
|
+
$args = result.args;
|
|
116
73
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
next.apply(null, [null].concat(args));
|
|
123
|
-
|
|
124
|
-
function _next(error) {
|
|
125
|
-
if (error) {
|
|
126
|
-
if (done) {
|
|
127
|
-
return;
|
|
74
|
+
} else if (maybePromiseLike instanceof Kareem.overwriteArguments) {
|
|
75
|
+
$args = maybePromiseLike.args;
|
|
128
76
|
}
|
|
77
|
+
} catch (error) {
|
|
129
78
|
if (error instanceof Kareem.skipWrappedFunction) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
done = true;
|
|
133
|
-
return callback(error);
|
|
79
|
+
skipWrappedFunction = error;
|
|
80
|
+
continue;
|
|
134
81
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (asyncPresLeft > 0) {
|
|
139
|
-
// Leave parallel hooks to run
|
|
140
|
-
return;
|
|
141
|
-
} else {
|
|
142
|
-
return callback(shouldSkipWrappedFunction);
|
|
82
|
+
if (error instanceof Kareem.overwriteArguments) {
|
|
83
|
+
$args = error.args;
|
|
84
|
+
continue;
|
|
143
85
|
}
|
|
86
|
+
throw error;
|
|
144
87
|
}
|
|
88
|
+
}
|
|
145
89
|
|
|
146
|
-
|
|
90
|
+
if (skipWrappedFunction) {
|
|
91
|
+
throw skipWrappedFunction;
|
|
147
92
|
}
|
|
93
|
+
|
|
94
|
+
return $args;
|
|
148
95
|
};
|
|
149
96
|
|
|
150
97
|
/**
|
|
@@ -152,34 +99,39 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
152
99
|
* @param {String} name The hook name to execute
|
|
153
100
|
* @param {*} context Overwrite the "this" for the hook
|
|
154
101
|
* @param {Array} [args] Apply custom arguments to the hook
|
|
155
|
-
* @returns {
|
|
102
|
+
* @returns {Array} The potentially modified arguments
|
|
156
103
|
*/
|
|
157
104
|
Kareem.prototype.execPreSync = function(name, context, args) {
|
|
158
105
|
const pres = this._pres.get(name) || [];
|
|
159
106
|
const numPres = pres.length;
|
|
107
|
+
let $args = args || [];
|
|
160
108
|
|
|
161
109
|
for (let i = 0; i < numPres; ++i) {
|
|
162
|
-
pres[i].fn.apply(context, args
|
|
110
|
+
const result = pres[i].fn.apply(context, $args);
|
|
111
|
+
if (result instanceof Kareem.overwriteArguments) {
|
|
112
|
+
$args = result.args;
|
|
113
|
+
}
|
|
163
114
|
}
|
|
115
|
+
|
|
116
|
+
return $args;
|
|
164
117
|
};
|
|
165
118
|
|
|
166
119
|
/**
|
|
167
120
|
* Execute all "post" hooks for "name"
|
|
168
121
|
* @param {String} name The hook name to execute
|
|
169
122
|
* @param {*} context Overwrite the "this" for the hook
|
|
170
|
-
* @param {Array
|
|
171
|
-
* @param {
|
|
172
|
-
* @param {
|
|
123
|
+
* @param {Array} args Apply custom arguments to the hook
|
|
124
|
+
* @param {Object} [options] Optional options
|
|
125
|
+
* @param {Error} [options.error] Error to pass to error-handling middleware
|
|
126
|
+
* @param {Function} [options.filter] Filter function to select which hooks to run
|
|
173
127
|
* @returns {void}
|
|
174
128
|
*/
|
|
175
|
-
Kareem.prototype.execPost = function(name, context, args, options
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
129
|
+
Kareem.prototype.execPost = async function execPost(name, context, args, options) {
|
|
130
|
+
let posts = this._posts.get(name) || [];
|
|
131
|
+
if (options?.filter) {
|
|
132
|
+
posts = posts.filter(options.filter);
|
|
179
133
|
}
|
|
180
|
-
const posts = this._posts.get(name) || [];
|
|
181
134
|
const numPosts = posts.length;
|
|
182
|
-
let currentPost = 0;
|
|
183
135
|
|
|
184
136
|
let firstError = null;
|
|
185
137
|
if (options && options.error) {
|
|
@@ -187,120 +139,108 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
187
139
|
}
|
|
188
140
|
|
|
189
141
|
if (!numPosts) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
142
|
+
if (firstError != null) {
|
|
143
|
+
throw firstError;
|
|
144
|
+
}
|
|
145
|
+
return args;
|
|
193
146
|
}
|
|
194
147
|
|
|
195
|
-
|
|
196
|
-
const post =
|
|
148
|
+
for (const currentPost of posts) {
|
|
149
|
+
const post = currentPost.fn;
|
|
197
150
|
let numArgs = 0;
|
|
198
|
-
const argLength = args.length;
|
|
199
151
|
const newArgs = [];
|
|
152
|
+
const argLength = args.length;
|
|
200
153
|
for (let i = 0; i < argLength; ++i) {
|
|
201
|
-
numArgs += args[i] && args[i]._kareemIgnore ? 0 : 1;
|
|
202
154
|
if (!args[i] || !args[i]._kareemIgnore) {
|
|
155
|
+
numArgs += 1;
|
|
203
156
|
newArgs.push(args[i]);
|
|
204
157
|
}
|
|
205
158
|
}
|
|
159
|
+
// If numCallbackParams set, fill in the rest with null to enforce consistent number of args
|
|
160
|
+
if (options?.numCallbackParams != null) {
|
|
161
|
+
numArgs = options.numCallbackParams;
|
|
162
|
+
for (let i = newArgs.length; i < numArgs; ++i) {
|
|
163
|
+
newArgs.push(null);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
206
166
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return next();
|
|
217
|
-
}
|
|
218
|
-
firstError = error;
|
|
219
|
-
}
|
|
220
|
-
if (++currentPost >= numPosts) {
|
|
221
|
-
return callback.call(null, firstError);
|
|
222
|
-
}
|
|
223
|
-
next();
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
callMiddlewareFunction(post, context,
|
|
227
|
-
[firstError].concat(newArgs).concat([_cb]), _cb);
|
|
167
|
+
let resolve;
|
|
168
|
+
let reject;
|
|
169
|
+
const cbPromise = new Promise((_resolve, _reject) => {
|
|
170
|
+
resolve = _resolve;
|
|
171
|
+
reject = _reject;
|
|
172
|
+
});
|
|
173
|
+
newArgs.push(function nextCallback(err) {
|
|
174
|
+
if (err) {
|
|
175
|
+
reject(err);
|
|
228
176
|
} else {
|
|
229
|
-
|
|
230
|
-
return callback.call(null, firstError);
|
|
231
|
-
}
|
|
232
|
-
next();
|
|
177
|
+
resolve();
|
|
233
178
|
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
if (firstError) {
|
|
182
|
+
if (isErrorHandlingMiddleware(currentPost, numArgs)) {
|
|
183
|
+
try {
|
|
184
|
+
const res = post.apply(context, [firstError].concat(newArgs));
|
|
185
|
+
if (isPromiseLike(res)) {
|
|
186
|
+
await res;
|
|
187
|
+
} else if (post.length === numArgs + 2) {
|
|
188
|
+
// `numArgs + 2` because we added the error and the callback
|
|
189
|
+
await cbPromise;
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
237
192
|
if (error instanceof Kareem.overwriteResult) {
|
|
238
193
|
args = error.args;
|
|
239
|
-
|
|
240
|
-
return callback.apply(null, [null].concat(args));
|
|
241
|
-
}
|
|
242
|
-
return next();
|
|
194
|
+
continue;
|
|
243
195
|
}
|
|
244
196
|
firstError = error;
|
|
245
|
-
return next();
|
|
246
197
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return callback.apply(null, [null].concat(args));
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
next();
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
if (isErrorHandlingMiddleware(posts[currentPost], numArgs)) {
|
|
256
|
-
// Skip error handlers if no error
|
|
257
|
-
if (++currentPost >= numPosts) {
|
|
258
|
-
return callback.apply(null, [null].concat(args));
|
|
259
|
-
}
|
|
260
|
-
return next();
|
|
198
|
+
} else {
|
|
199
|
+
continue;
|
|
261
200
|
}
|
|
262
|
-
|
|
263
|
-
|
|
201
|
+
} else {
|
|
202
|
+
if (isErrorHandlingMiddleware(currentPost, numArgs)) {
|
|
203
|
+
// Skip error handlers if no error
|
|
204
|
+
continue;
|
|
264
205
|
} else {
|
|
265
|
-
let
|
|
266
|
-
let maybePromiseLike;
|
|
206
|
+
let res = null;
|
|
267
207
|
try {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (maybePromiseLike instanceof Kareem.overwriteResult) {
|
|
284
|
-
args = maybePromiseLike.args;
|
|
208
|
+
res = post.apply(context, newArgs);
|
|
209
|
+
if (isPromiseLike(res)) {
|
|
210
|
+
res = await res;
|
|
211
|
+
} else if (post.length === numArgs + 1) {
|
|
212
|
+
// If post function takes a callback, wait for the post function to call the callback
|
|
213
|
+
res = await cbPromise;
|
|
214
|
+
}
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (error instanceof Kareem.overwriteResult) {
|
|
217
|
+
args = error.args;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
firstError = error;
|
|
221
|
+
continue;
|
|
285
222
|
}
|
|
286
223
|
|
|
287
|
-
if (
|
|
288
|
-
|
|
224
|
+
if (res instanceof Kareem.overwriteResult) {
|
|
225
|
+
args = res.args;
|
|
226
|
+
continue;
|
|
289
227
|
}
|
|
290
|
-
|
|
291
|
-
next();
|
|
292
228
|
}
|
|
293
229
|
}
|
|
294
230
|
}
|
|
295
231
|
|
|
296
|
-
|
|
232
|
+
if (firstError != null) {
|
|
233
|
+
throw firstError;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return args;
|
|
297
237
|
};
|
|
298
238
|
|
|
299
239
|
/**
|
|
300
240
|
* Execute all "post" hooks for "name" synchronously
|
|
301
241
|
* @param {String} name The hook name to execute
|
|
302
242
|
* @param {*} context Overwrite the "this" for the hook
|
|
303
|
-
* @param {Array
|
|
243
|
+
* @param {Array} args Apply custom arguments to the hook
|
|
304
244
|
* @returns {Array} The used arguments
|
|
305
245
|
*/
|
|
306
246
|
Kareem.prototype.execPostSync = function(name, context, args) {
|
|
@@ -326,9 +266,9 @@ Kareem.prototype.execPostSync = function(name, context, args) {
|
|
|
326
266
|
Kareem.prototype.createWrapperSync = function(name, fn) {
|
|
327
267
|
const _this = this;
|
|
328
268
|
return function syncWrapper() {
|
|
329
|
-
_this.execPreSync(name, this, arguments);
|
|
269
|
+
const modifiedArgs = _this.execPreSync(name, this, Array.from(arguments));
|
|
330
270
|
|
|
331
|
-
const toReturn = fn.apply(this,
|
|
271
|
+
const toReturn = fn.apply(this, modifiedArgs);
|
|
332
272
|
|
|
333
273
|
const result = _this.execPostSync(name, this, [toReturn]);
|
|
334
274
|
|
|
@@ -336,98 +276,37 @@ Kareem.prototype.createWrapperSync = function(name, fn) {
|
|
|
336
276
|
};
|
|
337
277
|
};
|
|
338
278
|
|
|
339
|
-
function _handleWrapError(instance, error, name, context, args, options, callback) {
|
|
340
|
-
if (options.useErrorHandlers) {
|
|
341
|
-
return instance.execPost(name, context, args, { error: error }, function(error) {
|
|
342
|
-
return typeof callback === 'function' && callback(error);
|
|
343
|
-
});
|
|
344
|
-
} else {
|
|
345
|
-
return typeof callback === 'function' && callback(error);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
279
|
/**
|
|
350
280
|
* Executes pre hooks, followed by the wrapped function, followed by post hooks.
|
|
351
281
|
* @param {String} name The name of the hook
|
|
352
282
|
* @param {Function} fn The function for the hook
|
|
353
283
|
* @param {*} context Overwrite the "this" for the hook
|
|
354
284
|
* @param {Array} args Apply custom arguments to the hook
|
|
355
|
-
* @param {Object}
|
|
356
|
-
* @param {Boolean} [options.checkForPromise]
|
|
285
|
+
* @param {Object} options Additional options for the hook
|
|
357
286
|
* @returns {void}
|
|
358
287
|
*/
|
|
359
|
-
Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const checkForPromise = options.checkForPromise;
|
|
367
|
-
|
|
368
|
-
this.execPre(name, context, args, function(error) {
|
|
369
|
-
if (error && !(error instanceof Kareem.skipWrappedFunction)) {
|
|
370
|
-
const numCallbackParams = options.numCallbackParams || 0;
|
|
371
|
-
const errorArgs = options.contextParameter ? [context] : [];
|
|
372
|
-
for (let i = errorArgs.length; i < numCallbackParams; ++i) {
|
|
373
|
-
errorArgs.push(null);
|
|
374
|
-
}
|
|
375
|
-
return _handleWrapError(_this, error, name, context, errorArgs,
|
|
376
|
-
options, lastArg);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
const numParameters = fn.length;
|
|
380
|
-
let ret;
|
|
381
|
-
|
|
288
|
+
Kareem.prototype.wrap = async function wrap(name, fn, context, args, options) {
|
|
289
|
+
let ret;
|
|
290
|
+
let skipWrappedFunction = false;
|
|
291
|
+
let modifiedArgs = args;
|
|
292
|
+
try {
|
|
293
|
+
modifiedArgs = await this.execPre(name, context, args);
|
|
294
|
+
} catch (error) {
|
|
382
295
|
if (error instanceof Kareem.skipWrappedFunction) {
|
|
383
|
-
ret = error.args
|
|
384
|
-
|
|
296
|
+
ret = error.args;
|
|
297
|
+
skipWrappedFunction = true;
|
|
385
298
|
} else {
|
|
386
|
-
|
|
387
|
-
ret = fn.apply(context, argsWithoutCb.concat(_cb));
|
|
388
|
-
} catch (err) {
|
|
389
|
-
return _cb(err);
|
|
390
|
-
}
|
|
299
|
+
await this.execPost(name, context, args, { ...options, error });
|
|
391
300
|
}
|
|
301
|
+
}
|
|
392
302
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return ret.then(
|
|
397
|
-
res => _cb(null, res),
|
|
398
|
-
err => _cb(err)
|
|
399
|
-
);
|
|
400
|
-
}
|
|
303
|
+
if (!skipWrappedFunction) {
|
|
304
|
+
ret = await fn.apply(context, modifiedArgs);
|
|
305
|
+
}
|
|
401
306
|
|
|
402
|
-
|
|
403
|
-
// promise, assume it is sync
|
|
404
|
-
if (numParameters < argsWithoutCb.length + 1) {
|
|
405
|
-
return _cb(null, ret);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
307
|
+
ret = await this.execPost(name, context, [ret], options);
|
|
408
308
|
|
|
409
|
-
|
|
410
|
-
const argsWithoutError = Array.from(arguments);
|
|
411
|
-
argsWithoutError.shift();
|
|
412
|
-
if (options.nullResultByDefault && argsWithoutError.length === 0) {
|
|
413
|
-
argsWithoutError.push(null);
|
|
414
|
-
}
|
|
415
|
-
if (arguments[0]) {
|
|
416
|
-
// Assume error
|
|
417
|
-
return _handleWrapError(_this, arguments[0], name, context,
|
|
418
|
-
argsWithoutError, options, lastArg);
|
|
419
|
-
} else {
|
|
420
|
-
_this.execPost(name, context, argsWithoutError, function() {
|
|
421
|
-
if (lastArg === null) {
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
arguments[0]
|
|
425
|
-
? lastArg(arguments[0])
|
|
426
|
-
: lastArg.apply(context, arguments);
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
});
|
|
309
|
+
return ret[0];
|
|
431
310
|
};
|
|
432
311
|
|
|
433
312
|
/**
|
|
@@ -449,8 +328,6 @@ Kareem.prototype.filter = function(fn) {
|
|
|
449
328
|
continue;
|
|
450
329
|
}
|
|
451
330
|
|
|
452
|
-
hooks.numAsync = hooks.filter(h => h.isAsync).length;
|
|
453
|
-
|
|
454
331
|
clone._pres.set(name, hooks);
|
|
455
332
|
}
|
|
456
333
|
|
|
@@ -491,53 +368,43 @@ Kareem.prototype.hasHooks = function(name) {
|
|
|
491
368
|
Kareem.prototype.createWrapper = function(name, fn, context, options) {
|
|
492
369
|
const _this = this;
|
|
493
370
|
if (!this.hasHooks(name)) {
|
|
494
|
-
// Fast path: if there's no hooks for this function, just return the
|
|
495
|
-
|
|
496
|
-
return function() {
|
|
497
|
-
nextTick(() => fn.apply(this, arguments));
|
|
498
|
-
};
|
|
371
|
+
// Fast path: if there's no hooks for this function, just return the function
|
|
372
|
+
return fn;
|
|
499
373
|
}
|
|
500
|
-
return function() {
|
|
374
|
+
return function kareemWrappedFunction() {
|
|
501
375
|
const _context = context || this;
|
|
502
|
-
_this.wrap(name, fn, _context, Array.from(arguments), options);
|
|
376
|
+
return _this.wrap(name, fn, _context, Array.from(arguments), options);
|
|
503
377
|
};
|
|
504
378
|
};
|
|
505
379
|
|
|
506
380
|
/**
|
|
507
381
|
* Register a new hook for "pre"
|
|
508
382
|
* @param {String} name The name of the hook
|
|
509
|
-
* @param {
|
|
383
|
+
* @param {Object} [options]
|
|
510
384
|
* @param {Function} fn The function to register for "name"
|
|
511
385
|
* @param {never} error Unused
|
|
512
386
|
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
|
513
387
|
* @returns {Kareem}
|
|
514
388
|
*/
|
|
515
|
-
Kareem.prototype.pre = function(name,
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
options =
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
fn = isAsync;
|
|
522
|
-
isAsync = false;
|
|
389
|
+
Kareem.prototype.pre = function(name, options, fn, error, unshift) {
|
|
390
|
+
if (typeof options === 'function') {
|
|
391
|
+
fn = options;
|
|
392
|
+
options = {};
|
|
393
|
+
} else if (options == null) {
|
|
394
|
+
options = {};
|
|
523
395
|
}
|
|
524
396
|
|
|
525
397
|
const pres = this._pres.get(name) || [];
|
|
526
398
|
this._pres.set(name, pres);
|
|
527
399
|
|
|
528
|
-
if (isAsync) {
|
|
529
|
-
pres.numAsync = pres.numAsync || 0;
|
|
530
|
-
++pres.numAsync;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
400
|
if (typeof fn !== 'function') {
|
|
534
401
|
throw new Error('pre() requires a function, got "' + typeof fn + '"');
|
|
535
402
|
}
|
|
536
403
|
|
|
537
404
|
if (unshift) {
|
|
538
|
-
pres.unshift(Object.assign({}, options, { fn: fn
|
|
405
|
+
pres.unshift(Object.assign({}, options, { fn: fn }));
|
|
539
406
|
} else {
|
|
540
|
-
pres.push(Object.assign({}, options, { fn: fn
|
|
407
|
+
pres.push(Object.assign({}, options, { fn: fn }));
|
|
541
408
|
}
|
|
542
409
|
|
|
543
410
|
return this;
|
|
@@ -547,6 +414,7 @@ Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
|
547
414
|
* Register a new hook for "post"
|
|
548
415
|
* @param {String} name The name of the hook
|
|
549
416
|
* @param {Object} [options]
|
|
417
|
+
* @param {Boolean} [options.errorHandler] Whether this is an error handler
|
|
550
418
|
* @param {Function} fn The function to register for "name"
|
|
551
419
|
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
|
552
420
|
* @returns {Kareem}
|
|
@@ -573,6 +441,24 @@ Kareem.prototype.post = function(name, options, fn, unshift) {
|
|
|
573
441
|
return this;
|
|
574
442
|
};
|
|
575
443
|
|
|
444
|
+
/**
|
|
445
|
+
* Register a new error handler for "name"
|
|
446
|
+
* @param {String} name The name of the hook
|
|
447
|
+
* @param {Object} [options]
|
|
448
|
+
* @param {Function} fn The function to register for "name"
|
|
449
|
+
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
|
450
|
+
* @returns {Kareem}
|
|
451
|
+
*/
|
|
452
|
+
|
|
453
|
+
Kareem.prototype.postError = function postError(name, options, fn, unshift) {
|
|
454
|
+
if (typeof options === 'function') {
|
|
455
|
+
unshift = !!fn;
|
|
456
|
+
fn = options;
|
|
457
|
+
options = {};
|
|
458
|
+
}
|
|
459
|
+
return this.post(name, { ...options, errorHandler: true }, fn, unshift);
|
|
460
|
+
};
|
|
461
|
+
|
|
576
462
|
/**
|
|
577
463
|
* Clone the current instance
|
|
578
464
|
* @returns {Kareem} The cloned instance
|
|
@@ -582,7 +468,6 @@ Kareem.prototype.clone = function() {
|
|
|
582
468
|
|
|
583
469
|
for (const key of this._pres.keys()) {
|
|
584
470
|
const clone = this._pres.get(key).slice();
|
|
585
|
-
clone.numAsync = this._pres.get(key).numAsync;
|
|
586
471
|
n._pres.set(key, clone);
|
|
587
472
|
}
|
|
588
473
|
for (const key of this._posts.keys()) {
|
|
@@ -608,8 +493,6 @@ Kareem.prototype.merge = function(other, clone) {
|
|
|
608
493
|
// Deduplicate based on `fn`
|
|
609
494
|
filter(p => sourcePres.map(_p => _p.fn).indexOf(p.fn) === -1);
|
|
610
495
|
const combined = sourcePres.concat(deduplicated);
|
|
611
|
-
combined.numAsync = sourcePres.numAsync || 0;
|
|
612
|
-
combined.numAsync += deduplicated.filter(p => p.isAsync).length;
|
|
613
496
|
ret._pres.set(key, combined);
|
|
614
497
|
}
|
|
615
498
|
for (const key of other._posts.keys()) {
|
|
@@ -622,42 +505,10 @@ Kareem.prototype.merge = function(other, clone) {
|
|
|
622
505
|
return ret;
|
|
623
506
|
};
|
|
624
507
|
|
|
625
|
-
function callMiddlewareFunction(fn, context, args, next) {
|
|
626
|
-
let maybePromiseLike;
|
|
627
|
-
try {
|
|
628
|
-
maybePromiseLike = fn.apply(context, args);
|
|
629
|
-
} catch (error) {
|
|
630
|
-
return next(error);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
if (isPromiseLike(maybePromiseLike)) {
|
|
634
|
-
maybePromiseLike.then(() => next(), err => next(err));
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
508
|
function isPromiseLike(v) {
|
|
639
509
|
return (typeof v === 'object' && v !== null && typeof v.then === 'function');
|
|
640
510
|
}
|
|
641
511
|
|
|
642
|
-
function decorateNextFn(fn) {
|
|
643
|
-
let called = false;
|
|
644
|
-
const _this = this;
|
|
645
|
-
return function() {
|
|
646
|
-
// Ensure this function can only be called once
|
|
647
|
-
if (called) {
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
called = true;
|
|
651
|
-
// Make sure to clear the stack so try/catch doesn't catch errors
|
|
652
|
-
// in subsequent middleware
|
|
653
|
-
return nextTick(() => fn.apply(_this, arguments));
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
const nextTick = typeof process === 'object' && process !== null && process.nextTick || function nextTick(cb) {
|
|
658
|
-
setTimeout(cb, 0);
|
|
659
|
-
};
|
|
660
|
-
|
|
661
512
|
function isErrorHandlingMiddleware(post, numArgs) {
|
|
662
513
|
if (post.errorHandler) {
|
|
663
514
|
return true;
|