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

View File

@@ -0,0 +1 @@
../../utils

View File

@@ -167,6 +167,12 @@ const nextConfig = {
} }
}, },
redirects, redirects,
experimental: {
outputFileTracingExcludes: {
"*": ["node_modules/@medusajs/icons"],
},
},
optimizePackageImports: ["@medusajs/icons", "@medusajs/ui"],
} }
export default withMDX(nextConfig) export default withMDX(nextConfig)

View File

@@ -126,16 +126,12 @@ const nextConfig = {
}, },
] ]
}, },
// Redirects shouldn't be necessary anymore since we have remark / rehype experimental: {
// plugins that fix links. But leaving this here in case we need it again. outputFileTracingExcludes: {
// async redirects() { "*": ["node_modules/@medusajs/icons"],
// // redirect original file paths to the rewrite },
// return slugChanges.map((item) => ({ },
// source: item.origSlug, optimizePackageImports: ["@medusajs/icons", "@medusajs/ui"],
// destination: item.newSlug,
// permanent: true,
// }))
// },
} }
const withBundleAnalyzer = bundleAnalyzer({ const withBundleAnalyzer = bundleAnalyzer({

View File

@@ -6,11 +6,11 @@ import { sidebar } from "../sidebar.mjs"
import path from "path" import path from "path"
async function main() { async function main() {
await generateTags(path.resolve("..", "..", "packages", "tags"))
await generateSidebar(sidebar) await generateSidebar(sidebar)
await generateSlugChanges() await generateSlugChanges()
await generateFilesMap() await generateFilesMap()
await generateEditedDates() await generateEditedDates()
await generateTags(path.resolve("..", "..", "packages", "tags"))
} }
void main() void main()

View File

@@ -1,6 +1,6 @@
import { statSync, readdirSync } from "fs" import { statSync, readdirSync } from "fs"
import path from "path" import path from "path"
import { getFileSlug } from "../../../packages/docs-utils/dist" import { getFileSlug } from "docs-utils"
const monoRepoPath = path.resolve("..", "..", "..") const monoRepoPath = path.resolve("..", "..", "..")

View File

@@ -9,7 +9,7 @@
}, },
"scripts": { "scripts": {
"build": "turbo run build", "build": "turbo run build",
"build:docs": "turbo run build --filter=docs-v2", "build:docs": "turbo run build --filter=book",
"build:resources": "turbo run build --filter=resources", "build:resources": "turbo run build --filter=resources",
"build:user-guide": "turbo run build --filter=user-guide", "build:user-guide": "turbo run build --filter=user-guide",
"build:packages": "turbo run build --filter='./packages/*'", "build:packages": "turbo run build --filter='./packages/*'",

View File

@@ -28,16 +28,19 @@
"watch": "tsc --watch" "watch": "tsc --watch"
}, },
"dependencies": { "dependencies": {
"remark-rehype-plugins": "*" "docs-utils": "*",
"tags": "*"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.11.20", "@types/node": "^20.11.20",
"docs-utils": "*",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"tsconfig": "*", "tsconfig": "*",
"types": "*", "types": "*",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"peerDependencies": {
"docs-utils": "*"
},
"engines": { "engines": {
"node": ">=18.17.0" "node": ">=18.17.0"
} }

View File

@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readdirSync, statSync } from "fs"
import path from "path" import path from "path"
import { getSidebarItemLink, sidebarAttachHrefCommonOptions } from "./index.js" import { getSidebarItemLink, sidebarAttachHrefCommonOptions } from "./index.js"
import getCoreFlowsRefSidebarChildren from "./utils/get-core-flows-ref-sidebar-children.js" import getCoreFlowsRefSidebarChildren from "./utils/get-core-flows-ref-sidebar-children.js"
import { parseTags } from "./utils/parse-tags.js"
export type ItemsToAdd = SidebarItem & { export type ItemsToAdd = SidebarItem & {
sidebar_position?: number sidebar_position?: number
@@ -12,7 +13,7 @@ const customGenerators: Record<string, () => Promise<ItemsToAdd[]>> = {
"core-flows": getCoreFlowsRefSidebarChildren, "core-flows": getCoreFlowsRefSidebarChildren,
} }
async function getSidebarItems( async function getAutogeneratedSidebarItems(
dir: string, dir: string,
nested = false nested = false
): Promise<ItemsToAdd[]> { ): Promise<ItemsToAdd[]> {
@@ -32,7 +33,7 @@ async function getSidebarItems(
} }
if (fileBasename !== "page.mdx" && statSync(filePath).isDirectory()) { if (fileBasename !== "page.mdx" && statSync(filePath).isDirectory()) {
const newItems = await getSidebarItems( const newItems = await getAutogeneratedSidebarItems(
filePath.replace(basePath, ""), filePath.replace(basePath, ""),
true true
) )
@@ -86,6 +87,26 @@ async function getSidebarItems(
return items 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> { async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> {
if (!item.type) { if (!item.type) {
throw new Error( throw new Error(
@@ -100,12 +121,16 @@ async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> {
return item return item
} }
if (item.autogenerate_path) { if (item.autogenerate_path) {
item.children = (await getSidebarItems(item.autogenerate_path)).map( item.children = (
(child) => { await getAutogeneratedSidebarItems(item.autogenerate_path)
delete child.sidebar_position ).map((child) => {
delete child.sidebar_position
return child return child
} })
} else if (item.autogenerate_tags) {
item.children = await getAutogeneratedTagSidebarItems(
item.autogenerate_tags
) )
} else if ( } else if (
item.custom_autogenerate && item.custom_autogenerate &&

View File

@@ -1,6 +1,6 @@
import { readdirSync } from "fs" import { readdirSync } from "fs"
import path from "path" import path from "path"
import { getFileSlugSync } from "../../docs-utils/dist/index.js" import { getFileSlugSync } from "docs-utils"
type Options = { type Options = {
basePath: string basePath: string

View File

@@ -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 { ItemsToAdd, sidebarAttachHrefCommonOptions } from "../index.js"
import { InteractiveSidebarItem } from "types" import { InteractiveSidebarItem } from "types"

View File

@@ -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
)
)
})
}

View File

@@ -0,0 +1,11 @@
import { matter } from "vfile-matter"
import { readSync } from "to-vfile"
import { FrontMatter } from "types"
export function getFileSlugSync(filePath: string): string | undefined {
const content = readSync(filePath)
matter(content)
return ((content.data.matter as FrontMatter).slug as string) || undefined
}

View File

@@ -1,6 +1,3 @@
import { matter } from "vfile-matter"
import { readSync } from "to-vfile"
import { FrontMatter } from "types"
import { getFrontMatter } from "./get-front-matter.js" import { getFrontMatter } from "./get-front-matter.js"
export async function getFileSlug( export async function getFileSlug(
@@ -13,11 +10,3 @@ export async function getFileSlug(
return fileFrontmatter.slug return fileFrontmatter.slug
} }
} }
export function getFileSlugSync(filePath: string): string | undefined {
const content = readSync(filePath)
matter(content)
return ((content.data.matter as FrontMatter).slug as string) || undefined
}

View File

@@ -1,3 +1,4 @@
export * from "./find-title.js" export * from "./find-title.js"
export * from "./get-file-slug-sync.js"
export * from "./get-file-slug.js" export * from "./get-file-slug.js"
export * from "./get-front-matter.js" export * from "./get-front-matter.js"

View File

@@ -30,18 +30,12 @@
"dependencies": { "dependencies": {
"@cloudinary/url-gen": "^1.17.0", "@cloudinary/url-gen": "^1.17.0",
"docs-utils": "*", "docs-utils": "*",
"remark-frontmatter": "^5.0.0",
"remark-parse": "^11.0.0",
"remark-stringify": "^11.0.0",
"to-vfile": "^8.0.0",
"unified": "^11.0.4", "unified": "^11.0.4",
"unist-builder": "3.0.0", "unist-builder": "3.0.0",
"unist-util-visit": "4.1.2", "unist-util-visit": "4.1.2"
"vfile-matter": "^5.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.11.20", "@types/node": "^20.11.20",
"docs-ui": "*",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"tsconfig": "*", "tsconfig": "*",
"types": "*", "types": "*",

View File

@@ -1,5 +1,5 @@
import path from "path" import path from "path"
import { getFileSlugSync } from "../../../docs-utils/dist/index.js" import { getFileSlugSync } from "docs-utils"
export type FixLinkOptions = { export type FixLinkOptions = {
currentPageFilePath: string currentPageFilePath: string

View File

@@ -35,12 +35,10 @@
"@types/node": "^20.11.20", "@types/node": "^20.11.20",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"tsconfig": "*", "tsconfig": "*",
"typescript": "^5.3.3" "typescript": "^5.3.3",
"@medusajs/icons": "^2.0.0"
}, },
"engines": { "engines": {
"node": ">=18.17.0" "node": ">=18.17.0"
},
"dependencies": {
"@medusajs/icons": "^2.0.0"
} }
} }

View File

@@ -57,6 +57,7 @@ export type SidebarSectionItems = {
export type RawSidebarItem = SidebarItem & { export type RawSidebarItem = SidebarItem & {
autogenerate_path?: string autogenerate_path?: string
autogenerate_tags?: string
custom_autogenerate?: string custom_autogenerate?: string
number?: string number?: string
} }

View File

@@ -7215,11 +7215,13 @@ __metadata:
dependencies: dependencies:
"@types/node": ^20.11.20 "@types/node": ^20.11.20
docs-utils: "*" docs-utils: "*"
remark-rehype-plugins: "*"
rimraf: ^5.0.5 rimraf: ^5.0.5
tags: "*"
tsconfig: "*" tsconfig: "*"
types: "*" types: "*"
typescript: ^5.3.3 typescript: ^5.3.3
peerDependencies:
docs-utils: "*"
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -14643,20 +14645,14 @@ __metadata:
dependencies: dependencies:
"@cloudinary/url-gen": ^1.17.0 "@cloudinary/url-gen": ^1.17.0
"@types/node": ^20.11.20 "@types/node": ^20.11.20
docs-ui: "*"
docs-utils: "*" docs-utils: "*"
remark-frontmatter: ^5.0.0
remark-parse: ^11.0.0
remark-stringify: ^11.0.0
rimraf: ^5.0.5 rimraf: ^5.0.5
to-vfile: ^8.0.0
tsconfig: "*" tsconfig: "*"
types: "*" types: "*"
typescript: ^5.3.3 typescript: ^5.3.3
unified: ^11.0.4 unified: ^11.0.4
unist-builder: 3.0.0 unist-builder: 3.0.0
unist-util-visit: 4.1.2 unist-util-visit: 4.1.2
vfile-matter: ^5.0.0
languageName: unknown languageName: unknown
linkType: soft linkType: soft