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:
@@ -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
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user