@beignet/core
Version:
Core framework primitives for Beignet
57 lines • 1.96 kB
JavaScript
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