UNPKG

exstack

Version:

A utility library designed to simplify and enhance Express.js applications.

77 lines (75 loc) 2.43 kB
//#region src/router/utils.ts /** * Merge paths. * @param {string[]} ...paths - The paths to merge. * @returns {string} The merged path. * @example * mergePath('/api', '/users') // '/api/users' * mergePath('/api/', '/users') // '/api/users' * mergePath('/api', '/') // '/api' * mergePath('/api/', '/') // '/api/' */ const mergePath = (base, sub, ...rest) => { if (rest.length) sub = mergePath(sub, ...rest); return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`; }; const tryDecode = (str, decoder) => { try { return decoder(str); } catch { return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => { try { return decoder(match); } catch { return match; } }); } }; /** * Detects and expands optional parameters in a route path. * * Example: * /api/animals/:type? * → ['/api/animals', '/api/animals/:type'] * * If there is no optional parameter, returns null. */ const checkOptionalParameter = (path) => { if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) return null; const segments = path.split("/"); const results = []; let basePath = ""; for (const segment of segments) if (segment && !segment.includes(":")) basePath += "/" + segment; else if (segment.includes(":")) if (segment.includes("?")) { results.push(basePath === "" ? "/" : basePath); const optionalSegment = segment.replace("?", ""); basePath += "/" + optionalSegment; results.push(basePath); } else basePath += "/" + segment; return [...new Set(results)]; }; /** * Cache for precompiled wildcard regular expressions. */ let wildcardRegExpCache = Object.create(null); /** * Converts a path with wildcards into a RegExp for quick matching. * Example: * /api/* → /^\/api(?:|\/.*)$/ */ function buildWildcardRegExp(path) { return wildcardRegExpCache[path] ??= /* @__PURE__ */ new RegExp(path === "*" ? "" : `^${path.replace(/\/\*$|([.\\+*[^\]$()])/g, (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)")}$`); } /** * Clears wildcard cache (useful after routes are built). */ function clearWildcardRegExpCache() { wildcardRegExpCache = Object.create(null); } //#endregion exports.buildWildcardRegExp = buildWildcardRegExp; exports.checkOptionalParameter = checkOptionalParameter; exports.clearWildcardRegExpCache = clearWildcardRegExpCache; exports.mergePath = mergePath; exports.tryDecode = tryDecode;