Comparing version 2.4.1 to 2.5.0
206
index.js
'use strict'; | ||
/** | ||
* Create a new instance | ||
*/ | ||
function Kareem() { | ||
@@ -24,2 +27,10 @@ this._pres = new Map(); | ||
/** | ||
* Execute all "pre" hooks for "name" | ||
* @param {String} name The hook name to execute | ||
* @param {*} context Overwrite the "this" for the hook | ||
* @param {Array|Function} args Optional arguments or directly the callback | ||
* @param {Function} [callback] The callback to call when executing all hooks are finished | ||
* @returns {void} | ||
*/ | ||
Kareem.prototype.execPre = function(name, context, args, callback) { | ||
@@ -30,10 +41,10 @@ if (arguments.length === 3) { | ||
} | ||
var pres = this._pres.get(name) || []; | ||
var numPres = pres.length; | ||
var numAsyncPres = pres.numAsync || 0; | ||
var currentPre = 0; | ||
var asyncPresLeft = numAsyncPres; | ||
var done = false; | ||
var $args = args; | ||
var shouldSkipWrappedFunction = null; | ||
const pres = this._pres.get(name) || []; | ||
const numPres = pres.length; | ||
const numAsyncPres = pres.numAsync || 0; | ||
let currentPre = 0; | ||
let asyncPresLeft = numAsyncPres; | ||
let done = false; | ||
const $args = args; | ||
let shouldSkipWrappedFunction = null; | ||
@@ -46,10 +57,10 @@ if (!numPres) { | ||
var next = function() { | ||
function next() { | ||
if (currentPre >= numPres) { | ||
return; | ||
} | ||
var pre = pres[currentPre]; | ||
const pre = pres[currentPre]; | ||
if (pre.isAsync) { | ||
var args = [ | ||
const args = [ | ||
decorateNextFn(_next), | ||
@@ -76,5 +87,5 @@ decorateNextFn(function(error) { | ||
} else if (pre.fn.length > 0) { | ||
var args = [decorateNextFn(_next)]; | ||
var _args = arguments.length >= 2 ? arguments : [null].concat($args); | ||
for (var i = 1; i < _args.length; ++i) { | ||
const args = [decorateNextFn(_next)]; | ||
const _args = arguments.length >= 2 ? arguments : [null].concat($args); | ||
for (let i = 1; i < _args.length; ++i) { | ||
args.push(_args[i]); | ||
@@ -110,3 +121,3 @@ } | ||
} | ||
}; | ||
} | ||
@@ -141,7 +152,14 @@ next.apply(null, [null].concat(args)); | ||
/** | ||
* Execute all "pre" hooks for "name" synchronously | ||
* @param {String} name The hook name to execute | ||
* @param {*} context Overwrite the "this" for the hook | ||
* @param {Array} [args] Apply custom arguments to the hook | ||
* @returns {void} | ||
*/ | ||
Kareem.prototype.execPreSync = function(name, context, args) { | ||
var pres = this._pres.get(name) || []; | ||
var numPres = pres.length; | ||
const pres = this._pres.get(name) || []; | ||
const numPres = pres.length; | ||
for (var i = 0; i < numPres; ++i) { | ||
for (let i = 0; i < numPres; ++i) { | ||
pres[i].fn.apply(context, args || []); | ||
@@ -151,2 +169,11 @@ } | ||
/** | ||
* Execute all "post" hooks for "name" | ||
* @param {String} name The hook name to execute | ||
* @param {*} context Overwrite the "this" for the hook | ||
* @param {Array|Function} args Apply custom arguments to the hook | ||
* @param {*} options Optional options or directly the callback | ||
* @param {Function} [callback] The callback to call when executing all hooks are finished | ||
* @returns {void} | ||
*/ | ||
Kareem.prototype.execPost = function(name, context, args, options, callback) { | ||
@@ -157,7 +184,7 @@ if (arguments.length < 5) { | ||
} | ||
var posts = this._posts.get(name) || []; | ||
var numPosts = posts.length; | ||
var currentPost = 0; | ||
const posts = this._posts.get(name) || []; | ||
const numPosts = posts.length; | ||
let currentPost = 0; | ||
var firstError = null; | ||
let firstError = null; | ||
if (options && options.error) { | ||
@@ -173,8 +200,8 @@ firstError = options.error; | ||
var next = function() { | ||
var post = posts[currentPost].fn; | ||
var numArgs = 0; | ||
var argLength = args.length; | ||
var newArgs = []; | ||
for (var i = 0; i < argLength; ++i) { | ||
function next() { | ||
const post = posts[currentPost].fn; | ||
let numArgs = 0; | ||
const argLength = args.length; | ||
const newArgs = []; | ||
for (let i = 0; i < argLength; ++i) { | ||
numArgs += args[i] && args[i]._kareemIgnore ? 0 : 1; | ||
@@ -187,3 +214,3 @@ if (!args[i] || !args[i]._kareemIgnore) { | ||
if (firstError) { | ||
if (post.length === numArgs + 2) { | ||
if (isErrorHandlingMiddleware(posts[currentPost], numArgs)) { | ||
const _cb = decorateNextFn(function(error) { | ||
@@ -235,3 +262,3 @@ if (error) { | ||
if (post.length === numArgs + 2) { | ||
if (isErrorHandlingMiddleware(posts[currentPost], numArgs)) { | ||
// Skip error handlers if no error | ||
@@ -275,3 +302,3 @@ if (++currentPost >= numPosts) { | ||
} | ||
}; | ||
} | ||
@@ -281,2 +308,9 @@ next(); | ||
/** | ||
* Execute all "post" hooks for "name" synchronously | ||
* @param {String} name The hook name to execute | ||
* @param {*} context Overwrite the "this" for the hook | ||
* @param {Array|Function} args Apply custom arguments to the hook | ||
* @returns {Array} The used arguments | ||
*/ | ||
Kareem.prototype.execPostSync = function(name, context, args) { | ||
@@ -296,10 +330,16 @@ const posts = this._posts.get(name) || []; | ||
/** | ||
* Create a synchronous wrapper for "fn" | ||
* @param {String} name The name of the hook | ||
* @param {Function} fn The function to wrap | ||
* @returns {Function} The wrapped function | ||
*/ | ||
Kareem.prototype.createWrapperSync = function(name, fn) { | ||
var kareem = this; | ||
const _this = this; | ||
return function syncWrapper() { | ||
kareem.execPreSync(name, this, arguments); | ||
_this.execPreSync(name, this, arguments); | ||
var toReturn = fn.apply(this, arguments); | ||
const toReturn = fn.apply(this, arguments); | ||
const result = kareem.execPostSync(name, this, [toReturn]); | ||
const result = _this.execPostSync(name, this, [toReturn]); | ||
@@ -320,5 +360,15 @@ return result[0]; | ||
/** | ||
* Executes pre hooks, followed by the wrapped function, followed by post hooks. | ||
* @param {String} name The name of the hook | ||
* @param {Function} fn The function for the hook | ||
* @param {*} context Overwrite the "this" for the hook | ||
* @param {Array} args Apply custom arguments to the hook | ||
* @param {Object} [options] | ||
* @param {Boolean} [options.checkForPromise] | ||
* @returns {void} | ||
*/ | ||
Kareem.prototype.wrap = function(name, fn, context, args, options) { | ||
const lastArg = (args.length > 0 ? args[args.length - 1] : null); | ||
let argsWithoutCb = Array.from(args); | ||
const argsWithoutCb = Array.from(args); | ||
typeof lastArg === 'function' && argsWithoutCb.pop(); | ||
@@ -334,3 +384,3 @@ const _this = this; | ||
const errorArgs = options.contextParameter ? [context] : []; | ||
for (var i = errorArgs.length; i < numCallbackParams; ++i) { | ||
for (let i = errorArgs.length; i < numCallbackParams; ++i) { | ||
errorArgs.push(null); | ||
@@ -396,2 +446,7 @@ } | ||
/** | ||
* Filter current instance for something specific and return the filtered clone | ||
* @param {Function} fn The filter function | ||
* @returns {Kareem} The cloned and filtered instance | ||
*/ | ||
Kareem.prototype.filter = function(fn) { | ||
@@ -433,2 +488,7 @@ const clone = this.clone(); | ||
/** | ||
* Check for a "name" to exist either in pre or post hooks | ||
* @param {String} name The name of the hook | ||
* @returns {Boolean} "true" if found, "false" otherwise | ||
*/ | ||
Kareem.prototype.hasHooks = function(name) { | ||
@@ -438,4 +498,12 @@ return this._pres.has(name) || this._posts.has(name); | ||
/** | ||
* Create a Wrapper for "fn" on "name" and return the wrapped function | ||
* @param {String} name The name of the hook | ||
* @param {Function} fn The function to wrap | ||
* @param {*} context Overwrite the "this" for the hook | ||
* @param {Object} [options] | ||
* @returns {Function} The wrapped function | ||
*/ | ||
Kareem.prototype.createWrapper = function(name, fn, context, options) { | ||
var _this = this; | ||
const _this = this; | ||
if (!this.hasHooks(name)) { | ||
@@ -449,3 +517,3 @@ // Fast path: if there's no hooks for this function, just return the | ||
return function() { | ||
var _context = context || this; | ||
const _context = context || this; | ||
_this.wrap(name, fn, _context, Array.from(arguments), options); | ||
@@ -455,2 +523,11 @@ }; | ||
/** | ||
* Register a new hook for "pre" | ||
* @param {String} name The name of the hook | ||
* @param {Boolean} [isAsync] | ||
* @param {Function} fn The function to register for "name" | ||
* @param {never} error Unused | ||
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook | ||
* @returns {Kareem} | ||
*/ | ||
Kareem.prototype.pre = function(name, isAsync, fn, error, unshift) { | ||
@@ -487,4 +564,12 @@ let options = {}; | ||
/** | ||
* Register a new hook for "post" | ||
* @param {String} name The name of the hook | ||
* @param {Object} [options] | ||
* @param {Function} fn The function to register for "name" | ||
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook | ||
* @returns {Kareem} | ||
*/ | ||
Kareem.prototype.post = function(name, options, fn, unshift) { | ||
const hooks = this._posts.get(name) || []; | ||
const posts = this._posts.get(name) || []; | ||
@@ -502,14 +587,18 @@ if (typeof options === 'function') { | ||
if (unshift) { | ||
hooks.unshift(Object.assign({}, options, { fn: fn })); | ||
posts.unshift(Object.assign({}, options, { fn: fn })); | ||
} else { | ||
hooks.push(Object.assign({}, options, { fn: fn })); | ||
posts.push(Object.assign({}, options, { fn: fn })); | ||
} | ||
this._posts.set(name, hooks); | ||
this._posts.set(name, posts); | ||
return this; | ||
}; | ||
/** | ||
* Clone the current instance | ||
* @returns {Kareem} The cloned instance | ||
*/ | ||
Kareem.prototype.clone = function() { | ||
const n = new Kareem(); | ||
for (let key of this._pres.keys()) { | ||
for (const key of this._pres.keys()) { | ||
const clone = this._pres.get(key).slice(); | ||
@@ -519,3 +608,3 @@ clone.numAsync = this._pres.get(key).numAsync; | ||
} | ||
for (let key of this._posts.keys()) { | ||
for (const key of this._posts.keys()) { | ||
n._posts.set(key, this._posts.get(key).slice()); | ||
@@ -527,7 +616,13 @@ } | ||
/** | ||
* Merge "other" into self or "clone" | ||
* @param {Kareem} other The instance to merge with | ||
* @param {Kareem} [clone] The instance to merge onto (if not defined, using "this") | ||
* @returns {Kareem} The merged instance | ||
*/ | ||
Kareem.prototype.merge = function(other, clone) { | ||
clone = arguments.length === 1 ? true : clone; | ||
var ret = clone ? this.clone() : this; | ||
const ret = clone ? this.clone() : this; | ||
for (let key of other._pres.keys()) { | ||
for (const key of other._pres.keys()) { | ||
const sourcePres = ret._pres.get(key) || []; | ||
@@ -542,3 +637,3 @@ const deduplicated = other._pres.get(key). | ||
} | ||
for (let key of other._posts.keys()) { | ||
for (const key of other._posts.keys()) { | ||
const sourcePosts = ret._posts.get(key) || []; | ||
@@ -571,4 +666,4 @@ const deduplicated = other._posts.get(key). | ||
function decorateNextFn(fn) { | ||
var called = false; | ||
var _this = this; | ||
let called = false; | ||
const _this = this; | ||
return function() { | ||
@@ -586,6 +681,13 @@ // Ensure this function can only be called once | ||
const nextTick = typeof process === 'object' && process !== null && process.nextTick || function nextTick(cb) { | ||
setTimeout(cb, 0); | ||
const nextTick = typeof process === 'object' && process !== null && process.nextTick || function nextTick(cb) { | ||
setTimeout(cb, 0); | ||
}; | ||
function isErrorHandlingMiddleware(post, numArgs) { | ||
if (post.errorHandler) { | ||
return true; | ||
} | ||
return post.fn.length === numArgs + 2; | ||
} | ||
module.exports = Kareem; |
{ | ||
"name": "kareem", | ||
"version": "2.4.1", | ||
"version": "2.5.0", | ||
"description": "Next-generation take on pre/post function hooks", | ||
@@ -9,3 +9,4 @@ "main": "index.js", | ||
"test": "mocha ./test/*", | ||
"test-travis": "nyc mocha ./test/*" | ||
"test-coverage": "nyc --reporter lcov mocha ./test/*", | ||
"docs": "node ./docs.js" | ||
}, | ||
@@ -17,6 +18,5 @@ "repository": { | ||
"devDependencies": { | ||
"@masteringjs/eslint-config": "0.0.1", | ||
"acquit": "1.x", | ||
"acquit-ignore": "0.1.x", | ||
"eslint": "8.15.0", | ||
"acquit-ignore": "0.2.x", | ||
"eslint": "8.20.0", | ||
"mocha": "9.2.0", | ||
@@ -26,3 +26,9 @@ "nyc": "15.1.0" | ||
"author": "Valeri Karpov <val@karpov.io>", | ||
"license": "Apache-2.0" | ||
"license": "Apache-2.0", | ||
"files": [ | ||
"index.js" | ||
], | ||
"engines": { | ||
"node": ">=12.0.0" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
5
0
38927
4
583
1