UNPKG

@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
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;