????JFIF??x?x????'
| Server IP : 172.67.174.47 / Your IP : 216.73.216.145 Web Server : LiteSpeed System : Linux premium151.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64 User : tempvsty ( 647) PHP Version : 8.0.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /././opt/alt/alt-nodejs18/root/lib/node_modules/npm/node_modules/bin-links/lib/ |
Upload File : |
// if the thing isn't there, skip it
// if there's a non-symlink there already, eexist
// if there's a symlink already, pointing somewhere else, eexist
// if there's a symlink already, pointing into our pkg, remove it first
// then create the symlink
const { resolve, dirname } = require('path')
const { lstat, mkdir, readlink, rm, symlink } = require('fs/promises')
const throwNonEnoent = er => {
if (er.code !== 'ENOENT') {
throw er
}
}
const rmOpts = {
recursive: true,
force: true,
}
// even in --force mode, we never create a link over a link we've
// already created. you can have multiple packages in a tree trying
// to contend for the same bin, or the same manpage listed multiple times,
// which creates a race condition and nondeterminism.
const seen = new Set()
const SKIP = Symbol('skip - missing or already installed')
const CLOBBER = Symbol('clobber - ours or in forceful mode')
const linkGently = async ({ path, to, from, absFrom, force }) => {
if (seen.has(to)) {
return false
}
seen.add(to)
// if the script or manpage isn't there, just ignore it.
// this arguably *should* be an install error of some sort,
// or at least a warning, but npm has always behaved this
// way in the past, so it'd be a breaking change
return Promise.all([
lstat(absFrom).catch(throwNonEnoent),
lstat(to).catch(throwNonEnoent),
]).then(([stFrom, stTo]) => {
// not present in package, skip it
if (!stFrom) {
return SKIP
}
// exists! maybe clobber if we can
if (stTo) {
if (!stTo.isSymbolicLink()) {
return force && rm(to, rmOpts).then(() => CLOBBER)
}
return readlink(to).then(target => {
if (target === from) {
return SKIP
} // skip it, already set up like we want it.
target = resolve(dirname(to), target)
if (target.indexOf(path) === 0 || force) {
return rm(to, rmOpts).then(() => CLOBBER)
}
// neither skip nor clobber
return false
})
} else {
// doesn't exist, dir might not either
return mkdir(dirname(to), { recursive: true })
}
})
.then(skipOrClobber => {
if (skipOrClobber === SKIP) {
return false
}
return symlink(from, to, 'file').catch(er => {
if (skipOrClobber === CLOBBER || force) {
return rm(to, rmOpts).then(() => symlink(from, to, 'file'))
}
throw er
}).then(() => true)
})
}
const resetSeen = () => {
for (const p of seen) {
seen.delete(p)
}
}
module.exports = Object.assign(linkGently, { resetSeen })