UNPKG

@scalar/api-reference

Version:

Generate beautiful API references from OpenAPI documents

107 lines (106 loc) 4.94 kB
//#region src/helpers/id-routing.ts var sanitizeBasePath = (basePath) => { return basePath.replace(/^\/+|\/+$/g, ""); }; var isHashBasePath = (basePath) => basePath.startsWith("#"); var sanitizeHashBasePath = (basePath) => { return basePath.replace(/^#+/, "").replace(/\/+$/g, ""); }; var applySlugPrefix = (base, slugPrefix) => { return slugPrefix ? `${slugPrefix}${base ? "/" : ""}${base}` : base; }; var stripBasePathPrefix = (value, basePath) => { if (value === basePath) return ""; if (value.startsWith(`${basePath}/`)) return value.slice(basePath.length + 1); return null; }; /** Extracts an element id from the hash when using hash routing */ var getIdFromHash = (location, slugPrefix) => { const url = typeof location === "string" ? new URL(location) : location; return applySlugPrefix(decodeURIComponent(url.hash.slice(1)), slugPrefix); }; /** Extracts an element id from the path when using path routing */ var getIdFromPath = (location, basePath, slugPrefix) => { const url = typeof location === "string" ? new URL(location) : location; const sanitized = sanitizeBasePath(basePath); const basePathWithSlash = sanitized ? `/${sanitized.split("/").map((segment) => encodeURIComponent(segment)).join("/")}` : ""; if (url.pathname.startsWith(basePathWithSlash)) { const remainder = url.pathname.slice(basePathWithSlash.length); return applySlugPrefix(decodeURIComponent(remainder.startsWith("/") ? remainder.slice(1) : remainder), slugPrefix); } return slugPrefix ?? ""; }; /** Extracts an element id from a hash-prefixed basePath */ var getIdFromHashBasePath = (location, basePath, slugPrefix) => { const url = typeof location === "string" ? new URL(location) : location; const remainder = stripBasePathPrefix(decodeURIComponent(url.hash.slice(1)), sanitizeHashBasePath(basePath)); if (remainder !== null) return applySlugPrefix(remainder, slugPrefix); return slugPrefix ?? ""; }; /** Determines whether a URL matches the provided basePath. */ var matchesBasePath = (location, basePath) => { const url = typeof location === "string" ? new URL(location) : location; if (isHashBasePath(basePath)) { const hash = decodeURIComponent(url.hash); return hash === basePath || hash.startsWith(`${basePath}/`); } const sanitized = sanitizeBasePath(basePath); const basePathWithSlash = sanitized ? `/${sanitized.split("/").map((segment) => encodeURIComponent(segment)).join("/")}` : ""; return url.pathname === basePathWithSlash || url.pathname.startsWith(`${basePathWithSlash}/`); }; /** * Extracts a navigation id from a URL based on the routing type * * @param url - The URL to extract the id from * @param basePath - The base path used in path routing * @param slugPrefix - If the document slug is not expected in the URL then we must prefix it */ var getIdFromUrl = (url, basePath, slugPrefix) => { if (typeof basePath !== "string") return getIdFromHash(url, slugPrefix); return isHashBasePath(basePath) ? getIdFromHashBasePath(url, basePath, slugPrefix) : getIdFromPath(url, basePath, slugPrefix); }; /** * Strips the first segment from an id and preserves trailing slashes * Used in single-document mode where the document slug is not needed in the URL * * @param id - The full id to process * @returns The id with the first segment removed, preserving trailing slash if present */ var stripFirstSegment = (id) => { const hasTrailingSlash = id.endsWith("/"); const result = id.split("/").filter(Boolean).slice(1).join("/"); return hasTrailingSlash && result ? `${result}/` : result; }; /** * Generate a new URL and applies the ID to the path or hash * depending on the type of routing used * * @param id - The id to apply to the URL * @param basePath - The base path used in path routing * @param isMultiDocument - Whether the document is multi-document or single-document. Single-document documents will strip the document slug from the id */ var makeUrlFromId = (_id, basePath, isMultiDocument) => { if (typeof window === "undefined") return; /** When there is only 1 document we don't need to include the document name in the URL */ const id = isMultiDocument ? _id : stripFirstSegment(_id); const url = new URL(window.location.href); if (typeof basePath === "string") if (isHashBasePath(basePath)) url.hash = [sanitizeHashBasePath(basePath), id].filter(Boolean).join("/"); else url.pathname = `${sanitizeBasePath(basePath)}/${id}`; else url.hash = id; return url; }; /** Extracts the schema parameters from the id if they are present */ var getSchemaParamsFromId = (id) => { const matcher = id.match(/(.*)(\.body\.|\.path\.|\.query\.|\.header\.)(.*)/); if (matcher && typeof matcher[1] === "string" && typeof matcher[2] === "string") return { rawId: matcher[1], params: matcher[2].slice(1) + matcher[3] }; return { rawId: id, params: "" }; }; //#endregion export { getIdFromUrl, getSchemaParamsFromId, makeUrlFromId, matchesBasePath }; //# sourceMappingURL=id-routing.js.map