File Explorer

/proc/self/task/8/root/var/lang/lib/node_modules/npm/node_modules/@npmcli/arborist/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 /.

link.js4.3 KB · 163 lines
const relpath = require('./relpath.js')const Node = require('./node.js')const _loadDeps = Symbol.for('Arborist.Node._loadDeps')const _target = Symbol.for('_target')const { dirname } = require('node:path')// defined by Node classconst _delistFromMeta = Symbol.for('_delistFromMeta')const _refreshLocation = Symbol.for('_refreshLocation')class Link extends Node {  constructor (options) {    const { root, realpath, target, parent, fsParent, isStoreLink } = options     if (!realpath && !(target && target.path)) {      throw new TypeError('must provide realpath for Link node')    }     super({      ...options,      realpath: realpath || target.path,      root: root || (parent ? parent.root      : fsParent ? fsParent.root      : target ? target.root      : null),    })     this.isStoreLink = isStoreLink || false     if (target) {      this.target = target    } else if (this.realpath === this.root.path) {      this.target = this.root    } else {      this.target = new Node({        ...options,        path: realpath,        parent: null,        fsParent: null,        root: this.root,      })    }  }   get version () {    return this.target ? this.target.version : this.package.version || ''  }   get target () {    return this[_target]  }   set target (target) {    const current = this[_target]    if (target === current) {      return    }     if (!target) {      if (current && current.linksIn) {        current.linksIn.delete(this)      }      if (this.path) {        this[_delistFromMeta]()        this[_target] = null        this.package = {}        this[_refreshLocation]()      } else {        this[_target] = null      }      return    }     if (!this.path) {      // temp node pending assignment to a tree      // we know it's not in the inventory yet, because no path.      if (target.path) {        this.realpath = target.path      } else {        target.path = target.realpath = this.realpath      }      target.root = this.root      this[_target] = target      target.linksIn.add(this)      this.package = target.package      return    }     // have to refresh metadata, because either realpath or package    // is very likely changing.    this[_delistFromMeta]()    this.package = target.package    this.realpath = target.path    this[_refreshLocation]()     target.root = this.root  }   // a link always resolves to the relative path to its target  get resolved () {    // the path/realpath guard is there for the benefit of setting    // these things in the "wrong" order    return this.path && this.realpath      ? `file:${relpath(dirname(this.path), this.realpath)}`      : null  }   set resolved (r) {}   // deps are resolved on the target, not the Link  // so this is a no-op  [_loadDeps] () {}   // Forward overrides to the target only when a rule names a dep it needs, directly or transitively (npm/cli#9357, #9619).  recalculateOutEdgesOverrides () {    if (!this.target || !this.overrides) {      return    }    if (!overrideMatchesSubtree(this.overrides, this.target)) {      return    }    this.target.updateOverridesEdgeInAdded(this.overrides)  }   // links can't have children, only their targets can  // fix it to an empty list so that we can still call  // things that iterate over them, just as a no-op  get children () {    return new Map()  }   set children (c) {}   get isLink () {    return true  }} // True when an override rule applies to an edge reachable from the target at any depth.// getEdgeRule matches on name and spec, returning the set itself when nothing applies, so a non-applicable version-qualified rule doesn't flip an intermediate node to "has overrides" (npm/cli#9357).// Not a method: runs from the Node super-constructor, before subclass private methods exist.const overrideMatchesSubtree = (overrides, target) => {  const seen = new Set()  const stack = [target]  while (stack.length) {    const node = stack.pop()    const resolved = node.isLink ? node.target : node    if (seen.has(resolved)) {      continue    }    seen.add(resolved)    for (const edge of resolved.edgesOut.values()) {      if (overrides.getEdgeRule(edge).name === edge.name) {        return true      }      if (edge.to) {        stack.push(edge.to)      }    }  }  return false} module.exports = Link