mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 18:27:56 +02:00
163 lines
4.2 KiB
TypeScript
163 lines
4.2 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import type {LoadedVersion, VersionTag} from './types';
|
|
import type {
|
|
SidebarItemDoc,
|
|
SidebarItem,
|
|
SidebarItemCategory,
|
|
SidebarItemCategoryLink,
|
|
} from './sidebars/types';
|
|
import type {
|
|
PropSidebars,
|
|
PropVersionMetadata,
|
|
PropSidebarItem,
|
|
PropSidebarItemCategory,
|
|
PropTagDocList,
|
|
PropTagDocListDoc,
|
|
PropSidebarItemLink,
|
|
PropVersionDocs,
|
|
DocMetadata,
|
|
} from '@docusaurus/plugin-content-docs';
|
|
import _ from 'lodash';
|
|
import {createDocsByIdIndex} from './docs';
|
|
|
|
export function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars {
|
|
const docsById = createDocsByIdIndex(loadedVersion.docs);
|
|
|
|
function getDocById(docId: string): DocMetadata {
|
|
const docMetadata = docsById[docId];
|
|
if (!docMetadata) {
|
|
throw new Error(
|
|
`Invalid sidebars file. The document with id "${docId}" was used in the sidebar, but no document with this id could be found.
|
|
Available document ids are:
|
|
- ${Object.keys(docsById).sort().join('\n- ')}`,
|
|
);
|
|
}
|
|
return docMetadata;
|
|
}
|
|
|
|
const convertDocLink = (item: SidebarItemDoc): PropSidebarItemLink => {
|
|
const docMetadata = getDocById(item.id);
|
|
const {
|
|
title,
|
|
permalink,
|
|
frontMatter: {sidebar_label: sidebarLabel},
|
|
} = docMetadata;
|
|
return {
|
|
type: 'link',
|
|
label: sidebarLabel || item.label || title,
|
|
href: permalink,
|
|
className: item.className,
|
|
customProps:
|
|
item.customProps ?? docMetadata.frontMatter.sidebar_custom_props,
|
|
docId: docMetadata.unversionedId,
|
|
};
|
|
};
|
|
|
|
function getCategoryLinkHref(
|
|
link: SidebarItemCategoryLink | undefined,
|
|
): string | undefined {
|
|
switch (link?.type) {
|
|
case 'doc':
|
|
return getDocById(link.id).permalink;
|
|
case 'generated-index':
|
|
return link.permalink;
|
|
default:
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
function convertCategory(item: SidebarItemCategory): PropSidebarItemCategory {
|
|
const {link, ...rest} = item;
|
|
const href = getCategoryLinkHref(link);
|
|
return {...rest, items: item.items.map(normalizeItem), ...(href && {href})};
|
|
}
|
|
|
|
function normalizeItem(item: SidebarItem): PropSidebarItem {
|
|
switch (item.type) {
|
|
case 'category':
|
|
return convertCategory(item);
|
|
case 'ref':
|
|
case 'doc':
|
|
return convertDocLink(item);
|
|
case 'link':
|
|
default:
|
|
return item;
|
|
}
|
|
}
|
|
|
|
// Transform the sidebar so that all sidebar item will be in the
|
|
// form of 'link' or 'category' only.
|
|
// This is what will be passed as props to the UI component.
|
|
return _.mapValues(loadedVersion.sidebars, (items) =>
|
|
items.map(normalizeItem),
|
|
);
|
|
}
|
|
|
|
function toVersionDocsProp(loadedVersion: LoadedVersion): PropVersionDocs {
|
|
return Object.fromEntries(
|
|
loadedVersion.docs.map((doc) => [
|
|
doc.unversionedId,
|
|
{
|
|
id: doc.unversionedId,
|
|
title: doc.title,
|
|
description: doc.description,
|
|
sidebar: doc.sidebar,
|
|
},
|
|
]),
|
|
);
|
|
}
|
|
|
|
export function toVersionMetadataProp(
|
|
pluginId: string,
|
|
loadedVersion: LoadedVersion,
|
|
): PropVersionMetadata {
|
|
return {
|
|
pluginId,
|
|
version: loadedVersion.versionName,
|
|
label: loadedVersion.label,
|
|
banner: loadedVersion.banner,
|
|
badge: loadedVersion.badge,
|
|
className: loadedVersion.className,
|
|
isLast: loadedVersion.isLast,
|
|
docsSidebars: toSidebarsProp(loadedVersion),
|
|
docs: toVersionDocsProp(loadedVersion),
|
|
};
|
|
}
|
|
|
|
export function toTagDocListProp({
|
|
allTagsPath,
|
|
tag,
|
|
docs,
|
|
}: {
|
|
allTagsPath: string;
|
|
tag: VersionTag;
|
|
docs: DocMetadata[];
|
|
}): PropTagDocList {
|
|
function toDocListProp(): PropTagDocListDoc[] {
|
|
const list = _.compact(
|
|
tag.docIds.map((id) => docs.find((doc) => doc.id === id)),
|
|
);
|
|
// Sort docs by title
|
|
list.sort((doc1, doc2) => doc1.title.localeCompare(doc2.title));
|
|
return list.map((doc) => ({
|
|
id: doc.id,
|
|
title: doc.title,
|
|
description: doc.description,
|
|
permalink: doc.permalink,
|
|
}));
|
|
}
|
|
|
|
return {
|
|
label: tag.label,
|
|
permalink: tag.permalink,
|
|
allTagsPath,
|
|
count: tag.docIds.length,
|
|
items: toDocListProp(),
|
|
};
|
|
}
|