@scalar/api-reference
Version:
Generate beautiful API references from OpenAPI documents
107 lines (106 loc) • 4.94 kB
JavaScript
//#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