UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

57 lines 1.96 kB
import { parsePathTemplate } from "../contracts/index.js"; export class PathDecodeError extends Error { constructor() { super("Malformed URL path"); this.name = "PathDecodeError"; } } function encodeStaticSegment(value) { return encodeURI(value).replace(/[?#]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`); } function matchPercentEncodingCase(value) { return value.replace(/%([0-9A-F]{2})/g, (_match, encoded) => { const digits = [...encoded] .map((digit) => /[A-F]/.test(digit) ? `[${digit}${digit.toLowerCase()}]` : digit) .join(""); return `%${digits}`; }); } export function compilePath(path) { const parsed = parsePathTemplate(path); const regexParts = parsed.segments.map((segment) => segment.kind === "dynamic" ? "([^/]+)" : matchPercentEncodingCase(encodeStaticSegment(segment.value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))); const pattern = new RegExp(`^/${regexParts.join("/")}$`); return { ...parsed, pattern }; } export function decodeMatchedParams(keys, match) { const params = {}; try { keys.forEach((key, index) => { params[key] = decodeURIComponent(match[index + 1]); }); } catch (error) { if (error instanceof URIError) { throw new PathDecodeError(); } throw error; } return params; } export function compareRouteSpecificity(a, b) { const maxLength = Math.max(a.segments.length, b.segments.length); for (let index = 0; index < maxLength; index++) { const aSegment = a.segments[index]; const bSegment = b.segments[index]; if (!aSegment) return 1; if (!bSegment) return -1; if (aSegment.kind === bSegment.kind) continue; return aSegment.kind === "static" ? -1 : 1; } return 0; } //# sourceMappingURL=route-matching.js.map