@stryke/path
Version:
A package containing various utilities that expand the functionality of NodeJs's built-in `path` module
237 lines (235 loc) • 7.96 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
const require_cwd = require('./cwd.cjs');
const require_regex = require('./regex.cjs');
const require_is_type = require('./is-type.cjs');
const require_slash = require('./slash.cjs');
const require_join_paths = require('./join-paths.cjs');
const require_append = require('./append.cjs');
let node_url = require("node:url");
//#region src/correct-path.ts
function normalizeWindowsPath(input = "") {
if (!input) return input;
return require_slash.slash(input).replace(require_regex.DRIVE_LETTER_START_REGEX, (r) => r.toUpperCase());
}
/**
* Corrects/normalized a file path.
*
* @param path - The path to correct.
* @returns The corrected path.
*/
function correctPath(path) {
if (!path || path.length === 0) return ".";
path = normalizeWindowsPath(path);
const isUNCPath = path.match(require_regex.UNC_REGEX);
const isPathAbsolute = require_is_type.isAbsolutePath(path);
const trailingSeparator = path.endsWith("/");
path = normalizeString(path, !isPathAbsolute);
if (path.length === 0) {
if (isPathAbsolute) return "/";
return trailingSeparator ? "./" : ".";
}
if (trailingSeparator) path += "/";
if (require_regex.DRIVE_LETTER_REGEX.test(path)) path += "/";
if (isUNCPath) {
if (!isPathAbsolute) return `//./${path}`;
return `//${path}`;
}
return !path.startsWith("/") && isPathAbsolute && !require_regex.DRIVE_LETTER_REGEX.test(path) ? `/${path}` : path;
}
/**
* Remove any star tokens (*) from the end of the file path
*
* @example
* stripStars("src/**") // returns "src"
* stripStars("src/*") // returns "src"
* stripStars("src/**\/*") // returns "src"
* stripStars("src/**\/*.txt") // returns "src"
* stripStars("src/**\/file.txt") // returns "src"
* stripStars("src/file.txt") // returns "src/file.txt"
* stripStars("") // returns "."
*
* @param path - The path to correct.
* @returns The corrected path.
*/
function stripStars(path) {
if (!path || path.length === 0) return ".";
path = correctPath(path);
let found = false;
return `${path.startsWith("/") ? "/" : ""}${path.split("/").reduce((ret, segment) => {
if (!segment?.trim()) return ret;
if (found || segment.includes("*")) {
found = true;
return ret;
}
return ret + (ret ? `/${segment}` : segment);
}, "")}`;
}
/**
* Resolves a string path, resolving '.' and '.' segments and allowing paths above the root.
*
* @param path - The path to normalize.
* @param allowAboveRoot - Whether to allow the resulting path to be above the root directory.
* @returns the normalize path string.
*/
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;
}
/**
* Converts a given path to an absolute path based on the current working directory.
*
* @param path - The path to convert to an absolute path.
* @param cwd - The current working directory to use as the base path if the path is not absolute.
* @returns The absolute path.
*/
function toAbsolutePath(path, cwd$1 = require_cwd.cwd()) {
if (require_is_type.isAbsolutePath(path)) return path;
return require_slash.slash(normalizeString(require_append.appendPath(path, cwd$1), true));
}
/**
* Converts a given path to a relative path based on the current working directory.
*
* @param path - The path to convert to a relative path.
* @param cwd - The current working directory to use as the base path if the path is not absolute.
* @returns The relative path.
*/
function toRelativePath(path, cwd$2 = require_cwd.cwd()) {
if (!path || path.length === 0) return ".";
if (require_is_type.isAbsolutePath(path)) path = require_slash.slash(normalizeString(path, true));
else path = require_slash.slash(normalizeString(require_join_paths.joinPaths(cwd$2, path), true));
if (path.startsWith("./")) return path.slice(2);
return path;
}
/**
* Adds a trailing slash to a path if it doesn't already have one.
*
* @param path - The path to modify.
* @returns The modified path with a trailing slash.
*/
function withTrailingSlash(path) {
const result = correctPath(path);
return result.endsWith("/") ? result : `${result}/`;
}
/**
* Removes a trailing slash from a path if it has one.
*
* @param path - The path to modify.
* @returns The modified path without a trailing slash.
*/
function withoutTrailingSlash(path) {
const result = correctPath(path);
return result.endsWith("/") ? result.slice(0, -1) : result;
}
/**
* Converts a file URL to a local file system path with normalized slashes.
*
* @example
* ```ts
* let filePath = fileURLToPath("file:///C:/Users/user/Documents/file.txt");
* // filePath = "C:/Users/user/Documents/file.txt"
*
* filePath = fileURLToPath(new URL("file:///C:/Users/user/Documents/file.txt"));
* // filePath = "C:/Users/user/Documents/file.txt"
* ```
*
* @param id - The file URL or local path to convert.
* @returns A normalized file system path.
*/
function fileURLToPath(id) {
if (typeof id === "string" && !id.startsWith("file://")) return correctPath(id);
return correctPath((0, node_url.fileURLToPath)(id));
}
/**
* Converts a local file system path to a file URL.
*
* @example
* ```ts
* let fileUrl = pathToFileURL("C:/Users/user/Documents/file.txt");
* // fileUrl = new URL("file:///C:/Users/user/Documents/file.txt")
*
* fileUrl = pathToFileURL(new URL("C:/Users/user/Documents/file.txt"));
* // fileUrl = new URL("file:///C:/Users/user/Documents/file.txt")
* ```
*
* @param id - The file system path to convert.
* @returns The resulting file URL as a URL object.
*/
function pathToFileURL(id) {
return (0, node_url.pathToFileURL)(fileURLToPath(id));
}
/**
* Converts a local file system path to a file URL string.
*
* @example
* ```ts
* let fileUrl = pathToFileURLString("C:/Users/user/Documents/file.txt");
* // fileUrl = "file:///C:/Users/user/Documents/file.txt"
*
* fileUrl = pathToFileURLString(new URL("C:/Users/user/Documents/file.txt"));
* // fileUrl = "file:///C:/Users/user/Documents/file.txt"
* ```
*
* @param id - The file system path to convert.
* @returns The resulting file URL as a string.
*/
function pathToFileURLString(id) {
return pathToFileURL(id).toString();
}
//#endregion
exports.correctPath = correctPath;
exports.fileURLToPath = fileURLToPath;
exports.normalizeString = normalizeString;
exports.normalizeWindowsPath = normalizeWindowsPath;
exports.pathToFileURL = pathToFileURL;
exports.pathToFileURLString = pathToFileURLString;
exports.stripStars = stripStars;
exports.toAbsolutePath = toAbsolutePath;
exports.toRelativePath = toRelativePath;
exports.withTrailingSlash = withTrailingSlash;
exports.withoutTrailingSlash = withoutTrailingSlash;