UNPKG

@flex-development/pathe

Version:

Universal drop-in replacement for node:path

57 lines (56 loc) 1.97 kB
import { DRIVE_PATH_REGEX } from "#internal/constants"; import validateString from "#internal/validate-string"; import dot from "#lib/dot"; import isSep from "#lib/is-sep"; import resolveWith from "#lib/resolve-with"; import sep from "#lib/sep"; var relative_default = relative; function relative(from, to, options) { if (!Array.isArray(from)) validateString(from, "from"); if (!Array.isArray(to)) validateString(to, "to"); if (from === to) return ""; from = resolveWith(from, options); to = resolveWith(to, options); if (from.toLowerCase() === to.toLowerCase()) return ""; const [fromLen, fromStart, fromEnd] = measure(from); const [toLen, toStart, toEnd] = measure(to); const length = fromLen < toLen ? fromLen : toLen; let lastCommonSep = -1; let i = 0; for (; i < length; i++) { const char = from.at(fromStart + i); if (char.toLowerCase() !== to.at(toStart + i).toLowerCase()) break; else if (isSep(char)) lastCommonSep = i; } if (i === length) { if (toLen > length) { if (isSep(to.at(toStart + i))) return to.slice(toStart + i + 1); if (i === 0 && isSep(from)) return to.slice(toStart + i); } if (fromLen > length) { if (isSep(from.at(fromStart + i))) lastCommonSep = i; else if (i === 0 && isSep(to)) lastCommonSep = i; } } else { if (lastCommonSep === -1) { if (DRIVE_PATH_REGEX.test(from) || DRIVE_PATH_REGEX.test(to)) return to; } } let out = ""; for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { if (i === fromEnd || isSep(from[i])) { out += `${out.length === 0 ? "" : sep}${dot.repeat(2)}`; } } return `${out}${to.slice(toStart + lastCommonSep, toEnd)}`; } function measure(path) { let start = 0; let end = path.length; while (start < path.length && isSep(path.at(start))) start++; while (end - 1 > start && isSep(path.at(end - 1))) end--; return [end - start, start, end]; } export { relative_default as default };