2017-01-07 07:22:48 +00:00
|
|
|
const got = require('got');
|
|
|
|
const semver = require('semver');
|
|
|
|
const stable = require('semver-stable');
|
|
|
|
|
|
|
|
var config = {};
|
|
|
|
|
|
|
|
module.exports = {
|
2017-01-09 21:04:13 +00:00
|
|
|
init: function(setConfig) {
|
|
|
|
config = setConfig;
|
2017-01-07 07:22:48 +00:00
|
|
|
},
|
2017-01-07 20:01:32 +00:00
|
|
|
getDependencies: function(packageContents) {
|
|
|
|
const allDependencies = [];
|
|
|
|
const dependencyTypes = ['dependencies', 'devDependencies'];
|
|
|
|
dependencyTypes.forEach(function(depType) {
|
|
|
|
Object.keys(packageContents[depType]).forEach(function(depName) {
|
|
|
|
allDependencies.push({
|
|
|
|
depType: depType,
|
|
|
|
depName: depName,
|
|
|
|
currentVersion: packageContents[depType][depName],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return allDependencies;
|
2017-01-07 07:22:48 +00:00
|
|
|
},
|
2017-01-07 20:01:32 +00:00
|
|
|
getAllDependencyUpgrades: function(packageContents) {
|
|
|
|
const allDependencyChecks = [];
|
|
|
|
const allDependencyUpgrades = [];
|
|
|
|
const dependencyTypes = ['dependencies', 'devDependencies'];
|
|
|
|
dependencyTypes.forEach(function(depType) {
|
|
|
|
if (!packageContents[depType]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Object.keys(packageContents[depType]).forEach(function(depName) {
|
|
|
|
var currentVersion = packageContents[depType][depName];
|
2017-01-09 21:44:36 +00:00
|
|
|
if (!isValidVersion(currentVersion)) {
|
2017-01-07 20:01:32 +00:00
|
|
|
if (config.verbose) {
|
|
|
|
console.log(`${depName}: Skipping invalid version ${currentVersion}`);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
allDependencyChecks.push(getDependencyUpgrades(depName, currentVersion)
|
|
|
|
.then(res => {
|
|
|
|
if (Object.keys(res).length > 0) {
|
2017-01-07 21:58:27 +00:00
|
|
|
if (config.verbose) {
|
|
|
|
console.log(`${depName}: Upgrades = ${JSON.stringify(res)}`);
|
|
|
|
}
|
2017-01-09 21:44:36 +00:00
|
|
|
Object.keys(res).forEach(function(key) {
|
2017-01-07 20:01:32 +00:00
|
|
|
allDependencyUpgrades.push({
|
2017-01-09 21:44:36 +00:00
|
|
|
upgradeType: (key === 'pin') ? 'pin' : 'upgrade',
|
2017-01-07 20:01:32 +00:00
|
|
|
depType: depType,
|
|
|
|
depName: depName,
|
|
|
|
currentVersion: currentVersion,
|
2017-01-09 21:44:36 +00:00
|
|
|
newVersion: res[key],
|
2017-01-07 20:01:32 +00:00
|
|
|
});
|
|
|
|
});
|
2017-01-07 21:58:27 +00:00
|
|
|
} else {
|
|
|
|
if (config.verbose) {
|
|
|
|
console.log(`${depName}: No upgrades required`);
|
|
|
|
}
|
2017-01-07 20:01:32 +00:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return Promise.all(allDependencyChecks).then(() => {
|
|
|
|
return allDependencyUpgrades;
|
|
|
|
});
|
|
|
|
},
|
2017-01-07 07:22:48 +00:00
|
|
|
};
|
2017-01-07 20:01:32 +00:00
|
|
|
|
|
|
|
function getDependency(depName) {
|
|
|
|
// supports scoped packages, e.g. @user/package
|
|
|
|
return got(`https://registry.npmjs.org/${depName.replace('/', '%2F')}`, { json: true });
|
|
|
|
}
|
2017-01-07 21:00:32 +00:00
|
|
|
|
|
|
|
function getDependencyUpgrades(depName, currentVersion) {
|
|
|
|
return getDependency(depName)
|
|
|
|
.then(res => {
|
|
|
|
if (!res.body['versions']) {
|
|
|
|
console.log(depName + ' versions is null');
|
|
|
|
}
|
2017-01-09 21:44:36 +00:00
|
|
|
if (isRange(currentVersion)) {
|
|
|
|
// Pin ranges to their maximum satisfying version
|
|
|
|
return { 'pin': semver.maxSatisfying(Object.keys(res.body.versions), currentVersion) };
|
|
|
|
}
|
|
|
|
const allUpgrades = {};
|
2017-01-07 21:00:32 +00:00
|
|
|
Object.keys(res.body['versions']).forEach(function(version) {
|
|
|
|
if (stable.is(currentVersion) && !stable.is(version)) {
|
|
|
|
// Ignore unstable versions, unless the current version is unstable
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (semver.gt(version, currentVersion)) {
|
|
|
|
// Group by major versions
|
|
|
|
var thisMajor = semver.major(version);
|
|
|
|
if (!allUpgrades[thisMajor] || semver.gt(version, allUpgrades[thisMajor])) {
|
|
|
|
allUpgrades[thisMajor] = version;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return allUpgrades;
|
|
|
|
});
|
|
|
|
}
|
2017-01-09 21:44:36 +00:00
|
|
|
|
|
|
|
function isRange(input) {
|
|
|
|
// Pinned versions also return true for semver.validRange
|
|
|
|
// We need to check first that they're not "valid" to get only ranges
|
|
|
|
return !semver.valid(input) && semver.validRange(input);
|
|
|
|
}
|
|
|
|
|
|
|
|
function isValidVersion(input) {
|
|
|
|
return semver.valid(input) || semver.validRange(input);
|
|
|
|
}
|