New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mendel-resolver

Package Overview
Dependencies
Maintainers
4
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mendel-resolver - npm Package Compare versions

Comparing version 4.0.0-alpha.0 to 4.0.0-alpha.1

.nyc_output/10f6e25e-1fdc-43b8-a859-6eb49c3d7d8b.json

20

bisource-resolver.js

@@ -15,4 +15,7 @@ const VariationalModuleResolver = require('./variational-resolver');

resolve(moduleName) {
const cacheKey = CachedBisourceVariationalResolver.isNodeModule(moduleName) ?
moduleName : path.resolve(this.basedir, moduleName);
const cacheKey = CachedBisourceVariationalResolver.isNodeModule(
moduleName
)
? moduleName
: path.resolve(this.basedir, moduleName);

@@ -22,4 +25,3 @@ if (this._cache.has(cacheKey))

return super.resolve(moduleName)
.then(deps => {
return super.resolve(moduleName).then((deps) => {
this._cache.set(cacheKey, deps);

@@ -34,7 +36,7 @@ return deps;

return Promise.resolve()
.then(() => this.biSourceHas(filePath))
.then(result => {
if (result) return filePath;
return super.fileExists(filePath);
});
.then(() => this.biSourceHas(filePath))
.then((result) => {
if (result) return filePath;
return super.fileExists(filePath);
});
}

@@ -41,0 +43,0 @@ }

const path = require('path');
const {stat, readFile} = require('fs');
const { stat, readFile } = require('fs');

@@ -16,7 +16,7 @@ function withPrefix(path) {

constructor({
cwd=process.cwd(),
basedir=process.cwd(),
extensions=['.js'],
runtimes=['main', 'module', 'browser'],
recordPackageJson=false,
cwd = process.cwd(),
basedir = process.cwd(),
extensions = ['.js'],
runtimes = ['main', 'module', 'browser'],
recordPackageJson = false,
} = {}) {

@@ -40,3 +40,3 @@ this.extensions = extensions;

static pReadFile(filePath, options={}) {
static pReadFile(filePath, options = {}) {
return new Promise((resolve, reject) => {

@@ -50,4 +50,15 @@ readFile(filePath, options, (err, result) => {

/***
* isNodeModule refers to detecting npm/yarn/pnpm modules.
* It does not check for 'node_modules' because its input is
* the string in `require('mod')` or `import * from 'mod'`.
* If it is not one of the following, it is a module:
* * ./relative/path
* * ../another/relative/path
* * /absolute/path
* * C:\absolute\windows\path
* * C:/another/windows/path
***/
static isNodeModule(name) {
return !/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[\\\/])/.test(name);
return !/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[\\/])/.test(name);
}

@@ -66,43 +77,61 @@

const moduleAbsPath = path.resolve(this.basedir, moduleName);
promise = this.resolveFile(moduleAbsPath)
.catch(() => this.resolveDir(moduleAbsPath));
promise = this.resolveFile(moduleAbsPath).catch(() =>
this.resolveDir(moduleAbsPath)
);
} else {
promise = this.resolveNodeModules(moduleName);
}
return promise
// Post process
.then((deps) => {
// Make the path relative to the `basedir`.
Object.keys(deps)
.filter(rt => deps[rt])
.forEach(rt => {
if (typeof deps[rt] === 'string') {
// It can be module name without real path for default
// node modules (like "path")
if (deps[rt].indexOf('/') < 0) return;
deps[rt] = withPrefix(path.relative(this.cwd, deps[rt]));
} else if (typeof deps[rt] === 'object') {
const rtDep = deps[rt];
Object.keys(rtDep)
.filter(key => rtDep[key])
.forEach(depKey => {
const newKey = depKey.indexOf('/') < 0 ? depKey :
withPrefix(path.relative(this.cwd, depKey));
const newValue = rtDep[depKey].indexOf('/') < 0 ?
rtDep[depKey] :
withPrefix(path.relative(this.cwd, rtDep[depKey]));
delete rtDep[depKey];
rtDep[newKey] = newValue;
});
}
});
return deps;
})
.catch(() => {
throw new Error(`${moduleName} failed to resolve.`);
});
return (
promise
// Post process
.then((deps) => {
// Make the path relative to the `basedir`.
Object.keys(deps)
.filter((rt) => deps[rt])
.forEach((rt) => {
if (typeof deps[rt] === 'string') {
// It can be module name without real path for default
// node modules (like "path")
if (deps[rt].indexOf('/') < 0) return;
deps[rt] = withPrefix(
path.relative(this.cwd, deps[rt])
);
} else if (typeof deps[rt] === 'object') {
const rtDep = deps[rt];
Object.keys(rtDep)
.filter((key) => rtDep[key])
.forEach((depKey) => {
const newKey =
depKey.indexOf('/') < 0
? depKey
: withPrefix(
path.relative(
this.cwd,
depKey
)
);
const newValue =
rtDep[depKey].indexOf('/') < 0
? rtDep[depKey]
: withPrefix(
path.relative(
this.cwd,
rtDep[depKey]
)
);
delete rtDep[depKey];
rtDep[newKey] = newValue;
});
}
});
return deps;
})
.catch(() => {
throw new Error(`${moduleName} failed to resolve.`);
})
);
}
fileExists(filePath) {
return ModuleResolver.pStat(filePath).then(stat => {
return ModuleResolver.pStat(filePath).then((stat) => {
if (stat.isFile() || stat.isFIFO()) return filePath;

@@ -118,7 +147,7 @@ throw new Error({

let promise = this.fileExists(moduleName);
this.extensions.forEach(ext => {
this.extensions.forEach((ext) => {
promise = promise.catch(() => this.fileExists(moduleName + ext));
});
return promise.then(filePath => {
return promise.then((filePath) => {
const reduced = this.runtimes.reduce((reduced, name) => {

@@ -133,4 +162,5 @@ reduced[name] = filePath;

resolveDir(moduleName) {
return this.resolvePackageJson(moduleName)
.catch(() => this.resolveFile(path.join(moduleName, 'index')));
return this.resolvePackageJson(moduleName).catch(() =>
this.resolveFile(path.join(moduleName, 'index'))
);
}

@@ -140,13 +170,14 @@

return ModuleResolver.pStat(dirName)
.then(stat => {
if (stat.isFile()) return ModuleResolver.pReadFile(dirName, 'utf8');
throw new Error({
message: `${dirName} does not have package.json as a File.`,
code: 'ENOENT',
.then((stat) => {
if (stat.isFile())
return ModuleResolver.pReadFile(dirName, 'utf8');
throw new Error({
message: `${dirName} does not have package.json as a File.`,
code: 'ENOENT',
});
})
.then((packageStr) => {
// if fails to parse, we will hit catch
return JSON.parse(packageStr);
});
})
.then((packageStr) => {
// if fails to parse, we will hit catch
return JSON.parse(packageStr);
});
}

@@ -157,69 +188,71 @@

return this.readPackageJson(packagePath)
.then(pkg => {
if (this.runtimes.every(name => !pkg[name]))
throw new Error('package.json without "main"');
.then((pkg) => {
if (this.runtimes.every((name) => !pkg[name]))
throw new Error('package.json without "main"');
const consider = new Map();
// A "package.json" can have below data structure
// {
// "main": "./foo",
// "browser": {
// "./foo": "./bar",
// "moduleA": "moduleB",
// "./baz": false,
// "./abc": "./xyz.js"
// }
// }
// In case of the main, it should resolve to either "./foo.js" or "./foo/index.js"
// In case of browser runtime, it should anything that requires "./foo" should map to "./bar.js" or "./bar/index.js"
this.runtimes.filter(name => pkg[name])
.forEach(name => {
if (typeof pkg[name] === 'string') consider.set(pkg[name]);
else if (typeof pkg[name] === 'object') {
Object.keys(pkg[name]).forEach(fromPath => {
consider.set(fromPath);
if (typeof pkg[name][fromPath] === 'string')
consider.set(pkg[name][fromPath]);
const consider = new Map();
// A "package.json" can have below data structure
// {
// "main": "./foo",
// "browser": {
// "./foo": "./bar",
// "moduleA": "moduleB",
// "./baz": false,
// "./abc": "./xyz.js"
// }
// }
// In case of the main, it should resolve to either "./foo.js" or "./foo/index.js"
// In case of browser runtime, it should anything that requires "./foo" should map to "./bar.js" or "./bar/index.js"
this.runtimes
.filter((name) => pkg[name])
.forEach((name) => {
if (typeof pkg[name] === 'string')
consider.set(pkg[name]);
else if (typeof pkg[name] === 'object') {
Object.keys(pkg[name]).forEach((fromPath) => {
consider.set(fromPath);
if (typeof pkg[name][fromPath] === 'string')
consider.set(pkg[name][fromPath]);
});
}
});
}
});
const furtherPaths = Array.from(consider.keys());
const furtherResolve = furtherPaths.map(depPath => {
let promise = this.resolve(path.join(moduleName, depPath));
if (ModuleResolver.isNodeModule(depPath))
promise = promise.catch(() => this.resolve(depPath));
return promise.catch(() => false);
});
return Promise.all(furtherResolve).then(resolves => {
if (resolves.every(resolve => resolve === false))
throw new Error('None of the path declared resolves');
resolves.forEach((resolved, index) => {
consider.set(furtherPaths[index], resolved);
const furtherPaths = Array.from(consider.keys());
const furtherResolve = furtherPaths.map((depPath) => {
let promise = this.resolve(path.join(moduleName, depPath));
if (ModuleResolver.isNodeModule(depPath))
promise = promise.catch(() => this.resolve(depPath));
return promise.catch(() => false);
});
return {deps: consider, pkg};
});
})
.then(({pkg, deps}) => {
const resolved = this.runtimes.reduce((reduced, name) => {
const runtimeVal = pkg[name] || pkg.main;
if (deps.has(runtimeVal))
reduced[name] = deps.get(runtimeVal)[name];
else if (typeof runtimeVal === 'object') {
const obj = reduced[name] = {};
Object.keys(runtimeVal).forEach(key => {
const val = runtimeVal[key];
if (!deps.get(key) && !deps.get(val)) return;
if (!deps.get(key) && deps.get(val))
return obj[key] = deps.get(val)[name];
if (deps.get(key) && typeof val !== 'string')
return obj[deps.get(key)[name]] = false;
obj[deps.get(key)[name]] = deps.get(val)[name];
return Promise.all(furtherResolve).then((resolves) => {
if (resolves.every((resolve) => resolve === false))
throw new Error('None of the path declared resolves');
resolves.forEach((resolved, index) => {
consider.set(furtherPaths[index], resolved);
});
}
return reduced;
}, {});
return { deps: consider, pkg };
});
})
.then(({ pkg, deps }) => {
const resolved = this.runtimes.reduce((reduced, name) => {
const runtimeVal = pkg[name] || pkg.main;
if (deps.has(runtimeVal))
reduced[name] = deps.get(runtimeVal)[name];
else if (typeof runtimeVal === 'object') {
const obj = (reduced[name] = {});
Object.keys(runtimeVal).forEach((key) => {
const val = runtimeVal[key];
if (!deps.get(key) && !deps.get(val)) return;
if (!deps.get(key) && deps.get(val))
return (obj[key] = deps.get(val)[name]);
if (deps.get(key) && typeof val !== 'string')
return (obj[deps.get(key)[name]] = false);
obj[deps.get(key)[name]] = deps.get(val)[name];
});
}
return reduced;
}, {});
if (this.recordPackageJson) resolved.packageJson = packagePath;
return resolved;
});
if (this.recordPackageJson) resolved.packageJson = packagePath;
return resolved;
});
}

@@ -232,11 +265,16 @@

promise = promise.catch(() => {
return ModuleResolver.pStat(nodeModulePath).then(stat => {
if (!stat.isDirectory()) throw new Error({
message: `${nodeModulePath} is not a directory.`,
code: 'ENOENT',
});
return ModuleResolver.pStat(nodeModulePath).then((stat) => {
if (!stat.isDirectory())
throw new Error({
message: `${nodeModulePath} is not a directory.`,
code: 'ENOENT',
});
const moduleFullPath = path.join(nodeModulePath, moduleName);
return this.resolveFile(moduleFullPath)
.catch(() => this.resolveDir(moduleFullPath));
const moduleFullPath = path.join(
nodeModulePath,
moduleName
);
return this.resolveFile(moduleFullPath).catch(() =>
this.resolveDir(moduleFullPath)
);
});

@@ -264,3 +302,3 @@ });

const splitRe = process.platform === 'win32' ? /[\/\\]/ : /\/+/;
const splitRe = process.platform === 'win32' ? /[/\\]/ : /\/+/;
const parts = start.split(splitRe);

@@ -271,6 +309,12 @@

if (modules === parts[i]) continue;
dirs.push(prefix + path.join(path.join.apply(path, parts.slice(0, i + 1)), modules));
dirs.push(
prefix +
path.join(
path.join.apply(path, parts.slice(0, i + 1)),
modules
)
);
}
if (process.platform === 'win32'){
if (process.platform === 'win32') {
dirs[dirs.length - 1] = dirs[dirs.length - 1].replace(':', ':\\');

@@ -277,0 +321,0 @@ }

{
"name": "mendel-resolver",
"version": "4.0.0-alpha.0",
"version": "4.0.0-alpha.1",
"description": "node-resolve + browser-resolve that is promise based in an OOP fashion",
"main": "index.js",
"scripts": {
"test": "tap test"
"test": "tap test/*.js --coverage-map=../../.tap.coverage.map.js --no-check-coverage"
},

@@ -13,7 +13,7 @@ "author": "Stephan Lee <stephanwlee@gmail.com>",

"type": "git",
"url": "https://github.com/yahoo/mendel"
"url": "https://github.com/considerinc/mendel"
},
"dependencies": {
"debug": "^4.3.4",
"mendel-development": "^4.0.0-alpha.0"
"mendel-development": "^4.0.0-alpha.1"
},

@@ -23,3 +23,3 @@ "devDependencies": {

},
"gitHead": "e91812ab9f13c60d431be5ce5e024d3a68073f42"
"gitHead": "6e24d114f4ff273753654df1aa5e6c124f626e25"
}

@@ -35,3 +35,3 @@ const ModuleResolver = require('./index');

if (match) {
const absChain = match.variation.chain.map(varDir => {
const absChain = match.variation.chain.map((varDir) => {
return path.resolve(path.resolve(this.projectRoot, varDir));

@@ -56,3 +56,3 @@ });

isNonProjectSource(modulePath) {
return this.varDirs.every(dir => {
return this.varDirs.every((dir) => {
return modulePath.indexOf(dir) === -1;

@@ -65,3 +65,3 @@ });

this.isBasePath(modulePath) ||
isNodeModule(modulePath) ||
isNodeModuleFile(modulePath) ||
this.isNonProjectSource(modulePath)

@@ -72,3 +72,2 @@ ) {

const moduleId = this.getModuleId(modulePath);

@@ -87,18 +86,25 @@ return this.variationChain.reduce((promise, variation) => {

const resolveFiles = this.runtimes
.filter(name => pkg[name])
.map(name => {
return this.resolveFile(path.join(moduleName, pkg[name]))
// `resolveFile` returns Object with all values the same and that is useless for us.
.then(fileResolved => ({name, path: fileResolved[name]}))
// Even if file does not resolve, let's not make the promise all fail fast.
.catch(() => {});
.filter((name) => pkg[name])
.map((name) => {
return (
this.resolveFile(path.join(moduleName, pkg[name]))
// `resolveFile` returns Object with all values the same and that is useless for us.
.then((fileResolved) => ({
name,
path: fileResolved[name],
}))
// Even if file does not resolve, let's not make the promise all fail fast.
.catch(() => {})
);
});
return Promise.all(resolveFiles).then(resolves => {
return Promise.all(resolveFiles).then((resolves) => {
const resolved = {};
// for failed case, we returned undefined in the catch above so lets filter that out.
resolves.filter(Boolean).forEach(({name, path}) => {
resolves.filter(Boolean).forEach(({ name, path }) => {
resolved[name] = path;
});
this.runtimes.filter(name => !resolved[name]).forEach(name => resolved[name] = resolved.main);
this.runtimes
.filter((name) => !resolved[name])
.forEach((name) => (resolved[name] = resolved.main));
return resolved;

@@ -109,18 +115,24 @@ });

resolveDir(moduleName) {
if (this.isBasePath(moduleName) || isNodeModule(moduleName)) return super.resolveDir(moduleName);
if (this.isBasePath(moduleName) || isNodeModuleFile(moduleName))
return super.resolveDir(moduleName);
const moduleId = this.getModuleId(moduleName);
let promise = Promise.reject();
this.variationChain.forEach(variation => {
this.variationChain.forEach((variation) => {
const packagePath = path.join(variation, moduleId, '/package.json');
promise = promise.catch(() => {
return this.readPackageJson(packagePath).then(varPackageJson => this._processPackageJson(moduleName, varPackageJson));
return this.readPackageJson(packagePath).then(
(varPackageJson) =>
this._processPackageJson(moduleName, varPackageJson)
);
});
});
return promise.catch(() => this.resolveFile(path.join(moduleName, 'index')));
return promise.catch(() =>
this.resolveFile(path.join(moduleName, 'index'))
);
}
}
function isNodeModule(id) {
function isNodeModuleFile(id) {
return id.indexOf('node_modules') >= 0;

@@ -127,0 +139,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc