dir.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. const Fetcher = require('./fetcher.js')
  2. const FileFetcher = require('./file.js')
  3. const cacache = require('cacache')
  4. const Minipass = require('minipass')
  5. const { promisify } = require('util')
  6. const readPackageJson = require('read-package-json-fast')
  7. const tarCreateOptions = require('./util/tar-create-options.js')
  8. const packlist = require('npm-packlist')
  9. const tar = require('tar')
  10. const _prepareDir = Symbol('_prepareDir')
  11. const { resolve } = require('path')
  12. const runScript = require('@npmcli/run-script')
  13. const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved')
  14. class DirFetcher extends Fetcher {
  15. constructor (spec, opts) {
  16. super(spec, opts)
  17. // just the fully resolved filename
  18. this.resolved = this.spec.fetchSpec
  19. }
  20. // exposes tarCreateOptions as public API
  21. static tarCreateOptions (manifest) {
  22. return tarCreateOptions(manifest)
  23. }
  24. get types () {
  25. return ['directory']
  26. }
  27. [_prepareDir] () {
  28. return this.manifest().then(mani => {
  29. if (!mani.scripts || !mani.scripts.prepare)
  30. return
  31. // we *only* run prepare.
  32. // pre/post-pack is run by the npm CLI for publish and pack,
  33. // but this function is *also* run when installing git deps
  34. const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe'
  35. // hide the banner if loglevel is silent, or if prepare running
  36. // in the background.
  37. const banner = this.opts.log && this.opts.log.level === 'silent' ? false
  38. : stdio === 'inherit'
  39. return runScript({
  40. pkg: mani,
  41. event: 'prepare',
  42. path: this.resolved,
  43. stdioString: true,
  44. stdio,
  45. banner,
  46. env: {
  47. npm_package_resolved: this.resolved,
  48. npm_package_integrity: this.integrity,
  49. npm_package_json: resolve(this.resolved, 'package.json'),
  50. },
  51. })
  52. })
  53. }
  54. [_tarballFromResolved] () {
  55. const stream = new Minipass()
  56. stream.resolved = this.resolved
  57. stream.integrity = this.integrity
  58. // run the prepare script, get the list of files, and tar it up
  59. // pipe to the stream, and proxy errors the chain.
  60. this[_prepareDir]()
  61. .then(() => packlist({ path: this.resolved }))
  62. .then(files => tar.c(tarCreateOptions(this.package), files)
  63. .on('error', er => stream.emit('error', er)).pipe(stream))
  64. .catch(er => stream.emit('error', er))
  65. return stream
  66. }
  67. manifest () {
  68. if (this.package)
  69. return Promise.resolve(this.package)
  70. return readPackageJson(this.resolved + '/package.json')
  71. .then(mani => this.package = {
  72. ...mani,
  73. _integrity: this.integrity && String(this.integrity),
  74. _resolved: this.resolved,
  75. _from: this.from,
  76. })
  77. }
  78. packument () {
  79. return FileFetcher.prototype.packument.apply(this)
  80. }
  81. }
  82. module.exports = DirFetcher