mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-28 02:53:15 -04:00
Merge pull request #45 from misterbyrne/retry-resolve-404s
Retry npm registry package resolving when 404s
This commit is contained in:
@@ -3,6 +3,7 @@ var url = require('url')
|
||||
var enc = global.encodeURIComponent
|
||||
var got = require('../got')
|
||||
var registryUrl = require('registry-url')
|
||||
var semver = require('semver')
|
||||
|
||||
/**
|
||||
* Resolves a package in the NPM registry. Done as part of `install()`.
|
||||
@@ -22,29 +23,65 @@ module.exports = function resolveNpm (pkg, log) {
|
||||
// { raw: 'rimraf@2', scope: null, name: 'rimraf', rawSpec: '2' || '' }
|
||||
return Promise.resolve()
|
||||
.then(_ => toUri(pkg))
|
||||
.then(url => {
|
||||
return got.get(url).then(res => {
|
||||
if (log) log('resolving')
|
||||
return res.promise
|
||||
})
|
||||
})
|
||||
.then(url => got.get(url).then(res => {
|
||||
if (log) log('resolving')
|
||||
return res.promise
|
||||
}))
|
||||
.then(res => JSON.parse(res.body))
|
||||
.then(res => {
|
||||
return {
|
||||
name: res.name,
|
||||
fullname: '' + res.name.replace('/', '!') + '@' + res.version,
|
||||
version: res.version, // used for displaying
|
||||
dist: res.dist
|
||||
}
|
||||
})
|
||||
.catch(errify)
|
||||
.catch(err => err.statusCode === 404
|
||||
? getAllVersionsAndMatchOnClient(pkg)
|
||||
: errify(err, pkg)
|
||||
)
|
||||
.then(res => ({
|
||||
name: res.name,
|
||||
fullname: '' + res.name.replace('/', '!') + '@' + res.version,
|
||||
version: res.version, // used for displaying
|
||||
dist: res.dist
|
||||
}))
|
||||
}
|
||||
|
||||
function errify (err) {
|
||||
if (err.statusCode === 404) {
|
||||
throw new Error("Module '" + pkg.raw + "' not found")
|
||||
}
|
||||
throw err
|
||||
function errify (err, pkg) {
|
||||
if (err.statusCode === 404) {
|
||||
throw new Error("Module '" + pkg.raw + "' not found")
|
||||
}
|
||||
throw err
|
||||
}
|
||||
|
||||
function getAllVersionsAndMatchOnClient (pkg) {
|
||||
return Promise.resolve()
|
||||
.then(_ => url.resolve(registryUrl(pkg.scope), pkg.name))
|
||||
.then(url => got.get(url).then(res => res.promise))
|
||||
.then(res => JSON.parse(res.body))
|
||||
.then(res => pickVersionFromRegistryDocument(res, pkg))
|
||||
.catch(err => errify(err, pkg))
|
||||
}
|
||||
|
||||
function pickVersionFromRegistryDocument (pkg, dep) {
|
||||
var versions = Object.keys(pkg.versions)
|
||||
if (dep.tag === 'tag' && dep.spec === 'latest') {
|
||||
var sortedVersions = versions.sort(semver.rcompare)
|
||||
return pkg(sortedVersions[0])
|
||||
}
|
||||
|
||||
if (dep.type === 'tag' && dep.spec !== 'latest') {
|
||||
var tagVersion = pkg['dist-tags'][dep.spec]
|
||||
if (pkg.versions[tagVersion]) {
|
||||
return pkg.versions[tagVersion]
|
||||
}
|
||||
} else {
|
||||
var spec = scopeWorkarounds(dep)
|
||||
var maxSatisfyingVersion = semver.maxSatisfying(versions, spec)
|
||||
if (maxSatisfyingVersion) {
|
||||
return pkg.versions[maxSatisfyingVersion]
|
||||
}
|
||||
}
|
||||
|
||||
var message = versions.length
|
||||
? 'Versions in registry:\n' + versions.join(', ') + '\n'
|
||||
: 'No valid version found.'
|
||||
var er = new Error('No compatible version found: ' +
|
||||
dep.raw + '\n' + message)
|
||||
throw er
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user