require-in-the-middle
Advanced tools
Comparing version 3.1.0 to 4.0.0
87
index.js
@@ -6,2 +6,3 @@ 'use strict' | ||
var resolve = require('resolve') | ||
var debug = require('debug')('require-in-the-middle') | ||
var parse = require('module-details-from-path') | ||
@@ -11,2 +12,5 @@ | ||
// 'foo/bar.js' or 'foo/bar/index.js' => 'foo/bar' | ||
var normalize = /([/\\]index)?(\.js)?$/ | ||
function Hook (modules, options, onrequire) { | ||
@@ -38,2 +42,4 @@ if (!(this instanceof Hook)) return new Hook(modules, options, onrequire) | ||
debug('registering require hook') | ||
this._require = Module.prototype.require = function (request) { | ||
@@ -44,2 +50,3 @@ if (self._unhooked) { | ||
// abort and pass the request onwards to the original require | ||
debug('ignoring require call - module is soft-unhooked') | ||
return self._origRequire.apply(this, arguments) | ||
@@ -50,6 +57,9 @@ } | ||
var core = filename.indexOf(path.sep) === -1 | ||
var name, basedir | ||
var moduleName, basedir | ||
debug('processing %s module require(\'%s\'): %s', core ? 'core' : 'non-core', request, filename) | ||
// return known patched modules immediately | ||
if (self.cache.hasOwnProperty(filename)) { | ||
debug('returning already patched cached module: %s', filename) | ||
return self.cache[filename] | ||
@@ -68,3 +78,6 @@ } | ||
// If it's already patched, just return it as-is. | ||
if (patched) return exports | ||
if (patched) { | ||
debug('module is in the process of being patched already - ignoring: %s', filename) | ||
return exports | ||
} | ||
@@ -76,25 +89,49 @@ // The module has already been loaded, | ||
if (core) { | ||
if (modules && modules.indexOf(filename) === -1) return exports // abort if module name isn't on whitelist | ||
name = filename | ||
if (modules && modules.indexOf(filename) === -1) { | ||
debug('ignoring core module not on whitelist: %s', filename) | ||
return exports // abort if module name isn't on whitelist | ||
} | ||
moduleName = filename | ||
} else { | ||
var stat = parse(filename) | ||
if (!stat) return exports // abort if filename could not be parsed | ||
name = stat.name | ||
if (!stat) { | ||
debug('could not parse filename: %s', filename) | ||
return exports // abort if filename could not be parsed | ||
} | ||
moduleName = stat.name | ||
basedir = stat.basedir | ||
if (modules && modules.indexOf(name) === -1) return exports // abort if module name isn't on whitelist | ||
var fullModuleName = resolveModuleName(stat) | ||
// figure out if this is the main module file, or a file inside the module | ||
try { | ||
var res = resolve.sync(name, { basedir: basedir }) | ||
} catch (e) { | ||
return exports // abort if module could not be resolved (e.g. no main in package.json and no index.js file) | ||
debug('resolved filename to module: %s (request: %s, resolved: %s, basedir: %s)', moduleName, request, fullModuleName, basedir) | ||
// Ex: require('foo/lib/../bar.js') | ||
// moduleName = 'foo' | ||
// fullModuleName = 'foo/bar' | ||
if (modules && modules.indexOf(moduleName) === -1) { | ||
if (modules.indexOf(fullModuleName) === -1) return exports // abort if module name isn't on whitelist | ||
// if we get to this point, it means that we're requiring a whitelisted sub-module | ||
moduleName = fullModuleName | ||
} else { | ||
// figure out if this is the main module file, or a file inside the module | ||
try { | ||
var res = resolve.sync(moduleName, { basedir: basedir }) | ||
} catch (e) { | ||
debug('could not resolve module: %s', moduleName) | ||
return exports // abort if module could not be resolved (e.g. no main in package.json and no index.js file) | ||
} | ||
if (res !== filename) { | ||
// this is a module-internal file | ||
if (options.internals) { | ||
// use the module-relative path to the file, prefixed by original module name | ||
moduleName = moduleName + path.sep + path.relative(basedir, filename) | ||
debug('preparing to process require of internal file: %s', moduleName) | ||
} else { | ||
debug('ignoring require of non-main module file: %s', res) | ||
return exports // abort if not main module file | ||
} | ||
} | ||
} | ||
if (res !== filename) { | ||
// this is a module-internal file | ||
if (options.internals) { | ||
// use the module-relative path to the file, prefixed by original module name | ||
name = name + path.sep + path.relative(basedir, filename) | ||
} else return exports // abort if not main module file | ||
} | ||
} | ||
@@ -107,5 +144,7 @@ | ||
self.cache[filename] = exports | ||
self.cache[filename] = onrequire(exports, name, basedir) | ||
debug('calling require hook: %s', moduleName) | ||
self.cache[filename] = onrequire(exports, moduleName, basedir) | ||
} | ||
debug('returning module: %s', moduleName) | ||
return self.cache[filename] | ||
@@ -119,3 +158,11 @@ } | ||
Module.prototype.require = this._origRequire | ||
debug('unhook successful') | ||
} else { | ||
debug('unhook unsuccessful') | ||
} | ||
} | ||
function resolveModuleName (stat) { | ||
const normalizedPath = path.sep !== '/' ? stat.path.split(path.sep).join('/') : stat.path | ||
return path.posix.join(stat.name, normalizedPath).replace(normalize, '') | ||
} |
{ | ||
"name": "require-in-the-middle", | ||
"version": "3.1.0", | ||
"version": "4.0.0", | ||
"description": "Module to hook into the Node.js require function", | ||
"main": "index.js", | ||
"dependencies": { | ||
"debug": "^4.1.1", | ||
"module-details-from-path": "^1.0.3", | ||
"resolve": "^1.5.0" | ||
"resolve": "^1.10.0" | ||
}, | ||
@@ -14,7 +15,7 @@ "devDependencies": { | ||
"roundround": "^0.2.0", | ||
"standard": "^11.0.0", | ||
"tape": "^4.9.0" | ||
"standard": "^12.0.1", | ||
"tape": "^4.10.1" | ||
}, | ||
"scripts": { | ||
"test": "standard && tape test/test.js" | ||
"test": "standard && tape test/*.js" | ||
}, | ||
@@ -44,5 +45,5 @@ "repository": { | ||
"coordinates": [ | ||
55.777202, | ||
12.592041 | ||
55.6773705, | ||
12.5614183 | ||
] | ||
} |
@@ -48,3 +48,4 @@ # require-in-the-middle | ||
trigger a call of the `onrequire` callback. If specified, this must be the | ||
first argument. | ||
first argument. Both regular modules (e.g. `react-dom`) and | ||
sub-modules (e.g. `react-dom/server`) can be specified in the array. | ||
- `options` <Object> An optional object containing fields that change when the | ||
@@ -51,0 +52,0 @@ `onrequire` callback is called. If specified, this must be the second |
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
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
10616
132
80
3
+ Addeddebug@^4.1.1
+ Addeddebug@4.3.7(transitive)
+ Addedms@2.1.3(transitive)
Updatedresolve@^1.10.0