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
|