kareem 2.6.2 → 3.0.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 +7 -0
- package/README.md +43 -54
- 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 +171 -330
- package/package.json +2 -2
- package/.eslintrc.json +0 -131
- package/.github/workflows/test.yml +0 -47
package/index.js
CHANGED
|
@@ -24,127 +24,69 @@ 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
|
-
* @
|
|
33
|
-
* @returns {void}
|
|
39
|
+
* @param {Array} args arguments passed to the pre hooks
|
|
40
|
+
* @returns {Array} The potentially modified arguments
|
|
34
41
|
*/
|
|
35
|
-
Kareem.prototype.execPre = function(name, context, args
|
|
36
|
-
if (arguments.length === 3) {
|
|
37
|
-
callback = args;
|
|
38
|
-
args = [];
|
|
39
|
-
}
|
|
42
|
+
Kareem.prototype.execPre = async function execPre(name, context, args) {
|
|
40
43
|
const pres = this._pres.get(name) || [];
|
|
41
44
|
const numPres = pres.length;
|
|
42
|
-
|
|
43
|
-
let
|
|
44
|
-
let asyncPresLeft = numAsyncPres;
|
|
45
|
-
let done = false;
|
|
46
|
-
const $args = args;
|
|
47
|
-
let shouldSkipWrappedFunction = null;
|
|
45
|
+
let $args = args;
|
|
46
|
+
let skipWrappedFunction = null;
|
|
48
47
|
|
|
49
48
|
if (!numPres) {
|
|
50
|
-
return
|
|
51
|
-
callback(null);
|
|
52
|
-
});
|
|
49
|
+
return $args;
|
|
53
50
|
}
|
|
54
51
|
|
|
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
|
-
}
|
|
52
|
+
for (const pre of pres) {
|
|
53
|
+
const args = [];
|
|
54
|
+
const _args = [null].concat($args);
|
|
55
|
+
for (let i = 1; i < _args.length; ++i) {
|
|
56
|
+
if (i === _args.length - 1 && typeof _args[i] === 'function') {
|
|
57
|
+
continue; // skip callbacks to avoid accidentally calling the callback from a hook
|
|
102
58
|
}
|
|
59
|
+
args.push(_args[i]);
|
|
60
|
+
}
|
|
103
61
|
|
|
62
|
+
try {
|
|
63
|
+
const maybePromiseLike = pre.fn.apply(context, args);
|
|
104
64
|
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
|
-
}
|
|
65
|
+
const result = await maybePromiseLike;
|
|
66
|
+
if (result instanceof Kareem.overwriteArguments) {
|
|
67
|
+
$args = result.args;
|
|
116
68
|
}
|
|
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;
|
|
69
|
+
} else if (maybePromiseLike instanceof Kareem.overwriteArguments) {
|
|
70
|
+
$args = maybePromiseLike.args;
|
|
128
71
|
}
|
|
72
|
+
} catch (error) {
|
|
129
73
|
if (error instanceof Kareem.skipWrappedFunction) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
done = true;
|
|
133
|
-
return callback(error);
|
|
74
|
+
skipWrappedFunction = error;
|
|
75
|
+
continue;
|
|
134
76
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (asyncPresLeft > 0) {
|
|
139
|
-
// Leave parallel hooks to run
|
|
140
|
-
return;
|
|
141
|
-
} else {
|
|
142
|
-
return callback(shouldSkipWrappedFunction);
|
|
77
|
+
if (error instanceof Kareem.overwriteArguments) {
|
|
78
|
+
$args = error.args;
|
|
79
|
+
continue;
|
|
143
80
|
}
|
|
81
|
+
throw error;
|
|
144
82
|
}
|
|
83
|
+
}
|
|
145
84
|
|
|
146
|
-
|
|
85
|
+
if (skipWrappedFunction) {
|
|
86
|
+
throw skipWrappedFunction;
|
|
147
87
|
}
|
|
88
|
+
|
|
89
|
+
return $args;
|
|
148
90
|
};
|
|
149
91
|
|
|
150
92
|
/**
|
|
@@ -152,34 +94,34 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
152
94
|
* @param {String} name The hook name to execute
|
|
153
95
|
* @param {*} context Overwrite the "this" for the hook
|
|
154
96
|
* @param {Array} [args] Apply custom arguments to the hook
|
|
155
|
-
* @returns {
|
|
97
|
+
* @returns {Array} The potentially modified arguments
|
|
156
98
|
*/
|
|
157
99
|
Kareem.prototype.execPreSync = function(name, context, args) {
|
|
158
100
|
const pres = this._pres.get(name) || [];
|
|
159
101
|
const numPres = pres.length;
|
|
102
|
+
let $args = args || [];
|
|
160
103
|
|
|
161
104
|
for (let i = 0; i < numPres; ++i) {
|
|
162
|
-
pres[i].fn.apply(context, args
|
|
105
|
+
const result = pres[i].fn.apply(context, $args);
|
|
106
|
+
if (result instanceof Kareem.overwriteArguments) {
|
|
107
|
+
$args = result.args;
|
|
108
|
+
}
|
|
163
109
|
}
|
|
110
|
+
|
|
111
|
+
return $args;
|
|
164
112
|
};
|
|
165
113
|
|
|
166
114
|
/**
|
|
167
115
|
* Execute all "post" hooks for "name"
|
|
168
116
|
* @param {String} name The hook name to execute
|
|
169
117
|
* @param {*} context Overwrite the "this" for the hook
|
|
170
|
-
* @param {Array
|
|
118
|
+
* @param {Array} args Apply custom arguments to the hook
|
|
171
119
|
* @param {*} options Optional options or directly the callback
|
|
172
|
-
* @param {Function} [callback] The callback to call when executing all hooks are finished
|
|
173
120
|
* @returns {void}
|
|
174
121
|
*/
|
|
175
|
-
Kareem.prototype.execPost = function(name, context, args, options
|
|
176
|
-
if (arguments.length < 5) {
|
|
177
|
-
callback = options;
|
|
178
|
-
options = null;
|
|
179
|
-
}
|
|
122
|
+
Kareem.prototype.execPost = async function execPost(name, context, args, options) {
|
|
180
123
|
const posts = this._posts.get(name) || [];
|
|
181
124
|
const numPosts = posts.length;
|
|
182
|
-
let currentPost = 0;
|
|
183
125
|
|
|
184
126
|
let firstError = null;
|
|
185
127
|
if (options && options.error) {
|
|
@@ -187,120 +129,108 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
187
129
|
}
|
|
188
130
|
|
|
189
131
|
if (!numPosts) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
132
|
+
if (firstError != null) {
|
|
133
|
+
throw firstError;
|
|
134
|
+
}
|
|
135
|
+
return args;
|
|
193
136
|
}
|
|
194
137
|
|
|
195
|
-
|
|
196
|
-
const post =
|
|
138
|
+
for (const currentPost of posts) {
|
|
139
|
+
const post = currentPost.fn;
|
|
197
140
|
let numArgs = 0;
|
|
198
|
-
const argLength = args.length;
|
|
199
141
|
const newArgs = [];
|
|
142
|
+
const argLength = args.length;
|
|
200
143
|
for (let i = 0; i < argLength; ++i) {
|
|
201
|
-
numArgs += args[i] && args[i]._kareemIgnore ? 0 : 1;
|
|
202
144
|
if (!args[i] || !args[i]._kareemIgnore) {
|
|
145
|
+
numArgs += 1;
|
|
203
146
|
newArgs.push(args[i]);
|
|
204
147
|
}
|
|
205
148
|
}
|
|
149
|
+
// If numCallbackParams set, fill in the rest with null to enforce consistent number of args
|
|
150
|
+
if (options?.numCallbackParams != null) {
|
|
151
|
+
numArgs = options.numCallbackParams;
|
|
152
|
+
for (let i = newArgs.length; i < numArgs; ++i) {
|
|
153
|
+
newArgs.push(null);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
206
156
|
|
|
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);
|
|
157
|
+
let resolve;
|
|
158
|
+
let reject;
|
|
159
|
+
const cbPromise = new Promise((_resolve, _reject) => {
|
|
160
|
+
resolve = _resolve;
|
|
161
|
+
reject = _reject;
|
|
162
|
+
});
|
|
163
|
+
newArgs.push(function nextCallback(err) {
|
|
164
|
+
if (err) {
|
|
165
|
+
reject(err);
|
|
228
166
|
} else {
|
|
229
|
-
|
|
230
|
-
return callback.call(null, firstError);
|
|
231
|
-
}
|
|
232
|
-
next();
|
|
167
|
+
resolve();
|
|
233
168
|
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (firstError) {
|
|
172
|
+
if (isErrorHandlingMiddleware(currentPost, numArgs)) {
|
|
173
|
+
try {
|
|
174
|
+
const res = post.apply(context, [firstError].concat(newArgs));
|
|
175
|
+
if (isPromiseLike(res)) {
|
|
176
|
+
await res;
|
|
177
|
+
} else if (post.length === numArgs + 2) {
|
|
178
|
+
// `numArgs + 2` because we added the error and the callback
|
|
179
|
+
await cbPromise;
|
|
180
|
+
}
|
|
181
|
+
} catch (error) {
|
|
237
182
|
if (error instanceof Kareem.overwriteResult) {
|
|
238
183
|
args = error.args;
|
|
239
|
-
|
|
240
|
-
return callback.apply(null, [null].concat(args));
|
|
241
|
-
}
|
|
242
|
-
return next();
|
|
184
|
+
continue;
|
|
243
185
|
}
|
|
244
186
|
firstError = error;
|
|
245
|
-
return next();
|
|
246
187
|
}
|
|
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();
|
|
188
|
+
} else {
|
|
189
|
+
continue;
|
|
261
190
|
}
|
|
262
|
-
|
|
263
|
-
|
|
191
|
+
} else {
|
|
192
|
+
if (isErrorHandlingMiddleware(currentPost, numArgs)) {
|
|
193
|
+
// Skip error handlers if no error
|
|
194
|
+
continue;
|
|
264
195
|
} else {
|
|
265
|
-
let
|
|
266
|
-
let maybePromiseLike;
|
|
196
|
+
let res = null;
|
|
267
197
|
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;
|
|
198
|
+
res = post.apply(context, newArgs);
|
|
199
|
+
if (isPromiseLike(res)) {
|
|
200
|
+
res = await res;
|
|
201
|
+
} else if (post.length === numArgs + 1) {
|
|
202
|
+
// If post function takes a callback, wait for the post function to call the callback
|
|
203
|
+
res = await cbPromise;
|
|
204
|
+
}
|
|
205
|
+
} catch (error) {
|
|
206
|
+
if (error instanceof Kareem.overwriteResult) {
|
|
207
|
+
args = error.args;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
firstError = error;
|
|
211
|
+
continue;
|
|
285
212
|
}
|
|
286
213
|
|
|
287
|
-
if (
|
|
288
|
-
|
|
214
|
+
if (res instanceof Kareem.overwriteResult) {
|
|
215
|
+
args = res.args;
|
|
216
|
+
continue;
|
|
289
217
|
}
|
|
290
|
-
|
|
291
|
-
next();
|
|
292
218
|
}
|
|
293
219
|
}
|
|
294
220
|
}
|
|
295
221
|
|
|
296
|
-
|
|
222
|
+
if (firstError != null) {
|
|
223
|
+
throw firstError;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return args;
|
|
297
227
|
};
|
|
298
228
|
|
|
299
229
|
/**
|
|
300
230
|
* Execute all "post" hooks for "name" synchronously
|
|
301
231
|
* @param {String} name The hook name to execute
|
|
302
232
|
* @param {*} context Overwrite the "this" for the hook
|
|
303
|
-
* @param {Array
|
|
233
|
+
* @param {Array} args Apply custom arguments to the hook
|
|
304
234
|
* @returns {Array} The used arguments
|
|
305
235
|
*/
|
|
306
236
|
Kareem.prototype.execPostSync = function(name, context, args) {
|
|
@@ -326,9 +256,9 @@ Kareem.prototype.execPostSync = function(name, context, args) {
|
|
|
326
256
|
Kareem.prototype.createWrapperSync = function(name, fn) {
|
|
327
257
|
const _this = this;
|
|
328
258
|
return function syncWrapper() {
|
|
329
|
-
_this.execPreSync(name, this, arguments);
|
|
259
|
+
const modifiedArgs = _this.execPreSync(name, this, Array.from(arguments));
|
|
330
260
|
|
|
331
|
-
const toReturn = fn.apply(this,
|
|
261
|
+
const toReturn = fn.apply(this, modifiedArgs);
|
|
332
262
|
|
|
333
263
|
const result = _this.execPostSync(name, this, [toReturn]);
|
|
334
264
|
|
|
@@ -336,98 +266,37 @@ Kareem.prototype.createWrapperSync = function(name, fn) {
|
|
|
336
266
|
};
|
|
337
267
|
};
|
|
338
268
|
|
|
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
269
|
/**
|
|
350
270
|
* Executes pre hooks, followed by the wrapped function, followed by post hooks.
|
|
351
271
|
* @param {String} name The name of the hook
|
|
352
272
|
* @param {Function} fn The function for the hook
|
|
353
273
|
* @param {*} context Overwrite the "this" for the hook
|
|
354
274
|
* @param {Array} args Apply custom arguments to the hook
|
|
355
|
-
* @param {Object}
|
|
356
|
-
* @param {Boolean} [options.checkForPromise]
|
|
275
|
+
* @param {Object} options Additional options for the hook
|
|
357
276
|
* @returns {void}
|
|
358
277
|
*/
|
|
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
|
-
|
|
278
|
+
Kareem.prototype.wrap = async function wrap(name, fn, context, args, options) {
|
|
279
|
+
let ret;
|
|
280
|
+
let skipWrappedFunction = false;
|
|
281
|
+
let modifiedArgs = args;
|
|
282
|
+
try {
|
|
283
|
+
modifiedArgs = await this.execPre(name, context, args);
|
|
284
|
+
} catch (error) {
|
|
382
285
|
if (error instanceof Kareem.skipWrappedFunction) {
|
|
383
|
-
ret = error.args
|
|
384
|
-
|
|
286
|
+
ret = error.args;
|
|
287
|
+
skipWrappedFunction = true;
|
|
385
288
|
} else {
|
|
386
|
-
|
|
387
|
-
ret = fn.apply(context, argsWithoutCb.concat(_cb));
|
|
388
|
-
} catch (err) {
|
|
389
|
-
return _cb(err);
|
|
390
|
-
}
|
|
289
|
+
await this.execPost(name, context, args, { ...options, error });
|
|
391
290
|
}
|
|
291
|
+
}
|
|
392
292
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return ret.then(
|
|
397
|
-
res => _cb(null, res),
|
|
398
|
-
err => _cb(err)
|
|
399
|
-
);
|
|
400
|
-
}
|
|
293
|
+
if (!skipWrappedFunction) {
|
|
294
|
+
ret = await fn.apply(context, modifiedArgs);
|
|
295
|
+
}
|
|
401
296
|
|
|
402
|
-
|
|
403
|
-
// promise, assume it is sync
|
|
404
|
-
if (numParameters < argsWithoutCb.length + 1) {
|
|
405
|
-
return _cb(null, ret);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
297
|
+
ret = await this.execPost(name, context, [ret], options);
|
|
408
298
|
|
|
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
|
-
});
|
|
299
|
+
return ret[0];
|
|
431
300
|
};
|
|
432
301
|
|
|
433
302
|
/**
|
|
@@ -449,8 +318,6 @@ Kareem.prototype.filter = function(fn) {
|
|
|
449
318
|
continue;
|
|
450
319
|
}
|
|
451
320
|
|
|
452
|
-
hooks.numAsync = hooks.filter(h => h.isAsync).length;
|
|
453
|
-
|
|
454
321
|
clone._pres.set(name, hooks);
|
|
455
322
|
}
|
|
456
323
|
|
|
@@ -491,53 +358,43 @@ Kareem.prototype.hasHooks = function(name) {
|
|
|
491
358
|
Kareem.prototype.createWrapper = function(name, fn, context, options) {
|
|
492
359
|
const _this = this;
|
|
493
360
|
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
|
-
};
|
|
361
|
+
// Fast path: if there's no hooks for this function, just return the function
|
|
362
|
+
return fn;
|
|
499
363
|
}
|
|
500
|
-
return function() {
|
|
364
|
+
return function kareemWrappedFunction() {
|
|
501
365
|
const _context = context || this;
|
|
502
|
-
_this.wrap(name, fn, _context, Array.from(arguments), options);
|
|
366
|
+
return _this.wrap(name, fn, _context, Array.from(arguments), options);
|
|
503
367
|
};
|
|
504
368
|
};
|
|
505
369
|
|
|
506
370
|
/**
|
|
507
371
|
* Register a new hook for "pre"
|
|
508
372
|
* @param {String} name The name of the hook
|
|
509
|
-
* @param {
|
|
373
|
+
* @param {Object} [options]
|
|
510
374
|
* @param {Function} fn The function to register for "name"
|
|
511
375
|
* @param {never} error Unused
|
|
512
376
|
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
|
513
377
|
* @returns {Kareem}
|
|
514
378
|
*/
|
|
515
|
-
Kareem.prototype.pre = function(name,
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
options =
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
fn = isAsync;
|
|
522
|
-
isAsync = false;
|
|
379
|
+
Kareem.prototype.pre = function(name, options, fn, error, unshift) {
|
|
380
|
+
if (typeof options === 'function') {
|
|
381
|
+
fn = options;
|
|
382
|
+
options = {};
|
|
383
|
+
} else if (options == null) {
|
|
384
|
+
options = {};
|
|
523
385
|
}
|
|
524
386
|
|
|
525
387
|
const pres = this._pres.get(name) || [];
|
|
526
388
|
this._pres.set(name, pres);
|
|
527
389
|
|
|
528
|
-
if (isAsync) {
|
|
529
|
-
pres.numAsync = pres.numAsync || 0;
|
|
530
|
-
++pres.numAsync;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
390
|
if (typeof fn !== 'function') {
|
|
534
391
|
throw new Error('pre() requires a function, got "' + typeof fn + '"');
|
|
535
392
|
}
|
|
536
393
|
|
|
537
394
|
if (unshift) {
|
|
538
|
-
pres.unshift(Object.assign({}, options, { fn: fn
|
|
395
|
+
pres.unshift(Object.assign({}, options, { fn: fn }));
|
|
539
396
|
} else {
|
|
540
|
-
pres.push(Object.assign({}, options, { fn: fn
|
|
397
|
+
pres.push(Object.assign({}, options, { fn: fn }));
|
|
541
398
|
}
|
|
542
399
|
|
|
543
400
|
return this;
|
|
@@ -547,6 +404,7 @@ Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
|
547
404
|
* Register a new hook for "post"
|
|
548
405
|
* @param {String} name The name of the hook
|
|
549
406
|
* @param {Object} [options]
|
|
407
|
+
* @param {Boolean} [options.errorHandler] Whether this is an error handler
|
|
550
408
|
* @param {Function} fn The function to register for "name"
|
|
551
409
|
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
|
552
410
|
* @returns {Kareem}
|
|
@@ -573,6 +431,24 @@ Kareem.prototype.post = function(name, options, fn, unshift) {
|
|
|
573
431
|
return this;
|
|
574
432
|
};
|
|
575
433
|
|
|
434
|
+
/**
|
|
435
|
+
* Register a new error handler for "name"
|
|
436
|
+
* @param {String} name The name of the hook
|
|
437
|
+
* @param {Object} [options]
|
|
438
|
+
* @param {Function} fn The function to register for "name"
|
|
439
|
+
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
|
440
|
+
* @returns {Kareem}
|
|
441
|
+
*/
|
|
442
|
+
|
|
443
|
+
Kareem.prototype.postError = function postError(name, options, fn, unshift) {
|
|
444
|
+
if (typeof options === 'function') {
|
|
445
|
+
unshift = !!fn;
|
|
446
|
+
fn = options;
|
|
447
|
+
options = {};
|
|
448
|
+
}
|
|
449
|
+
return this.post(name, { ...options, errorHandler: true }, fn, unshift);
|
|
450
|
+
};
|
|
451
|
+
|
|
576
452
|
/**
|
|
577
453
|
* Clone the current instance
|
|
578
454
|
* @returns {Kareem} The cloned instance
|
|
@@ -582,7 +458,6 @@ Kareem.prototype.clone = function() {
|
|
|
582
458
|
|
|
583
459
|
for (const key of this._pres.keys()) {
|
|
584
460
|
const clone = this._pres.get(key).slice();
|
|
585
|
-
clone.numAsync = this._pres.get(key).numAsync;
|
|
586
461
|
n._pres.set(key, clone);
|
|
587
462
|
}
|
|
588
463
|
for (const key of this._posts.keys()) {
|
|
@@ -608,8 +483,6 @@ Kareem.prototype.merge = function(other, clone) {
|
|
|
608
483
|
// Deduplicate based on `fn`
|
|
609
484
|
filter(p => sourcePres.map(_p => _p.fn).indexOf(p.fn) === -1);
|
|
610
485
|
const combined = sourcePres.concat(deduplicated);
|
|
611
|
-
combined.numAsync = sourcePres.numAsync || 0;
|
|
612
|
-
combined.numAsync += deduplicated.filter(p => p.isAsync).length;
|
|
613
486
|
ret._pres.set(key, combined);
|
|
614
487
|
}
|
|
615
488
|
for (const key of other._posts.keys()) {
|
|
@@ -622,42 +495,10 @@ Kareem.prototype.merge = function(other, clone) {
|
|
|
622
495
|
return ret;
|
|
623
496
|
};
|
|
624
497
|
|
|
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
498
|
function isPromiseLike(v) {
|
|
639
499
|
return (typeof v === 'object' && v !== null && typeof v.then === 'function');
|
|
640
500
|
}
|
|
641
501
|
|
|
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
502
|
function isErrorHandlingMiddleware(post, numArgs) {
|
|
662
503
|
if (post.errorHandler) {
|
|
663
504
|
return true;
|