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

cortex-shrinkwrap

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cortex-shrinkwrap - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0

lib/shrinktree.js

276

lib/index.js
var path = require('path');
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var semver = require('semver');
var async = require('async');
var sortedObject = require('sorted-object');
var async = require('async');
var depTravel = require('cortex-deps-traveller');
var shrinktree = require('./shrinktree');
var Visitor = depTravel.Visitor;
module.exports = function(pkg, cache_root, options, callback) {

@@ -20,223 +23,104 @@ if (!pkg || !cache_root) {

var readjson = require('read-cortex-json');
var rootName = pkg.name,
rootVersion = pkg.version,
enableDev = options.dev,
var enableDev = options.dev,
enableAsync = options.async,
enablePrerelease = options.enablePrerelease === true;
stableOnly = options.stableOnly !== false;
var holder = new EventEmitter();
var depCache = {}, verCache = {};
if (options.hasOwnProperty('enablePrerelease'))
stableOnly = !options.enablePrerelease;
process.nextTick(function() {
depCache[rootName + '@' + rootVersion] = mergeDependencies(pkg, true);
shrinkPackage(rootName, rootVersion, function(name, range, callback) {
if (name == rootName && range == rootVersion) {
return process.nextTick(callback.bind(null, null, range, depCache[name + '@' + range]));
var firstRoot = true;
var traveller = shrinktree(pkg, cache_root, {
stableOnly: stableOnly,
pkgDeps: function(pkg) {
var dependencies = {};
if (pkg.dependencies) {
for (var d in pkg.dependencies) {
dependencies[d] = pkg.dependencies[d];
}
}
readVersions(name, function(err, versions) {
if (err) return callback(err);
var ver = semver.maxSatisfying(versions, range);
if (!ver) {
// TODO: whether go to registry, issue #1
return callback({
message: "Can not resolve package " + name + " from range: " + range + " in available versions: " + versions
});
if (firstRoot) {
firstRoot = false;
if (enableDev) {
var devDependencies = pkg.devDependencies || {};
for (var d in devDependencies) {
dependencies[d] = devDependencies[d];
}
var pkgDir = path.join(cache_root, name, ver, 'package');
var swPath = path.join(pkgDir, 'cortex-shrinkwrap.json');
fs.exists(swPath, function(exists) {
if (exists) {
fs.readFile(swPath, 'utf8', function(err, content) {
var s;
try {
s = JSON.parse(content);
} catch (e) {
e.message = "Error when read: " + swPath + " " + e.message;
return callback(e);
}
callback(null, ver, s.dependencies, true);
});
} else {
readjson.read(pkgDir, function(err, pkg) {
if (err) return callback(err);
callback(null, ver, depCache[name + "@" + ver] = mergeDependencies(pkg));
});
}
});
});
},
function(err, shrinked) {
if (err) return callback(err);
// resolve engines
var engines;
var taskEngs = {};
for (var name in (pkg.engines || {})) {
(function(range) {
taskEngs[name] = function(cb) {
readVersions(name, function(err, versions) {
if (err) return cb(err);
var ver = semver.maxSatisfying(versions, range);
if (!ver) {
return cb({
message: "Can not resolve engine " + name + " from range: " + range + " in available versions: " + versions
});
}
cb(null, {
from: [name, range].join('@'),
version: ver
});
});
};
})(pkg.engines[name]);
} else if (!isEmptyObject(pkg.devDependencies)) {
for (var d in pkg.devDependencies) {
this.emit("ignoreDev", d);
}
}
async.parallel(taskEngs, function(err, results) {
if (err) return callback(err);
var rs = {};
rs.name = rootName;
rs.version = rootVersion;
if (!isEmptyObject(results)) {
rs.engines = results;
}
if (!isEmptyObject(shrinked.dependencies))
if (!isEmptyObject(shrinked.dependencies))
rs.dependencies = shrinked.dependencies;
callback(err, rs);
});
});
});
return holder;
function readVersions(name, cb) {
// no multi process
if (verCache[name]) {
cb(null, verCache[name]);
} else {
var pkg_root = path.join(cache_root, name);
fs.exists(pkg_root, function(exists) {
if (!exists)
return cb({
message: "No pacakge '" + name + "' installed, please run 'cortex install' first"
});
fs.readdir(pkg_root, function(err, files) {
if (err) return cb(err);
var vers = files.filter(semver.valid);
if (!enablePrerelease) {
vers = vers.filter(function(ver) {
return ver.indexOf('-') == -1;
});
}
cb(null, verCache[name] = vers);
});
});
}
}
function mergeDependencies(pkg, isRoot) {
var dependencies = {};
if (pkg.dependencies) {
for (var d in pkg.dependencies) {
dependencies[d] = pkg.dependencies[d];
}
}
if (isRoot) {
if (enableDev) {
var devDependencies = pkg.devDependencies || {};
for (var d in devDependencies) {
dependencies[d] = devDependencies[d];
if (enableAsync) {
var asyncDependencies = pkg.asyncDependencies || {};
for (var ad in asyncDependencies) {
dependencies[ad] = asyncDependencies[ad];
}
} else if (!isEmptyObject(pkg.devDependencies)) {
for (var d in pkg.devDependencies) {
holder.emit("ignoreDev", d);
} else if (pkg.asyncDependencies) {
for (var ad in pkg.asyncDependencies) {
this.emit("ignoreAsync", ad);
}
}
}
if (enableAsync) {
var asyncDependencies = pkg.asyncDependencies || {};
for (var ad in asyncDependencies) {
dependencies[ad] = asyncDependencies[ad];
}
} else if (pkg.asyncDependencies) {
for (var ad in pkg.asyncDependencies) {
holder.emit("ignoreAsync", ad);
}
return sortedObject(dependencies);
}
}, function(err, json) {
if (err) return callback(err);
delete json.from;
json.name = pkg.name;
return sortedObject(dependencies);
}
};
// resolve engines
var engines;
var taskEngs = {};
for (var name in (pkg.engines || {})) {
(function(range) {
taskEngs[name] = function(cb) {
traveller.readVersions(name, function(err, versions) {
if (err) return cb(err);
var ver = semver.maxSatisfying(versions, range);
if (!ver) {
return cb({
message: "Can not resolve engine " + name + " from range: " + range + " in available versions: " + versions
});
}
function shrinkPackage(pkgName, range, findDeps, callback) {
var tasks = {};
findDeps(pkgName, range, function(err, version, dependencies, nested) {
if (err) return callback(err);
if (nested) {
if (isEmptyObject(dependencies)) {
return callback(null, {
from: pkgName + '@' + range,
version: version
});
} else {
return callback(null, {
from: pkgName + '@' + range,
version: version,
dependencies: dependencies
});
}
}
for (var name in dependencies) {
(function(name, range) {
tasks[name] = function(cb) {
shrinkPackage(name, range, findDeps, function(err, shrink) {
cb(err, shrink);
cb(null, {
from: [name, range].join('@'),
version: ver
});
});
};
})(name, dependencies[name]);
})(pkg.engines[name]);
}
async.parallel(tasks, function(err, rs) {
async.parallel(taskEngs, function(err, results) {
if (err) return callback(err);
if (isEmptyObject(rs)) {
callback(null, {
from: pkgName + '@' + range,
version: version
});
} else {
callback(null, {
from: pkgName + '@' + range,
version: version,
dependencies: rs
});
var rs = {};
rs.name = json.name;
rs.version = json.version;
if (!isEmptyObject(results)) {
rs.engines = results;
}
if (!isEmptyObject(json.dependencies))
rs.dependencies = json.dependencies;
callback(err, rs);
});
});
}
return traveller;
};
module.exports.shrinktree = require('./shrinktree');
function isEmptyObject(obj) {

@@ -250,2 +134,2 @@ if (!obj) return true;

return true;
}
}
{
"name": "cortex-shrinkwrap",
"version": "1.0.2",
"version": "1.1.0",
"description": "Lock down the versions of a package's dependencies",

@@ -27,5 +27,5 @@ "main": "./lib/index.js",

"devDependencies": {
"mocha": "^1.20.0",
"jshint": "^2.5.1",
"underscore": "^1.6.0"
"mocha": "~1.20.0",
"jshint": "~2.5.1",
"underscore": "~1.6.0"
},

@@ -36,4 +36,5 @@ "dependencies": {

"semver": "~2.3.0",
"sorted-object": "~1.0.0"
"sorted-object": "~1.0.0",
"cortex-deps-traveller": "~0.0.1"
}
}

@@ -58,13 +58,71 @@ # Cortex Shrinkwrap

### pkg
### shrinkwrap(pkg, cache_root, [options], callback)
#### pkg
Pakcage information stored in cortex.json.
### Options
#### cache_root
Path of cortex build cache.
#### Options
* dev: whehter include `devDependencies`
* async: whether incldue `asyncDependencies`
* enablePrerelease: whether include prerelease version in shrinkwrap, default value is =false=
* stableOnly: only include stable version in shrinkwrap, default value is =true=
* enablePrerelease(=Deprecated=): whether include prerelease version in shrinkwrap, default value is =false=
#### callback(err, shrinkedJson)
### shrinktree((name, range)|pkg, cache_root, [options], callback)
Generate a simple deps tree with information of shrinkwrap.json
```javascript
var shrinktree = require('cortex-shrinkwrap').shrinktree
shrinktree('deep-eql', "~0.1.0", cache_root, function(err, tree) {
});
// or provide a package json if already have one
shrinktree({
name: 'deep-eql',
version: '0.1.0',
dependencies: {
'type-detect': "~1.0.0"
}
}, cache_root, {
enableDev: true
}, function(err, tree) {
});
```
#### name
Package name of the tree root
#### range
Range of the tree root
#### pkg
Package json as the root
#### cache_root
Path of cortex build cache
#### Options
The same as options in shrinkwrap
## License

@@ -71,0 +129,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