Files
authentik/website/docusaurus-theme/releases/node.mjs
2026-01-16 15:42:13 +01:00

140 lines
3.7 KiB
JavaScript

/**
* @file Docusaurus release utils.
*
* @import { SidebarItemConfig } from "@docusaurus/plugin-content-docs/src/sidebars/types.js"
* @import { AKReleaseFile, AKReleasesPluginEnvironment } from "./common.mjs"
*/
import { readFileSync } from "node:fs";
import { extname, join } from "node:path";
import { parseFileContentFrontMatter } from "@docusaurus/utils/lib/markdownUtils.js";
import FastGlob from "fast-glob";
import { coerce } from "semver";
/**
* Number of supported releases to show in the sidebar.
*/
export const SUPPORTED_RELEASE_COUNT = 3;
/**
* @typedef {FastGlob.Entry & AKReleaseFile} AKReleaseFileEntry
*/
/**
* Reads and parses the front matter of recent release files.
*
* @param {string} releasesParentDirectory
* @param {AKReleaseFileEntry} release
* @param {number} index
*/
function parseRelease(releasesParentDirectory, release, index) {
if (index > SUPPORTED_RELEASE_COUNT - 1) {
return release;
}
const extension = extname(release.dirent.name);
const fileContent = readFileSync(
join(releasesParentDirectory, `${release.path}${extension}`),
"utf-8",
);
const { frontMatter } = parseFileContentFrontMatter(fileContent);
if (frontMatter.beta) {
release.name += " (Release Candidate)";
}
return {
...release,
frontMatter,
};
}
/**
* Collect all Markdown files from the releases directory.
*
* @param {string} releasesParentDirectory
* @returns {AKReleaseFile[]}
*/
export function collectReleaseFiles(releasesParentDirectory) {
/**
* @type {AKReleaseFileEntry[]}
*/
const releaseFiles = FastGlob.sync("releases/**/v*.{md,mdx}", {
cwd: releasesParentDirectory,
onlyFiles: true,
objectMode: true,
})
.map((fileEntry) => {
return {
...fileEntry,
path: fileEntry.path.replace(/\.mdx?$/, ""),
name: fileEntry.name.replace(/^v/, "").replace(/\.mdx?$/, ""),
};
})
.sort((a, b) => {
const aSemVer = coerce(a.name);
const bSemVer = coerce(b.name);
if (aSemVer && bSemVer) {
return bSemVer.compare(aSemVer);
}
return b.name.localeCompare(a.name);
});
const parsedReleaseFiles = releaseFiles.map((release, index) =>
parseRelease(releasesParentDirectory, release, index),
);
return parsedReleaseFiles;
}
/**
*
* @param {AKReleaseFile[]} releaseFiles
*/
export function createReleaseSidebarEntries(releaseFiles) {
/**
* @type {SidebarItemConfig[]}
*/
let sidebarEntries = releaseFiles.map((fileEntry) => {
return {
type: "doc",
id: fileEntry.path,
label: fileEntry.name,
key: `release-${fileEntry.name}`,
};
});
if (releaseFiles.length > SUPPORTED_RELEASE_COUNT) {
// Then we add the rest of the releases as a category.
sidebarEntries = [
...sidebarEntries.slice(0, SUPPORTED_RELEASE_COUNT),
{
type: "category",
label: "Previous versions",
items: sidebarEntries.slice(SUPPORTED_RELEASE_COUNT),
},
];
}
return sidebarEntries;
}
/**
* Prepare the environment variables for the releases plugin.
*
* @returns {AKReleasesPluginEnvironment}
*/
export function prepareReleaseEnvironment() {
return {
branch: process.env.BRANCH,
currentReleaseOrigin: process.env.CURRENT_RELEASE_ORIGIN || "https://docs.goauthentik.io",
preReleaseOrigin: process.env.PRE_RELEASE_ORIGIN || "https://next.goauthentik.io",
apiReferenceOrigin: process.env.API_REFERENCE_ORIGIN || "https://api.goauthentik.io",
};
}