renovate/lib/api/npm.js
Rhys Arkins ea9ace2a76 feat: branch worker updates (#736)
This is a major refactor of branch code to prepare for Yarn workspaces plus creating PRs for branches with failing lockfiles. Marked as "feature" to cause a minor version bump due to the moderate chance of accidentally breaking something.
2017-08-26 16:10:18 +02:00

88 lines
2.4 KiB
JavaScript

// Most of this borrowed from https://github.com/sindresorhus/package-json/blob/master/index.js
const got = require('got');
const url = require('url');
const ini = require('ini');
const registryUrl = require('registry-url');
const registryAuthToken = require('registry-auth-token');
const parse = require('github-url-from-git');
module.exports = {
setNpmrc,
getDependency,
resetCache,
};
let npmCache = {};
let npmrc = null;
function resetCache() {
npmCache = {};
}
async function setNpmrc(input) {
npmrc = ini.parse(input);
}
async function getDependency(name, logger) {
logger.debug(`getDependency(${name})`);
const scope = name.split('/')[0];
const regUrl = registryUrl(scope, { npmrc });
const pkgUrl = url.resolve(
regUrl,
encodeURIComponent(name).replace(/^%40/, '@')
);
const authInfo = registryAuthToken(regUrl, { npmrc });
const headers = {};
if (authInfo) {
headers.authorization = `${authInfo.type} ${authInfo.token}`;
} else if (process.env.NPM_TOKEN) {
headers.authorization = `Bearer ${process.env.NPM_TOKEN}`;
}
// Cache based on combinatino of package URL and headers
const cacheKey = pkgUrl + JSON.stringify(headers);
// Return from cache if present
if (npmCache[cacheKey]) {
logger.debug(`Returning cached version of ${name}`);
return npmCache[cacheKey];
}
// Retrieve from API if not cached
try {
const res = await got(pkgUrl, {
json: true,
headers,
});
// Determine repository URL
let repositoryUrl;
if (res.body.repository) {
repositoryUrl = parse(res.body.repository.url);
}
if (!repositoryUrl) {
repositoryUrl = res.body.homepage;
}
// Simplify response before caching and returning
const dep = {
name: res.body.name,
homepage: res.body.homepage,
repositoryUrl,
versions: res.body.versions,
'dist-tags': res.body['dist-tags'],
'renovate-config':
res.body.versions[res.body['dist-tags'].latest]['renovate-config'],
};
Object.keys(dep.versions).forEach(version => {
// We don't use any of the version payload currently
dep.versions[version] = { time: res.body.time[version] };
});
npmCache[cacheKey] = dep;
logger.trace({ dependency: dep }, 'dependency');
return dep;
} catch (err) {
logger.debug({ err }, `Dependency not found: ${name}`);
return null;
}
}