UNPKG

@stryke/path

Version:

A package containing various utilities that expand the functionality of NodeJs's built-in `path` module

344 lines (342 loc) 14 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_join_paths = require('./join-paths.cjs'); const require_correct_path = require('./correct-path.cjs'); let _stryke_type_checks_is_set_string = require("@stryke/type-checks/is-set-string"); let _stryke_types_base = require("@stryke/types/base"); //#region src/file-path-fns.ts /** * Find the file name from a file path. * * @example * ```ts * const fileName = findFileName("C:\\Users\\user\\Documents\\file.txt"); * // fileName = "file.txt" * ``` * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns The file name */ function findFileName(filePath, options = {}) { const { requireExtension = false, withExtension = true } = options; const result = require_correct_path.normalizeWindowsPath(filePath)?.split(filePath?.includes("\\") ? "\\" : "/")?.pop() ?? ""; if (requireExtension === true && !result.includes(".")) return _stryke_types_base.EMPTY_STRING; if (withExtension === false && result.includes(".")) return result.replace(`.${findFileExtension(result, options) ?? ""}`, "") || _stryke_types_base.EMPTY_STRING; return result; } /** * Find the full file path's directories from a file path. * * @remarks * The functionality of this method is similar to the {@link _path.dirname} function in Node's path module. * * @example * ```ts * const folderPath = findFilePath("C:\\Users\\user\\Documents\\file.txt"); * // folderPath = "C:\\Users\\user\\Documents" * ``` * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns The full file path's directories */ function findFilePath(filePath, options = {}) { const normalizedPath = require_correct_path.normalizeWindowsPath(filePath); const result = normalizedPath.replace(new RegExp(`\/${findFileName(normalizedPath, { requireExtension: false, ...options })}$`), ""); return result === "/" ? result : result.replace(/\/$/, ""); } const dirname = findFilePath; /** * Find the top most folder containing the file from a file path. * * @remarks * The functionality of this method is similar to the {@link _path.basename} function in Node's path module. * If you're looking for the full path of the folder (for example: `C:\\Users\\user\\Documents` instead of just `Documents`) containing the file, use {@link findFilePath} instead. * * @example * const folderPath = findFolderName("C:\\Users\\user\\Documents\\file.txt"); * // folderPath = "Documents" * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns The folder containing the file */ function findFolderName(filePath, options) { const segments = findFilePath(filePath, options).split("/"); let lastSegment = ""; for (let i = segments.length - 1; i >= 0; i--) { const val = segments[i]; if (val) { lastSegment = val; break; } } return lastSegment ?? _stryke_types_base.EMPTY_STRING; } const basename = findFolderName; /** * Find the file extension from a file path. * * @remarks * The functionality of this method is similar to the {@link path.extname} function in Node's path module. * The file extension is the part of the file name that comes after the last dot (`.`) in the file name. If the file name does not contain a dot, or if it ends with a dot, this function will return `undefined`. * * The returned extension **will not** include the dot, for example `txt` or `js` instead of `.txt` or `.js`. * * @example * ```ts * findFileExtension("C:\\Users\\user\\Documents\\file.config.ts"); // Returns "ts" * findFileExtension("C:\\Users\\user\\Documents\\file.d.ts"); // Returns "ts" * findFileExtension("C:\\Users\\user\\Documents\\file.d.ts", { fullExtension: true }); // Returns "d.ts" * findFileExtension("C:\\Users\\user\\Documents\\file.ts.map"); // Returns "ts" * findFileExtension("C:\\Users\\user\\Documents\\file.ts.map", { fullExtension: true }); // Returns "ts.map" * findFileExtension("C:\\Users\\user\\Documents\\file"); // Returns undefined * ``` * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns The file extension or undefined if no extension is found */ function findFileExtension(filePath, options) { if (filePath.endsWith(".") || filePath.endsWith("/")) return; const match = (options?.fullExtension ? require_regex.FULL_FILE_EXTENSION_REGEX : require_regex.FILE_EXTENSION_REGEX).exec(require_correct_path.normalizeWindowsPath(filePath)); return match && match.length > 0 && (0, _stryke_type_checks_is_set_string.isSetString)(match[0]) ? match[0].replace(".", "") : void 0; } const extname = findFileExtension; /** * Find the file extension including the `"."` character prefix from a file path. * * @remarks * The file extension is the part of the file name that comes after (and including) the last dot (`.`) in the file name. If the file name does not contain a dot, or if it ends with a dot, this function will return `undefined`. * * The returned extension **will** include the dot, for example `.txt` or `.js` instead of `txt` or `js`. * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns The file extension (including the `"."` prefix) or undefined if no extension is found */ function findFileDotExtension(filePath, options) { const ext = findFileExtension(filePath, options); return ext ? `.${ext}` : void 0; } /** * Find the file extension from a file path or an empty string. * * @remarks * The file extension is the part of the file name that comes after the last dot (`.`) in the file name. If the file name does not contain a dot, or if it ends with a dot, this function will return `undefined`. * * The returned extension **will not** include the dot, for example `txt` or `js` instead of `.txt` or `.js`. * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns The file extension or an empty string if no extension is found */ function findFileExtensionSafe(filePath, options) { return findFileExtension(filePath, options) ?? _stryke_types_base.EMPTY_STRING; } /** * Find the file extension including the `"."` character prefix from a file path or an empty string. * * @remarks * The file extension is the part of the file name that comes after (and including) the last dot (`.`) in the file name. If the file name does not contain a dot, or if it ends with a dot, this function will return `undefined`. * * The returned extension **will** include the dot, for example `.txt` or `.js` instead of `txt` or `js`. * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns The file extension (including the `"."` prefix) or an empty string if no extension is found */ function findFileDotExtensionSafe(filePath, options) { const ext = findFileExtension(filePath, options); return ext ? `.${ext}` : ""; } /** * Check if a file path has a file name. * * @param filePath - The file path to process * @returns An indicator specifying if the file path has a file name */ function hasFileName(filePath) { return Boolean(findFileName(filePath)); } /** * Check if a file path has a file path. * * @param filePath - The file path to process * @returns An indicator specifying if the file path has a file path */ function hasFilePath(filePath) { return Boolean(findFilePath(filePath)); } /** * Check if a file path has a folder name. * * @param filePath - The file path to process * @returns An indicator specifying if the file path has a folder name */ function hasFolderName(filePath) { return Boolean(findFolderName(filePath)); } /** * Check if a file path has a file extension. * * @param filePath - The file path to process * @param options - Options to control the file name extraction * @returns An indicator specifying if the file path has a file extension */ function hasFileExtension(filePath, options) { return Boolean(findFileExtension(filePath, options)); } /** * Resolve the file path to an absolute path. * * @param path - The path to resolve * @param cwd - The current working directory * @returns The resolved path */ function resolvePath(path, cwd$1 = require_cwd.cwd()) { const paths = require_correct_path.normalizeWindowsPath(path).split("/"); let resolvedPath = ""; let resolvedAbsolute = false; for (let index = paths.length - 1; index >= -1 && !resolvedAbsolute; index--) { const path = index >= 0 ? paths[index] : cwd$1; if (!path || path.length === 0) continue; resolvedPath = require_join_paths.joinPaths(path, resolvedPath); resolvedAbsolute = require_is_type.isAbsolutePath(path); } resolvedPath = require_correct_path.normalizeString(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute && !require_is_type.isAbsolutePath(resolvedPath)) return `/${resolvedPath}`; return resolvedPath.length > 0 ? resolvedPath : "."; } function resolve(...paths) { paths = paths.map((argument) => require_correct_path.normalizeWindowsPath(argument)); let resolvedPath = ""; let resolvedAbsolute = false; for (let index = paths.length - 1; index >= -1 && !resolvedAbsolute; index--) { const path = index >= 0 ? paths[index] : require_cwd.cwd(); if (!path || path.length === 0) continue; resolvedPath = `${path}/${resolvedPath}`; resolvedAbsolute = require_is_type.isAbsolute(path); } resolvedPath = require_correct_path.normalizeString(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute && !require_is_type.isAbsolute(resolvedPath)) return `/${resolvedPath}`; return resolvedPath.length > 0 ? resolvedPath : "."; } /** * Resolve the file path to an absolute path. * * @param paths - The paths to resolve * @returns The resolved path */ function resolvePaths(...paths) { return resolvePath(require_join_paths.joinPaths(...paths.map((path) => require_correct_path.normalizeWindowsPath(path)))); } /** * Get the relative path from one file to another. * * @remarks * This function is similar to the `path.relative` function in Node's path module. * * @param from - The base path to start from * @param to - The target path to resolve relative to the base path * @returns The relative path from the base path to the target path */ function relative(from, to) { const _from = resolve(from).replace(require_regex.ROOT_FOLDER_REGEX, "$1").split("/"); const _to = resolve(to).replace(require_regex.ROOT_FOLDER_REGEX, "$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("/"); } /** * Get the relative path from one file to another. * * @remarks * This function wraps the `path.relative` function in Node's path module. * * @param from - The base path to start from * @param to - The target path to resolve relative to the base path * @param withEndSlash - Whether to include a trailing slash at the end of the path * @returns The relative path from the base path to the target path */ function relativePath(from, to, withEndSlash = false) { return relative(withEndSlash !== true ? from.replace(/\/$/, "") : from, withEndSlash !== true ? to.replace(/\/$/, "") : to); } /** * Find the file path relative to the workspace root path. * * @param filePath - The file path to process * @returns The resolved file path */ function relativeToCurrentDir(filePath) { return relativePath(filePath, require_cwd.cwd()); } /** * Check if the path is a relative path. * * @param path - The path to check * @returns An indicator specifying if the path is a relative path */ function parsePath(path, options) { const root = /^[/\\]|^[a-z]:[/\\]/i.exec(path)?.[0]?.replace(/\\/g, "/") || ""; const normalizedPath = require_correct_path.normalizeWindowsPath(path); const segments = normalizedPath.replace(/\/$/, "").split("/").slice(0, -1); if (segments.length === 1 && /^[A-Z]:$/i.test(segments[0])) segments[0] += "/"; const base = findFolderName(normalizedPath, options); const dir = segments.join("/") || (require_is_type.isAbsolutePath(path) ? "/" : "."); const ext = findFileExtensionSafe(path, options); return { root, dir, base, ext, name: base.slice(0, base.length - ext.length) }; } /** * Rename the file name with a new name. * * @param filePath - The current file path being processed * @param newFileName - The updated file name being processed * @param options - Options to control the file name extraction * @returns The modified or unmodified file path. */ function renameFile(filePath, newFileName, options) { const file = parsePath(filePath, options); return require_join_paths.joinPaths(file.dir, newFileName.includes(".") ? newFileName : newFileName + file.ext); } //#endregion exports.basename = basename; exports.dirname = dirname; exports.extname = extname; exports.findFileDotExtension = findFileDotExtension; exports.findFileDotExtensionSafe = findFileDotExtensionSafe; exports.findFileExtension = findFileExtension; exports.findFileExtensionSafe = findFileExtensionSafe; exports.findFileName = findFileName; exports.findFilePath = findFilePath; exports.findFolderName = findFolderName; exports.hasFileExtension = hasFileExtension; exports.hasFileName = hasFileName; exports.hasFilePath = hasFilePath; exports.hasFolderName = hasFolderName; exports.parsePath = parsePath; exports.relative = relative; exports.relativePath = relativePath; exports.relativeToCurrentDir = relativeToCurrentDir; exports.renameFile = renameFile; exports.resolve = resolve; exports.resolvePath = resolvePath; exports.resolvePaths = resolvePaths;