File Explorer

/var/lang/lib/node_modules/npm/node_modules/npm-bundled/lib

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

0 dirs
1 file
index.js6.4 KB · 255 lines
'use strict' // walk the tree of deps starting from the top level list of bundled deps// Any deps at the top level that are depended on by a bundled dep that// does not have that dep in its own node_modules folder are considered// bundled deps as well.  This list of names can be passed to npm-packlist// as the "bundled" argument.  Additionally, packageJsonCache is shared so// packlist doesn't have to re-read files already consumed in this pass const fs = require('fs')const path = require('path')const EE = require('events').EventEmitter// we don't care about the package bins, but we share a pj cache// with other modules that DO care about it, so keep it nice.const normalizePackageBin = require('npm-normalize-package-bin') class BundleWalker extends EE {  constructor (opt) {    opt = opt || {}    super(opt)    this.path = path.resolve(opt.path || process.cwd())     this.parent = opt.parent || null    if (this.parent) {      this.result = this.parent.result      // only collect results in node_modules folders at the top level      // since the node_modules in a bundled dep is included always      if (!this.parent.parent) {        const base = path.basename(this.path)        const scope = path.basename(path.dirname(this.path))        this.result.add(/^@/.test(scope) ? scope + '/' + base : base)      }      this.root = this.parent.root      this.packageJsonCache = this.parent.packageJsonCache    } else {      this.result = new Set()      this.root = this.path      this.packageJsonCache = opt.packageJsonCache || new Map()    }     this.seen = new Set()    this.didDone = false    this.children = 0    this.node_modules = []    this.package = null    this.bundle = null  }   addListener (ev, fn) {    return this.on(ev, fn)  }   on (ev, fn) {    const ret = super.on(ev, fn)    if (ev === 'done' && this.didDone) {      this.emit('done', this.result)    }    return ret  }   done () {    if (!this.didDone) {      this.didDone = true      if (!this.parent) {        const res = Array.from(this.result)        this.result = res        this.emit('done', res)      } else {        this.emit('done')      }    }  }   start () {    const pj = path.resolve(this.path, 'package.json')    if (this.packageJsonCache.has(pj)) {      this.onPackage(this.packageJsonCache.get(pj))    } else {      this.readPackageJson(pj)    }    return this  }   readPackageJson (pj) {    fs.readFile(pj, (er, data) =>      er ? this.done() : this.onPackageJson(pj, data))  }   onPackageJson (pj, data) {    try {      this.package = normalizePackageBin(JSON.parse(data + ''))    } catch (er) {      return this.done()    }    this.packageJsonCache.set(pj, this.package)    this.onPackage(this.package)  }   allDepsBundled (pkg) {    return Object.keys(pkg.dependencies || {}).concat(      Object.keys(pkg.optionalDependencies || {}))  }   onPackage (pkg) {    // all deps are bundled if we got here as a child.    // otherwise, only bundle bundledDeps    // Get a unique-ified array with a short-lived Set    const bdRaw = this.parent ? this.allDepsBundled(pkg)      : pkg.bundleDependencies || pkg.bundledDependencies || []     const bd = Array.from(new Set(      Array.isArray(bdRaw) ? bdRaw      : bdRaw === true ? this.allDepsBundled(pkg)      : Object.keys(bdRaw)))     if (!bd.length) {      return this.done()    }     this.bundle = bd    this.readModules()  }   readModules () {    readdirNodeModules(this.path + '/node_modules', (er, nm) =>      er ? this.onReaddir([]) : this.onReaddir(nm))  }   onReaddir (nm) {    // keep track of what we have, in case children need it    this.node_modules = nm     this.bundle.forEach(dep => this.childDep(dep))    if (this.children === 0) {      this.done()    }  }   childDep (dep) {    if (this.node_modules.indexOf(dep) !== -1) {      if (!this.seen.has(dep)) {        this.seen.add(dep)        this.child(dep)      }    } else if (this.parent) {      this.parent.childDep(dep)    }  }   child (dep) {    const p = this.path + '/node_modules/' + dep    this.children += 1    const child = new BundleWalker({      path: p,      parent: this,    })    child.on('done', () => {      if (--this.children === 0) {        this.done()      }    })    child.start()  }} class BundleWalkerSync extends BundleWalker {  start () {    super.start()    this.done()    return this  }   readPackageJson (pj) {    try {      this.onPackageJson(pj, fs.readFileSync(pj))    } catch {      // empty catch    }    return this  }   readModules () {    try {      this.onReaddir(readdirNodeModulesSync(this.path + '/node_modules'))    } catch {      this.onReaddir([])    }  }   child (dep) {    new BundleWalkerSync({      path: this.path + '/node_modules/' + dep,      parent: this,    }).start()  }} const readdirNodeModules = (nm, cb) => {  fs.readdir(nm, (er, set) => {    if (er) {      cb(er)    } else {      const scopes = set.filter(f => /^@/.test(f))      if (!scopes.length) {        cb(null, set)      } else {        const unscoped = set.filter(f => !/^@/.test(f))        let count = scopes.length        scopes.forEach(scope => {          fs.readdir(nm + '/' + scope, (readdirEr, pkgs) => {            if (readdirEr || !pkgs.length) {              unscoped.push(scope)            } else {              unscoped.push.apply(unscoped, pkgs.map(p => scope + '/' + p))            }            if (--count === 0) {              cb(null, unscoped)            }          })        })      }    }  })} const readdirNodeModulesSync = nm => {  const set = fs.readdirSync(nm)  const unscoped = set.filter(f => !/^@/.test(f))  const scopes = set.filter(f => /^@/.test(f)).map(scope => {    try {      const pkgs = fs.readdirSync(nm + '/' + scope)      return pkgs.length ? pkgs.map(p => scope + '/' + p) : [scope]    } catch (er) {      return [scope]    }  }).reduce((a, b) => a.concat(b), [])  return unscoped.concat(scopes)} const walk = (options, callback) => {  const p = new Promise((resolve, reject) => {    new BundleWalker(options).on('done', resolve).on('error', reject).start()  })  return callback ? p.then(res => callback(null, res), callback) : p} const walkSync = options => {  return new BundleWalkerSync(options).start().result} module.exports = walkwalk.sync = walkSyncwalk.BundleWalker = BundleWalkerwalk.BundleWalkerSync = BundleWalkerSync