| Server IP : 82.148.16.210 / Your IP : 216.73.216.19 Web Server : nginx/1.29.5 System : Linux mail.sarafai.ru 6.1.0-43-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.162-1 (2026-02-08) x86_64 User : root ( 0) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /usr/share/node_modules/watchpack/lib/ |
Upload File : |
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const fs = require("fs");
const path = require("path");
// macOS, Linux, and Windows all rely on these errors
const EXPECTED_ERRORS = new Set(["EINVAL", "ENOENT"]);
// On Windows there is also this error in some cases
if (process.platform === "win32") EXPECTED_ERRORS.add("UNKNOWN");
class LinkResolver {
constructor() {
this.cache = new Map();
}
/**
* @param {string} file path to file or directory
* @returns {string[]} array of file and all symlinks contributed in the resolving process (first item is the resolved file)
*/
resolve(file) {
const cacheEntry = this.cache.get(file);
if (cacheEntry !== undefined) {
return cacheEntry;
}
const parent = path.dirname(file);
if (parent === file) {
// At root of filesystem there can't be a link
const result = Object.freeze([file]);
this.cache.set(file, result);
return result;
}
// resolve the parent directory to find links there and get the real path
const parentResolved = this.resolve(parent);
let realFile = file;
// is the parent directory really somewhere else?
if (parentResolved[0] !== parent) {
// get the real location of file
const basename = path.basename(file);
realFile = path.resolve(parentResolved[0], basename);
}
// try to read the link content
try {
const linkContent = fs.readlinkSync(realFile);
// resolve the link content relative to the parent directory
const resolvedLink = path.resolve(parentResolved[0], linkContent);
// recursive resolve the link content for more links in the structure
const linkResolved = this.resolve(resolvedLink);
// merge parent and link resolve results
let result;
if (linkResolved.length > 1 && parentResolved.length > 1) {
// when both contain links we need to duplicate them with a Set
const resultSet = new Set(linkResolved);
// add the link
resultSet.add(realFile);
// add all symlinks of the parent
for (let i = 1; i < parentResolved.length; i++) {
resultSet.add(parentResolved[i]);
}
result = Object.freeze(Array.from(resultSet));
} else if (parentResolved.length > 1) {
// we have links in the parent but not for the link content location
result = parentResolved.slice();
result[0] = linkResolved[0];
// add the link
result.push(realFile);
Object.freeze(result);
} else if (linkResolved.length > 1) {
// we can return the link content location result
result = linkResolved.slice();
// add the link
result.push(realFile);
Object.freeze(result);
} else {
// neither link content location nor parent have links
// this link is the only link here
result = Object.freeze([
// the resolve real location
linkResolved[0],
// add the link
realFile
]);
}
this.cache.set(file, result);
return result;
} catch (e) {
if (!EXPECTED_ERRORS.has(e.code)) {
throw e;
}
// no link
const result = parentResolved.slice();
result[0] = realFile;
Object.freeze(result);
this.cache.set(file, result);
return result;
}
}
}
module.exports = LinkResolver;