file.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. 'use strict'
  2. const BB = require('bluebird')
  3. const cacache = require('cacache')
  4. const Fetcher = require('../fetch')
  5. const fs = require('fs')
  6. const pipe = BB.promisify(require('mississippi').pipe)
  7. const through = require('mississippi').through
  8. const readFileAsync = BB.promisify(fs.readFile)
  9. const statAsync = BB.promisify(fs.stat)
  10. const MAX_BULK_SIZE = 2 * 1024 * 1024 // 2MB
  11. // `file` packages refer to local tarball files.
  12. const fetchFile = module.exports = Object.create(null)
  13. Fetcher.impl(fetchFile, {
  14. packument (spec, opts) {
  15. return BB.reject(new Error('Not implemented yet'))
  16. },
  17. manifest (spec, opts) {
  18. // We can't do much here. `finalizeManifest` will take care of
  19. // calling `tarball` to fill out all the necessary details.
  20. return BB.resolve(null)
  21. },
  22. // All the heavy lifting for `file` packages is done here.
  23. // They're never cached. We just read straight out of the file.
  24. // TODO - maybe they *should* be cached?
  25. tarball (spec, opts) {
  26. const src = spec._resolved || spec.fetchSpec
  27. const stream = through()
  28. statAsync(src).then(stat => {
  29. if (spec._resolved) { stream.emit('manifest', spec) }
  30. if (stat.size <= MAX_BULK_SIZE) {
  31. // YAY LET'S DO THING IN BULK
  32. return readFileAsync(src).then(data => {
  33. if (opts.cache) {
  34. return cacache.put(
  35. opts.cache, `pacote:tarball:file:${src}`, data, {
  36. integrity: opts.integrity
  37. }
  38. ).then(integrity => ({ data, integrity }))
  39. } else {
  40. return { data }
  41. }
  42. }).then(info => {
  43. if (info.integrity) { stream.emit('integrity', info.integrity) }
  44. stream.write(info.data, () => {
  45. stream.end()
  46. })
  47. })
  48. } else {
  49. let integrity
  50. const cacheWriter = !opts.cache
  51. ? BB.resolve(null)
  52. : (pipe(
  53. fs.createReadStream(src),
  54. cacache.put.stream(opts.cache, `pacote:tarball:${src}`, {
  55. integrity: opts.integrity
  56. }).on('integrity', d => { integrity = d })
  57. ))
  58. return cacheWriter.then(() => {
  59. if (integrity) { stream.emit('integrity', integrity) }
  60. return pipe(fs.createReadStream(src), stream)
  61. })
  62. }
  63. }).catch(err => stream.emit('error', err))
  64. return stream
  65. },
  66. fromManifest (manifest, spec, opts) {
  67. return this.tarball(manifest || spec, opts)
  68. }
  69. })