|
'use strict'; |
|
|
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; |
|
function normalizeWindowsPath(input = "") { |
|
if (!input) { |
|
return input; |
|
} |
|
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); |
|
} |
|
|
|
const _UNC_REGEX = /^[/\\]{2}/; |
|
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; |
|
const _DRIVE_LETTER_RE = /^[A-Za-z]:$/; |
|
const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; |
|
const sep = "/"; |
|
const delimiter = ":"; |
|
const normalize = function(path) { |
|
if (path.length === 0) { |
|
return "."; |
|
} |
|
path = normalizeWindowsPath(path); |
|
const isUNCPath = path.match(_UNC_REGEX); |
|
const isPathAbsolute = isAbsolute(path); |
|
const trailingSeparator = path[path.length - 1] === "/"; |
|
path = normalizeString(path, !isPathAbsolute); |
|
if (path.length === 0) { |
|
if (isPathAbsolute) { |
|
return "/"; |
|
} |
|
return trailingSeparator ? "./" : "."; |
|
} |
|
if (trailingSeparator) { |
|
path += "/"; |
|
} |
|
if (_DRIVE_LETTER_RE.test(path)) { |
|
path += "/"; |
|
} |
|
if (isUNCPath) { |
|
if (!isPathAbsolute) { |
|
return `//./${path}`; |
|
} |
|
return `//${path}`; |
|
} |
|
return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; |
|
}; |
|
const join = function(...arguments_) { |
|
if (arguments_.length === 0) { |
|
return "."; |
|
} |
|
let joined; |
|
for (const argument of arguments_) { |
|
if (argument && argument.length > 0) { |
|
if (joined === void 0) { |
|
joined = argument; |
|
} else { |
|
joined += `/${argument}`; |
|
} |
|
} |
|
} |
|
if (joined === void 0) { |
|
return "."; |
|
} |
|
return normalize(joined.replace(/\/\/+/g, "/")); |
|
}; |
|
function cwd() { |
|
if (typeof process !== "undefined" && typeof process.cwd === "function") { |
|
return process.cwd().replace(/\\/g, "/"); |
|
} |
|
return "/"; |
|
} |
|
const resolve = function(...arguments_) { |
|
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); |
|
let resolvedPath = ""; |
|
let resolvedAbsolute = false; |
|
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { |
|
const path = index >= 0 ? arguments_[index] : cwd(); |
|
if (!path || path.length === 0) { |
|
continue; |
|
} |
|
resolvedPath = `${path}/${resolvedPath}`; |
|
resolvedAbsolute = isAbsolute(path); |
|
} |
|
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); |
|
if (resolvedAbsolute && !isAbsolute(resolvedPath)) { |
|
return `/${resolvedPath}`; |
|
} |
|
return resolvedPath.length > 0 ? resolvedPath : "."; |
|
}; |
|
function normalizeString(path, allowAboveRoot) { |
|
let res = ""; |
|
let lastSegmentLength = 0; |
|
let lastSlash = -1; |
|
let dots = 0; |
|
let char = null; |
|
for (let index = 0; index <= path.length; ++index) { |
|
if (index < path.length) { |
|
char = path[index]; |
|
} else if (char === "/") { |
|
break; |
|
} else { |
|
char = "/"; |
|
} |
|
if (char === "/") { |
|
if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { |
|
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { |
|
if (res.length > 2) { |
|
const lastSlashIndex = res.lastIndexOf("/"); |
|
if (lastSlashIndex === -1) { |
|
res = ""; |
|
lastSegmentLength = 0; |
|
} else { |
|
res = res.slice(0, lastSlashIndex); |
|
lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); |
|
} |
|
lastSlash = index; |
|
dots = 0; |
|
continue; |
|
} else if (res.length > 0) { |
|
res = ""; |
|
lastSegmentLength = 0; |
|
lastSlash = index; |
|
dots = 0; |
|
continue; |
|
} |
|
} |
|
if (allowAboveRoot) { |
|
res += res.length > 0 ? "/.." : ".."; |
|
lastSegmentLength = 2; |
|
} |
|
} else { |
|
if (res.length > 0) { |
|
res += `/${path.slice(lastSlash + 1, index)}`; |
|
} else { |
|
res = path.slice(lastSlash + 1, index); |
|
} |
|
lastSegmentLength = index - lastSlash - 1; |
|
} |
|
lastSlash = index; |
|
dots = 0; |
|
} else if (char === "." && dots !== -1) { |
|
++dots; |
|
} else { |
|
dots = -1; |
|
} |
|
} |
|
return res; |
|
} |
|
const isAbsolute = function(p) { |
|
return _IS_ABSOLUTE_RE.test(p); |
|
}; |
|
const toNamespacedPath = function(p) { |
|
return normalizeWindowsPath(p); |
|
}; |
|
const _EXTNAME_RE = /.(\.[^./]+)$/; |
|
const extname = function(p) { |
|
const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); |
|
return match && match[1] || ""; |
|
}; |
|
const relative = function(from, to) { |
|
const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); |
|
const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); |
|
if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { |
|
return _to.join("/"); |
|
} |
|
const _fromCopy = [..._from]; |
|
for (const segment of _fromCopy) { |
|
if (_to[0] !== segment) { |
|
break; |
|
} |
|
_from.shift(); |
|
_to.shift(); |
|
} |
|
return [..._from.map(() => ".."), ..._to].join("/"); |
|
}; |
|
const dirname = function(p) { |
|
const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); |
|
if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) { |
|
segments[0] += "/"; |
|
} |
|
return segments.join("/") || (isAbsolute(p) ? "/" : "."); |
|
}; |
|
const format = function(p) { |
|
const segments = [p.root, p.dir, p.base ?? p.name + p.ext].filter(Boolean); |
|
return normalizeWindowsPath( |
|
p.root ? resolve(...segments) : segments.join("/") |
|
); |
|
}; |
|
const basename = function(p, extension) { |
|
const lastSegment = normalizeWindowsPath(p).split("/").pop(); |
|
return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment; |
|
}; |
|
const parse = function(p) { |
|
const root = normalizeWindowsPath(p).split("/").shift() || "/"; |
|
const base = basename(p); |
|
const extension = extname(base); |
|
return { |
|
root, |
|
dir: dirname(p), |
|
base, |
|
ext: extension, |
|
name: base.slice(0, base.length - extension.length) |
|
}; |
|
}; |
|
|
|
const path = { |
|
__proto__: null, |
|
basename: basename, |
|
delimiter: delimiter, |
|
dirname: dirname, |
|
extname: extname, |
|
format: format, |
|
isAbsolute: isAbsolute, |
|
join: join, |
|
normalize: normalize, |
|
normalizeString: normalizeString, |
|
parse: parse, |
|
relative: relative, |
|
resolve: resolve, |
|
sep: sep, |
|
toNamespacedPath: toNamespacedPath |
|
}; |
|
|
|
exports.basename = basename; |
|
exports.delimiter = delimiter; |
|
exports.dirname = dirname; |
|
exports.extname = extname; |
|
exports.format = format; |
|
exports.isAbsolute = isAbsolute; |
|
exports.join = join; |
|
exports.normalize = normalize; |
|
exports.normalizeString = normalizeString; |
|
exports.normalizeWindowsPath = normalizeWindowsPath; |
|
exports.parse = parse; |
|
exports.path = path; |
|
exports.relative = relative; |
|
exports.resolve = resolve; |
|
exports.sep = sep; |
|
exports.toNamespacedPath = toNamespacedPath; |
|
|