kareem 2.3.3 → 2.4.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/.github/workflows/test.yml +30 -0
- package/CHANGELOG.md +10 -0
- package/index.js +117 -76
- package/package.json +3 -3
- package/test/post.test.js +65 -0
- package/test/pre.test.js +18 -0
- package/test/wrap.test.js +98 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
push:
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
node: [12, 14, 16, 18]
|
|
15
|
+
os: [ubuntu-20.04]
|
|
16
|
+
include:
|
|
17
|
+
- os: ubuntu-20.04
|
|
18
|
+
mongo-os: ubuntu2004
|
|
19
|
+
name: Node ${{ matrix.node }}
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # v3
|
|
22
|
+
|
|
23
|
+
- name: Setup node
|
|
24
|
+
uses: actions/setup-node@5b52f097d36d4b0b2f94ed6de710023fbb8b2236 # v3.1.0
|
|
25
|
+
with:
|
|
26
|
+
node-version: ${{ matrix.node }}
|
|
27
|
+
|
|
28
|
+
- run: npm install
|
|
29
|
+
|
|
30
|
+
- run: npm test
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
<a name="2.4.0"></a>
|
|
4
|
+
## 2.4.0 (2022-06-13)
|
|
5
|
+
|
|
6
|
+
* feat: add `overwriteResult()` and `skipWrappedFunction()` for more advanced control flow
|
|
7
|
+
|
|
8
|
+
<a name="2.3.4"></a>
|
|
9
|
+
## 2.3.4 (2022-02-10)
|
|
10
|
+
|
|
11
|
+
* perf: various performance improvements #27 #24 #23 #22 #21 #20
|
|
12
|
+
|
|
3
13
|
<a name="2.3.3"></a>
|
|
4
14
|
## 2.3.3 (2021-12-26)
|
|
5
15
|
|
package/index.js
CHANGED
|
@@ -5,21 +5,38 @@ function Kareem() {
|
|
|
5
5
|
this._posts = new Map();
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
Kareem.skipWrappedFunction = function skipWrappedFunction() {
|
|
9
|
+
if (!(this instanceof Kareem.skipWrappedFunction)) {
|
|
10
|
+
return new Kareem.skipWrappedFunction(...arguments);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
this.args = [...arguments];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
Kareem.overwriteResult = function overwriteResult() {
|
|
17
|
+
if (!(this instanceof Kareem.overwriteResult)) {
|
|
18
|
+
return new Kareem.overwriteResult(...arguments);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this.args = [...arguments];
|
|
22
|
+
};
|
|
23
|
+
|
|
8
24
|
Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
9
25
|
if (arguments.length === 3) {
|
|
10
26
|
callback = args;
|
|
11
27
|
args = [];
|
|
12
28
|
}
|
|
13
|
-
var pres =
|
|
29
|
+
var pres = this._pres.get(name) || [];
|
|
14
30
|
var numPres = pres.length;
|
|
15
31
|
var numAsyncPres = pres.numAsync || 0;
|
|
16
32
|
var currentPre = 0;
|
|
17
33
|
var asyncPresLeft = numAsyncPres;
|
|
18
34
|
var done = false;
|
|
19
35
|
var $args = args;
|
|
36
|
+
var shouldSkipWrappedFunction = null;
|
|
20
37
|
|
|
21
38
|
if (!numPres) {
|
|
22
|
-
return
|
|
39
|
+
return nextTick(function() {
|
|
23
40
|
callback(null);
|
|
24
41
|
});
|
|
25
42
|
}
|
|
@@ -38,11 +55,15 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
38
55
|
if (done) {
|
|
39
56
|
return;
|
|
40
57
|
}
|
|
41
|
-
|
|
42
|
-
|
|
58
|
+
if (error instanceof Kareem.skipWrappedFunction) {
|
|
59
|
+
shouldSkipWrappedFunction = error;
|
|
60
|
+
} else {
|
|
61
|
+
done = true;
|
|
62
|
+
return callback(error);
|
|
63
|
+
}
|
|
43
64
|
}
|
|
44
65
|
if (--asyncPresLeft === 0 && currentPre >= numPres) {
|
|
45
|
-
return callback(
|
|
66
|
+
return callback(shouldSkipWrappedFunction);
|
|
46
67
|
}
|
|
47
68
|
})
|
|
48
69
|
];
|
|
@@ -57,25 +78,25 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
57
78
|
|
|
58
79
|
callMiddlewareFunction(pre.fn, context, args, args[0]);
|
|
59
80
|
} else {
|
|
60
|
-
let
|
|
81
|
+
let maybePromiseLike = null;
|
|
61
82
|
try {
|
|
62
|
-
|
|
83
|
+
maybePromiseLike = pre.fn.call(context);
|
|
63
84
|
} catch (err) {
|
|
64
85
|
if (err != null) {
|
|
65
86
|
return callback(err);
|
|
66
87
|
}
|
|
67
88
|
}
|
|
68
89
|
|
|
69
|
-
if (
|
|
70
|
-
|
|
90
|
+
if (isPromiseLike(maybePromiseLike)) {
|
|
91
|
+
maybePromiseLike.then(() => _next(), err => _next(err));
|
|
71
92
|
} else {
|
|
72
93
|
if (++currentPre >= numPres) {
|
|
73
94
|
if (asyncPresLeft > 0) {
|
|
74
95
|
// Leave parallel hooks to run
|
|
75
96
|
return;
|
|
76
97
|
} else {
|
|
77
|
-
return
|
|
78
|
-
callback(
|
|
98
|
+
return nextTick(function() {
|
|
99
|
+
callback(shouldSkipWrappedFunction);
|
|
79
100
|
});
|
|
80
101
|
}
|
|
81
102
|
}
|
|
@@ -91,8 +112,12 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
91
112
|
if (done) {
|
|
92
113
|
return;
|
|
93
114
|
}
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
if (error instanceof Kareem.skipWrappedFunction) {
|
|
116
|
+
shouldSkipWrappedFunction = error;
|
|
117
|
+
} else {
|
|
118
|
+
done = true;
|
|
119
|
+
return callback(error);
|
|
120
|
+
}
|
|
96
121
|
}
|
|
97
122
|
|
|
98
123
|
if (++currentPre >= numPres) {
|
|
@@ -100,7 +125,7 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
100
125
|
// Leave parallel hooks to run
|
|
101
126
|
return;
|
|
102
127
|
} else {
|
|
103
|
-
return callback(
|
|
128
|
+
return callback(shouldSkipWrappedFunction);
|
|
104
129
|
}
|
|
105
130
|
}
|
|
106
131
|
|
|
@@ -109,7 +134,7 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
109
134
|
};
|
|
110
135
|
|
|
111
136
|
Kareem.prototype.execPreSync = function(name, context, args) {
|
|
112
|
-
var pres =
|
|
137
|
+
var pres = this._pres.get(name) || [];
|
|
113
138
|
var numPres = pres.length;
|
|
114
139
|
|
|
115
140
|
for (var i = 0; i < numPres; ++i) {
|
|
@@ -122,7 +147,7 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
122
147
|
callback = options;
|
|
123
148
|
options = null;
|
|
124
149
|
}
|
|
125
|
-
var posts =
|
|
150
|
+
var posts = this._posts.get(name) || [];
|
|
126
151
|
var numPosts = posts.length;
|
|
127
152
|
var currentPost = 0;
|
|
128
153
|
|
|
@@ -132,7 +157,7 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
132
157
|
}
|
|
133
158
|
|
|
134
159
|
if (!numPosts) {
|
|
135
|
-
return
|
|
160
|
+
return nextTick(function() {
|
|
136
161
|
callback.apply(null, [firstError].concat(args));
|
|
137
162
|
});
|
|
138
163
|
}
|
|
@@ -151,8 +176,15 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
151
176
|
|
|
152
177
|
if (firstError) {
|
|
153
178
|
if (post.length === numArgs + 2) {
|
|
154
|
-
|
|
179
|
+
const _cb = decorateNextFn(function(error) {
|
|
155
180
|
if (error) {
|
|
181
|
+
if (error instanceof Kareem.overwriteResult) {
|
|
182
|
+
args = error.args;
|
|
183
|
+
if (++currentPost >= numPosts) {
|
|
184
|
+
return callback.call(null, firstError);
|
|
185
|
+
}
|
|
186
|
+
return next();
|
|
187
|
+
}
|
|
156
188
|
firstError = error;
|
|
157
189
|
}
|
|
158
190
|
if (++currentPost >= numPosts) {
|
|
@@ -172,6 +204,13 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
172
204
|
} else {
|
|
173
205
|
const _cb = decorateNextFn(function(error) {
|
|
174
206
|
if (error) {
|
|
207
|
+
if (error instanceof Kareem.overwriteResult) {
|
|
208
|
+
args = error.args;
|
|
209
|
+
if (++currentPost >= numPosts) {
|
|
210
|
+
return callback.apply(null, [null].concat(args));
|
|
211
|
+
}
|
|
212
|
+
return next();
|
|
213
|
+
}
|
|
175
214
|
firstError = error;
|
|
176
215
|
return next();
|
|
177
216
|
}
|
|
@@ -194,23 +233,27 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
194
233
|
callMiddlewareFunction(post, context, newArgs.concat([_cb]), _cb);
|
|
195
234
|
} else {
|
|
196
235
|
let error;
|
|
197
|
-
let
|
|
236
|
+
let maybePromiseLike;
|
|
198
237
|
try {
|
|
199
|
-
|
|
238
|
+
maybePromiseLike = post.apply(context, newArgs);
|
|
200
239
|
} catch (err) {
|
|
201
240
|
error = err;
|
|
202
241
|
firstError = err;
|
|
203
242
|
}
|
|
204
243
|
|
|
205
|
-
if (
|
|
206
|
-
return
|
|
244
|
+
if (isPromiseLike(maybePromiseLike)) {
|
|
245
|
+
return maybePromiseLike.then((res) => _cb(res), err => _cb(err));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (maybePromiseLike instanceof Kareem.overwriteResult) {
|
|
249
|
+
args = maybePromiseLike.args;
|
|
207
250
|
}
|
|
208
251
|
|
|
209
252
|
if (++currentPost >= numPosts) {
|
|
210
253
|
return callback.apply(null, [error].concat(args));
|
|
211
254
|
}
|
|
212
255
|
|
|
213
|
-
next(
|
|
256
|
+
next();
|
|
214
257
|
}
|
|
215
258
|
}
|
|
216
259
|
};
|
|
@@ -219,12 +262,17 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
219
262
|
};
|
|
220
263
|
|
|
221
264
|
Kareem.prototype.execPostSync = function(name, context, args) {
|
|
222
|
-
const posts =
|
|
265
|
+
const posts = this._posts.get(name) || [];
|
|
223
266
|
const numPosts = posts.length;
|
|
224
267
|
|
|
225
268
|
for (let i = 0; i < numPosts; ++i) {
|
|
226
|
-
posts[i].fn.apply(context, args || []);
|
|
269
|
+
const res = posts[i].fn.apply(context, args || []);
|
|
270
|
+
if (res instanceof Kareem.overwriteResult) {
|
|
271
|
+
args = res.args;
|
|
272
|
+
}
|
|
227
273
|
}
|
|
274
|
+
|
|
275
|
+
return args;
|
|
228
276
|
};
|
|
229
277
|
|
|
230
278
|
Kareem.prototype.createWrapperSync = function(name, fn) {
|
|
@@ -234,37 +282,33 @@ Kareem.prototype.createWrapperSync = function(name, fn) {
|
|
|
234
282
|
|
|
235
283
|
var toReturn = fn.apply(this, arguments);
|
|
236
284
|
|
|
237
|
-
kareem.execPostSync(name, this, [toReturn]);
|
|
285
|
+
const result = kareem.execPostSync(name, this, [toReturn]);
|
|
238
286
|
|
|
239
|
-
return
|
|
287
|
+
return result[0];
|
|
240
288
|
};
|
|
241
289
|
}
|
|
242
290
|
|
|
243
291
|
function _handleWrapError(instance, error, name, context, args, options, callback) {
|
|
244
292
|
if (options.useErrorHandlers) {
|
|
245
|
-
|
|
246
|
-
return instance.execPost(name, context, args, _options, function(error) {
|
|
293
|
+
return instance.execPost(name, context, args, { error: error }, function(error) {
|
|
247
294
|
return typeof callback === 'function' && callback(error);
|
|
248
295
|
});
|
|
249
296
|
} else {
|
|
250
|
-
return typeof callback === 'function'
|
|
251
|
-
callback(error) :
|
|
252
|
-
undefined;
|
|
297
|
+
return typeof callback === 'function' && callback(error);
|
|
253
298
|
}
|
|
254
299
|
}
|
|
255
300
|
|
|
256
301
|
Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
257
302
|
const lastArg = (args.length > 0 ? args[args.length - 1] : null);
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
args;
|
|
303
|
+
let argsWithoutCb = Array.from(args);
|
|
304
|
+
typeof lastArg === 'function' && argsWithoutCb.pop();
|
|
261
305
|
const _this = this;
|
|
262
306
|
|
|
263
307
|
options = options || {};
|
|
264
308
|
const checkForPromise = options.checkForPromise;
|
|
265
309
|
|
|
266
310
|
this.execPre(name, context, args, function(error) {
|
|
267
|
-
if (error) {
|
|
311
|
+
if (error && !(error instanceof Kareem.skipWrappedFunction)) {
|
|
268
312
|
const numCallbackParams = options.numCallbackParams || 0;
|
|
269
313
|
const errorArgs = options.contextParameter ? [context] : [];
|
|
270
314
|
for (var i = errorArgs.length; i < numCallbackParams; ++i) {
|
|
@@ -274,17 +318,22 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
274
318
|
options, lastArg);
|
|
275
319
|
}
|
|
276
320
|
|
|
277
|
-
const end = (typeof lastArg === 'function' ? args.length - 1 : args.length);
|
|
278
321
|
const numParameters = fn.length;
|
|
279
322
|
let ret;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return _cb(
|
|
323
|
+
|
|
324
|
+
if (error instanceof Kareem.skipWrappedFunction) {
|
|
325
|
+
ret = error.args[0];
|
|
326
|
+
return _cb(null, ...error.args);
|
|
327
|
+
} else {
|
|
328
|
+
try {
|
|
329
|
+
ret = fn.apply(context, argsWithoutCb.concat(_cb));
|
|
330
|
+
} catch (err) {
|
|
331
|
+
return _cb(err);
|
|
332
|
+
}
|
|
284
333
|
}
|
|
285
334
|
|
|
286
335
|
if (checkForPromise) {
|
|
287
|
-
if (ret
|
|
336
|
+
if (isPromiseLike(ret)) {
|
|
288
337
|
// Thenable, use it
|
|
289
338
|
return ret.then(
|
|
290
339
|
res => _cb(null, res),
|
|
@@ -294,14 +343,14 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
294
343
|
|
|
295
344
|
// If `fn()` doesn't have a callback argument and doesn't return a
|
|
296
345
|
// promise, assume it is sync
|
|
297
|
-
if (numParameters <
|
|
346
|
+
if (numParameters < argsWithoutCb.length + 1) {
|
|
298
347
|
return _cb(null, ret);
|
|
299
348
|
}
|
|
300
349
|
}
|
|
301
350
|
|
|
302
351
|
function _cb() {
|
|
303
|
-
const
|
|
304
|
-
|
|
352
|
+
const argsWithoutError = Array.from(arguments);
|
|
353
|
+
argsWithoutError.shift();
|
|
305
354
|
if (options.nullResultByDefault && argsWithoutError.length === 0) {
|
|
306
355
|
argsWithoutError.push(null);
|
|
307
356
|
}
|
|
@@ -311,15 +360,12 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
311
360
|
argsWithoutError, options, lastArg);
|
|
312
361
|
} else {
|
|
313
362
|
_this.execPost(name, context, argsWithoutError, function() {
|
|
314
|
-
if (
|
|
315
|
-
return
|
|
316
|
-
lastArg(arguments[0]) :
|
|
317
|
-
undefined;
|
|
363
|
+
if (lastArg === null) {
|
|
364
|
+
return;
|
|
318
365
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
lastArg.apply(context, arguments)
|
|
322
|
-
undefined;
|
|
366
|
+
arguments[0]
|
|
367
|
+
? lastArg(arguments[0])
|
|
368
|
+
: lastArg.apply(context, arguments)
|
|
323
369
|
});
|
|
324
370
|
}
|
|
325
371
|
}
|
|
@@ -372,28 +418,26 @@ Kareem.prototype.createWrapper = function(name, fn, context, options) {
|
|
|
372
418
|
// Fast path: if there's no hooks for this function, just return the
|
|
373
419
|
// function wrapped in a nextTick()
|
|
374
420
|
return function() {
|
|
375
|
-
|
|
421
|
+
nextTick(() => fn.apply(this, arguments));
|
|
376
422
|
};
|
|
377
423
|
}
|
|
378
424
|
return function() {
|
|
379
425
|
var _context = context || this;
|
|
380
|
-
|
|
381
|
-
_this.wrap(name, fn, _context, args, options);
|
|
426
|
+
_this.wrap(name, fn, _context, Array.from(arguments), options);
|
|
382
427
|
};
|
|
383
428
|
};
|
|
384
429
|
|
|
385
430
|
Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
386
431
|
let options = {};
|
|
387
|
-
if (typeof isAsync === 'object' && isAsync
|
|
432
|
+
if (typeof isAsync === 'object' && isAsync !== null) {
|
|
388
433
|
options = isAsync;
|
|
389
434
|
isAsync = options.isAsync;
|
|
390
435
|
} else if (typeof arguments[1] !== 'boolean') {
|
|
391
|
-
error = fn;
|
|
392
436
|
fn = isAsync;
|
|
393
437
|
isAsync = false;
|
|
394
438
|
}
|
|
395
439
|
|
|
396
|
-
const pres =
|
|
440
|
+
const pres = this._pres.get(name) || [];
|
|
397
441
|
this._pres.set(name, pres);
|
|
398
442
|
|
|
399
443
|
if (isAsync) {
|
|
@@ -415,7 +459,7 @@ Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
|
415
459
|
};
|
|
416
460
|
|
|
417
461
|
Kareem.prototype.post = function(name, options, fn, unshift) {
|
|
418
|
-
const hooks =
|
|
462
|
+
const hooks = this._posts.get(name) || [];
|
|
419
463
|
|
|
420
464
|
if (typeof options === 'function') {
|
|
421
465
|
unshift = !!fn;
|
|
@@ -456,7 +500,7 @@ Kareem.prototype.merge = function(other, clone) {
|
|
|
456
500
|
var ret = clone ? this.clone() : this;
|
|
457
501
|
|
|
458
502
|
for (let key of other._pres.keys()) {
|
|
459
|
-
const sourcePres =
|
|
503
|
+
const sourcePres = ret._pres.get(key) || [];
|
|
460
504
|
const deduplicated = other._pres.get(key).
|
|
461
505
|
// Deduplicate based on `fn`
|
|
462
506
|
filter(p => sourcePres.map(_p => _p.fn).indexOf(p.fn) === -1);
|
|
@@ -466,7 +510,7 @@ Kareem.prototype.merge = function(other, clone) {
|
|
|
466
510
|
ret._pres.set(key, combined);
|
|
467
511
|
}
|
|
468
512
|
for (let key of other._posts.keys()) {
|
|
469
|
-
const sourcePosts =
|
|
513
|
+
const sourcePosts = ret._posts.get(key) || [];
|
|
470
514
|
const deduplicated = other._posts.get(key).
|
|
471
515
|
filter(p => sourcePosts.indexOf(p) === -1);
|
|
472
516
|
ret._posts.set(key, sourcePosts.concat(deduplicated));
|
|
@@ -475,28 +519,21 @@ Kareem.prototype.merge = function(other, clone) {
|
|
|
475
519
|
return ret;
|
|
476
520
|
};
|
|
477
521
|
|
|
478
|
-
function get(map, key, def) {
|
|
479
|
-
if (map.has(key)) {
|
|
480
|
-
return map.get(key);
|
|
481
|
-
}
|
|
482
|
-
return def;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
522
|
function callMiddlewareFunction(fn, context, args, next) {
|
|
486
|
-
let
|
|
523
|
+
let maybePromiseLike;
|
|
487
524
|
try {
|
|
488
|
-
|
|
525
|
+
maybePromiseLike = fn.apply(context, args);
|
|
489
526
|
} catch (error) {
|
|
490
527
|
return next(error);
|
|
491
528
|
}
|
|
492
529
|
|
|
493
|
-
if (
|
|
494
|
-
|
|
530
|
+
if (isPromiseLike(maybePromiseLike)) {
|
|
531
|
+
maybePromiseLike.then(() => next(), err => next(err));
|
|
495
532
|
}
|
|
496
533
|
}
|
|
497
534
|
|
|
498
|
-
function
|
|
499
|
-
return v
|
|
535
|
+
function isPromiseLike(v) {
|
|
536
|
+
return (typeof v === 'object' && v !== null && typeof v.then === 'function');
|
|
500
537
|
}
|
|
501
538
|
|
|
502
539
|
function decorateNextFn(fn) {
|
|
@@ -510,8 +547,12 @@ function decorateNextFn(fn) {
|
|
|
510
547
|
called = true;
|
|
511
548
|
// Make sure to clear the stack so try/catch doesn't catch errors
|
|
512
549
|
// in subsequent middleware
|
|
513
|
-
return
|
|
550
|
+
return nextTick(() => fn.apply(_this, arguments));
|
|
514
551
|
};
|
|
515
552
|
}
|
|
516
553
|
|
|
554
|
+
const nextTick = typeof process === 'object' && process !== null && process.nextTick || function nextTick(cb) {
|
|
555
|
+
setTimeout(cb, 0);
|
|
556
|
+
}
|
|
557
|
+
|
|
517
558
|
module.exports = Kareem;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kareem",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Next-generation take on pre/post function hooks",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"acquit": "1.x",
|
|
16
16
|
"acquit-ignore": "0.1.x",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
17
|
+
"mocha": "9.2.0",
|
|
18
|
+
"nyc": "15.1.0"
|
|
19
19
|
},
|
|
20
20
|
"author": "Valeri Karpov <val@karpov.io>",
|
|
21
21
|
"license": "Apache-2.0"
|
package/test/post.test.js
CHANGED
|
@@ -165,6 +165,71 @@ describe('execPost', function() {
|
|
|
165
165
|
done();
|
|
166
166
|
});
|
|
167
167
|
});
|
|
168
|
+
|
|
169
|
+
it('supports overwriteResult', function(done) {
|
|
170
|
+
hooks.post('cook', function(eggs, callback) {
|
|
171
|
+
callback(Kareem.overwriteResult(5));
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
hooks.post('cook', function(eggs, callback) {
|
|
175
|
+
assert.equal(eggs, 5);
|
|
176
|
+
callback();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
var options = {};
|
|
180
|
+
hooks.execPost('cook', null, [4], options, function(error, eggs) {
|
|
181
|
+
assert.equal(eggs, 5);
|
|
182
|
+
done();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('supports sync returning overwriteResult', function(done) {
|
|
187
|
+
hooks.post('cook', function() {
|
|
188
|
+
return Kareem.overwriteResult(5);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
hooks.post('cook', function(eggs, callback) {
|
|
192
|
+
assert.equal(eggs, 5);
|
|
193
|
+
callback();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
var options = {};
|
|
197
|
+
hooks.execPost('cook', null, [4], options, function(error, eggs) {
|
|
198
|
+
assert.ifError(error);
|
|
199
|
+
assert.equal(eggs, 5);
|
|
200
|
+
done();
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('supports sync overwriteResult', function() {
|
|
205
|
+
hooks.post('cook', function(eggs) {
|
|
206
|
+
return Kareem.overwriteResult(5);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
hooks.post('cook', function(eggs) {
|
|
210
|
+
assert.equal(eggs, 5);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
var options = {};
|
|
214
|
+
const res = hooks.execPostSync('cook', null, [4], options);
|
|
215
|
+
assert.deepEqual(res, [5]);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('supports overwriteResult with promises', function(done) {
|
|
219
|
+
hooks.post('cook', function(eggs) {
|
|
220
|
+
return Promise.resolve(Kareem.overwriteResult(5));
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
hooks.post('cook', function(eggs) {
|
|
224
|
+
assert.equal(eggs, 5);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
var options = {};
|
|
228
|
+
hooks.execPost('cook', null, [4], options, function(error, eggs) {
|
|
229
|
+
assert.equal(eggs, 5);
|
|
230
|
+
done();
|
|
231
|
+
});
|
|
232
|
+
});
|
|
168
233
|
});
|
|
169
234
|
|
|
170
235
|
describe('execPostSync', function() {
|
package/test/pre.test.js
CHANGED
|
@@ -307,6 +307,24 @@ describe('execPre', function() {
|
|
|
307
307
|
done();
|
|
308
308
|
});
|
|
309
309
|
});
|
|
310
|
+
|
|
311
|
+
it('supports skipWrappedFunction', function(done) {
|
|
312
|
+
var execed = {};
|
|
313
|
+
|
|
314
|
+
hooks.pre('cook', function(callback) {
|
|
315
|
+
callback(Kareem.skipWrappedFunction(42));
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
hooks.pre('cook', function() {
|
|
319
|
+
execed.second = true;
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
hooks.execPre('cook', null, function(err) {
|
|
323
|
+
assert.ok(execed.second);
|
|
324
|
+
assert.ok(err instanceof Kareem.skipWrappedFunction);
|
|
325
|
+
done();
|
|
326
|
+
});
|
|
327
|
+
});
|
|
310
328
|
});
|
|
311
329
|
|
|
312
330
|
describe('execPreSync', function() {
|
package/test/wrap.test.js
CHANGED
|
@@ -287,6 +287,91 @@ describe('wrap()', function() {
|
|
|
287
287
|
25);
|
|
288
288
|
});
|
|
289
289
|
|
|
290
|
+
it('supports overwriteResult', function(done) {
|
|
291
|
+
hooks.post('cook', function(eggs, callback) {
|
|
292
|
+
callback(Kareem.overwriteResult(5));
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
const args = [(err, res) => {
|
|
296
|
+
assert.ifError(err);
|
|
297
|
+
assert.equal(res, 5);
|
|
298
|
+
done();
|
|
299
|
+
}];
|
|
300
|
+
|
|
301
|
+
hooks.wrap(
|
|
302
|
+
'cook',
|
|
303
|
+
function(callback) {
|
|
304
|
+
callback(null, 4);
|
|
305
|
+
},
|
|
306
|
+
null,
|
|
307
|
+
args);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('supports skipWrappedFunction', function(done) {
|
|
311
|
+
const execed = {};
|
|
312
|
+
hooks.pre('cook', function pre(callback) {
|
|
313
|
+
execed.pre = true;
|
|
314
|
+
callback(Kareem.skipWrappedFunction(3));
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
hooks.post('cook', function(res, callback) {
|
|
318
|
+
assert.equal(res, 3);
|
|
319
|
+
execed.post = true;
|
|
320
|
+
callback();
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const args = [(err, res) => {
|
|
324
|
+
assert.ifError(err);
|
|
325
|
+
assert.equal(res, 3);
|
|
326
|
+
assert.ok(execed.pre);
|
|
327
|
+
assert.ok(execed.post);
|
|
328
|
+
assert.ok(!execed.wrapped);
|
|
329
|
+
done();
|
|
330
|
+
}];
|
|
331
|
+
|
|
332
|
+
hooks.wrap(
|
|
333
|
+
'cook',
|
|
334
|
+
function wrapped(callback) {
|
|
335
|
+
execed.wrapped = true;
|
|
336
|
+
callback();
|
|
337
|
+
},
|
|
338
|
+
null,
|
|
339
|
+
args);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('supports skipWrappedFunction with arguments', function(done) {
|
|
343
|
+
const execed = {};
|
|
344
|
+
hooks.pre('cook', function pre(callback, arg) {
|
|
345
|
+
execed.pre = true;
|
|
346
|
+
assert.strictEqual(arg, 4);
|
|
347
|
+
callback(Kareem.skipWrappedFunction(3));
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
hooks.post('cook', function(res, callback) {
|
|
351
|
+
assert.equal(res, 3);
|
|
352
|
+
execed.post = true;
|
|
353
|
+
callback();
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
const args = [4, (err, res) => {
|
|
357
|
+
assert.ifError(err);
|
|
358
|
+
assert.equal(res, 3);
|
|
359
|
+
assert.ok(execed.pre);
|
|
360
|
+
assert.ok(execed.post);
|
|
361
|
+
assert.ok(!execed.wrapped);
|
|
362
|
+
done();
|
|
363
|
+
}];
|
|
364
|
+
|
|
365
|
+
hooks.wrap(
|
|
366
|
+
'cook',
|
|
367
|
+
function wrapped(arg, callback) {
|
|
368
|
+
execed.wrapped = true;
|
|
369
|
+
callback();
|
|
370
|
+
},
|
|
371
|
+
null,
|
|
372
|
+
args);
|
|
373
|
+
});
|
|
374
|
+
|
|
290
375
|
it('handles post errors with no args', function(done) {
|
|
291
376
|
hooks.pre('cook', function(done) {
|
|
292
377
|
obj.waffles = false;
|
|
@@ -363,4 +448,17 @@ describe('wrap()', function() {
|
|
|
363
448
|
assert.equal(calledFn, 1);
|
|
364
449
|
assert.equal(calledPost, 1);
|
|
365
450
|
});
|
|
451
|
+
|
|
452
|
+
it('sync wrappers with overwriteResult', function() {
|
|
453
|
+
hooks.pre('cook', function() {
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
hooks.post('cook', function() {
|
|
457
|
+
return Kareem.overwriteResult(5);
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
const wrapper = hooks.createWrapperSync('cook', function() { return 4; });
|
|
461
|
+
|
|
462
|
+
assert.strictEqual(wrapper(), 5);
|
|
463
|
+
});
|
|
366
464
|
});
|