kareem 2.0.6 → 2.2.1
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/index.js +61 -36
- package/package.json +1 -1
- package/test/examples.test.js +6 -6
- package/test/misc.test.js +33 -0
- package/test/post.test.js +6 -4
- package/test/pre.test.js +6 -4
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function Kareem() {
|
|
4
|
-
this._pres =
|
|
5
|
-
this._posts =
|
|
4
|
+
this._pres = new Map();
|
|
5
|
+
this._posts = new Map();
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
@@ -218,10 +218,10 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
218
218
|
};
|
|
219
219
|
|
|
220
220
|
Kareem.prototype.execPostSync = function(name, context, args) {
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
const posts = get(this._posts, name, []);
|
|
222
|
+
const numPosts = posts.length;
|
|
223
223
|
|
|
224
|
-
for (
|
|
224
|
+
for (let i = 0; i < numPosts; ++i) {
|
|
225
225
|
posts[i].apply(context, args || []);
|
|
226
226
|
}
|
|
227
227
|
};
|
|
@@ -253,18 +253,19 @@ function _handleWrapError(instance, error, name, context, args, options, callbac
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
const lastArg = (args.length > 0 ? args[args.length - 1] : null);
|
|
257
|
+
const argsWithoutCb = typeof lastArg === 'function' ?
|
|
258
258
|
args.slice(0, args.length - 1) :
|
|
259
259
|
args;
|
|
260
|
-
|
|
260
|
+
const _this = this;
|
|
261
261
|
|
|
262
262
|
options = options || {};
|
|
263
|
+
const checkForPromise = options.checkForPromise;
|
|
263
264
|
|
|
264
265
|
this.execPre(name, context, args, function(error) {
|
|
265
266
|
if (error) {
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
const numCallbackParams = options.numCallbackParams || 0;
|
|
268
|
+
const errorArgs = options.contextParameter ? [context] : [];
|
|
268
269
|
for (var i = errorArgs.length; i < numCallbackParams; ++i) {
|
|
269
270
|
errorArgs.push(null);
|
|
270
271
|
}
|
|
@@ -272,12 +273,29 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
272
273
|
options, lastArg);
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
|
|
276
|
-
|
|
276
|
+
const end = (typeof lastArg === 'function' ? args.length - 1 : args.length);
|
|
277
|
+
const numParameters = fn.length;
|
|
278
|
+
const ret = fn.apply(context, args.slice(0, end).concat(_cb));
|
|
279
|
+
|
|
280
|
+
if (checkForPromise) {
|
|
281
|
+
if (ret != null && typeof ret.then === 'function') {
|
|
282
|
+
// Thenable, use it
|
|
283
|
+
return ret.then(
|
|
284
|
+
res => _cb(null, res),
|
|
285
|
+
err => _cb(err)
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// If `fn()` doesn't have a callback argument and doesn't return a
|
|
290
|
+
// promise, assume it is sync
|
|
291
|
+
if (numParameters < end + 1) {
|
|
292
|
+
return _cb(null, ret);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
277
295
|
|
|
278
296
|
function _cb() {
|
|
279
|
-
|
|
280
|
-
|
|
297
|
+
const args = arguments;
|
|
298
|
+
const argsWithoutError = Array.prototype.slice.call(arguments, 1);
|
|
281
299
|
if (options.nullResultByDefault && argsWithoutError.length === 0) {
|
|
282
300
|
argsWithoutError.push(null);
|
|
283
301
|
}
|
|
@@ -302,9 +320,13 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
302
320
|
});
|
|
303
321
|
};
|
|
304
322
|
|
|
323
|
+
Kareem.prototype.hasHooks = function(name) {
|
|
324
|
+
return this._pres.has(name) || this._posts.has(name);
|
|
325
|
+
};
|
|
326
|
+
|
|
305
327
|
Kareem.prototype.createWrapper = function(name, fn, context, options) {
|
|
306
328
|
var _this = this;
|
|
307
|
-
if (this.
|
|
329
|
+
if (!this.hasHooks(name)) {
|
|
308
330
|
// Fast path: if there's no hooks for this function, just return the
|
|
309
331
|
// function wrapped in a nextTick()
|
|
310
332
|
return function() {
|
|
@@ -325,8 +347,8 @@ Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
|
325
347
|
isAsync = false;
|
|
326
348
|
}
|
|
327
349
|
|
|
328
|
-
|
|
329
|
-
|
|
350
|
+
const pres = get(this._pres, name, []);
|
|
351
|
+
this._pres.set(name, pres);
|
|
330
352
|
|
|
331
353
|
if (isAsync) {
|
|
332
354
|
pres.numAsync = pres.numAsync || 0;
|
|
@@ -343,25 +365,27 @@ Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
|
343
365
|
};
|
|
344
366
|
|
|
345
367
|
Kareem.prototype.post = function(name, fn, unshift) {
|
|
346
|
-
|
|
368
|
+
const hooks = get(this._posts, name, []);
|
|
347
369
|
|
|
348
370
|
if (unshift) {
|
|
349
|
-
|
|
371
|
+
hooks.unshift(fn);
|
|
350
372
|
} else {
|
|
351
|
-
|
|
373
|
+
hooks.push(fn);
|
|
352
374
|
}
|
|
375
|
+
this._posts.set(name, hooks);
|
|
353
376
|
return this;
|
|
354
377
|
};
|
|
355
378
|
|
|
356
379
|
Kareem.prototype.clone = function() {
|
|
357
380
|
const n = new Kareem();
|
|
358
381
|
|
|
359
|
-
for (let key of
|
|
360
|
-
|
|
361
|
-
|
|
382
|
+
for (let key of this._pres.keys()) {
|
|
383
|
+
const clone = this._pres.get(key).slice();
|
|
384
|
+
clone.numAsync = this._pres.get(key).numAsync;
|
|
385
|
+
n._pres.set(key, clone);
|
|
362
386
|
}
|
|
363
|
-
for (let key of
|
|
364
|
-
n._posts
|
|
387
|
+
for (let key of this._posts.keys()) {
|
|
388
|
+
n._posts.set(key, this._posts.get(key).slice());
|
|
365
389
|
}
|
|
366
390
|
|
|
367
391
|
return n;
|
|
@@ -370,28 +394,29 @@ Kareem.prototype.clone = function() {
|
|
|
370
394
|
Kareem.prototype.merge = function(other) {
|
|
371
395
|
var ret = this.clone();
|
|
372
396
|
|
|
373
|
-
for (let key of
|
|
397
|
+
for (let key of other._pres.keys()) {
|
|
374
398
|
const sourcePres = get(ret._pres, key, []);
|
|
375
|
-
const deduplicated = other._pres
|
|
399
|
+
const deduplicated = other._pres.get(key).
|
|
376
400
|
// Deduplicate based on `fn`
|
|
377
401
|
filter(p => sourcePres.map(_p => _p.fn).indexOf(p.fn) === -1);
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
402
|
+
const combined = sourcePres.concat(deduplicated);
|
|
403
|
+
combined.numAsync = sourcePres.numAsync || 0;
|
|
404
|
+
combined.numAsync += deduplicated.filter(p => p.isAsync).length;
|
|
405
|
+
ret._pres.set(key, combined);
|
|
381
406
|
}
|
|
382
|
-
for (let key of
|
|
407
|
+
for (let key of other._posts.keys()) {
|
|
383
408
|
const sourcePosts = get(ret._posts, key, []);
|
|
384
|
-
const deduplicated = other._posts
|
|
409
|
+
const deduplicated = other._posts.get(key).
|
|
385
410
|
filter(p => sourcePosts.indexOf(p) === -1);
|
|
386
|
-
ret._posts
|
|
411
|
+
ret._posts.set(key, sourcePosts.concat(deduplicated));
|
|
387
412
|
}
|
|
388
413
|
|
|
389
414
|
return ret;
|
|
390
415
|
};
|
|
391
416
|
|
|
392
|
-
function get(
|
|
393
|
-
if (
|
|
394
|
-
return
|
|
417
|
+
function get(map, key, def) {
|
|
418
|
+
if (map.has(key)) {
|
|
419
|
+
return map.get(key);
|
|
395
420
|
}
|
|
396
421
|
return def;
|
|
397
422
|
}
|
package/package.json
CHANGED
package/test/examples.test.js
CHANGED
|
@@ -355,8 +355,8 @@ describe('clone()', function() {
|
|
|
355
355
|
k1.post('cook', function() {});
|
|
356
356
|
|
|
357
357
|
var k2 = k1.clone();
|
|
358
|
-
assert.deepEqual(
|
|
359
|
-
assert.deepEqual(
|
|
358
|
+
assert.deepEqual(Array.from(k2._pres.keys()), ['cook']);
|
|
359
|
+
assert.deepEqual(Array.from(k2._posts.keys()), ['cook']);
|
|
360
360
|
});
|
|
361
361
|
});
|
|
362
362
|
|
|
@@ -371,9 +371,9 @@ describe('merge()', function() {
|
|
|
371
371
|
var test2 = function() {};
|
|
372
372
|
k2.pre('cook', test2);
|
|
373
373
|
var k3 = k2.merge(k1);
|
|
374
|
-
assert.equal(k3._pres
|
|
375
|
-
assert.equal(k3._pres
|
|
376
|
-
assert.equal(k3._pres
|
|
377
|
-
assert.equal(k3._posts
|
|
374
|
+
assert.equal(k3._pres.get('cook').length, 2);
|
|
375
|
+
assert.equal(k3._pres.get('cook')[0].fn, test2);
|
|
376
|
+
assert.equal(k3._pres.get('cook')[1].fn, test1);
|
|
377
|
+
assert.equal(k3._posts.get('cook').length, 1);
|
|
378
378
|
});
|
|
379
379
|
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Kareem = require('../');
|
|
5
|
+
|
|
6
|
+
describe('hasHooks', function() {
|
|
7
|
+
it('returns false for toString (Automattic/mongoose#6538)', function() {
|
|
8
|
+
const k = new Kareem();
|
|
9
|
+
assert.ok(!k.hasHooks('toString'));
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('merge', function() {
|
|
14
|
+
it('handles async pres if source doesnt have them', function() {
|
|
15
|
+
const k1 = new Kareem();
|
|
16
|
+
k1.pre('cook', true, function(next, done) {
|
|
17
|
+
execed.first = true;
|
|
18
|
+
setTimeout(
|
|
19
|
+
function() {
|
|
20
|
+
done('error!');
|
|
21
|
+
},
|
|
22
|
+
5);
|
|
23
|
+
|
|
24
|
+
next();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
assert.equal(k1._pres.get('cook').numAsync, 1);
|
|
28
|
+
|
|
29
|
+
const k2 = new Kareem();
|
|
30
|
+
const k3 = k2.merge(k1);
|
|
31
|
+
assert.equal(k3._pres.get('cook').numAsync, 1);
|
|
32
|
+
});
|
|
33
|
+
});
|
package/test/post.test.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Kareem = require('../');
|
|
3
5
|
|
|
4
6
|
describe('execPost', function() {
|
|
5
7
|
var hooks;
|
|
@@ -25,8 +27,8 @@ describe('execPost', function() {
|
|
|
25
27
|
var f2 = function() {};
|
|
26
28
|
hooks.post('cook', f1);
|
|
27
29
|
hooks.post('cook', f2, true);
|
|
28
|
-
assert.strictEqual(hooks._posts
|
|
29
|
-
assert.strictEqual(hooks._posts
|
|
30
|
+
assert.strictEqual(hooks._posts.get('cook')[0], f2);
|
|
31
|
+
assert.strictEqual(hooks._posts.get('cook')[1], f1);
|
|
30
32
|
});
|
|
31
33
|
|
|
32
34
|
it('multiple posts', function(done) {
|
package/test/pre.test.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Kareem = require('../');
|
|
3
5
|
|
|
4
6
|
describe('execPre', function() {
|
|
5
7
|
var hooks;
|
|
@@ -59,8 +61,8 @@ describe('execPre', function() {
|
|
|
59
61
|
var f2 = function() {};
|
|
60
62
|
hooks.pre('cook', false, f1);
|
|
61
63
|
hooks.pre('cook', false, f2, null, true);
|
|
62
|
-
assert.strictEqual(hooks._pres
|
|
63
|
-
assert.strictEqual(hooks._pres
|
|
64
|
+
assert.strictEqual(hooks._pres.get('cook')[0].fn, f2);
|
|
65
|
+
assert.strictEqual(hooks._pres.get('cook')[1].fn, f1);
|
|
64
66
|
});
|
|
65
67
|
|
|
66
68
|
it('handles async errors', function(done) {
|