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