| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | const { resolve } = require('node:path')const packlist = require('npm-packlist')const runScript = require('@npmcli/run-script')const tar = require('tar')const { Minipass } = require('minipass')const Fetcher = require('./fetcher.js')const FileFetcher = require('./file.js')const _ = require('./util/protected.js')const tarCreateOptions = require('./util/tar-create-options.js')class DirFetcher extends Fetcher {  constructor (spec, opts) {    super(spec, opts)    // just the fully resolved filename    this.resolved = this.spec.fetchSpec    this.tree = opts.tree || null    this.Arborist = opts.Arborist || null  }  // exposes tarCreateOptions as public API  static tarCreateOptions (manifest) {    return tarCreateOptions(manifest)  }  get types () {    return ['directory']  }  #prepareDir () {    return this.manifest().then(mani => {      if (!mani.scripts || !mani.scripts.prepare) {        return      }      if (this.opts.ignoreScripts) {        return      }      // we *only* run prepare.      // pre/post-pack is run by the npm CLI for publish and pack,      // but this function is *also* run when installing git deps      const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe'      return runScript({        // this || undefined is because runScript will be unhappy with the default null value        scriptShell: this.opts.scriptShell || undefined,        pkg: mani,        event: 'prepare',        path: this.resolved,        stdio,        env: {          npm_package_resolved: this.resolved,          npm_package_integrity: this.integrity,          npm_package_json: resolve(this.resolved, 'package.json'),        },      })    })  }  [_.tarballFromResolved] () {    if (!this.tree && !this.Arborist) {      throw new Error('DirFetcher requires either a tree or an Arborist constructor to pack')    }    const stream = new Minipass()    stream.resolved = this.resolved    stream.integrity = this.integrity    const { prefix, workspaces } = this.opts    // run the prepare script, get the list of files, and tar it up    // pipe to the stream, and proxy errors the chain.    this.#prepareDir()      .then(async () => {        if (!this.tree) {          const arb = new this.Arborist({ path: this.resolved })          this.tree = await arb.loadActual()        }        return packlist(this.tree, { path: this.resolved, prefix, workspaces })      })      .then(files => tar.c(tarCreateOptions(this.package), files)        .on('error', er => stream.emit('error', er)).pipe(stream))      .catch(er => stream.emit('error', er))    return stream  }  manifest () {    if (this.package) {      return Promise.resolve(this.package)    }    return this[_.readPackageJson](this.resolved)      .then(mani => this.package = {        ...mani,        _integrity: this.integrity && String(this.integrity),        _resolved: this.resolved,        _from: this.from,      })  }  packument () {    return FileFetcher.prototype.packument.apply(this)  }}module.exports = DirFetcher
 |