kareem 2.2.2 → 2.3.2
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/.travis.yml +2 -0
- package/CHANGELOG.md +793 -0
- package/README.md +295 -303
- package/docs.js +3 -1
- package/index.js +68 -13
- package/package.json +7 -15
- package/test/examples.test.js +47 -0
- package/test/misc.test.js +38 -0
- package/test/post.test.js +15 -2
- package/test/pre.test.js +33 -0
package/docs.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
var acquit = require('acquit');
|
|
2
2
|
|
|
3
|
+
require('acquit-ignore')();
|
|
4
|
+
|
|
3
5
|
var content = require('fs').readFileSync('./test/examples.test.js').toString();
|
|
4
6
|
var blocks = acquit.parse(content);
|
|
5
7
|
|
|
@@ -29,7 +31,7 @@ for (var i = 0; i < blocks.length; ++i) {
|
|
|
29
31
|
acquit.trimEachLine(it.comments[0]) + '\n\n' :
|
|
30
32
|
'';
|
|
31
33
|
mdOutput += '```javascript\n';
|
|
32
|
-
mdOutput +=
|
|
34
|
+
mdOutput += it.code + '\n';
|
|
33
35
|
mdOutput += '```\n\n';
|
|
34
36
|
}
|
|
35
37
|
}
|
package/index.js
CHANGED
|
@@ -57,12 +57,13 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
57
57
|
|
|
58
58
|
callMiddlewareFunction(pre.fn, context, args, args[0]);
|
|
59
59
|
} else {
|
|
60
|
-
let error = null;
|
|
61
60
|
let maybePromise = null;
|
|
62
61
|
try {
|
|
63
62
|
maybePromise = pre.fn.call(context);
|
|
64
63
|
} catch (err) {
|
|
65
|
-
|
|
64
|
+
if (err != null) {
|
|
65
|
+
return callback(err);
|
|
66
|
+
}
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
if (isPromise(maybePromise)) {
|
|
@@ -74,11 +75,11 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
74
75
|
return;
|
|
75
76
|
} else {
|
|
76
77
|
return process.nextTick(function() {
|
|
77
|
-
callback(
|
|
78
|
+
callback(null);
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
|
-
next(
|
|
82
|
+
next();
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
};
|
|
@@ -137,7 +138,7 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
var next = function() {
|
|
140
|
-
var post = posts[currentPost];
|
|
141
|
+
var post = posts[currentPost].fn;
|
|
141
142
|
var numArgs = 0;
|
|
142
143
|
var argLength = args.length;
|
|
143
144
|
var newArgs = [];
|
|
@@ -222,7 +223,7 @@ Kareem.prototype.execPostSync = function(name, context, args) {
|
|
|
222
223
|
const numPosts = posts.length;
|
|
223
224
|
|
|
224
225
|
for (let i = 0; i < numPosts; ++i) {
|
|
225
|
-
posts[i].apply(context, args || []);
|
|
226
|
+
posts[i].fn.apply(context, args || []);
|
|
226
227
|
}
|
|
227
228
|
};
|
|
228
229
|
|
|
@@ -320,6 +321,42 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
320
321
|
});
|
|
321
322
|
};
|
|
322
323
|
|
|
324
|
+
Kareem.prototype.filter = function(fn) {
|
|
325
|
+
const clone = this.clone();
|
|
326
|
+
|
|
327
|
+
const pres = Array.from(clone._pres.keys());
|
|
328
|
+
for (const name of pres) {
|
|
329
|
+
const hooks = this._pres.get(name).
|
|
330
|
+
map(h => Object.assign({}, h, { name: name })).
|
|
331
|
+
filter(fn);
|
|
332
|
+
|
|
333
|
+
if (hooks.length === 0) {
|
|
334
|
+
clone._pres.delete(name);
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
hooks.numAsync = hooks.filter(h => h.isAsync).length;
|
|
339
|
+
|
|
340
|
+
clone._pres.set(name, hooks);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const posts = Array.from(clone._posts.keys());
|
|
344
|
+
for (const name of posts) {
|
|
345
|
+
const hooks = this._posts.get(name).
|
|
346
|
+
map(h => Object.assign({}, h, { name: name })).
|
|
347
|
+
filter(fn);
|
|
348
|
+
|
|
349
|
+
if (hooks.length === 0) {
|
|
350
|
+
clone._posts.delete(name);
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
clone._posts.set(name, hooks);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return clone;
|
|
358
|
+
};
|
|
359
|
+
|
|
323
360
|
Kareem.prototype.hasHooks = function(name) {
|
|
324
361
|
return this._pres.has(name) || this._posts.has(name);
|
|
325
362
|
};
|
|
@@ -341,7 +378,11 @@ Kareem.prototype.createWrapper = function(name, fn, context, options) {
|
|
|
341
378
|
};
|
|
342
379
|
|
|
343
380
|
Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
344
|
-
|
|
381
|
+
let options = {};
|
|
382
|
+
if (typeof isAsync === 'object' && isAsync != null) {
|
|
383
|
+
options = isAsync;
|
|
384
|
+
isAsync = options.isAsync;
|
|
385
|
+
} else if (typeof arguments[1] !== 'boolean') {
|
|
345
386
|
error = fn;
|
|
346
387
|
fn = isAsync;
|
|
347
388
|
isAsync = false;
|
|
@@ -355,22 +396,36 @@ Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) {
|
|
|
355
396
|
++pres.numAsync;
|
|
356
397
|
}
|
|
357
398
|
|
|
399
|
+
if (typeof fn !== 'function') {
|
|
400
|
+
throw new Error('pre() requires a function, got "' + typeof fn + '"');
|
|
401
|
+
}
|
|
402
|
+
|
|
358
403
|
if (unshift) {
|
|
359
|
-
pres.unshift({ fn: fn, isAsync: isAsync });
|
|
404
|
+
pres.unshift(Object.assign({}, options, { fn: fn, isAsync: isAsync }));
|
|
360
405
|
} else {
|
|
361
|
-
pres.push({ fn: fn, isAsync: isAsync });
|
|
406
|
+
pres.push(Object.assign({}, options, { fn: fn, isAsync: isAsync }));
|
|
362
407
|
}
|
|
363
408
|
|
|
364
409
|
return this;
|
|
365
410
|
};
|
|
366
411
|
|
|
367
|
-
Kareem.prototype.post = function(name, fn, unshift) {
|
|
412
|
+
Kareem.prototype.post = function(name, options, fn, unshift) {
|
|
368
413
|
const hooks = get(this._posts, name, []);
|
|
369
414
|
|
|
415
|
+
if (typeof options === 'function') {
|
|
416
|
+
unshift = !!fn;
|
|
417
|
+
fn = options;
|
|
418
|
+
options = {};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (typeof fn !== 'function') {
|
|
422
|
+
throw new Error('post() requires a function, got "' + typeof fn + '"');
|
|
423
|
+
}
|
|
424
|
+
|
|
370
425
|
if (unshift) {
|
|
371
|
-
hooks.unshift(fn);
|
|
426
|
+
hooks.unshift(Object.assign({}, options, { fn: fn }));
|
|
372
427
|
} else {
|
|
373
|
-
hooks.push(fn);
|
|
428
|
+
hooks.push(Object.assign({}, options, { fn: fn }));
|
|
374
429
|
}
|
|
375
430
|
this._posts.set(name, hooks);
|
|
376
431
|
return this;
|
|
@@ -393,7 +448,7 @@ Kareem.prototype.clone = function() {
|
|
|
393
448
|
|
|
394
449
|
Kareem.prototype.merge = function(other, clone) {
|
|
395
450
|
clone = arguments.length === 1 ? true : clone;
|
|
396
|
-
var ret = clone ? this.clone() :
|
|
451
|
+
var ret = clone ? this.clone() : this;
|
|
397
452
|
|
|
398
453
|
for (let key of other._pres.keys()) {
|
|
399
454
|
const sourcePres = get(ret._pres, key, []);
|
package/package.json
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kareem",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "Next-generation take on pre/post function hooks",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
8
|
-
"test-travis": "
|
|
7
|
+
"test": "mocha ./test/*",
|
|
8
|
+
"test-travis": "nyc mocha ./test/*"
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git://github.com/vkarpov15/kareem.git"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"acquit": "
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"istanbul": "0.4.5",
|
|
20
|
-
"jscs": "1.9.0",
|
|
21
|
-
"mocha": "3.2.0"
|
|
22
|
-
},
|
|
23
|
-
"jscsConfig": {
|
|
24
|
-
"preset": "airbnb",
|
|
25
|
-
"requireMultipleVarDecl": null,
|
|
26
|
-
"disallowMultipleVarDecl": true
|
|
15
|
+
"acquit": "1.x",
|
|
16
|
+
"acquit-ignore": "0.1.x",
|
|
17
|
+
"nyc": "11.x",
|
|
18
|
+
"mocha": "5.x"
|
|
27
19
|
},
|
|
28
20
|
"author": "Valeri Karpov <val@karpov.io>",
|
|
29
21
|
"license": "Apache-2.0"
|
package/test/examples.test.js
CHANGED
|
@@ -17,7 +17,10 @@ describe('pre hooks', function() {
|
|
|
17
17
|
|
|
18
18
|
it('runs without any hooks specified', function(done) {
|
|
19
19
|
hooks.execPre('cook', null, function() {
|
|
20
|
+
// ...
|
|
21
|
+
// acquit:ignore:start
|
|
20
22
|
done();
|
|
23
|
+
// acquit:ignore:end
|
|
21
24
|
});
|
|
22
25
|
});
|
|
23
26
|
|
|
@@ -34,7 +37,9 @@ describe('pre hooks', function() {
|
|
|
34
37
|
|
|
35
38
|
hooks.execPre('cook', null, function() {
|
|
36
39
|
assert.equal(1, count);
|
|
40
|
+
// acquit:ignore:start
|
|
37
41
|
done();
|
|
42
|
+
// acquit:ignore:end
|
|
38
43
|
});
|
|
39
44
|
});
|
|
40
45
|
|
|
@@ -55,7 +60,9 @@ describe('pre hooks', function() {
|
|
|
55
60
|
hooks.execPre('cook', null, function() {
|
|
56
61
|
assert.equal(1, count1);
|
|
57
62
|
assert.equal(1, count2);
|
|
63
|
+
// acquit:ignore:start
|
|
58
64
|
done();
|
|
65
|
+
// acquit:ignore:end
|
|
59
66
|
});
|
|
60
67
|
});
|
|
61
68
|
|
|
@@ -78,7 +85,9 @@ describe('pre hooks', function() {
|
|
|
78
85
|
assert.equal(null, error);
|
|
79
86
|
assert.equal(1, count1);
|
|
80
87
|
assert.equal(1, count2);
|
|
88
|
+
// acquit:ignore:start
|
|
81
89
|
done();
|
|
90
|
+
// acquit:ignore:end
|
|
82
91
|
});
|
|
83
92
|
});
|
|
84
93
|
|
|
@@ -102,7 +111,9 @@ describe('pre hooks', function() {
|
|
|
102
111
|
assert.equal(null, error);
|
|
103
112
|
assert.equal(3, obj.bacon);
|
|
104
113
|
assert.equal(4, obj.eggs);
|
|
114
|
+
// acquit:ignore:start
|
|
105
115
|
done();
|
|
116
|
+
// acquit:ignore:end
|
|
106
117
|
});
|
|
107
118
|
});
|
|
108
119
|
|
|
@@ -140,7 +151,9 @@ describe('pre hooks', function() {
|
|
|
140
151
|
assert.equal(3, obj.bacon);
|
|
141
152
|
assert.equal(4, obj.eggs);
|
|
142
153
|
assert.equal(false, obj.waffles);
|
|
154
|
+
// acquit:ignore:start
|
|
143
155
|
done();
|
|
156
|
+
// acquit:ignore:end
|
|
144
157
|
});
|
|
145
158
|
});
|
|
146
159
|
|
|
@@ -162,7 +175,9 @@ describe('pre hooks', function() {
|
|
|
162
175
|
|
|
163
176
|
hooks.execPre('cook', obj, function() {
|
|
164
177
|
assert.equal(3, obj.bacon);
|
|
178
|
+
// acquit:ignore:start
|
|
165
179
|
done();
|
|
180
|
+
// acquit:ignore:end
|
|
166
181
|
});
|
|
167
182
|
});
|
|
168
183
|
});
|
|
@@ -193,7 +208,9 @@ describe('post hooks', function() {
|
|
|
193
208
|
assert.ifError(error);
|
|
194
209
|
assert.equal(1, eggs);
|
|
195
210
|
assert.equal(2, bacon);
|
|
211
|
+
// acquit:ignore:start
|
|
196
212
|
done();
|
|
213
|
+
// acquit:ignore:end
|
|
197
214
|
});
|
|
198
215
|
});
|
|
199
216
|
|
|
@@ -220,7 +237,33 @@ describe('post hooks', function() {
|
|
|
220
237
|
assert.ok(execed.second);
|
|
221
238
|
assert.equal(1, eggs);
|
|
222
239
|
assert.equal(2, bacon);
|
|
240
|
+
// acquit:ignore:start
|
|
223
241
|
done();
|
|
242
|
+
// acquit:ignore:end
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
/* You can also return a promise from your post hooks instead of calling
|
|
247
|
+
* `next()`. When the returned promise resolves, kareem will kick off the
|
|
248
|
+
* next middleware.
|
|
249
|
+
*/
|
|
250
|
+
it('supports returning a promise', function(done) {
|
|
251
|
+
hooks.post('cook', function(bacon) {
|
|
252
|
+
return new Promise(resolve => {
|
|
253
|
+
setTimeout(() => {
|
|
254
|
+
this.bacon = 3;
|
|
255
|
+
resolve();
|
|
256
|
+
}, 100);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
var obj = { bacon: 0 };
|
|
261
|
+
|
|
262
|
+
hooks.execPost('cook', obj, obj, function() {
|
|
263
|
+
assert.equal(obj.bacon, 3);
|
|
264
|
+
// acquit:ignore:start
|
|
265
|
+
done();
|
|
266
|
+
// acquit:ignore:end
|
|
224
267
|
});
|
|
225
268
|
});
|
|
226
269
|
});
|
|
@@ -271,7 +314,9 @@ describe('wrap()', function() {
|
|
|
271
314
|
assert.equal('no', obj.tofu);
|
|
272
315
|
|
|
273
316
|
assert.equal(obj, result);
|
|
317
|
+
// acquit:ignore:start
|
|
274
318
|
done();
|
|
319
|
+
// acquit:ignore:end
|
|
275
320
|
});
|
|
276
321
|
|
|
277
322
|
hooks.wrap(
|
|
@@ -343,7 +388,9 @@ describe('createWrapper()', function() {
|
|
|
343
388
|
assert.equal('no', obj.tofu);
|
|
344
389
|
|
|
345
390
|
assert.equal(obj, result);
|
|
391
|
+
// acquit:ignore:start
|
|
346
392
|
done();
|
|
393
|
+
// acquit:ignore:end
|
|
347
394
|
});
|
|
348
395
|
});
|
|
349
396
|
});
|
package/test/misc.test.js
CHANGED
|
@@ -31,3 +31,41 @@ describe('merge', function() {
|
|
|
31
31
|
assert.equal(k3._pres.get('cook').numAsync, 1);
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
+
|
|
35
|
+
describe('filter', function() {
|
|
36
|
+
it('returns clone with only hooks that match `fn()`', function() {
|
|
37
|
+
const k1 = new Kareem();
|
|
38
|
+
|
|
39
|
+
k1.pre('update', { document: true }, f1);
|
|
40
|
+
k1.pre('update', { query: true }, f2);
|
|
41
|
+
k1.pre('remove', { document: true }, f3);
|
|
42
|
+
|
|
43
|
+
k1.post('update', { document: true }, f1);
|
|
44
|
+
k1.post('update', { query: true }, f2);
|
|
45
|
+
k1.post('remove', { document: true }, f3);
|
|
46
|
+
|
|
47
|
+
const k2 = k1.filter(hook => hook.document);
|
|
48
|
+
assert.equal(k2._pres.get('update').length, 1);
|
|
49
|
+
assert.equal(k2._pres.get('update')[0].fn, f1);
|
|
50
|
+
assert.equal(k2._pres.get('remove').length, 1);
|
|
51
|
+
assert.equal(k2._pres.get('remove')[0].fn, f3);
|
|
52
|
+
|
|
53
|
+
assert.equal(k2._posts.get('update').length, 1);
|
|
54
|
+
assert.equal(k2._posts.get('update')[0].fn, f1);
|
|
55
|
+
assert.equal(k2._posts.get('remove').length, 1);
|
|
56
|
+
assert.equal(k2._posts.get('remove')[0].fn, f3);
|
|
57
|
+
|
|
58
|
+
const k3 = k1.filter(hook => hook.query);
|
|
59
|
+
assert.equal(k3._pres.get('update').length, 1);
|
|
60
|
+
assert.equal(k3._pres.get('update')[0].fn, f2);
|
|
61
|
+
assert.ok(!k3._pres.has('remove'));
|
|
62
|
+
|
|
63
|
+
assert.equal(k3._posts.get('update').length, 1);
|
|
64
|
+
assert.equal(k3._posts.get('update')[0].fn, f2);
|
|
65
|
+
assert.ok(!k3._posts.has('remove'));
|
|
66
|
+
|
|
67
|
+
function f1() {}
|
|
68
|
+
function f2() {}
|
|
69
|
+
function f3() {}
|
|
70
|
+
});
|
|
71
|
+
});
|
package/test/post.test.js
CHANGED
|
@@ -27,10 +27,23 @@ describe('execPost', function() {
|
|
|
27
27
|
var f2 = function() {};
|
|
28
28
|
hooks.post('cook', f1);
|
|
29
29
|
hooks.post('cook', f2, true);
|
|
30
|
-
assert.strictEqual(hooks._posts.get('cook')[0], f2);
|
|
31
|
-
assert.strictEqual(hooks._posts.get('cook')[1], f1);
|
|
30
|
+
assert.strictEqual(hooks._posts.get('cook')[0].fn, f2);
|
|
31
|
+
assert.strictEqual(hooks._posts.get('cook')[1].fn, f1);
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
+
it('arbitrary options', function() {
|
|
35
|
+
const f1 = function() {};
|
|
36
|
+
const f2 = function() {};
|
|
37
|
+
hooks.post('cook', { foo: 'bar' }, f1);
|
|
38
|
+
hooks.post('cook', { bar: 'baz' }, f2, true);
|
|
39
|
+
assert.equal(hooks._posts.get('cook')[1].foo, 'bar');
|
|
40
|
+
assert.equal(hooks._posts.get('cook')[0].bar, 'baz');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('throws error if no function', function() {
|
|
44
|
+
assert.throws(() => hooks.post('test'), /got "undefined"/);
|
|
45
|
+
});
|
|
46
|
+
|
|
34
47
|
it('multiple posts', function(done) {
|
|
35
48
|
hooks.post('cook', function(eggs, callback) {
|
|
36
49
|
setTimeout(
|
package/test/pre.test.js
CHANGED
|
@@ -65,6 +65,19 @@ describe('execPre', function() {
|
|
|
65
65
|
assert.strictEqual(hooks._pres.get('cook')[1].fn, f1);
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
+
it('throws error if no function', function() {
|
|
69
|
+
assert.throws(() => hooks.pre('test'), /got "undefined"/);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('arbitrary options', function() {
|
|
73
|
+
const f1 = function() {};
|
|
74
|
+
const f2 = function() {};
|
|
75
|
+
hooks.pre('cook', { foo: 'bar' }, f1);
|
|
76
|
+
hooks.pre('cook', { bar: 'baz' }, f2, null, true);
|
|
77
|
+
assert.equal(hooks._pres.get('cook')[1].foo, 'bar');
|
|
78
|
+
assert.equal(hooks._pres.get('cook')[0].bar, 'baz');
|
|
79
|
+
});
|
|
80
|
+
|
|
68
81
|
it('handles async errors', function(done) {
|
|
69
82
|
var execed = {};
|
|
70
83
|
|
|
@@ -274,6 +287,26 @@ describe('execPre', function() {
|
|
|
274
287
|
done();
|
|
275
288
|
});
|
|
276
289
|
});
|
|
290
|
+
|
|
291
|
+
it('handles sync errors in pre if there are more hooks', function(done) {
|
|
292
|
+
var execed = {};
|
|
293
|
+
|
|
294
|
+
hooks.pre('cook', function() {
|
|
295
|
+
execed.first = true;
|
|
296
|
+
throw new Error('Oops!');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
hooks.pre('cook', function() {
|
|
300
|
+
execed.second = true;
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
hooks.execPre('cook', null, function(err) {
|
|
304
|
+
assert.ok(err);
|
|
305
|
+
assert.ok(execed.first);
|
|
306
|
+
assert.equal(err.message, 'Oops!');
|
|
307
|
+
done();
|
|
308
|
+
});
|
|
309
|
+
});
|
|
277
310
|
});
|
|
278
311
|
|
|
279
312
|
describe('execPreSync', function() {
|