1const { relative } = require('path')
2
3const Arborist = require('@npmcli/arborist')
4const npa = require('npm-package-arg')
5const pkgContents = require('@npmcli/installed-package-contents')
6const pacote = require('pacote')
7const { tarCreateOptions } = pacote.DirFetcher
8const tar = require('tar')
9
10// returns a simplified tarball when reading files from node_modules folder,
11// thus avoiding running the prepare scripts and the extra logic from packlist
12const nodeModulesTarball = (manifest, opts) =>
13  pkgContents({ path: manifest._resolved, depth: 1 })
14    .then(files =>
15      files.map(file => relative(manifest._resolved, file))
16    )
17    .then(files =>
18      tar.c(tarCreateOptions(manifest), files).concat()
19    )
20
21const tarball = (manifest, opts) => {
22  const resolved = manifest._resolved
23  const where = opts.where || process.cwd()
24
25  const fromNodeModules = npa(resolved).type === 'directory'
26    && /node_modules[\\/](@[^\\/]+\/)?[^\\/]+[\\/]?$/.test(relative(where, resolved))
27
28  if (fromNodeModules) {
29    return nodeModulesTarball(manifest, opts)
30  }
31
32  return pacote.tarball(manifest._resolved, {
33    ...opts,
34    Arborist,
35  })
36}
37
38module.exports = tarball
39