UNPKG

@lorenzo_lewis/starlight-utils

Version:

Utilities to use with your 🌟 Starlight site.

99 lines (81 loc) • 3.47 kB
import { defineRouteMiddleware, type StarlightRouteData, } from "@astrojs/starlight/route-data"; import { AstroError } from "astro/errors"; import config from "virtual:starlight-utils/config"; export const onRequest = defineRouteMiddleware((context) => { // Initialize object context.locals.starlightUtils = {}; // Logic for navLinks if (config?.navLinks?.leading) { const sidebarLabel = config?.navLinks?.leading?.useSidebarLabelled; if (!sidebarLabel) { throw new AstroError( `No sidebar label was specified for the ${JSON.stringify(config?.navLinks?.leading)} entry in the Astro config.` ); } const starlightRouteSidebar = context.locals.starlightRoute.sidebar; const navLinks: typeof starlightRouteSidebar = []; const filteredSidebar: typeof starlightRouteSidebar = []; starlightRouteSidebar.forEach((entry) => { const condition = entry.label === config?.navLinks?.leading?.useSidebarLabelled; condition ? navLinks.push(entry) : filteredSidebar.push(entry); }); if (navLinks.length != 1 || !navLinks[0]) { throw new AstroError( `Could not find the sidebar labelled \`${sidebarLabel}\` that was referenced in the Starlight Utils config.` ); } if (navLinks[0].type !== "group") { throw new AstroError( `\`${navLinks[0].label}\` cannot be used with multi-sidebar. The sidebar entry specified in the Astro config must be either a group or autogenerated. See https://starlight.astro.build/guides/sidebar/#groups and https://starlight.astro.build/guides/sidebar/#autogenerated-groups for more details.` ); } if (navLinks[0].entries.some((entry) => entry.type !== "link")) { throw new AstroError( `Only links can be specified for nav links. No groups or autogenerated types are allowed.` ); } // Set navLinks value context.locals.starlightUtils.navLinks = [...navLinks[0].entries]; // Set the filtered sidebar context.locals.starlightRoute.sidebar = filteredSidebar; } // Logic for multi-sidebar if (config?.multiSidebar) { // All entries must be group types const data = context.locals.starlightRoute.sidebar.map((entry) => { if (entry.type != "group") { throw new AstroError( `\`${entry.label}\` cannot be used with multi-sidebar. Each top-level \`sidebar\` item in the Starlight config must be either a group or autogenerated. See https://starlight.astro.build/guides/sidebar/#groups and https://starlight.astro.build/guides/sidebar/#autogenerated-groups for more details.` ); } // Recursively check if a group of sidebar entries contains the current page const findIfIsCurrent = ( entry: StarlightRouteData["sidebar"][number] ): boolean => { if (entry.type === "link") { return entry.isCurrent; } return entry.entries.some((item) => findIfIsCurrent(item)); }; const isCurrentSidebar = findIfIsCurrent(entry); return { isCurrentSidebar, sidebar: [...entry.entries], label: entry, }; }); // If the current page being built isn't contained in a sidebar, then render the first sidebar if (data[0] && !data.some(({ isCurrentSidebar }) => isCurrentSidebar)) { data[0].isCurrentSidebar = true; } context.locals.starlightUtils.multiSidebar = data; } });