"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const utils = require("./utils.cjs"); function joinPaths(paths) { return cleanPath( paths.filter((val) => { return val !== void 0; }).join("/") ); } function cleanPath(path) { return path.replace(/\/{2,}/g, "/"); } function trimPathLeft(path) { return path === "/" ? path : path.replace(/^\/{1,}/, ""); } function trimPathRight(path) { return path === "/" ? path : path.replace(/\/{1,}$/, ""); } function trimPath(path) { return trimPathRight(trimPathLeft(path)); } function removeTrailingSlash(value, basepath) { if ((value == null ? void 0 : value.endsWith("/")) && value !== "/" && value !== `${basepath}/`) { return value.slice(0, -1); } return value; } function exactPathTest(pathName1, pathName2, basepath) { return removeTrailingSlash(pathName1, basepath) === removeTrailingSlash(pathName2, basepath); } function resolvePath({ basepath, base, to, trailingSlash = "never", caseSensitive }) { var _a, _b; base = removeBasepath(basepath, base, caseSensitive); to = removeBasepath(basepath, to, caseSensitive); let baseSegments = parsePathname(base); const toSegments = parsePathname(to); if (baseSegments.length > 1 && ((_a = utils.last(baseSegments)) == null ? void 0 : _a.value) === "/") { baseSegments.pop(); } toSegments.forEach((toSegment, index) => { if (toSegment.value === "/") { if (!index) { baseSegments = [toSegment]; } else if (index === toSegments.length - 1) { baseSegments.push(toSegment); } else ; } else if (toSegment.value === "..") { baseSegments.pop(); } else if (toSegment.value === ".") ; else { baseSegments.push(toSegment); } }); if (baseSegments.length > 1) { if (((_b = utils.last(baseSegments)) == null ? void 0 : _b.value) === "/") { if (trailingSlash === "never") { baseSegments.pop(); } } else if (trailingSlash === "always") { baseSegments.push({ type: "pathname", value: "/" }); } } const joined = joinPaths([basepath, ...baseSegments.map((d) => d.value)]); return cleanPath(joined); } function parsePathname(pathname) { if (!pathname) { return []; } pathname = cleanPath(pathname); const segments = []; if (pathname.slice(0, 1) === "/") { pathname = pathname.substring(1); segments.push({ type: "pathname", value: "/" }); } if (!pathname) { return segments; } const split = pathname.split("/").filter(Boolean); segments.push( ...split.map((part) => { if (part === "$" || part === "*") { return { type: "wildcard", value: part }; } if (part.charAt(0) === "$") { return { type: "param", value: part }; } return { type: "pathname", value: part.includes("%25") ? part.split("%25").map((segment) => decodeURI(segment)).join("%25") : decodeURI(part) }; }) ); if (pathname.slice(-1) === "/") { pathname = pathname.substring(1); segments.push({ type: "pathname", value: "/" }); } return segments; } function interpolatePath({ path, params, leaveWildcards, leaveParams, decodeCharMap }) { const interpolatedPathSegments = parsePathname(path); function encodeParam(key) { const value = params[key]; const isValueString = typeof value === "string"; if (["*", "_splat"].includes(key)) { return isValueString ? encodeURI(value) : value; } else { return isValueString ? encodePathParam(value, decodeCharMap) : value; } } const usedParams = {}; const interpolatedPath = joinPaths( interpolatedPathSegments.map((segment) => { if (segment.type === "wildcard") { usedParams._splat = params._splat; const value = encodeParam("_splat"); if (leaveWildcards) return `${segment.value}${value ?? ""}`; return value; } if (segment.type === "param") { const key = segment.value.substring(1); usedParams[key] = params[key]; if (leaveParams) { const value = encodeParam(segment.value); return `${segment.value}${value ?? ""}`; } return encodeParam(key) ?? "undefined"; } return segment.value; }) ); return { usedParams, interpolatedPath }; } function encodePathParam(value, decodeCharMap) { let encoded = encodeURIComponent(value); if (decodeCharMap) { for (const [encodedChar, char] of decodeCharMap) { encoded = encoded.replaceAll(encodedChar, char); } } return encoded; } function matchPathname(basepath, currentPathname, matchLocation) { const pathParams = matchByPath(basepath, currentPathname, matchLocation); if (matchLocation.to && !pathParams) { return; } return pathParams ?? {}; } function removeBasepath(basepath, pathname, caseSensitive = false) { const normalizedBasepath = caseSensitive ? basepath : basepath.toLowerCase(); const normalizedPathname = caseSensitive ? pathname : pathname.toLowerCase(); switch (true) { // default behaviour is to serve app from the root - pathname // left untouched case normalizedBasepath === "/": return pathname; // shortcut for removing the basepath if it matches the pathname case normalizedPathname === normalizedBasepath: return ""; // in case pathname is shorter than basepath - there is // nothing to remove case pathname.length < basepath.length: return pathname; // avoid matching partial segments - strict equality handled // earlier, otherwise, basepath separated from pathname with // separator, therefore lack of separator means partial // segment match (`/app` should not match `/application`) case normalizedPathname[normalizedBasepath.length] !== "/": return pathname; // remove the basepath from the pathname if it starts with it case normalizedPathname.startsWith(normalizedBasepath): return pathname.slice(basepath.length); // otherwise, return the pathname as is default: return pathname; } } function matchByPath(basepath, from, matchLocation) { if (basepath !== "/" && !from.startsWith(basepath)) { return void 0; } from = removeBasepath(basepath, from, matchLocation.caseSensitive); const to = removeBasepath( basepath, `${matchLocation.to ?? "$"}`, matchLocation.caseSensitive ); const baseSegments = parsePathname(from); const routeSegments = parsePathname(to); if (!from.startsWith("/")) { baseSegments.unshift({ type: "pathname", value: "/" }); } if (!to.startsWith("/")) { routeSegments.unshift({ type: "pathname", value: "/" }); } const params = {}; const isMatch = (() => { for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) { const baseSegment = baseSegments[i]; const routeSegment = routeSegments[i]; const isLastBaseSegment = i >= baseSegments.length - 1; const isLastRouteSegment = i >= routeSegments.length - 1; if (routeSegment) { if (routeSegment.type === "wildcard") { const _splat = decodeURI( joinPaths(baseSegments.slice(i).map((d) => d.value)) ); params["*"] = _splat; params["_splat"] = _splat; return true; } if (routeSegment.type === "pathname") { if (routeSegment.value === "/" && !(baseSegment == null ? void 0 : baseSegment.value)) { return true; } if (baseSegment) { if (matchLocation.caseSensitive) { if (routeSegment.value !== baseSegment.value) { return false; } } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) { return false; } } } if (!baseSegment) { return false; } if (routeSegment.type === "param") { if (baseSegment.value === "/") { return false; } if (baseSegment.value.charAt(0) !== "$") { params[routeSegment.value.substring(1)] = decodeURIComponent( baseSegment.value ); } } } if (!isLastBaseSegment && isLastRouteSegment) { params["**"] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value)); return !!matchLocation.fuzzy && (routeSegment == null ? void 0 : routeSegment.value) !== "/"; } } return true; })(); return isMatch ? params : void 0; } exports.cleanPath = cleanPath; exports.exactPathTest = exactPathTest; exports.interpolatePath = interpolatePath; exports.joinPaths = joinPaths; exports.matchByPath = matchByPath; exports.matchPathname = matchPathname; exports.parsePathname = parsePathname; exports.removeBasepath = removeBasepath; exports.removeTrailingSlash = removeTrailingSlash; exports.resolvePath = resolvePath; exports.trimPath = trimPath; exports.trimPathLeft = trimPathLeft; exports.trimPathRight = trimPathRight; //# sourceMappingURL=path.cjs.map