docs: support generating sidebar items with tags (#10672)

* docs: support generating sidebar items with tags

* small fix

* fix dependencies

* test

* test fix

* test fix

* test fix

* test fix

* another fix

* revert change

* fix for resources
This commit is contained in:
Shahed Nasser
2024-12-19 18:24:36 +02:00
committed by GitHub
parent 1118e35924
commit 65007c49f6
19 changed files with 119 additions and 54 deletions
+5 -2
View File
@@ -28,16 +28,19 @@
"watch": "tsc --watch"
},
"dependencies": {
"remark-rehype-plugins": "*"
"docs-utils": "*",
"tags": "*"
},
"devDependencies": {
"@types/node": "^20.11.20",
"docs-utils": "*",
"rimraf": "^5.0.5",
"tsconfig": "*",
"types": "*",
"typescript": "^5.3.3"
},
"peerDependencies": {
"docs-utils": "*"
},
"engines": {
"node": ">=18.17.0"
}
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readdirSync, statSync } from "fs"
import path from "path"
import { getSidebarItemLink, sidebarAttachHrefCommonOptions } from "./index.js"
import getCoreFlowsRefSidebarChildren from "./utils/get-core-flows-ref-sidebar-children.js"
import { parseTags } from "./utils/parse-tags.js"
export type ItemsToAdd = SidebarItem & {
sidebar_position?: number
@@ -12,7 +13,7 @@ const customGenerators: Record<string, () => Promise<ItemsToAdd[]>> = {
"core-flows": getCoreFlowsRefSidebarChildren,
}
async function getSidebarItems(
async function getAutogeneratedSidebarItems(
dir: string,
nested = false
): Promise<ItemsToAdd[]> {
@@ -32,7 +33,7 @@ async function getSidebarItems(
}
if (fileBasename !== "page.mdx" && statSync(filePath).isDirectory()) {
const newItems = await getSidebarItems(
const newItems = await getAutogeneratedSidebarItems(
filePath.replace(basePath, ""),
true
)
@@ -86,6 +87,26 @@ async function getSidebarItems(
return items
}
async function getAutogeneratedTagSidebarItems(
tags: string
): Promise<ItemsToAdd[]> {
const items: ItemsToAdd[] = []
const parsedTags = parseTags(tags)
items.push(
...parsedTags.map(
(tagItem) =>
({
type: "link",
...tagItem,
}) as ItemsToAdd
)
)
return sidebarAttachHrefCommonOptions(items)
}
async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> {
if (!item.type) {
throw new Error(
@@ -100,12 +121,16 @@ async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> {
return item
}
if (item.autogenerate_path) {
item.children = (await getSidebarItems(item.autogenerate_path)).map(
(child) => {
delete child.sidebar_position
item.children = (
await getAutogeneratedSidebarItems(item.autogenerate_path)
).map((child) => {
delete child.sidebar_position
return child
}
return child
})
} else if (item.autogenerate_tags) {
item.children = await getAutogeneratedTagSidebarItems(
item.autogenerate_tags
)
} else if (
item.custom_autogenerate &&
@@ -1,6 +1,6 @@
import { readdirSync } from "fs"
import path from "path"
import { getFileSlugSync } from "../../docs-utils/dist/index.js"
import { getFileSlugSync } from "docs-utils"
type Options = {
basePath: string
@@ -1,4 +1,4 @@
import { getFrontMatter, findPageTitle } from "../../../docs-utils/dist/index.js"
import { getFrontMatter, findPageTitle } from "docs-utils"
import { ItemsToAdd, sidebarAttachHrefCommonOptions } from "../index.js"
import { InteractiveSidebarItem } from "types"
@@ -0,0 +1,44 @@
import { getTagItems } from "tags"
import { Tag } from "types"
export const parseTags = (tagNames: string): Tag => {
const parsedTags: Tag = []
tagNames.split(",").forEach((tagName) => {
const intersectingTags = getIntersectionTags(tagName)
if (!intersectingTags.length) {
return
}
parsedTags.push(...intersectingTags)
})
return parsedTags
}
const getIntersectionTags = (tags: string): Tag => {
const tagsToIntersect: Tag[] = tags
.split("+")
.map((tagName) => getTagItems(tagName))
.filter((tag) => tag !== undefined) as Tag[]
if (!tagsToIntersect.length) {
return []
}
if (tagsToIntersect.length === 1) {
return tagsToIntersect[0]
}
return tagsToIntersect[0].filter((tagItem) => {
return tagsToIntersect
.slice(1)
.every((otherTag) =>
otherTag.some(
(otherTagItem) =>
otherTagItem.title === tagItem.title &&
otherTagItem.path === tagItem.path
)
)
})
}