Files
authentik/website/docusaurus-theme/components/VersionPicker/utils.ts
2025-12-18 21:59:48 +00:00

98 lines
2.7 KiB
TypeScript

import type { AKReleasesPluginData } from "@goauthentik/docusaurus-theme/releases/common";
import { usePluginData } from "@docusaurus/useGlobalData";
import useIsBrowser from "@docusaurus/useIsBrowser";
import { useMemo } from "react";
import { coerce } from "semver";
export const LocalhostAliases: ReadonlySet<string> = new Set(["localhost", "127.0.0.1"]);
export function normalizeReleaseName(name: string): string {
return name.split(" ")[0] || name;
}
/**
* Given a semver, create the URL for the version.
*/
export function createVersionURL(releaseName: string): string {
const semver = normalizeReleaseName(releaseName);
const subdomain = `version-${semver.replace(".", "-")}`;
return `https://${subdomain}.goauthentik.io`;
}
/**
* Given a hostname, parse the semver from the subdomain.
*/
export function parseBranchSemVer(hostname?: string | null): string | null {
if (!hostname) return null;
const [, possibleSemVer] = hostname.match(/version-(.+)/) || [];
if (!possibleSemVer) return null;
const formattedSemVer = possibleSemVer.replace("-", ".");
if (!coerce(formattedSemVer)) return null;
return formattedSemVer;
}
export function useHostname() {
const browser = useIsBrowser();
const hostname = useMemo(() => {
if (!browser) return null;
const searchParams = new URLSearchParams(window.location.search);
// Query parameter used for debugging.
// Note that this doesn't synchronize with Docusaurus's router state.
const subdomain = searchParams.get("version");
if (subdomain) return subdomain;
return window.location.hostname;
}, [browser]);
return hostname;
}
export function useCachedVersionPluginData(): AKReleasesPluginData | null {
const pluginData = usePluginData("ak-releases-plugin", undefined) as
| AKReleasesPluginData
| undefined;
return pluginData ?? null;
}
function preferredPreReleaseOrigin(browser: boolean, fallback: string): string {
if (browser && LocalhostAliases.has(window.location.hostname)) {
return window.location.origin;
}
return fallback;
}
export function useVersionPluginData(): AKReleasesPluginData | null {
const browser = useIsBrowser();
const cachedPluginData = useCachedVersionPluginData();
return useMemo(() => {
if (!cachedPluginData) return null;
const preReleaseOrigin = preferredPreReleaseOrigin(
browser,
cachedPluginData.env.preReleaseOrigin,
);
return {
...cachedPluginData,
env: {
...cachedPluginData.env,
preReleaseOrigin,
},
};
}, [browser, cachedPluginData]);
}