summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/pacote/lib
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/pacote/lib')
-rw-r--r--deps/npm/node_modules/pacote/lib/extract-stream.js26
-rw-r--r--deps/npm/node_modules/pacote/lib/fetchers/file.js14
-rw-r--r--deps/npm/node_modules/pacote/lib/fetchers/git.js20
-rw-r--r--deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js12
-rw-r--r--deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js4
-rw-r--r--deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js80
-rw-r--r--deps/npm/node_modules/pacote/lib/finalize-manifest.js12
-rw-r--r--deps/npm/node_modules/pacote/lib/util/git.js155
-rw-r--r--deps/npm/node_modules/pacote/lib/util/gunzip-maybe.js24
-rw-r--r--deps/npm/node_modules/pacote/lib/util/opt-check.js5
-rw-r--r--deps/npm/node_modules/pacote/lib/util/pack-dir.js4
-rw-r--r--deps/npm/node_modules/pacote/lib/with-tarball-stream.js135
12 files changed, 147 insertions, 344 deletions
diff --git a/deps/npm/node_modules/pacote/lib/extract-stream.js b/deps/npm/node_modules/pacote/lib/extract-stream.js
index b7694876ba..b3c720b07f 100644
--- a/deps/npm/node_modules/pacote/lib/extract-stream.js
+++ b/deps/npm/node_modules/pacote/lib/extract-stream.js
@@ -1,6 +1,5 @@
'use strict'
-const PassThrough = require('stream').PassThrough
const path = require('path')
const tar = require('tar')
@@ -11,29 +10,7 @@ function computeMode (fileMode, optMode, umask) {
return (fileMode | optMode) & ~(umask || 0)
}
-function pkgJsonTransform (spec, opts) {
- return entry => {
- if (entry.path === 'package.json') {
- const transformed = new PassThrough()
- let str = ''
- entry.on('end', () => transformed.end(str.replace(
- /}\s*$/,
- `\n,"_resolved": ${
- JSON.stringify(opts.resolved || '')
- }\n,"_integrity": ${
- JSON.stringify(opts.integrity || '')
- }\n,"_from": ${
- JSON.stringify(spec.toString())
- }\n}`
- )))
- entry.on('error', e => transformed.emit('error'))
- entry.on('data', d => { str += d })
- return transformed
- }
- }
-}
-
-function extractStream (spec, dest, opts) {
+function extractStream (dest, opts) {
opts = opts || {}
const sawIgnores = new Set()
return tar.x({
@@ -43,7 +20,6 @@ function extractStream (spec, dest, opts) {
onwarn: msg => opts.log && opts.log.warn('tar', msg),
uid: opts.uid,
gid: opts.gid,
- transform: opts.resolved && pkgJsonTransform(spec, opts),
onentry (entry) {
if (entry.type.toLowerCase() === 'file') {
entry.mode = computeMode(entry.mode, opts.fmode, opts.umask)
diff --git a/deps/npm/node_modules/pacote/lib/fetchers/file.js b/deps/npm/node_modules/pacote/lib/fetchers/file.js
index 5688cd1bdd..48bec0c2d8 100644
--- a/deps/npm/node_modules/pacote/lib/fetchers/file.js
+++ b/deps/npm/node_modules/pacote/lib/fetchers/file.js
@@ -52,13 +52,13 @@ Fetcher.impl(fetchFile, {
} else {
let integrity
const cacheWriter = !opts.cache
- ? BB.resolve(null)
- : (pipe(
- fs.createReadStream(src),
- cacache.put.stream(opts.cache, `pacote:tarball:${src}`, {
- integrity: opts.integrity
- }).on('integrity', d => { integrity = d })
- ))
+ ? BB.resolve(null)
+ : (pipe(
+ fs.createReadStream(src),
+ cacache.put.stream(opts.cache, `pacote:tarball:${src}`, {
+ integrity: opts.integrity
+ }).on('integrity', d => { integrity = d })
+ ))
return cacheWriter.then(() => {
if (integrity) { stream.emit('integrity', integrity) }
return pipe(fs.createReadStream(src), stream)
diff --git a/deps/npm/node_modules/pacote/lib/fetchers/git.js b/deps/npm/node_modules/pacote/lib/fetchers/git.js
index 6ce966ae5d..11b5695255 100644
--- a/deps/npm/node_modules/pacote/lib/fetchers/git.js
+++ b/deps/npm/node_modules/pacote/lib/fetchers/git.js
@@ -135,16 +135,16 @@ function resolve (url, spec, name, opts) {
const isSemver = !!spec.gitRange
return git.revs(url, opts).then(remoteRefs => {
return isSemver
- ? pickManifest({
- versions: remoteRefs.versions,
- 'dist-tags': remoteRefs['dist-tags'],
- name: name
- }, spec.gitRange, opts)
- : remoteRefs
- ? BB.resolve(
- remoteRefs.refs[spec.gitCommittish] || remoteRefs.refs[remoteRefs.shas[spec.gitCommittish]]
- )
- : null
+ ? pickManifest({
+ versions: remoteRefs.versions,
+ 'dist-tags': remoteRefs['dist-tags'],
+ name: name
+ }, spec.gitRange, opts)
+ : remoteRefs
+ ? BB.resolve(
+ remoteRefs.refs[spec.gitCommittish] || remoteRefs.refs[remoteRefs.shas[spec.gitCommittish]]
+ )
+ : null
})
}
diff --git a/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js b/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js
index 3a2a4a5a77..a947ccea55 100644
--- a/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js
+++ b/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js
@@ -68,12 +68,12 @@ function logRequest (uri, res, startTime, opts) {
function getCacheMode (opts) {
return opts.offline
- ? 'only-if-cached'
- : opts.preferOffline
- ? 'force-cache'
- : opts.preferOnline
- ? 'no-cache'
- : 'default'
+ ? 'only-if-cached'
+ : opts.preferOffline
+ ? 'force-cache'
+ : opts.preferOnline
+ ? 'no-cache'
+ : 'default'
}
function getHeaders (uri, registry, opts) {
diff --git a/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js b/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js
index 4e5a8010e2..4488ddb4c7 100644
--- a/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js
+++ b/deps/npm/node_modules/pacote/lib/fetchers/registry/manifest.js
@@ -28,8 +28,8 @@ function manifest (spec, opts) {
function metadataUrl (registry, name) {
const normalized = registry.slice(-1) !== '/'
- ? registry + '/'
- : registry
+ ? registry + '/'
+ : registry
return url.resolve(normalized, name)
}
diff --git a/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js b/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js
index 89158d3929..2c63872e7f 100644
--- a/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js
+++ b/deps/npm/node_modules/pacote/lib/fetchers/registry/tarball.js
@@ -7,40 +7,22 @@ const manifest = require('./manifest')
const optCheck = require('../../util/opt-check')
const PassThrough = require('stream').PassThrough
const pickRegistry = require('./pick-registry')
+const pipe = BB.promisify(require('mississippi').pipe)
const ssri = require('ssri')
const url = require('url')
module.exports = tarball
function tarball (spec, opts) {
opts = optCheck(opts)
- const registry = pickRegistry(spec, opts)
const stream = new PassThrough()
- let mani
- if (
- opts.resolved &&
- // spec.type === 'version' &&
- opts.resolved.indexOf(registry) === 0
- ) {
- // fakeChild is a shortcut to avoid looking up a manifest!
- mani = BB.resolve({
- name: spec.name,
- version: spec.fetchSpec,
- _integrity: opts.integrity,
- _resolved: opts.resolved,
- _fakeChild: true
- })
- } else {
- // We can't trust opts.resolved if it's going to a separate host.
- mani = manifest(spec, opts)
- }
-
- mani.then(mani => {
- !mani._fakeChild && stream.emit('manifest', mani)
- const fetchStream = fromManifest(mani, spec, opts).on(
- 'integrity', i => stream.emit('integrity', i)
+ manifest(spec, opts).then(manifest => {
+ stream.emit('manifest', manifest)
+ return pipe(
+ fromManifest(manifest, spec, opts).on(
+ 'integrity', i => stream.emit('integrity', i)
+ ),
+ stream
)
- fetchStream.on('error', err => stream.emit('error', err))
- fetchStream.pipe(stream)
}).catch(err => stream.emit('error', err))
return stream
}
@@ -51,43 +33,45 @@ function fromManifest (manifest, spec, opts) {
opts.scope = spec.scope || opts.scope
const stream = new PassThrough()
const registry = pickRegistry(spec, opts)
- const uri = getTarballUrl(spec, registry, manifest, opts)
+ const uri = getTarballUrl(registry, manifest)
fetch(uri, registry, Object.assign({
headers: {
'pacote-req-type': 'tarball',
- 'pacote-pkg-id': `registry:${manifest.name}@${uri}`
+ 'pacote-pkg-id': `registry:${
+ spec.type === 'remote'
+ ? spec
+ : `${manifest.name}@${manifest.version}`
+ }`
},
integrity: manifest._integrity,
algorithms: [
manifest._integrity
- ? ssri.parse(manifest._integrity).pickAlgorithm()
- : 'sha1'
+ ? ssri.parse(manifest._integrity).pickAlgorithm()
+ : 'sha1'
],
spec
- }, opts))
- .then(res => {
- const hash = res.headers.get('x-local-cache-hash')
- if (hash) {
- stream.emit('integrity', decodeURIComponent(hash))
- }
- res.body.on('error', err => stream.emit('error', err))
- res.body.pipe(stream)
- })
- .catch(err => stream.emit('error', err))
+ }, opts)).then(res => {
+ const hash = res.headers.get('x-local-cache-hash')
+ if (hash) {
+ stream.emit('integrity', decodeURIComponent(hash))
+ }
+ res.body.on('error', err => stream.emit('error', err))
+ res.body.pipe(stream)
+ }).catch(err => stream.emit('error', err))
return stream
}
-function getTarballUrl (spec, registry, mani, opts) {
- const reg = url.parse(registry)
- const tarball = url.parse(mani._resolved)
+function getTarballUrl (registry, manifest) {
// https://github.com/npm/npm/pull/9471
//
- // TL;DR: Some alternative registries host tarballs on http and packuments
- // on https, and vice-versa. There's also a case where people who can't use
- // SSL to access the npm registry, for example, might use
- // `--registry=http://registry.npmjs.org/`. In this case, we need to
- // rewrite `tarball` to match the protocol.
+ // TL;DR: Some alternative registries host tarballs on http and packuments on
+ // https, and vice-versa. There's also a case where people who can't use SSL
+ // to access the npm registry, for example, might use
+ // `--registry=http://registry.npmjs.org/`. In this case, we need to rewrite
+ // `tarball` to match the protocol.
//
+ const reg = url.parse(registry)
+ const tarball = url.parse(manifest._resolved)
if (reg.hostname === tarball.hostname && reg.protocol !== tarball.protocol) {
tarball.protocol = reg.protocol
// Ports might be same host different protocol!
diff --git a/deps/npm/node_modules/pacote/lib/finalize-manifest.js b/deps/npm/node_modules/pacote/lib/finalize-manifest.js
index a5ec7a7348..86b273b215 100644
--- a/deps/npm/node_modules/pacote/lib/finalize-manifest.js
+++ b/deps/npm/node_modules/pacote/lib/finalize-manifest.js
@@ -38,8 +38,8 @@ function finalizeManifest (pkg, spec, opts) {
opts = optCheck(opts)
const cachedManifest = (opts.cache && key && !opts.preferOnline && !opts.fullMetadata)
- ? cacache.get.info(opts.cache, key, opts)
- : BB.resolve(null)
+ ? cacache.get.info(opts.cache, key, opts)
+ : BB.resolve(null)
return cachedManifest.then(cached => {
if (cached && cached.metadata.manifest) {
@@ -47,8 +47,8 @@ function finalizeManifest (pkg, spec, opts) {
} else {
return tarballedProps(pkg, spec, opts).then(props => {
return pkg && pkg.name
- ? new Manifest(pkg, props, opts.fullMetadata)
- : new Manifest(props, null, opts.fullMetadata)
+ ? new Manifest(pkg, props, opts.fullMetadata)
+ : new Manifest(props, null, opts.fullMetadata)
}).then(manifest => {
const cacheKey = key || finalKey(manifest, spec)
if (!opts.cache || !cacheKey) {
@@ -169,8 +169,8 @@ function tarballedProps (pkg, spec, opts) {
// to add to bin
if (paths && paths.length) {
const dirBin = mani
- ? (mani && mani.directories && mani.directories.bin)
- : (pkg && pkg.directories && pkg.directories.bin)
+ ? (mani && mani.directories && mani.directories.bin)
+ : (pkg && pkg.directories && pkg.directories.bin)
if (dirBin) {
extraProps.bin = {}
paths.forEach(filePath => {
diff --git a/deps/npm/node_modules/pacote/lib/util/git.js b/deps/npm/node_modules/pacote/lib/util/git.js
index b854208ef9..a6162ceeba 100644
--- a/deps/npm/node_modules/pacote/lib/util/git.js
+++ b/deps/npm/node_modules/pacote/lib/util/git.js
@@ -12,10 +12,8 @@ const optCheck = require('./opt-check')
const osenv = require('osenv')
const path = require('path')
const pinflight = require('promise-inflight')
-const promiseRetry = require('promise-retry')
const uniqueFilename = require('unique-filename')
const which = BB.promisify(require('which'))
-const semver = require('semver')
const GOOD_ENV_VARS = new Set([
'GIT_ASKPASS',
@@ -27,23 +25,6 @@ const GOOD_ENV_VARS = new Set([
'GIT_SSL_NO_VERIFY'
])
-const GIT_TRANSIENT_ERRORS = [
- 'remote error: Internal Server Error',
- 'The remote end hung up unexpectedly',
- 'Connection timed out',
- 'Operation timed out',
- 'Failed to connect to .* Timed out',
- 'Connection reset by peer',
- 'SSL_ERROR_SYSCALL',
- 'The requested URL returned error: 503'
-].join('|')
-
-const GIT_TRANSIENT_ERROR_RE = new RegExp(GIT_TRANSIENT_ERRORS)
-
-function shouldRetry (error) {
- return GIT_TRANSIENT_ERROR_RE.test(error)
-}
-
const GIT_ = 'GIT_'
let GITENV
function gitEnv () {
@@ -132,51 +113,57 @@ function revs (repo, opts) {
return pinflight(`ls-remote:${repo}`, () => {
return spawnGit(['ls-remote', '-h', '-t', repo], {
env: gitEnv()
- }, opts).then((stdout) => {
- return stdout.split('\n').reduce((revs, line) => {
- const split = line.split(/\s+/, 2)
- if (split.length < 2) { return revs }
- const sha = split[0].trim()
- const ref = split[1].trim().match(/(?:refs\/[^/]+\/)?(.*)/)[1]
- if (!ref) { return revs } // ???
- if (ref.endsWith(CARET_BRACES)) { return revs } // refs/tags/x^{} crap
- const type = refType(line)
- const doc = {sha, ref, type}
-
- revs.refs[ref] = doc
- // We can check out shallow clones on specific SHAs if we have a ref
- if (revs.shas[sha]) {
- revs.shas[sha].push(ref)
- } else {
- revs.shas[sha] = [ref]
- }
-
- if (type === 'tag') {
- const match = ref.match(/v?(\d+\.\d+\.\d+(?:[-+].+)?)$/)
- if (match && semver.valid(match[1], true)) {
- revs.versions[semver.clean(match[1], true)] = doc
+ }, opts).then(child => {
+ let stdout = ''
+ let stderr = ''
+ child.stdout.on('data', d => { stdout += d })
+ child.stderr.on('data', d => { stderr += d })
+ return finished(child).catch(err => {
+ err.message = `Error while executing:\n${GITPATH} ls-remote -h -t ${repo}\n\n${stderr}\n${err.message}`
+ throw err
+ }).then(() => {
+ return stdout.split('\n').reduce((revs, line) => {
+ const split = line.split(/\s+/, 2)
+ if (split.length < 2) { return revs }
+ const sha = split[0].trim()
+ const ref = split[1].trim().match(/(?:refs\/[^/]+\/)?(.*)/)[1]
+ if (!ref) { return revs } // ???
+ if (ref.endsWith(CARET_BRACES)) { return revs } // refs/tags/x^{} crap
+ const type = refType(line)
+ const doc = {sha, ref, type}
+
+ revs.refs[ref] = doc
+ // We can check out shallow clones on specific SHAs if we have a ref
+ if (revs.shas[sha]) {
+ revs.shas[sha].push(ref)
+ } else {
+ revs.shas[sha] = [ref]
}
- }
- return revs
- }, {versions: {}, 'dist-tags': {}, refs: {}, shas: {}})
- }, err => {
- err.message = `Error while executing:\n${GITPATH} ls-remote -h -t ${repo}\n\n${err.stderr}\n${err.message}`
- throw err
- }).then(revs => {
- if (revs.refs.HEAD) {
- const HEAD = revs.refs.HEAD
- Object.keys(revs.versions).forEach(v => {
- if (v.sha === HEAD.sha) {
- revs['dist-tags'].HEAD = v
- if (!revs.refs.latest) {
- revs['dist-tags'].latest = revs.refs.HEAD
+ if (type === 'tag') {
+ const match = ref.match(/v?(\d+\.\d+\.\d+)$/)
+ if (match) {
+ revs.versions[match[1]] = doc
}
}
- })
- }
- REVS.set(repo, revs)
- return revs
+
+ return revs
+ }, {versions: {}, 'dist-tags': {}, refs: {}, shas: {}})
+ }).then(revs => {
+ if (revs.refs.HEAD) {
+ const HEAD = revs.refs.HEAD
+ Object.keys(revs.versions).forEach(v => {
+ if (v.sha === HEAD.sha) {
+ revs['dist-tags'].HEAD = v
+ if (!revs.refs.latest) {
+ revs['dist-tags'].latest = revs.refs.HEAD
+ }
+ }
+ })
+ }
+ REVS.set(repo, revs)
+ return revs
+ })
})
})
}
@@ -185,18 +172,7 @@ module.exports._exec = execGit
function execGit (gitArgs, gitOpts, opts) {
opts = optCheck(opts)
return checkGit().then(gitPath => {
- return promiseRetry((retry, number) => {
- if (number !== 1) {
- opts.log.silly('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number)
- }
- return execFileAsync(gitPath, gitArgs, mkOpts(gitOpts, opts)).catch((err) => {
- if (shouldRetry(err)) {
- retry(err)
- } else {
- throw err
- }
- })
- }, opts.retry)
+ return execFileAsync(gitPath, gitArgs, mkOpts(gitOpts, opts))
})
}
@@ -204,28 +180,7 @@ module.exports._spawn = spawnGit
function spawnGit (gitArgs, gitOpts, opts) {
opts = optCheck(opts)
return checkGit().then(gitPath => {
- return promiseRetry((retry, number) => {
- if (number !== 1) {
- opts.log.silly('pacote', 'Retrying git command: ' + gitArgs.join(' ') + ' attempt # ' + number)
- }
- const child = cp.spawn(gitPath, gitArgs, mkOpts(gitOpts, opts))
-
- let stdout = ''
- let stderr = ''
- child.stdout.on('data', d => { stdout += d })
- child.stderr.on('data', d => { stderr += d })
-
- return finished(child).catch(err => {
- if (shouldRetry(stderr)) {
- retry(err)
- } else {
- err.stderr = stderr
- throw err
- }
- }).then(() => {
- return stdout
- })
- }, opts.retry)
+ return cp.spawn(gitPath, gitArgs, mkOpts(gitOpts, opts))
})
}
@@ -258,10 +213,10 @@ const REFS_HEADS = 'refs/heads/'
const HEAD = 'HEAD'
function refType (ref) {
return ref.indexOf(REFS_TAGS) !== -1
- ? 'tag'
- : ref.indexOf(REFS_HEADS) !== -1
- ? 'branch'
- : ref.endsWith(HEAD)
- ? 'head'
- : 'other'
+ ? 'tag'
+ : ref.indexOf(REFS_HEADS) !== -1
+ ? 'branch'
+ : ref.endsWith(HEAD)
+ ? 'head'
+ : 'other'
}
diff --git a/deps/npm/node_modules/pacote/lib/util/gunzip-maybe.js b/deps/npm/node_modules/pacote/lib/util/gunzip-maybe.js
new file mode 100644
index 0000000000..055de2921a
--- /dev/null
+++ b/deps/npm/node_modules/pacote/lib/util/gunzip-maybe.js
@@ -0,0 +1,24 @@
+'use strict'
+
+const duplex = require('mississippi').duplex
+const through = require('mississippi').through
+const zlib = require('zlib')
+
+function hasGzipHeader (c) {
+ return c[0] === 0x1F && c[1] === 0x8B && c[2] === 0x08
+}
+
+module.exports = gunzip
+function gunzip () {
+ const stream = duplex()
+ const peeker = through((chunk, enc, cb) => {
+ const newStream = hasGzipHeader(chunk)
+ ? zlib.createGunzip()
+ : through()
+ stream.setReadable(newStream)
+ stream.setWritable(newStream)
+ stream.write(chunk)
+ })
+ stream.setWritable(peeker)
+ return stream
+}
diff --git a/deps/npm/node_modules/pacote/lib/util/opt-check.js b/deps/npm/node_modules/pacote/lib/util/opt-check.js
index d13a69e4dc..711f46c91a 100644
--- a/deps/npm/node_modules/pacote/lib/util/opt-check.js
+++ b/deps/npm/node_modules/pacote/lib/util/opt-check.js
@@ -25,7 +25,6 @@ function PacoteOptions (opts) {
this.proxy = opts.proxy
this.noProxy = opts.noProxy
this.registry = opts.registry || 'https://registry.npmjs.org'
- this.resolved = opts.resolved
this.retry = opts.retry // for npm-registry-client
this.scope = opts.scope
this.userAgent = opts.userAgent || `${pkg.name}@${pkg.version}/node@${process.version}+${process.arch} (${process.platform})`
@@ -45,8 +44,8 @@ function PacoteOptions (opts) {
this.fullMetadata = opts.fullMetadata
this.alwaysAuth = opts.alwaysAuth
this.includeDeprecated = opts.includeDeprecated == null
- ? true
- : opts.includeDeprecated
+ ? true
+ : opts.includeDeprecated
this.dirPacker = opts.dirPacker || null
diff --git a/deps/npm/node_modules/pacote/lib/util/pack-dir.js b/deps/npm/node_modules/pacote/lib/util/pack-dir.js
index 62776692e1..7625f4faf8 100644
--- a/deps/npm/node_modules/pacote/lib/util/pack-dir.js
+++ b/deps/npm/node_modules/pacote/lib/util/pack-dir.js
@@ -14,8 +14,8 @@ function packDir (manifest, label, dir, target, opts) {
opts = optCheck(opts)
const packer = opts.dirPacker
- ? BB.resolve(opts.dirPacker(manifest, dir))
- : mkPacker(dir)
+ ? BB.resolve(opts.dirPacker(manifest, dir))
+ : mkPacker(dir)
if (!opts.cache) {
return packer.then(packer => pipe(packer, target))
diff --git a/deps/npm/node_modules/pacote/lib/with-tarball-stream.js b/deps/npm/node_modules/pacote/lib/with-tarball-stream.js
deleted file mode 100644
index 653a4a688a..0000000000
--- a/deps/npm/node_modules/pacote/lib/with-tarball-stream.js
+++ /dev/null
@@ -1,135 +0,0 @@
-'use strict'
-
-const BB = require('bluebird')
-
-const cacache = require('cacache')
-const fetch = require('./fetch.js')
-const fs = require('fs')
-const npa = require('npm-package-arg')
-const optCheck = require('./util/opt-check.js')
-const path = require('path')
-const ssri = require('ssri')
-const retry = require('promise-retry')
-
-const statAsync = BB.promisify(fs.stat)
-
-const RETRIABLE_ERRORS = new Set(['ENOENT', 'EINTEGRITY', 'Z_DATA_ERROR'])
-
-module.exports = withTarballStream
-function withTarballStream (spec, opts, streamHandler) {
- opts = optCheck(opts)
- spec = npa(spec, opts.where)
-
- // First, we check for a file: resolved shortcut
- const tryFile = (
- !opts.preferOnline &&
- opts.integrity &&
- opts.resolved &&
- opts.resolved.startsWith('file:')
- )
- ? BB.try(() => {
- // NOTE - this is a special shortcut! Packages installed as files do not
- // have a `resolved` field -- this specific case only occurs when you have,
- // say, a git dependency or a registry dependency that you've packaged into
- // a local file, and put that file: spec in the `resolved` field.
- opts.log.silly('pacote', `trying ${spec} by local file: ${opts.resolved}`)
- const file = path.resolve(opts.where || '.', opts.resolved.substr(5))
- return statAsync(file)
- .then(() => {
- const verifier = ssri.integrityStream({integrity: opts.integrity})
- const stream = fs.createReadStream(file)
- .on('error', err => verifier.emit('error', err))
- .pipe(verifier)
- return streamHandler(stream)
- })
- .catch(err => {
- if (err.code === 'EINTEGRITY') {
- opts.log.warn('pacote', `EINTEGRITY while extracting ${spec} from ${file}.You will have to recreate the file.`)
- opts.log.verbose('pacote', `EINTEGRITY for ${spec}: ${err.message}`)
- }
- throw err
- })
- })
- : BB.reject(Object.assign(new Error('no file!'), {code: 'ENOENT'}))
-
- const tryDigest = tryFile
- .catch(err => {
- if (
- opts.preferOnline ||
- !opts.cache ||
- !opts.integrity ||
- !RETRIABLE_ERRORS.has(err.code)
- ) {
- throw err
- } else {
- opts.log.silly('tarball', `trying ${spec} by hash: ${opts.integrity}`)
- const stream = cacache.get.stream.byDigest(
- opts.cache, opts.integrity, opts
- )
- stream.once('error', err => stream.on('newListener', (ev, l) => {
- if (ev === 'error') { l(err) }
- }))
- return streamHandler(stream)
- .catch(err => {
- if (err.code === 'EINTEGRITY' || err.code === 'Z_DATA_ERROR') {
- opts.log.warn('tarball', `cached data for ${spec} (${opts.integrity}) seems to be corrupted. Refreshing cache.`)
- return cleanUpCached(opts.cache, opts.integrity, opts)
- .then(() => { throw err })
- } else {
- throw err
- }
- })
- }
- })
-
- const trySpec = tryDigest
- .catch(err => {
- if (!RETRIABLE_ERRORS.has(err.code)) {
- // If it's not one of our retriable errors, bail out and give up.
- throw err
- } else {
- opts.log.silly(
- 'tarball',
- `no local data for ${spec}. Extracting by manifest.`
- )
- return BB.resolve(retry((tryAgain, attemptNum) => {
- const tardata = fetch.tarball(spec, opts)
- if (!opts.resolved) {
- tardata.on('manifest', m => {
- opts.resolved = m._resolved
- })
- tardata.on('integrity', i => {
- opts.integrity = i
- })
- }
- return BB.try(() => streamHandler(tardata))
- .catch(err => {
- // Retry once if we have a cache, to clear up any weird conditions.
- // Don't retry network errors, though -- make-fetch-happen has already
- // taken care of making sure we're all set on that front.
- if (opts.cache && err.code && !err.code.match(/^E\d{3}$/)) {
- if (err.code === 'EINTEGRITY' || err.code === 'Z_DATA_ERROR') {
- opts.log.warn('tarball', `tarball data for ${spec} (${opts.integrity}) seems to be corrupted. Trying one more time.`)
- }
- return cleanUpCached(opts.cache, err.sri, opts)
- .then(() => tryAgain(err))
- } else {
- throw err
- }
- })
- }, {retries: 1}))
- }
- })
-
- return trySpec
- .catch(err => {
- if (err.code === 'EINTEGRITY') {
- err.message = `Verification failed while extracting ${spec}:\n${err.message}`
- }
- throw err
- })
-}
-
-function cleanUpCached (cachePath, integrity, opts) {
- return cacache.rm.content(cachePath, integrity, opts)
-}