123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- "use strict";
- const fs = require("fs");
- const path = require("path");
- const EXPECTED_ERRORS = new Set(["EINVAL", "ENOENT"]);
- if (process.platform === "win32") EXPECTED_ERRORS.add("UNKNOWN");
- class LinkResolver {
- constructor() {
- this.cache = new Map();
- }
-
- resolve(file) {
- const cacheEntry = this.cache.get(file);
- if (cacheEntry !== undefined) {
- return cacheEntry;
- }
- const parent = path.dirname(file);
- if (parent === file) {
-
- const result = Object.freeze([file]);
- this.cache.set(file, result);
- return result;
- }
-
- const parentResolved = this.resolve(parent);
- let realFile = file;
-
- if (parentResolved[0] !== parent) {
-
- const basename = path.basename(file);
- realFile = path.resolve(parentResolved[0], basename);
- }
-
- try {
- const linkContent = fs.readlinkSync(realFile);
-
- const resolvedLink = path.resolve(parentResolved[0], linkContent);
-
- const linkResolved = this.resolve(resolvedLink);
-
- let result;
- if (linkResolved.length > 1 && parentResolved.length > 1) {
-
- const resultSet = new Set(linkResolved);
-
- resultSet.add(realFile);
-
- for (let i = 1; i < parentResolved.length; i++) {
- resultSet.add(parentResolved[i]);
- }
- result = Object.freeze(Array.from(resultSet));
- } else if (parentResolved.length > 1) {
-
- result = parentResolved.slice();
- result[0] = linkResolved[0];
-
- result.push(realFile);
- Object.freeze(result);
- } else if (linkResolved.length > 1) {
-
- result = linkResolved.slice();
-
- result.push(realFile);
- Object.freeze(result);
- } else {
-
-
- result = Object.freeze([
-
- linkResolved[0],
-
- realFile
- ]);
- }
- this.cache.set(file, result);
- return result;
- } catch (e) {
- if (!EXPECTED_ERRORS.has(e.code)) {
- throw e;
- }
-
- const result = parentResolved.slice();
- result[0] = realFile;
- Object.freeze(result);
- this.cache.set(file, result);
- return result;
- }
- }
- }
- module.exports = LinkResolver;
|