Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
dir.js106 linesDownload Raw Back to lib
1const { resolve } = require('node:path')
2const packlist = require('npm-packlist')
3const runScript = require('@npmcli/run-script')
4const tar = require('tar')
5const { Minipass } = require('minipass')
6const Fetcher = require('./fetcher.js')
7const FileFetcher = require('./file.js')
8const _ = require('./util/protected.js')
9const tarCreateOptions = require('./util/tar-create-options.js')
10
11class DirFetcher extends Fetcher {
12  constructor (spec, opts) {
13    super(spec, opts)
14    // just the fully resolved filename
15    this.resolved = this.spec.fetchSpec
16
17    this.tree = opts.tree || null
18    this.Arborist = opts.Arborist || null
19  }
20
21  // exposes tarCreateOptions as public API
22  static tarCreateOptions (manifest) {
23    return tarCreateOptions(manifest)
24  }
25
26  get types () {
27    return ['directory']
28  }
29
30  #prepareDir () {
31    return this.manifest().then(mani => {
32      if (!mani.scripts || !mani.scripts.prepare) {
33        return
34      }
35      if (this.opts.ignoreScripts) {
36        return
37      }
38
39      // we *only* run prepare.
40      // pre/post-pack is run by the npm CLI for publish and pack,
41      // but this function is *also* run when installing git deps
42      const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe'
43
44      return runScript({
45        // this || undefined is because runScript will be unhappy with the default null value
46        scriptShell: this.opts.scriptShell || undefined,
47        pkg: mani,
48        event: 'prepare',
49        path: this.resolved,
50        stdio,
51        env: {
52          npm_package_resolved: this.resolved,
53          npm_package_integrity: this.integrity,
54          npm_package_json: resolve(this.resolved, 'package.json'),
55        },
56      })
57    })
58  }
59
60  [_.tarballFromResolved] () {
61    if (!this.tree && !this.Arborist) {
62      throw new Error('DirFetcher requires either a tree or an Arborist constructor to pack')
63    }
64
65    const stream = new Minipass()
66    stream.resolved = this.resolved
67    stream.integrity = this.integrity
68
69    const { prefix, workspaces } = this.opts
70
71    // run the prepare script, get the list of files, and tar it up
72    // pipe to the stream, and proxy errors the chain.
73    this.#prepareDir()
74      .then(async () => {
75        if (!this.tree) {
76          const arb = new this.Arborist({ path: this.resolved })
77          this.tree = await arb.loadActual()
78        }
79        return packlist(this.tree, { path: this.resolved, prefix, workspaces })
80      })
81      .then(files => tar.c(tarCreateOptions(this.package), files)
82        .on('error', er => stream.emit('error', er)).pipe(stream))
83      .catch(er => stream.emit('error', er))
84    return stream
85  }
86
87  manifest () {
88    if (this.package) {
89      return Promise.resolve(this.package)
90    }
91
92    return this[_.readPackageJson](this.resolved)
93      .then(mani => this.package = {
94        ...mani,
95        _integrity: this.integrity && String(this.integrity),
96        _resolved: this.resolved,
97        _from: this.from,
98      })
99  }
100
101  packument () {
102    return FileFetcher.prototype.packument.apply(this)
103  }
104}
105module.exports = DirFetcher
106 
codekingpro/portable-devtools · Team Ai