UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

43 lines (42 loc) • 1.69 kB
import { collapseDuplicateLeadingSlashes } from "@astrojs/internal-helpers/path"; /** * Sanitizes the parameters object by normalizing string values and replacing certain characters with their URL-encoded equivalents. * @param {Record<string, string | number>} params - The parameters object to be sanitized. * @returns {Record<string, string | number>} The sanitized parameters object. */ function sanitizeParams(params) { return Object.fromEntries(Object.entries(params).map(([key, value]) => { if (typeof value === "string") { return [key, value.normalize().replace(/#/g, "%23").replace(/\?/g, "%3F")]; } return [key, value]; })); } function getParameter(part, params) { if (part.spread) { return params[part.content.slice(3)] ?? ""; } if (part.dynamic) { if (params[part.content] === undefined) { throw new TypeError(`Missing parameter: ${part.content}`); } return params[part.content]; } return part.content.normalize().replace(/\?/g, "%3F").replace(/#/g, "%23").replace(/%5B/g, "[").replace(/%5D/g, "]"); } function getSegment(segment, params) { const segmentPath = segment.map((part) => getParameter(part, params)).join(""); return segmentPath ? collapseDuplicateLeadingSlashes("/" + segmentPath) : ""; } export function getRouteGenerator(segments, addTrailingSlash) { return (params) => { const sanitizedParams = sanitizeParams(params); // Unless trailingSlash config is set to 'always', don't automatically append it. let trailing = ""; if (addTrailingSlash === "always" && segments.length) { trailing = "/"; } const path = segments.map((segment) => getSegment(segment, sanitizedParams)).join("") + trailing; return path || "/"; }; }