Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add jsdocs for pathe/utils #170

Merged
merged 3 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 13 additions & 16 deletions src/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ 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 _EXTNAME_RE = /.(\.[^./]+)$/;

// Force POSIX constants

// Force POSIX contants
export const sep = "/";
export const delimiter = ":";
export const sep: typeof path.sep = "/";

export const delimiter: typeof path.delimiter = ":";

// normalize
export const normalize: typeof path.normalize = function (path: string) {
if (path.length === 0) {
return ".";
Expand Down Expand Up @@ -58,7 +60,6 @@ export const normalize: typeof path.normalize = function (path: string) {
return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
};

// join
export const join: typeof path.join = function (...arguments_) {
if (arguments_.length === 0) {
return ".";
Expand Down Expand Up @@ -88,7 +89,6 @@ function cwd() {
return "/";
}

// resolve
export const resolve: typeof path.resolve = function (...arguments_) {
// Normalize windows arguments
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
Expand Down Expand Up @@ -125,7 +125,13 @@ export const resolve: typeof path.resolve = function (...arguments_) {
return resolvedPath.length > 0 ? resolvedPath : ".";
};

// Resolves . and .. elements in a path with directory names
/**
* Resolves a string path, resolving '.' and '.' segments and allowing paths above the root.
*
* @param path - The path to normalise.
* @param allowAboveRoot - Whether to allow the resulting path to be above the root directory.
* @returns the normalised path string.
*/
export function normalizeString(path: string, allowAboveRoot: boolean) {
let res = "";
let lastSegmentLength = 0;
Expand Down Expand Up @@ -193,24 +199,19 @@ export function normalizeString(path: string, allowAboveRoot: boolean) {
return res;
}

// isAbsolute
export const isAbsolute: typeof path.isAbsolute = function (p) {
return _IS_ABSOLUTE_RE.test(p);
};

// toNamespacedPath
export const toNamespacedPath: typeof path.toNamespacedPath = function (p) {
return normalizeWindowsPath(p);
};

// extname
const _EXTNAME_RE = /.(\.[^./]+)$/;
export const extname: typeof path.extname = function (p) {
const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
return (match && match[1]) || "";
};

// relative
export const relative: typeof path.relative = function (from, to) {
const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
Expand All @@ -231,7 +232,6 @@ export const relative: typeof path.relative = function (from, to) {
return [..._from.map(() => ".."), ..._to].join("/");
};

// dirname
export const dirname: typeof path.dirname = function (p) {
const segments = normalizeWindowsPath(p)
.replace(/\/$/, "")
Expand All @@ -243,23 +243,20 @@ export const dirname: typeof path.dirname = function (p) {
return segments.join("/") || (isAbsolute(p) ? "/" : ".");
};

// format
export const format: typeof path.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("/"),
);
};

// basename
export const basename: typeof path.basename = function (p, extension) {
const lastSegment = normalizeWindowsPath(p).split("/").pop();
return extension && lastSegment.endsWith(extension)
? lastSegment.slice(0, -extension.length)
: lastSegment;
};

// parse
export const parse: typeof path.parse = function (p) {
const root = normalizeWindowsPath(p).split("/").shift() || "/";
const base = basename(p);
Expand Down
21 changes: 21 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ const pathSeparators = new Set(["/", "\\", undefined]);

const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias");

/**
* Normalises alias mappings, ensuring that more specific aliases are resolved before less specific ones.
* This function also ensures that aliases do not resolve to themselves cyclically.
*
* @param _aliases - A set of alias mappings where each key is an alias and its value is the actual path it points to.
* @returns a set of normalised alias mappings.
*/
export function normalizeAliases(_aliases: Record<string, string>) {
if ((_aliases as any)[normalizedAliasSymbol]) {
return _aliases;
Expand Down Expand Up @@ -39,6 +46,14 @@ export function normalizeAliases(_aliases: Record<string, string>) {
return aliases;
}

/**
* Resolves a path string to its alias if applicable, otherwise returns the original path.
* This function normalises the path, resolves the alias and then joins it to the alias target if necessary.
*
* @param path - The path string to resolve.
* @param aliases - A set of alias mappings to use for resolution.
* @returns the resolved path as a string.
*/
export function resolveAlias(path: string, aliases: Record<string, string>) {
const _path = normalizeWindowsPath(path);
aliases = normalizeAliases(aliases);
Expand All @@ -59,6 +74,12 @@ export function resolveAlias(path: string, aliases: Record<string, string>) {

const FILENAME_RE = /(^|[/\\])([^/\\]+?)(?=(\.[^.]+)?$)/;

/**
* Extracts the filename from a given path, excluding any directory paths and the file extension.
*
* @param path - The full path of the file from which to extract the filename.
* @returns the filename without the extension, or `undefined` if the filename cannot be extracted.
*/
export function filename(path: string) {
return path.match(FILENAME_RE)?.[2];
}
Expand Down
Loading