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 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
- var posts = get(this._posts, name, []);
222
- var numPosts = posts.length;
221
+ const posts = get(this._posts, name, []);
222
+ const numPosts = posts.length;
223
223
 
224
- for (var i = 0; i < numPosts; ++i) {
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
- var lastArg = (args.length > 0 ? args[args.length - 1] : null);
257
- var argsWithoutCb = typeof lastArg === 'function' ?
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
- var _this = this;
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
- var numCallbackParams = options.numCallbackParams || 0;
267
- var errorArgs = options.contextParameter ? [context] : [];
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
- var end = (typeof lastArg === 'function' ? args.length - 1 : args.length);
276
- fn.apply(context, args.slice(0, end).concat(_cb));
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
- var args = arguments;
280
- var argsWithoutError = Array.prototype.slice.call(arguments, 1);
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._pres[name] == null && this._posts[name] == null) {
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
- this._pres[name] = get(this._pres, name, []);
329
- const pres = this._pres[name];
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
- this._posts[name] = get(this._posts, name, []);
368
+ const hooks = get(this._posts, name, []);
347
369
 
348
370
  if (unshift) {
349
- this._posts[name].unshift(fn);
371
+ hooks.unshift(fn);
350
372
  } else {
351
- this._posts[name].push(fn);
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 Object.keys(this._pres)) {
360
- n._pres[key] = this._pres[key].slice();
361
- n._pres[key].numAsync = this._pres[key].numAsync;
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 Object.keys(this._posts)) {
364
- n._posts[key] = this._posts[key].slice();
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 Object.keys(other._pres)) {
397
+ for (let key of other._pres.keys()) {
374
398
  const sourcePres = get(ret._pres, key, []);
375
- const deduplicated = other._pres[key].
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
- ret._pres[key] = sourcePres.concat(deduplicated);
379
- ret._pres[key].numAsync = get(ret._pres[key], 'numAsync', 0);
380
- ret._pres[key].numAsync += deduplicated.filter(p => p.isAsync).length;
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 Object.keys(other._posts)) {
407
+ for (let key of other._posts.keys()) {
383
408
  const sourcePosts = get(ret._posts, key, []);
384
- const deduplicated = other._posts[key].
409
+ const deduplicated = other._posts.get(key).
385
410
  filter(p => sourcePosts.indexOf(p) === -1);
386
- ret._posts[key] = sourcePosts.concat(deduplicated);
411
+ ret._posts.set(key, sourcePosts.concat(deduplicated));
387
412
  }
388
413
 
389
414
  return ret;
390
415
  };
391
416
 
392
- function get(obj, key, def) {
393
- if (obj[key] != null) {
394
- return obj[key];
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kareem",
3
- "version": "2.0.6",
3
+ "version": "2.2.1",
4
4
  "description": "Next-generation take on pre/post function hooks",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -355,8 +355,8 @@ describe('clone()', function() {
355
355
  k1.post('cook', function() {});
356
356
 
357
357
  var k2 = k1.clone();
358
- assert.deepEqual(['cook'], Object.keys(k2._pres));
359
- assert.deepEqual(['cook'], Object.keys(k2._posts));
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['cook'].length, 2);
375
- assert.equal(k3._pres['cook'][0].fn, test2);
376
- assert.equal(k3._pres['cook'][1].fn, test1);
377
- assert.equal(k3._posts['cook'].length, 1);
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
- var assert = require('assert');
2
- var Kareem = require('../');
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['cook'][0], f2);
29
- assert.strictEqual(hooks._posts['cook'][1], f1);
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
- var assert = require('assert');
2
- var Kareem = require('../');
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['cook'][0].fn, f2);
63
- assert.strictEqual(hooks._pres['cook'][1].fn, f1);
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) {