refactor(content-docs): clean up sidebars logic; validate generator returns (#6596)

* refactor(content-docs): clean up sidebars logic; validate generator returns

* remove another TODO

* fix types

* refactors

* refactor...
This commit is contained in:
Joshua Chen 2022-02-04 09:46:25 +08:00 committed by GitHub
parent d6bdf7e804
commit e3fd3e74ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 750 additions and 615 deletions

View file

@ -6,12 +6,12 @@
*/
import type {
SidebarItem,
SidebarItemDoc,
SidebarItemCategory,
SidebarItemsGenerator,
SidebarItemsGeneratorDoc,
SidebarItemCategoryLink,
NormalizedSidebarItemCategory,
NormalizedSidebarItem,
SidebarItemCategoryLinkConfig,
} from './types';
import {sortBy, last} from 'lodash';
import {addTrailingSlash, posixPath} from '@docusaurus/utils';
@ -48,7 +48,6 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
numberPrefixParser,
isCategoryIndex,
docs: allDocs,
options,
item: {dirName: autogenDir},
categoriesMetadata,
}) => {
@ -125,7 +124,9 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
* Step 3. Recursively transform the tree-like structure to sidebar items.
* (From a record to an array of items, akin to normalizing shorthand)
*/
function generateSidebar(fsModel: Dir): Promise<WithPosition<SidebarItem>[]> {
function generateSidebar(
fsModel: Dir,
): Promise<WithPosition<NormalizedSidebarItem>[]> {
function createDocItem(id: string): WithPosition<SidebarItemDoc> {
const {
sidebarPosition: position,
@ -145,7 +146,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
dir: Dir,
fullPath: string,
folderName: string,
): Promise<WithPosition<SidebarItemCategory>> {
): Promise<WithPosition<NormalizedSidebarItemCategory>> {
const categoryMetadata =
categoriesMetadata[posixPath(path.join(autogenDir, fullPath))];
const className = categoryMetadata?.className;
@ -160,18 +161,19 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
// using the "local id" (myDoc) or "qualified id" (dirName/myDoc)
function findDocByLocalId(localId: string): SidebarItemDoc | undefined {
return allItems.find(
(item) => item.type === 'doc' && getLocalDocId(item.id) === localId,
) as SidebarItemDoc | undefined;
(item): item is SidebarItemDoc =>
item.type === 'doc' && getLocalDocId(item.id) === localId,
);
}
function findConventionalCategoryDocLink(): SidebarItemDoc | undefined {
return allItems.find((item) => {
return allItems.find((item): item is SidebarItemDoc => {
if (item.type !== 'doc') {
return false;
}
const doc = getDoc(item.id);
return isCategoryIndex(toCategoryIndexMatcherParam(doc));
}) as SidebarItemDoc | undefined;
});
}
function getCategoryLinkedDocId(): string | undefined {
@ -190,13 +192,13 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
const categoryLinkedDocId = getCategoryLinkedDocId();
const link: SidebarItemCategoryLink | undefined = categoryLinkedDocId
? {
type: 'doc',
id: categoryLinkedDocId, // We "remap" a potentially "local id" to a "qualified id"
}
: // TODO typing issue
(categoryMetadata?.link as SidebarItemCategoryLink | undefined);
const link: SidebarItemCategoryLinkConfig | null | undefined =
categoryLinkedDocId
? {
type: 'doc',
id: categoryLinkedDocId, // We "remap" a potentially "local id" to a "qualified id"
}
: categoryMetadata?.link;
// If a doc is linked, remove it from the category subItems
const items = allItems.filter(
@ -206,9 +208,8 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
return {
type: 'category',
label: categoryMetadata?.label ?? filename,
collapsible:
categoryMetadata?.collapsible ?? options.sidebarCollapsible,
collapsed: categoryMetadata?.collapsed ?? options.sidebarCollapsed,
collapsible: categoryMetadata?.collapsible,
collapsed: categoryMetadata?.collapsed,
position: categoryMetadata?.position ?? numberPrefix,
...(className !== undefined && {className}),
items,
@ -219,7 +220,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
dir: Dir | null, // The directory item to be transformed.
itemKey: string, // For docs, it's the doc ID; for categories, it's used to generate the next `relativePath`.
fullPath: string, // `dir`'s full path relative to the autogen dir.
): Promise<WithPosition<SidebarItem>> {
): Promise<WithPosition<NormalizedSidebarItem>> {
return dir
? createCategoryItem(dir, fullPath, itemKey)
: createDocItem(itemKey.substring(docIdPrefix.length));
@ -238,7 +239,9 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
* consecutive sidebar slices (i.e. a whole category composed of multiple
* autogenerated items)
*/
function sortItems(sidebarItems: WithPosition<SidebarItem>[]): SidebarItem[] {
function sortItems(
sidebarItems: WithPosition<NormalizedSidebarItem>[],
): NormalizedSidebarItem[] {
const processedSidebarItems = sidebarItems.map((item) => {
if (item.type === 'category') {
return {...item, items: sortItems(item.items)};