import { usePageData , usePageFrontmatter } from "@vuepress/client" ; import type { PageHeader } from "@vuepress/client" ; import { isArray , isPlainObject , isString , resolveLocalePath } from "@vuepress/shared" ; import { computed , inject , provide } from "vue" ; import type { ComputedRef , InjectionKey } from "vue" ; import { useRoute } from "vue-router" ; import type { GungnirThemeData , GungnirThemeNormalPageFrontmatter , ResolvedSidebarItem , SidebarConfigArray , SidebarConfigObject , SidebarItem } from "../../shared" ; import { useNavLink , useThemeLocaleData } from "." ; export type SidebarItemsRef = ComputedRef < ResolvedSidebarItem [ ] > ; export const sidebarItemsSymbol = Symbol ( "sidebarItems" ) ; /**
 * Inject sidebar items global computed
 */ export const useSidebarItems = ( ) : SidebarItemsRef => { const sidebarItems = inject ( sidebarItemsSymbol ) ; if ( ! sidebarItems ) { throw new Error ( "useSidebarItems() is called without provider." ) ; } return sidebarItems ; } ; /**
 * Create sidebar items ref and provide as global computed in setup
 */ export const setupSidebarItems = ( ) : void => { const themeLocale = useThemeLocaleData ( ) ; const frontmatter = usePageFrontmatter < GungnirThemeNormalPageFrontmatter > ( ) ; const sidebarItems = computed ( ( ) => resolveSidebarItems ( frontmatter . value , themeLocale . value ) ) ; provide ( sidebarItemsSymbol , sidebarItems ) ; } ; /**
 * Resolve sidebar items global computed
 *
 * It should only be resolved and provided once
 */ export const resolveSidebarItems = ( frontmatter , themeLocale ) : ResolvedSidebarItem [ ] => { const sidebarConfig = frontmatter . sidebar ?? themeLocale . sidebar ?? "auto" ; const sidebarDepth = frontmatter . sidebarDepth ?? themeLocale . sidebarDepth ?? 2 ; if ( frontmatter . home || sidebarConfig === false ) { return [ ] ; } if ( sidebarConfig === "auto" ) { return resolveAutoSidebarItems ( sidebarDepth ) ; } if ( isArray ( sidebarConfig ) ) { return resolveArraySidebarItems ( sidebarConfig , sidebarDepth ) ; } if ( isPlainObject ( sidebarConfig ) ) { return resolveMultiSidebarItems ( sidebarConfig , sidebarDepth ) ; } return [ ] ; } ; /**
 * Util to transform page header to sidebar item
 */ export const headerToSidebarItem = ( header , sidebarDepth ) : ResolvedSidebarItem => ( { text : header . title , link : `#${ header . slug }` , children : headersToSidebarItemChildren ( header . children , sidebarDepth ) } ) ; export const headersToSidebarItemChildren = ( headers , sidebarDepth ) : ResolvedSidebarItem [ ] => sidebarDepth > 0 ? headers . map ( ( header ) => headerToSidebarItem ( header , sidebarDepth - 1 ) ) : [ ] ; /**
 * Resolve sidebar items if the config is `auto`
 */ export const resolveAutoSidebarItems = ( sidebarDepth ) : ResolvedSidebarItem [ ] => { const page = usePageData ( ) ; return [ { text : page . value . title , children : headersToSidebarItemChildren ( page . value . headers , sidebarDepth ) } ] ; } ; /**
 * Resolve sidebar items if the config is an array
 */ export const resolveArraySidebarItems = ( sidebarConfig , sidebarDepth ) : ResolvedSidebarItem [ ] => { const route = useRoute ( ) ; const page = usePageData ( ) ; const handleChildItem = ( item ) : ResolvedSidebarItem => { let childItem ; if ( isString ( item ) ) { childItem = useNavLink ( item ) ; } else { childItem = item as ResolvedSidebarItem ; } if ( childItem . children ) { return { ... childItem , children : childItem . children . map ( ( item ) => handleChildItem ( item ) ) } ; } if ( childItem . link === route . path ) { const headers = page . value . headers [ 0 ] ?. level === 1 ? page . value . headers [ 0 ] . children : page . value . headers ; return { ... childItem , children : headersToSidebarItemChildren ( headers , sidebarDepth ) } ; } return childItem ; } ; return sidebarConfig . map ( ( item ) => handleChildItem ( item ) ) ; } ; /**
 * Resolve sidebar items if the config is a key -> value (path-prefix -> array) object
 */ export const resolveMultiSidebarItems = ( sidebarConfig , sidebarDepth ) : ResolvedSidebarItem [ ] => { const route = useRoute ( ) ; const sidebarPath = resolveLocalePath ( sidebarConfig , route . path ) ; const matchedSidebarConfig = sidebarConfig [ sidebarPath ] ?? [ ] ; return resolveArraySidebarItems ( matchedSidebarConfig , sidebarDepth ) ; } ;