1'use strict' 2 3const BB = require('bluebird') 4 5const fs = require('fs') 6const getStream = require('get-stream') 7const mkdirp = BB.promisify(require('mkdirp')) 8const npa = require('npm-package-arg') 9const optCheck = require('./lib/util/opt-check.js') 10const PassThrough = require('stream').PassThrough 11const path = require('path') 12const rimraf = BB.promisify(require('rimraf')) 13const withTarballStream = require('./lib/with-tarball-stream.js') 14 15module.exports = tarball 16function tarball (spec, opts) { 17 opts = optCheck(opts) 18 spec = npa(spec, opts.where) 19 return withTarballStream(spec, opts, stream => getStream.buffer(stream)) 20} 21 22module.exports.stream = tarballStream 23function tarballStream (spec, opts) { 24 opts = optCheck(opts) 25 spec = npa(spec, opts.where) 26 const output = new PassThrough() 27 let hasTouchedOutput = false 28 let lastError = null 29 withTarballStream(spec, opts, stream => { 30 if (hasTouchedOutput && lastError) { 31 throw lastError 32 } else if (hasTouchedOutput) { 33 throw new Error('abort, abort!') 34 } else { 35 return new BB((resolve, reject) => { 36 stream.on('error', reject) 37 output.on('error', reject) 38 output.on('error', () => { hasTouchedOutput = true }) 39 output.on('finish', resolve) 40 stream.pipe(output) 41 stream.once('data', () => { hasTouchedOutput = true }) 42 }).catch(err => { 43 lastError = err 44 throw err 45 }) 46 } 47 }) 48 .catch(err => output.emit('error', err)) 49 return output 50} 51 52module.exports.toFile = tarballToFile 53function tarballToFile (spec, dest, opts) { 54 opts = optCheck(opts) 55 spec = npa(spec, opts.where) 56 return mkdirp(path.dirname(dest)) 57 .then(() => withTarballStream(spec, opts, stream => { 58 return rimraf(dest) 59 .then(() => new BB((resolve, reject) => { 60 const writer = fs.createWriteStream(dest) 61 stream.on('error', reject) 62 writer.on('error', reject) 63 writer.on('close', resolve) 64 stream.pipe(writer) 65 })) 66 })) 67} 68