From 112ff4fe6b79a038fcf256be05928d0c97efd0af Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 17:08:09 +0200 Subject: [PATCH] fix sourceToPermalink resolution bug --- .../src/blogUtils.ts | 7 ---- .../src/index.ts | 37 ++++++++++++++++-- .../src/index.ts | 38 +++++++++++++------ 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index b7c76c031d81..3215c9da279b 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -26,7 +26,6 @@ import { isUnlisted, isDraft, readLastUpdateData, - type SourceToPermalink, } from '@docusaurus/utils'; import {validateBlogPostFrontMatter} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; @@ -44,12 +43,6 @@ export function truncate(fileString: string, truncateMarker: RegExp): string { return fileString.split(truncateMarker, 1).shift()!; } -export function getSourceToPermalink(blogPosts: BlogPost[]): SourceToPermalink { - return new Map( - blogPosts.map(({metadata: {source, permalink}}) => [source, permalink]), - ); -} - export function paginateBlogPosts({ blogPosts, basePageUrl, diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index dc64b8b45155..aa6b8034256e 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -19,9 +19,9 @@ import { getDataFilePath, DEFAULT_PLUGIN_ID, resolveMarkdownLinkPathname, + type SourceToPermalink, } from '@docusaurus/utils'; import { - getSourceToPermalink, getBlogTags, paginateBlogPosts, shouldBeListed, @@ -49,6 +49,32 @@ import type {RuleSetUseItem} from 'webpack'; const PluginName = 'docusaurus-plugin-content-blog'; +// TODO this is bad, we should have a better way to do this (new lifecycle?) +// The source to permalink is currently a mutable map passed to the mdx loader +// for link resolution +function createSourceToPermalinkHelper() { + const sourceToPermalink: SourceToPermalink = new Map(); + + function computeSourceToPermalink(content: BlogContent): SourceToPermalink { + return new Map( + content.blogPosts.map(({metadata: {source, permalink}}) => [ + source, + permalink, + ]), + ); + } + + // Mutable map update :/ + function update(content: BlogContent): void { + sourceToPermalink.clear(); + computeSourceToPermalink(content).forEach((value, key) => { + sourceToPermalink.set(key, value); + }); + } + + return {get: () => sourceToPermalink, update}; +} + export default async function pluginContentBlog( context: LoadContext, options: PluginOptions, @@ -95,6 +121,8 @@ export default async function pluginContentBlog( contentPaths, }); + const sourceToPermalinkHelper = createSourceToPermalinkHelper(); + return { name: PluginName, @@ -193,6 +221,8 @@ export default async function pluginContentBlog( }, async contentLoaded({content, actions}) { + sourceToPermalinkHelper.update(content); + await createAllRoutes({ baseUrl, content, @@ -206,7 +236,7 @@ export default async function pluginContentBlog( return translateContent(content, translationFiles); }, - configureWebpack(_config, isServer, utils, content) { + configureWebpack() { const { admonitions, rehypePlugins, @@ -216,7 +246,6 @@ export default async function pluginContentBlog( beforeDefaultRehypePlugins, } = options; - const sourceToPermalink = getSourceToPermalink(content.blogPosts); const contentDirs = getContentPathList(contentPaths); function createMDXLoader(): RuleSetUseItem { @@ -263,7 +292,7 @@ export default async function pluginContentBlog( resolveMarkdownLink: ({linkPathname, sourceFilePath}) => { const permalink = resolveMarkdownLinkPathname(linkPathname, { sourceFilePath, - sourceToPermalink, + sourceToPermalink: sourceToPermalinkHelper.get(), siteDir, contentPaths, }); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 9e8a253b4708..63081dc84a0f 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -58,6 +58,28 @@ import type {LoadContext, Plugin} from '@docusaurus/types'; import type {DocFile, FullVersion} from './types'; import type {RuleSetUseItem} from 'webpack'; +// TODO this is bad, we should have a better way to do this (new lifecycle?) +// The source to permalink is currently a mutable map passed to the mdx loader +// for link resolution +function createSourceToPermalinkHelper() { + const sourceToPermalink: SourceToPermalink = new Map(); + + function computeSourceToPermalink(content: LoadedContent): SourceToPermalink { + const allDocs = content.loadedVersions.flatMap((v) => v.docs); + return new Map(allDocs.map(({source, permalink}) => [source, permalink])); + } + + // Mutable map update :/ + function update(content: LoadedContent): void { + sourceToPermalink.clear(); + computeSourceToPermalink(content).forEach((value, key) => { + sourceToPermalink.set(key, value); + }); + } + + return {get: () => sourceToPermalink, update}; +} + export default async function pluginContentDocs( context: LoadContext, options: PluginOptions, @@ -84,6 +106,8 @@ export default async function pluginContentDocs( // TODO env should be injected into all plugins const env = process.env.NODE_ENV as DocEnv; + const sourceToPermalinkHelper = createSourceToPermalinkHelper(); + return { name: 'docusaurus-plugin-content-docs', @@ -228,6 +252,8 @@ export default async function pluginContentDocs( }, async contentLoaded({content, actions}) { + sourceToPermalinkHelper.update(content); + const versions: FullVersion[] = content.loadedVersions.map(toFullVersion); await createAllRoutes({ @@ -258,16 +284,6 @@ export default async function pluginContentDocs( // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970 .map(addTrailingPathSeparator); - // TODO this does not re-run when content gets updated in dev! - // it's probably better to restore a mutable cache in the plugin - function getSourceToPermalink(): SourceToPermalink { - const allDocs = content.loadedVersions.flatMap((v) => v.docs); - return new Map( - allDocs.map(({source, permalink}) => [source, permalink]), - ); - } - const sourceToPermalink = getSourceToPermalink(); - function createMDXLoader(): RuleSetUseItem { const loaderOptions: MDXLoaderOptions = { admonitions: options.admonitions, @@ -302,7 +318,7 @@ export default async function pluginContentDocs( ); const permalink = resolveMarkdownLinkPathname(linkPathname, { sourceFilePath, - sourceToPermalink, + sourceToPermalink: sourceToPermalinkHelper.get(), siteDir, contentPaths: version, });