kareem 2.3.5 → 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 +5 -0
- package/index.js +71 -17
- package/package.json +1 -1
- 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
package/index.js
CHANGED
|
@@ -5,6 +5,22 @@ 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;
|
|
@@ -17,6 +33,7 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
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
39
|
return nextTick(function() {
|
|
@@ -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
|
];
|
|
@@ -75,7 +96,7 @@ Kareem.prototype.execPre = function(name, context, args, callback) {
|
|
|
75
96
|
return;
|
|
76
97
|
} else {
|
|
77
98
|
return nextTick(function() {
|
|
78
|
-
callback(
|
|
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
|
|
|
@@ -153,6 +178,13 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
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
|
}
|
|
@@ -203,7 +242,11 @@ Kareem.prototype.execPost = function(name, context, args, options, callback) {
|
|
|
203
242
|
}
|
|
204
243
|
|
|
205
244
|
if (isPromiseLike(maybePromiseLike)) {
|
|
206
|
-
return maybePromiseLike.then(() => _cb(), err => _cb(err));
|
|
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) {
|
|
@@ -223,8 +266,13 @@ Kareem.prototype.execPostSync = function(name, context, args) {
|
|
|
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,9 +282,9 @@ 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
|
|
|
@@ -252,7 +300,7 @@ function _handleWrapError(instance, error, name, context, args, options, callbac
|
|
|
252
300
|
|
|
253
301
|
Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
254
302
|
const lastArg = (args.length > 0 ? args[args.length - 1] : null);
|
|
255
|
-
|
|
303
|
+
let argsWithoutCb = Array.from(args);
|
|
256
304
|
typeof lastArg === 'function' && argsWithoutCb.pop();
|
|
257
305
|
const _this = this;
|
|
258
306
|
|
|
@@ -260,7 +308,7 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
260
308
|
const checkForPromise = options.checkForPromise;
|
|
261
309
|
|
|
262
310
|
this.execPre(name, context, args, function(error) {
|
|
263
|
-
if (error) {
|
|
311
|
+
if (error && !(error instanceof Kareem.skipWrappedFunction)) {
|
|
264
312
|
const numCallbackParams = options.numCallbackParams || 0;
|
|
265
313
|
const errorArgs = options.contextParameter ? [context] : [];
|
|
266
314
|
for (var i = errorArgs.length; i < numCallbackParams; ++i) {
|
|
@@ -272,10 +320,16 @@ Kareem.prototype.wrap = function(name, fn, context, args, options) {
|
|
|
272
320
|
|
|
273
321
|
const numParameters = fn.length;
|
|
274
322
|
let ret;
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
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
|
+
}
|
|
279
333
|
}
|
|
280
334
|
|
|
281
335
|
if (checkForPromise) {
|
package/package.json
CHANGED
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
|
});
|