mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-15 17:22:35 +02:00
feat(core): simplify plugin API, support route.props (#10042)
This commit is contained in:
parent
d1590e37ac
commit
5c1d6464d8
26 changed files with 2858 additions and 2240 deletions
File diff suppressed because it is too large
Load diff
|
@ -31,7 +31,6 @@ import type {
|
|||
Options,
|
||||
PluginOptions,
|
||||
PropSidebarItemLink,
|
||||
PropSidebars,
|
||||
} from '@docusaurus/plugin-content-docs';
|
||||
import type {
|
||||
SidebarItemsGeneratorOption,
|
||||
|
@ -76,36 +75,11 @@ const createFakeActions = (contentDir: string) => {
|
|||
},
|
||||
};
|
||||
|
||||
// Query by prefix, because files have a hash at the end so it's not
|
||||
// convenient to query by full filename
|
||||
function getCreatedDataByPrefix(prefix: string) {
|
||||
const entry = Object.entries(dataContainer).find(([key]) =>
|
||||
key.startsWith(prefix),
|
||||
);
|
||||
if (!entry) {
|
||||
throw new Error(`No created entry found for prefix "${prefix}".
|
||||
Entries created:
|
||||
- ${Object.keys(dataContainer).join('\n- ')}
|
||||
`);
|
||||
}
|
||||
return JSON.parse(entry[1] as string) as PropSidebars;
|
||||
}
|
||||
|
||||
// Extra fns useful for tests!
|
||||
const utils = {
|
||||
getGlobalData: () => globalDataContainer,
|
||||
getRouteConfigs: () => routeConfigs,
|
||||
|
||||
checkVersionMetadataPropCreated: (version: LoadedVersion | undefined) => {
|
||||
if (!version) {
|
||||
throw new Error('Version not found');
|
||||
}
|
||||
const versionMetadataProp = getCreatedDataByPrefix(
|
||||
`version-${_.kebabCase(version.versionName)}-metadata-prop`,
|
||||
);
|
||||
expect(versionMetadataProp.docsSidebars).toEqual(toSidebarsProp(version));
|
||||
},
|
||||
|
||||
expectSnapshot: () => {
|
||||
// Sort the route config like in src/server/plugins/index.ts for
|
||||
// consistent snapshot ordering
|
||||
|
@ -335,11 +309,8 @@ describe('simple website', () => {
|
|||
await plugin.contentLoaded!({
|
||||
content,
|
||||
actions,
|
||||
allContent: {},
|
||||
});
|
||||
|
||||
utils.checkVersionMetadataPropCreated(currentVersion);
|
||||
|
||||
utils.expectSnapshot();
|
||||
|
||||
expect(utils.getGlobalData()).toMatchSnapshot();
|
||||
|
@ -464,14 +435,8 @@ describe('versioned website', () => {
|
|||
await plugin.contentLoaded!({
|
||||
content,
|
||||
actions,
|
||||
allContent: {},
|
||||
});
|
||||
|
||||
utils.checkVersionMetadataPropCreated(currentVersion);
|
||||
utils.checkVersionMetadataPropCreated(version101);
|
||||
utils.checkVersionMetadataPropCreated(version100);
|
||||
utils.checkVersionMetadataPropCreated(versionWithSlugs);
|
||||
|
||||
utils.expectSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -569,12 +534,8 @@ describe('versioned website (community)', () => {
|
|||
await plugin.contentLoaded!({
|
||||
content,
|
||||
actions,
|
||||
allContent: {},
|
||||
});
|
||||
|
||||
utils.checkVersionMetadataPropCreated(currentVersion);
|
||||
utils.checkVersionMetadataPropCreated(version100);
|
||||
|
||||
utils.expectSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -73,6 +73,9 @@ export default async function pluginContentDocs(
|
|||
'docusaurus-plugin-content-docs',
|
||||
);
|
||||
const dataDir = path.join(pluginDataDirRoot, pluginId);
|
||||
// TODO Docusaurus v4 breaking change
|
||||
// module aliasing should be automatic
|
||||
// we should never find local absolute FS paths in the codegen registry
|
||||
const aliasedSource = (source: string) =>
|
||||
`~docs/${posixPath(path.relative(pluginDataDirRoot, source))}`;
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import _ from 'lodash';
|
|||
import logger from '@docusaurus/logger';
|
||||
import {
|
||||
docuHash,
|
||||
createSlugger,
|
||||
normalizeUrl,
|
||||
aliasedSitePathToRelativePath,
|
||||
} from '@docusaurus/utils';
|
||||
|
@ -29,7 +28,6 @@ import type {
|
|||
CategoryGeneratedIndexMetadata,
|
||||
DocMetadata,
|
||||
PluginOptions,
|
||||
PropTagsListPage,
|
||||
} from '@docusaurus/plugin-content-docs';
|
||||
|
||||
function createDocRouteMetadata(docMeta: DocMetadata): RouteMetadata {
|
||||
|
@ -41,36 +39,23 @@ function createDocRouteMetadata(docMeta: DocMetadata): RouteMetadata {
|
|||
|
||||
async function buildVersionCategoryGeneratedIndexRoutes({
|
||||
version,
|
||||
actions,
|
||||
options,
|
||||
aliasedSource,
|
||||
}: BuildVersionRoutesParam): Promise<RouteConfig[]> {
|
||||
const slugs = createSlugger();
|
||||
|
||||
async function buildCategoryGeneratedIndexRoute(
|
||||
categoryGeneratedIndex: CategoryGeneratedIndexMetadata,
|
||||
): Promise<RouteConfig> {
|
||||
const {sidebar, ...prop} = categoryGeneratedIndex;
|
||||
|
||||
const propFileName = slugs.slug(
|
||||
`${version.path}-${categoryGeneratedIndex.sidebar}-category-${categoryGeneratedIndex.title}`,
|
||||
);
|
||||
|
||||
const propData = await actions.createData(
|
||||
`${docuHash(`category/${propFileName}`)}.json`,
|
||||
JSON.stringify(prop, null, 2),
|
||||
);
|
||||
|
||||
return {
|
||||
path: categoryGeneratedIndex.permalink,
|
||||
component: options.docCategoryGeneratedIndexComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
categoryGeneratedIndex: aliasedSource(propData),
|
||||
props: {
|
||||
categoryGeneratedIndex,
|
||||
},
|
||||
// Same as doc, this sidebar route attribute permits to associate this
|
||||
// subpage to the given sidebar
|
||||
...(sidebar && {sidebar}),
|
||||
...(categoryGeneratedIndex.sidebar && {
|
||||
sidebar: categoryGeneratedIndex.sidebar,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -90,7 +75,7 @@ async function buildVersionDocRoutes({
|
|||
// Note that this created data path must be in sync with
|
||||
// metadataPath provided to mdx-loader.
|
||||
`${docuHash(doc.source)}.json`,
|
||||
JSON.stringify(doc, null, 2),
|
||||
doc,
|
||||
);
|
||||
|
||||
const docRoute: RouteConfig = {
|
||||
|
@ -131,7 +116,7 @@ async function buildVersionSidebarRoute(param: BuildVersionRoutesParam) {
|
|||
async function buildVersionTagsRoutes(
|
||||
param: BuildVersionRoutesParam,
|
||||
): Promise<RouteConfig[]> {
|
||||
const {version, options, actions, aliasedSource} = param;
|
||||
const {version, options} = param;
|
||||
const versionTags = getVersionTags(version.docs);
|
||||
|
||||
async function buildTagsListRoute(): Promise<RouteConfig | null> {
|
||||
|
@ -139,37 +124,27 @@ async function buildVersionTagsRoutes(
|
|||
if (Object.keys(versionTags).length === 0) {
|
||||
return null;
|
||||
}
|
||||
const tagsProp: PropTagsListPage['tags'] = toTagsListTagsProp(versionTags);
|
||||
const tagsPropPath = await actions.createData(
|
||||
`${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
|
||||
JSON.stringify(tagsProp, null, 2),
|
||||
);
|
||||
return {
|
||||
path: version.tagsPath,
|
||||
exact: true,
|
||||
component: options.docTagsListComponent,
|
||||
modules: {
|
||||
tags: aliasedSource(tagsPropPath),
|
||||
props: {
|
||||
tags: toTagsListTagsProp(versionTags),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function buildTagDocListRoute(tag: VersionTag): Promise<RouteConfig> {
|
||||
const tagProps = toTagDocListProp({
|
||||
allTagsPath: version.tagsPath,
|
||||
tag,
|
||||
docs: version.docs,
|
||||
});
|
||||
const tagPropPath = await actions.createData(
|
||||
`${docuHash(`tag-${tag.permalink}`)}.json`,
|
||||
JSON.stringify(tagProps, null, 2),
|
||||
);
|
||||
return {
|
||||
path: tag.permalink,
|
||||
component: options.docTagDocListComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
tag: aliasedSource(tagPropPath),
|
||||
props: {
|
||||
tag: toTagDocListProp({
|
||||
allTagsPath: version.tagsPath,
|
||||
tag,
|
||||
docs: version.docs,
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -189,7 +164,7 @@ type BuildVersionRoutesParam = Omit<BuildAllRoutesParam, 'versions'> & {
|
|||
async function buildVersionRoutes(
|
||||
param: BuildVersionRoutesParam,
|
||||
): Promise<RouteConfig> {
|
||||
const {version, actions, options, aliasedSource} = param;
|
||||
const {version, options} = param;
|
||||
|
||||
async function buildVersionSubRoutes() {
|
||||
const [sidebarRoute, tagsRoutes] = await Promise.all([
|
||||
|
@ -201,19 +176,15 @@ async function buildVersionRoutes(
|
|||
}
|
||||
|
||||
async function doBuildVersionRoutes(): Promise<RouteConfig> {
|
||||
const versionProp = toVersionMetadataProp(options.id, version);
|
||||
const versionPropPath = await actions.createData(
|
||||
`${docuHash(`version-${version.versionName}-metadata-prop`)}.json`,
|
||||
JSON.stringify(versionProp, null, 2),
|
||||
);
|
||||
const subRoutes = await buildVersionSubRoutes();
|
||||
return {
|
||||
path: version.path,
|
||||
exact: false,
|
||||
component: options.docVersionRootComponent,
|
||||
routes: subRoutes,
|
||||
modules: {
|
||||
version: aliasedSource(versionPropPath),
|
||||
routes: await buildVersionSubRoutes(),
|
||||
props: {
|
||||
// TODO Docusaurus v4 breaking change?
|
||||
// expose version metadata as route context instead of props
|
||||
version: toVersionMetadataProp(options.id, version),
|
||||
},
|
||||
priority: version.routePriority,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue