UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

60 lines (59 loc) 2.62 kB
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}/`)); }