Repository: facebook/docusaurus
File: packages/docusaurus-plugin-content-blog/src/authors.ts (TypeScript)

Code before:
      return {
        ...authorInput,
        socials: normalizeSocials(authorInput.socials ?? {}),
      };
    }

    return Array.isArray(frontMatter.authors)
      ? frontMatter.authors.map(normalizeAuthor)
      : [normalizeAuthor(frontMatter.authors)];
  }

  function getAuthorsMapAuthor(key: string | undefined): Author | undefined {
    if (key) {
      if (!authorsMap || Object.keys(authorsMap).length === 0) {
        throw new Error(`Can't reference blog post authors by a key (such as '${key}') because no authors map file could be loaded.
Please double-check your blog plugin config (in particular 'authorsMapPath'), ensure the file exists at the configured path, is not empty, and is valid!`);
      }
      const author = authorsMap[key];
      if (!author) {
        throw Error(`Blog author with key "${key}" not found in the authors map file.
Valid author keys are:
${Object.keys(authorsMap)
  .map((validKey) => `- ${validKey}`)
  .join('\n')}`);
      }
      return author;
    }
    return undefined;
  }

  function toAuthor(frontMatterAuthor: BlogPostFrontMatterAuthor): Author {
    const author = {
      // Author def from authorsMap can be locally overridden by front matter
      ...getAuthorsMapAuthor(frontMatterAuthor.key),
      ...frontMatterAuthor,
    };

    return {
      ...author,
      key: author.key ?? null,
      page: author.page ?? null,
      imageURL: normalizeImageUrl({imageURL: author.imageURL, baseUrl}),
    };
  }
}

export function getBlogPostAuthors(params: AuthorsParam): Author[] {
  const authorLegacy = getFrontMatterAuthorLegacy(params);
  const authors = getFrontMatterAuthors(params);

  if (authorLegacy) {

Review comment (security):
Here if author front matter has no social key, the result will be `social: {}`.

If the key was absent before normalization, we'd rather keep it absent after normalization (unless it's an explicit goal of the normalization to always have an object for empty (in which case the normalized type shouldn't allow null/undefined anymore)

Code after:
  }

  return undefined;
}

function getFrontMatterAuthors(params: AuthorsParam): Author[] {
  const {authorsMap, frontMatter, baseUrl} = params;
  return normalizeFrontMatterAuthors().map(toAuthor);

  function normalizeFrontMatterAuthors(): BlogPostFrontMatterAuthor[] {
    if (frontMatter.authors === undefined) {
      return [];
    }

    function normalizeAuthor(
      authorInput: string | BlogPostFrontMatterAuthor,
    ): BlogPostFrontMatterAuthor {
      if (typeof authorInput === 'string') {
        // We could allow users to provide an author's name here, but we only
        // support keys, otherwise, a typo in a key would fall back to
        // becoming a name and may end up unnoticed
        return {key: authorInput};
      }
      return {
        ...authorInput,
        socials: normalizeSocials(authorInput.socials ?? {}),
      };
    }

    return Array.isArray(frontMatter.authors)
      ? frontMatter.authors.map(normalizeAuthor)
      : [normalizeAuthor(frontMatter.authors)];
  }

  function getAuthorsMapAuthor(key: string | undefined): Author | undefined {
    if (key) {
      if (!authorsMap || Object.keys(authorsMap).length === 0) {
        throw new Error(`Can't reference blog post authors by a key (such as '${key}') because no authors map file could be loaded.
Please double-check your blog plugin config (in particular 'authorsMapPath'), ensure the file exists at the configured path, is not empty, and is valid!`);
      }
      const author = authorsMap[key];
      if (!author) {
        throw Error(`Blog author with key "${key}" not found in the authors map file.
Valid author keys are:
${Object.keys(authorsMap)
  .map((validKey) => `- ${validKey}`)
  .join('\n')}`);
      }
      return author;
    }
    return undefined;