From 8641befd4bf9d009aa5befdaeac6090c211433fa Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 19:21:14 +0200 Subject: [PATCH] Ensure author socials normalization is wired properly --- .../__fixtures__/authorsMapFiles/authors.yml | 8 ++- .../2018-12-14-Happy-First-Birthday-Slash.md | 3 + .../__fixtures__/website/blog/authors.yml | 4 ++ .../src/__tests__/authors.test.ts | 67 +++++++++++++++++++ .../src/authors.ts | 28 ++++++-- .../src/blogUtils.ts | 8 --- .../docusaurus-utils/src/dataFileUtils.ts | 1 + .../_blog tests/2024-07-03-dual-author.mdx | 8 +-- 8 files changed, 107 insertions(+), 20 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml index ac09421385d9..62f84790dade 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml @@ -4,15 +4,19 @@ JMarcey: title: Technical Lead & Developer Advocate at Facebook url: http://twitter.com/JoelMarcey image_url: https://github.com/JoelMarcey.png - twitter: JoelMarcey + socials: + twitter: https://twitter.com/JoelMarcey + x: https://x.com/JoelMarcey slorber: name: Sébastien Lorber title: Docusaurus maintainer url: https://sebastienlorber.com image_url: https://github.com/slorber.png - twitter: sebastienlorber email: lorber.sebastien@gmail.com + socials: + twitter: sebastienlorber + x: sebastienlorber yangshun: name: Yangshun Tay diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md index 10ba9373aa47..b8b206e3fb92 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md @@ -2,6 +2,9 @@ title: Happy 1st Birthday Slash! authors: - name: Yangshun Tay + socials: + x: https://x.com/yangshunz + github: yangshun - slorber tags: [birthday,inlineTag,globalTag] --- diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml index a704e9e9841b..c44d2ee68da6 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml @@ -3,3 +3,7 @@ slorber: title: Docusaurus maintainer email: lorber.sebastien@gmail.com url: https://sebastienlorber.com + socials: + twitter: sebastienlorber + x: https://x.com/sebastienlorber + github: slorber diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts index 9ca49bf739d0..51576d635a55 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts @@ -255,6 +255,52 @@ describe('getBlogPostAuthors', () => { ]); }); + it('can normalize inline authors', () => { + expect( + getBlogPostAuthors({ + frontMatter: { + authors: [ + { + name: 'Seb1', + socials: { + x: 'https://x.com/sebastienlorber', + twitter: 'sebastienlorber', + github: 'slorber', + }, + }, + { + name: 'Seb2', + socials: { + x: 'sebastienlorber', + twitter: 'https://twitter.com/sebastienlorber', + github: 'https://github.com/slorber', + }, + }, + ], + }, + authorsMap: {}, + baseUrl: '/', + }), + ).toEqual([ + { + name: 'Seb1', + socials: { + x: 'https://x.com/sebastienlorber', + twitter: 'https://twitter.com/sebastienlorber', + github: 'https://github.com/slorber', + }, + }, + { + name: 'Seb2', + socials: { + x: 'https://x.com/sebastienlorber', + twitter: 'https://twitter.com/sebastienlorber', + github: 'https://github.com/slorber', + }, + }, + ]); + }); + it('throw when using author key with no authorsMap', () => { expect(() => getBlogPostAuthors({ @@ -412,6 +458,27 @@ describe('getAuthorsMap', () => { }), ).resolves.toBeUndefined(); }); + + describe('getAuthorsMap returns normalized', () => { + it('socials', async () => { + const authorsMap = await getAuthorsMap({ + contentPaths, + authorsMapPath: 'authors.yml', + }); + expect(authorsMap.slorber.socials).toMatchInlineSnapshot(` + { + "twitter": "https://twitter.com/sebastienlorber", + "x": "https://x.com/sebastienlorber", + } + `); + expect(authorsMap.JMarcey.socials).toMatchInlineSnapshot(` + { + "twitter": "https://twitter.com/JoelMarcey", + "x": "https://x.com/JoelMarcey", + } + `); + }); + }); }); describe('validateAuthorsMap', () => { diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index 2873bbf940c6..557180279a06 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -5,8 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +import * as _ from 'lodash'; import {getDataFileData, normalizeUrl} from '@docusaurus/utils'; import {Joi, URISchema} from '@docusaurus/utils-validation'; +import {normalizeSocials} from './authorsSocials'; import type {BlogContentPaths} from './types'; import type { Author, @@ -58,18 +60,32 @@ export function validateAuthorsMap(content: unknown): AuthorsMap { return value; } +function normalizeAuthor(author: Author): Author { + return { + ...author, + socials: author.socials ? normalizeSocials(author.socials) : undefined, + }; +} + +function normalizeAuthorsMap(authorsMap: AuthorsMap): AuthorsMap { + return _.mapValues(authorsMap, normalizeAuthor); +} + export async function getAuthorsMap(params: { authorsMapPath: string; contentPaths: BlogContentPaths; }): Promise { - return getDataFileData( + const authorsMap = await getDataFileData( { filePath: params.authorsMapPath, contentPaths: params.contentPaths, fileType: 'authors map', }, + // TODO annoying to test: tightly coupled FS reads + validation... validateAuthorsMap, ); + + return authorsMap ? normalizeAuthorsMap(authorsMap) : undefined; } type AuthorsParam = { @@ -122,7 +138,7 @@ function getFrontMatterAuthorLegacy({ function normalizeFrontMatterAuthors( frontMatterAuthors: BlogPostFrontMatterAuthors = [], ): BlogPostFrontMatterAuthor[] { - function normalizeAuthor( + function normalizeFrontMatterAuthor( authorInput: string | Author, ): BlogPostFrontMatterAuthor { if (typeof authorInput === 'string') { @@ -135,8 +151,8 @@ function normalizeFrontMatterAuthors( } return Array.isArray(frontMatterAuthors) - ? frontMatterAuthors.map(normalizeAuthor) - : [normalizeAuthor(frontMatterAuthors)]; + ? frontMatterAuthors.map(normalizeFrontMatterAuthor) + : [normalizeFrontMatterAuthor(frontMatterAuthors)]; } function getFrontMatterAuthors(params: AuthorsParam): Author[] { @@ -165,11 +181,11 @@ ${Object.keys(authorsMap) } function toAuthor(frontMatterAuthor: BlogPostFrontMatterAuthor): Author { - return { + return normalizeAuthor({ // Author def from authorsMap can be locally overridden by front matter ...getAuthorsMapAuthor(frontMatterAuthor.key), ...frontMatterAuthor, - }; + }); } return frontMatterAuthors.map(toAuthor); diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 3e3d2994e66f..68f429cc8c0c 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -31,7 +31,6 @@ import {getTagsFile} from '@docusaurus/utils-validation'; import {validateBlogPostFrontMatter} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; import {reportAuthorsProblems} from './authorsProblems'; -import {normalizeSocials} from './authorsSocials'; import type {TagsFile} from '@docusaurus/utils'; import type {LoadContext, ParseFrontMatter} from '@docusaurus/types'; import type { @@ -384,13 +383,6 @@ export async function generateBlogPosts( authorsMapPath: options.authorsMapPath, }); - if (authorsMap) { - Object.entries(authorsMap).forEach(([, author]) => { - if (author.socials) { - author.socials = normalizeSocials(author.socials); - } - }); - } const tagsFile = await getTagsFile({contentPaths, tags: options.tags}); async function doProcessBlogSourceFile(blogSourceFile: string) { diff --git a/packages/docusaurus-utils/src/dataFileUtils.ts b/packages/docusaurus-utils/src/dataFileUtils.ts index 937d22b9cf2b..ba671d6e8875 100644 --- a/packages/docusaurus-utils/src/dataFileUtils.ts +++ b/packages/docusaurus-utils/src/dataFileUtils.ts @@ -63,6 +63,7 @@ export async function getDataFileData( try { const contentString = await fs.readFile(filePath, {encoding: 'utf8'}); const unsafeContent = Yaml.load(contentString); + // TODO we shouldn't validate here: it makes validation harder to test return validate(unsafeContent); } catch (err) { logger.error`The ${params.fileType} file at path=${filePath} looks invalid.`; diff --git a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx index 00c6adc18130..025001460de1 100644 --- a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx +++ b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx @@ -4,10 +4,10 @@ authors: - name: Sébastien Lorber imageURL: https://github.com/slorber.png socials: - twitter: https://x.com/sebastienlorber - github: https://github.com/slorber - stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber - linkedin: https://www.linkedin.com/in/sebastienlorber/ + twitter: sebastienlorber + github: slorber + stackoverflow: /users/82609/sebastien-lorber + linkedin: sebastienlorber newsletter: https://thisweekinreact.com/newsletter - name: Sébastien Lorber imageURL: https://github.com/slorber.png