shelving
Version:
Toolkit for using data in JavaScript.
60 lines (59 loc) • 2.62 kB
JavaScript
import { RequiredError } from "../error/RequiredError.js";
import { notOptional } from "./optional.js";
/** Is a string path an absolute path? */
export function isAbsolutePath(path) {
return path.startsWith("/");
}
/** Is a string path an absolute path? */
export function isRelativePath(path) {
return path.startsWith("./") || path.startsWith("../");
}
function _cleanPath(path) {
return path
.replace(/[/\\]+/g, "/") // Normalise slashes.
.replace(/(?!^)\/$/g, ""); // Trailing slashes.
}
/**
* Resolve a relative or absolute path and return the absolute path, or `undefined` if not a valid path.
* - Uses `new URL` to do path processing, so URL strings can also be resolved.
* - Returned paths are cleaned with `cleanPath()` so runs of slashes and trailing slashes are removed.
*
* @param value Absolute path e.g. `/a/b/c`, relative path e.g. `./a` or `b` or `../c`, URL string e.g. `http://shax.com/a/b/c`, or `URL` instance.
* @param base Absolute path used for resolving relative paths in `possible`
* @return Absolute path with a leading trailing slash, e.g. `/a/c/b`
*/
export function getPath(value, base = "/") {
if (notOptional(value)) {
try {
const { pathname, search, hash } = new URL(value, `http://j.com${base}/`);
if (isAbsolutePath(pathname))
return `${_cleanPath(pathname)}${search}${hash}`;
}
catch {
//
}
}
}
/**
* Resolve a relative or absolute path and return the path, or throw `RequiredError` if not a valid path.
* - Internally uses `new URL` to do path processing but shouldn't ever reveal that fact.
* - Returned paths are cleaned with `cleanPath()` so runs of slashes and trailing slashes are removed.
*
* @param value Absolute path e.g. `/a/b/c`, relative path e.g. `./a` or `b` or `../c`, URL string e.g. `http://shax.com/a/b/c`, or `URL` instance.
* @param base Absolute path used for resolving relative paths in `possible`
* @return Absolute path with a leading trailing slash, e.g. `/a/c/b`
*/
export function requirePath(value, base, caller = requirePath) {
const path = getPath(value, base);
if (!path)
throw new RequiredError("Invalid URL", { received: value, caller });
return path;
}
/** Is a target path active? */
export function isPathActive(target, current) {
return target === current;
}
/** Is a target path proud (i.e. is the current path, or is a child of the current path)? */
export function isPathProud(target, current) {
return target === current || (target !== "/" && target.startsWith(`${current}/`));
}