From 5e10d3334762d4d0fcbf34ad208fff27285c2eaf Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 14 May 2024 13:03:13 +0200 Subject: [PATCH 001/142] feat(docs): predefined tag list --- .../src/docs.ts | 47 ++++++++++++++++++- .../src/options.ts | 6 +++ .../src/plugin-content-docs.d.ts | 2 + .../src/tags.ts | 17 +++++++ website/docusaurus.config.ts | 1 + 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 7c94593fa0cf..86eff424ee51 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -22,10 +22,13 @@ import { isDraft, readLastUpdateData, } from '@docusaurus/utils'; +import YAML from 'js-yaml'; import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; import {stripPathNumberPrefixes} from './numberPrefix'; import {toDocNavigationLink, toNavigationLink} from './sidebars/utils'; +import {createTagSchema, validateTags} from './tags'; +import type {FrontMatterTag} from '@docusaurus/utils'; import type { MetadataOptions, PluginOptions, @@ -76,6 +79,44 @@ export async function readVersionDocs( export type DocEnv = 'production' | 'development'; +async function processFileTagsPath( + options: MetadataOptions, + contentPath: string, + frontMatterTags: FrontMatterTag[] | undefined, +) { + if (options.tagsFilePath && !contentPath.includes('versioned_docs')) { + const tagsPath = path.join(contentPath, options.tagsFilePath); + const tagsFileContent = await fs.readFile(tagsPath, 'utf-8'); + const data = YAML.load(tagsFileContent); + const tags = validateTags(data); + const validTagsSchema = createTagSchema(Object.keys(tags.value)); + console.log('frontMatterTags', frontMatterTags); + if (frontMatterTags !== undefined && Array.isArray(frontMatterTags)) { + const labels = frontMatterTags.map((tag) => + typeof tag === 'string' ? tag : tag.label, + ); + const tagList = validTagsSchema.validate(labels); + + if (tagList.error) { + throw new Error( + `There was an error validating tags: ${tagList.error.message}`, + {cause: tagList}, + ); + } + console.log('tagList:', tagList.value); + } + if (tags.error) { + throw new Error( + `There was an error extracting tags: ${tags.error.message}`, + {cause: tags}, + ); + } + // console.log('tags:', tags); + return tags.value; + } + return []; +} + async function doProcessDocMetadata({ docFile, versionMetadata, @@ -206,6 +247,10 @@ async function doProcessDocMetadata({ const draft = isDraft({env, frontMatter}); const unlisted = isUnlisted({env, frontMatter}); + const blogTags = options.tagsFilePath + ? await processFileTagsPath(options, contentPath, frontMatter.tags) + : normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags); + // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. // Adding properties to object after instantiation will cause hidden @@ -221,7 +266,7 @@ async function doProcessDocMetadata({ draft, unlisted, editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(), - tags: normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags), + tags: blogTags, version: versionMetadata.versionName, lastUpdatedBy: lastUpdate.lastUpdatedBy, lastUpdatedAt: lastUpdate.lastUpdatedAt, diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index a7c2e1d1e1cc..f2f4b43fa4c8 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -54,6 +54,8 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsible: true, sidebarCollapsed: true, breadcrumbs: true, + onBrokenTags: 'warn', + tagsFilePath: '', }; const VersionOptionsSchema = Joi.object({ @@ -140,6 +142,10 @@ const OptionsSchema = Joi.object({ lastVersion: Joi.string().optional(), versions: VersionsOptionsSchema, breadcrumbs: Joi.bool().default(DEFAULT_OPTIONS.breadcrumbs), + onBrokenTags: Joi.string() + .equal('ignore', 'log', 'warn', 'throw') + .default(DEFAULT_OPTIONS.onBrokenTags), + tagsFilePath: Joi.string().default(DEFAULT_OPTIONS.tagsFilePath), }); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index bae47646fbd5..96e6faad5d7f 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -101,6 +101,7 @@ declare module '@docusaurus/plugin-content-docs' { numberPrefixParser: NumberPrefixParser; /** Enable or disable the breadcrumbs on doc pages. */ breadcrumbs: boolean; + tagsFilePath: string; }; export type PathOptions = { @@ -224,6 +225,7 @@ declare module '@docusaurus/plugin-content-docs' { * `routeBasePath`. **DO NOT** include a trailing slash. */ tagsBasePath: string; + onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type Options = Partial< Overwrite< diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index 1fd784c213fa..b50983f1051f 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -7,6 +7,7 @@ import _ from 'lodash'; import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils'; +import {Joi} from '@docusaurus/utils-validation'; import type {VersionTags} from './types'; import type {DocMetadata} from '@docusaurus/plugin-content-docs'; @@ -25,3 +26,19 @@ export function getVersionTags(docs: DocMetadata[]): VersionTags { }; }); } + +export const tagSchema = Joi.object().pattern( + Joi.string(), + Joi.object({ + label: Joi.string().required(), + description: Joi.string().required(), + }), +); + +export function validateTags(tags: unknown): Joi.ValidationResult { + return tagSchema.validate(tags); +} + +export function createTagSchema(tags: string[]): Joi.Schema { + return Joi.array().items(Joi.string().valid(...tags)); +} diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index aae27b1a4d8e..79801ca112eb 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -466,6 +466,7 @@ export default async function createConfigAsync() { label: `${getNextVersionName()} 🚧`, }, }, + tagsFilePath: 'tags.yml', }, blog: { // routeBasePath: '/', From 5c915f9f4cea224945834d7052edaa1ab206e6fd Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 14 May 2024 14:15:44 +0200 Subject: [PATCH 002/142] refactor: split into functions --- .../src/docs.ts | 75 ++++++++++--------- .../src/plugin-content-docs.d.ts | 2 +- .../src/tags.ts | 23 ++++++ 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 86eff424ee51..85989a9b3c95 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -27,8 +27,8 @@ import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; import {stripPathNumberPrefixes} from './numberPrefix'; import {toDocNavigationLink, toNavigationLink} from './sidebars/utils'; -import {createTagSchema, validateTags} from './tags'; -import type {FrontMatterTag} from '@docusaurus/utils'; +import {createTagSchema, validateFrontMatterTags, validateTags} from './tags'; +import type {FrontMatterTag, Tag} from '@docusaurus/utils'; import type { MetadataOptions, PluginOptions, @@ -79,42 +79,32 @@ export async function readVersionDocs( export type DocEnv = 'production' | 'development'; +async function getTagsFilePath( + options: MetadataOptions, + contentPath: string, +): Promise { + const tagsPath = path.join(contentPath, options.tagsFilePath); + const tagsFileContent = await fs.readFile(tagsPath, 'utf-8'); + const data = YAML.load(tagsFileContent); + const tags = validateTags(data); + if (tags.error) { + throw new Error( + `There was an error extracting tags: ${tags.error.message}`, + {cause: tags}, + ); + } + return tags.value; +} + async function processFileTagsPath( options: MetadataOptions, contentPath: string, frontMatterTags: FrontMatterTag[] | undefined, ) { - if (options.tagsFilePath && !contentPath.includes('versioned_docs')) { - const tagsPath = path.join(contentPath, options.tagsFilePath); - const tagsFileContent = await fs.readFile(tagsPath, 'utf-8'); - const data = YAML.load(tagsFileContent); - const tags = validateTags(data); - const validTagsSchema = createTagSchema(Object.keys(tags.value)); - console.log('frontMatterTags', frontMatterTags); - if (frontMatterTags !== undefined && Array.isArray(frontMatterTags)) { - const labels = frontMatterTags.map((tag) => - typeof tag === 'string' ? tag : tag.label, - ); - const tagList = validTagsSchema.validate(labels); - - if (tagList.error) { - throw new Error( - `There was an error validating tags: ${tagList.error.message}`, - {cause: tagList}, - ); - } - console.log('tagList:', tagList.value); - } - if (tags.error) { - throw new Error( - `There was an error extracting tags: ${tags.error.message}`, - {cause: tags}, - ); - } - // console.log('tags:', tags); - return tags.value; - } - return []; + const tags = await getTagsFilePath(options, contentPath); + const validTagsSchema = createTagSchema(Object.keys(tags)); + validateFrontMatterTags(frontMatterTags, validTagsSchema); + return tags; } async function doProcessDocMetadata({ @@ -247,9 +237,22 @@ async function doProcessDocMetadata({ const draft = isDraft({env, frontMatter}); const unlisted = isUnlisted({env, frontMatter}); - const blogTags = options.tagsFilePath - ? await processFileTagsPath(options, contentPath, frontMatter.tags) - : normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags); + // console.log( + // 'blogtags check:', + // options.tagsFilePath || options.onBrokenTags === 'ignore', + // ); + + console.log( + 'normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags):', + normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags), + ); + const blogTags = + !options.tagsFilePath || options.onBrokenTags === 'ignore' + ? normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags) + : await processFileTagsPath(options, contentPath, frontMatter.tags); + + // console.log('blogTags:', blogTags); + // console.log('versionMetadata.tagsPath:', versionMetadata.tagsPath); // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 96e6faad5d7f..3ff7a998fa4c 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -102,6 +102,7 @@ declare module '@docusaurus/plugin-content-docs' { /** Enable or disable the breadcrumbs on doc pages. */ breadcrumbs: boolean; tagsFilePath: string; + onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type PathOptions = { @@ -225,7 +226,6 @@ declare module '@docusaurus/plugin-content-docs' { * `routeBasePath`. **DO NOT** include a trailing slash. */ tagsBasePath: string; - onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type Options = Partial< Overwrite< diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index b50983f1051f..c3365ff092fa 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -8,6 +8,7 @@ import _ from 'lodash'; import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils'; import {Joi} from '@docusaurus/utils-validation'; +import type {FrontMatterTag} from '@docusaurus/utils'; import type {VersionTags} from './types'; import type {DocMetadata} from '@docusaurus/plugin-content-docs'; @@ -42,3 +43,25 @@ export function validateTags(tags: unknown): Joi.ValidationResult { export function createTagSchema(tags: string[]): Joi.Schema { return Joi.array().items(Joi.string().valid(...tags)); } + +export function validateFrontMatterTags( + frontMatterTags: FrontMatterTag[] | undefined, + validTagsSchema: Joi.Schema, +): void { + if (frontMatterTags === undefined || !Array.isArray(frontMatterTags)) { + return; + } + + const labels = frontMatterTags.map((tag) => + typeof tag === 'string' ? tag : tag.permalink, + ); + + const tagList = validTagsSchema.validate(labels); + + if (tagList.error) { + throw new Error( + `There was an error validating tags: ${tagList.error.message}`, + {cause: tagList}, + ); + } +} From 5f0c14e1e44ef7182989754afdfbd04e1cf4818a Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Tue, 14 May 2024 12:20:26 +0000 Subject: [PATCH 003/142] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index cc4e06e18cc5..9366131f2135 100644 --- a/project-words.txt +++ b/project-words.txt @@ -27,6 +27,7 @@ beforeinstallprompt Bhatt blockquotes Blockquotes +blogtags Bokmål browserstack buble From fa572f86c2e2eb13ae19b2317d846dcf7d82b05a Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 14 May 2024 14:47:30 +0200 Subject: [PATCH 004/142] wip --- .../src/docs.ts | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 85989a9b3c95..11ac8b611911 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -100,11 +100,15 @@ async function processFileTagsPath( options: MetadataOptions, contentPath: string, frontMatterTags: FrontMatterTag[] | undefined, -) { +): Promise { const tags = await getTagsFilePath(options, contentPath); const validTagsSchema = createTagSchema(Object.keys(tags)); validateFrontMatterTags(frontMatterTags, validTagsSchema); - return tags; + const transformedTags = Object.entries(tags).map(([key, value]) => ({ + label: value.label, + permalink: key, + })); + return transformedTags; } async function doProcessDocMetadata({ @@ -237,23 +241,11 @@ async function doProcessDocMetadata({ const draft = isDraft({env, frontMatter}); const unlisted = isUnlisted({env, frontMatter}); - // console.log( - // 'blogtags check:', - // options.tagsFilePath || options.onBrokenTags === 'ignore', - // ); - - console.log( - 'normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags):', - normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags), - ); const blogTags = !options.tagsFilePath || options.onBrokenTags === 'ignore' ? normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags) : await processFileTagsPath(options, contentPath, frontMatter.tags); - // console.log('blogTags:', blogTags); - // console.log('versionMetadata.tagsPath:', versionMetadata.tagsPath); - // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. // Adding properties to object after instantiation will cause hidden From 85e0bf4bd170ddee2f474b9d0711fda5bb19f9a4 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Tue, 14 May 2024 12:53:50 +0000 Subject: [PATCH 005/142] refactor: apply lint autofix --- project-words.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index 9366131f2135..cc4e06e18cc5 100644 --- a/project-words.txt +++ b/project-words.txt @@ -27,7 +27,6 @@ beforeinstallprompt Bhatt blockquotes Blockquotes -blogtags Bokmål browserstack buble From 307df02102ea16e24afe4b622041086beca31d00 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 14 May 2024 15:20:57 +0200 Subject: [PATCH 006/142] wip: fix duplicated routes --- packages/docusaurus-plugin-content-docs/src/docs.ts | 11 +++++++++-- website/docs/installation.mdx | 1 + website/docs/tags.yml | 6 ++++++ website/docusaurus.config.ts | 1 + website/versioned_docs/version-3.2.1/tags.yml | 6 ++++++ website/versioned_docs/version-3.3.2/tags.yml | 6 ++++++ 6 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 website/docs/tags.yml create mode 100644 website/versioned_docs/version-3.2.1/tags.yml create mode 100644 website/versioned_docs/version-3.3.2/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 11ac8b611911..66757f92d735 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -100,6 +100,7 @@ async function processFileTagsPath( options: MetadataOptions, contentPath: string, frontMatterTags: FrontMatterTag[] | undefined, + versionTagsPath: string, ): Promise { const tags = await getTagsFilePath(options, contentPath); const validTagsSchema = createTagSchema(Object.keys(tags)); @@ -108,7 +109,8 @@ async function processFileTagsPath( label: value.label, permalink: key, })); - return transformedTags; + + return normalizeFrontMatterTags(versionTagsPath, transformedTags); } async function doProcessDocMetadata({ @@ -244,7 +246,12 @@ async function doProcessDocMetadata({ const blogTags = !options.tagsFilePath || options.onBrokenTags === 'ignore' ? normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags) - : await processFileTagsPath(options, contentPath, frontMatter.tags); + : await processFileTagsPath( + options, + contentPath, + frontMatter.tags, + versionMetadata.tagsPath, + ); // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. diff --git a/website/docs/installation.mdx b/website/docs/installation.mdx index f9f29dac424f..8b398eac1ae4 100644 --- a/website/docs/installation.mdx +++ b/website/docs/installation.mdx @@ -1,5 +1,6 @@ --- description: How to install Docusaurus locally, and start a Docusaurus site in no time. +tags: [installation, getting-started] --- # Installation diff --git a/website/docs/tags.yml b/website/docs/tags.yml new file mode 100644 index 000000000000..c4718703baae --- /dev/null +++ b/website/docs/tags.yml @@ -0,0 +1,6 @@ +getting-started: + description: Get started with the basics of using the API. + label: Getting Started +installation: + description: How to install the API. + label: installation diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 79801ca112eb..416700d6d64d 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -467,6 +467,7 @@ export default async function createConfigAsync() { }, }, tagsFilePath: 'tags.yml', + onBrokenTags: 'throw', }, blog: { // routeBasePath: '/', diff --git a/website/versioned_docs/version-3.2.1/tags.yml b/website/versioned_docs/version-3.2.1/tags.yml new file mode 100644 index 000000000000..b5aea8df76cb --- /dev/null +++ b/website/versioned_docs/version-3.2.1/tags.yml @@ -0,0 +1,6 @@ +getting-started: + description: Get started with the basics of using the API. + label: Getting Started +introduction: + description: Learn about the basics of the API. + label: Introduction diff --git a/website/versioned_docs/version-3.3.2/tags.yml b/website/versioned_docs/version-3.3.2/tags.yml new file mode 100644 index 000000000000..b5aea8df76cb --- /dev/null +++ b/website/versioned_docs/version-3.3.2/tags.yml @@ -0,0 +1,6 @@ +getting-started: + description: Get started with the basics of using the API. + label: Getting Started +introduction: + description: Learn about the basics of the API. + label: Introduction From 0a822f33da7b9594ada4fcea44284f0c5b632b7b Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 14 May 2024 16:33:50 +0200 Subject: [PATCH 007/142] wip --- .../src/docs.ts | 37 +++++++++++++------ .../src/tags.ts | 26 +++++++++---- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 66757f92d735..b0e3e07b52b7 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -89,22 +89,34 @@ async function getTagsFilePath( const tags = validateTags(data); if (tags.error) { throw new Error( - `There was an error extracting tags: ${tags.error.message}`, + `There was an error extracting tags from file: ${tags.error.message}`, {cause: tags}, ); } return tags.value; } -async function processFileTagsPath( - options: MetadataOptions, - contentPath: string, - frontMatterTags: FrontMatterTag[] | undefined, - versionTagsPath: string, -): Promise { +async function processFileTagsPath({ + options, + contentPath, + source, + frontMatterTags, + versionTagsPath, +}: { + options: MetadataOptions; + contentPath: string; + source: string; + frontMatterTags: FrontMatterTag[] | undefined; + versionTagsPath: string; +}): Promise { const tags = await getTagsFilePath(options, contentPath); const validTagsSchema = createTagSchema(Object.keys(tags)); - validateFrontMatterTags(frontMatterTags, validTagsSchema); + validateFrontMatterTags({ + frontMatterTags, + validTagsSchema, + source, + onBrokenTags: options.onBrokenTags, + }); const transformedTags = Object.entries(tags).map(([key, value]) => ({ label: value.label, permalink: key, @@ -246,12 +258,13 @@ async function doProcessDocMetadata({ const blogTags = !options.tagsFilePath || options.onBrokenTags === 'ignore' ? normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags) - : await processFileTagsPath( + : await processFileTagsPath({ options, contentPath, - frontMatter.tags, - versionMetadata.tagsPath, - ); + source, + frontMatterTags: frontMatter.tags, + versionTagsPath: versionMetadata.tagsPath, + }); // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index c3365ff092fa..a9e58e4a0e5d 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -8,9 +8,13 @@ import _ from 'lodash'; import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils'; import {Joi} from '@docusaurus/utils-validation'; +import logger from '@docusaurus/logger'; import type {FrontMatterTag} from '@docusaurus/utils'; import type {VersionTags} from './types'; -import type {DocMetadata} from '@docusaurus/plugin-content-docs'; +import type { + DocMetadata, + MetadataOptions, +} from '@docusaurus/plugin-content-docs'; export function getVersionTags(docs: DocMetadata[]): VersionTags { const groups = groupTaggedItems(docs, (doc) => doc.tags); @@ -44,10 +48,17 @@ export function createTagSchema(tags: string[]): Joi.Schema { return Joi.array().items(Joi.string().valid(...tags)); } -export function validateFrontMatterTags( - frontMatterTags: FrontMatterTag[] | undefined, - validTagsSchema: Joi.Schema, -): void { +export function validateFrontMatterTags({ + frontMatterTags, + validTagsSchema, + source, + onBrokenTags, +}: { + frontMatterTags: FrontMatterTag[] | undefined; + validTagsSchema: Joi.Schema; + source: string; + onBrokenTags: MetadataOptions['onBrokenTags']; +}): void { if (frontMatterTags === undefined || !Array.isArray(frontMatterTags)) { return; } @@ -59,9 +70,8 @@ export function validateFrontMatterTags( const tagList = validTagsSchema.validate(labels); if (tagList.error) { - throw new Error( - `There was an error validating tags: ${tagList.error.message}`, - {cause: tagList}, + logger.report(onBrokenTags)( + `Broken tags found in ${source} [${labels}] : ${tagList.error.message}`, ); } } From 523c15af394d98d301a16c1cc9df675714e508c3 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 15 May 2024 15:20:41 +0200 Subject: [PATCH 008/142] wip tests --- .../__fixtures__/simple-tags/docs/tags.yml | 3 ++ .../simple-tags/docusaurus.config.js | 26 ++++++++++++ .../src/__tests__/tags.test.ts | 42 +++++++++++++++++++ .../src/docs.ts | 39 +++++++++-------- 4 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/tags.yml create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/tags.yml new file mode 100644 index 000000000000..fd66420a585d --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/tags.yml @@ -0,0 +1,3 @@ +open: + label: Open Source + description: Learn about the open source diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js new file mode 100644 index 000000000000..bd7de0da9fcb --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js @@ -0,0 +1,26 @@ +/** + * 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. + */ + +module.exports = { + title: 'My Site', + tagline: 'The tagline of my site', + url: 'https://your-docusaurus-site.example.com', + baseUrl: '/', + favicon: 'img/favicon.ico', + markdown: { + parseFrontMatter: async (params) => { + // Reuse the default parser + const result = await params.defaultParseFrontMatter(params); + if (result.frontMatter.last_update?.author) { + result.frontMatter.last_update.author = + result.frontMatter.last_update.author + + ' (processed by parseFrontMatter)'; + } + return result; + }, + }, +}; diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts new file mode 100644 index 000000000000..d07d71a637ab --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -0,0 +1,42 @@ +/** + * 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 path from 'path'; +import {fromPartial} from '@total-typescript/shoehorn'; +import {processFileTagsPath} from '../docs'; + +describe('processFileTagsPath', () => { + it('docs with valid tags', async () => { + // const siteDir = path.join(__dirname, '__fixtures__', 'simple-tags'); + // const context = await loadContext({siteDir}); + // console.log('context:', context); + + const contentPath = path.join( + __dirname, + '__fixtures__', + 'simple-tags', + 'docs', + ); + + const tagsFilePath = 'tags.yml'; + + const process = processFileTagsPath({ + contentPath, + options: fromPartial({ + tagsFilePath, + onBrokenTags: 'throw', + }), + source: path.join(contentPath, 'hello.md'), + versionTagsPath: '/processFileTagsPath/tags', + frontMatterTags: ['tag1', 'tag2'], + }); + console.log('process:', process); + await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( + `"Broken tags found in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md [tag1,tag2] : "[0]" must be [open]"`, + ); + }); +}); diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index b0e3e07b52b7..a2a48c53c493 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -79,7 +79,7 @@ export async function readVersionDocs( export type DocEnv = 'production' | 'development'; -async function getTagsFilePath( +async function getTagDefinition( options: MetadataOptions, contentPath: string, ): Promise { @@ -96,7 +96,7 @@ async function getTagsFilePath( return tags.value; } -async function processFileTagsPath({ +export async function processFileTagsPath({ options, contentPath, source, @@ -109,15 +109,25 @@ async function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; }): Promise { - const tags = await getTagsFilePath(options, contentPath); - const validTagsSchema = createTagSchema(Object.keys(tags)); + // console.log('options:', options); + // console.log('====================================================='); + // console.log('contentPath:', contentPath); + // console.log('source:', source); + // console.log('frontMatterTags:', frontMatterTags); + // console.log('versionTagsPath:', versionTagsPath); + if (!options.tagsFilePath || options.onBrokenTags === 'ignore') { + return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); + } + + const definedTags = await getTagDefinition(options, contentPath); + const validTagsSchema = createTagSchema(Object.keys(definedTags)); validateFrontMatterTags({ frontMatterTags, validTagsSchema, source, onBrokenTags: options.onBrokenTags, }); - const transformedTags = Object.entries(tags).map(([key, value]) => ({ + const transformedTags = Object.entries(definedTags).map(([key, value]) => ({ label: value.label, permalink: key, })); @@ -255,17 +265,6 @@ async function doProcessDocMetadata({ const draft = isDraft({env, frontMatter}); const unlisted = isUnlisted({env, frontMatter}); - const blogTags = - !options.tagsFilePath || options.onBrokenTags === 'ignore' - ? normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags) - : await processFileTagsPath({ - options, - contentPath, - source, - frontMatterTags: frontMatter.tags, - versionTagsPath: versionMetadata.tagsPath, - }); - // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. // Adding properties to object after instantiation will cause hidden @@ -281,7 +280,13 @@ async function doProcessDocMetadata({ draft, unlisted, editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(), - tags: blogTags, + tags: await processFileTagsPath({ + options, + contentPath, + source, + frontMatterTags: frontMatter.tags, + versionTagsPath: versionMetadata.tagsPath, + }), version: versionMetadata.versionName, lastUpdatedBy: lastUpdate.lastUpdatedBy, lastUpdatedAt: lastUpdate.lastUpdatedAt, From 913b263fd0e061a66c97d3fc00e1fa34bf9a5f90 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 15 May 2024 15:39:26 +0200 Subject: [PATCH 009/142] wip tests --- .../__fixtures__/simple-tags/docs/hello.md | 4 +++ .../src/__tests__/tags.test.ts | 26 +++++++++++++------ .../src/docs.ts | 6 ----- 3 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md new file mode 100644 index 000000000000..76c74759f50d --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md @@ -0,0 +1,4 @@ +--- +id: test +tags: ['hello', 'world'] +--- diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index d07d71a637ab..528dd3616f14 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -6,15 +6,14 @@ */ import path from 'path'; +import fs from 'fs-extra'; import {fromPartial} from '@total-typescript/shoehorn'; +import {parseMarkdownFile} from '@docusaurus/utils'; import {processFileTagsPath} from '../docs'; +import {validateDocFrontMatter} from '../frontMatter'; describe('processFileTagsPath', () => { it('docs with valid tags', async () => { - // const siteDir = path.join(__dirname, '__fixtures__', 'simple-tags'); - // const context = await loadContext({siteDir}); - // console.log('context:', context); - const contentPath = path.join( __dirname, '__fixtures__', @@ -23,6 +22,18 @@ describe('processFileTagsPath', () => { ); const tagsFilePath = 'tags.yml'; + const filePath = path.join(contentPath, 'hello.md'); + const {frontMatter: unsafeFrontMatter} = await parseMarkdownFile({ + filePath, + fileContent: await fs.readFile(filePath, 'utf-8'), + parseFrontMatter: async (params) => { + const result = await params.defaultParseFrontMatter(params); + return { + ...result, + }; + }, + }); + const frontMatter = validateDocFrontMatter(unsafeFrontMatter); const process = processFileTagsPath({ contentPath, @@ -30,13 +41,12 @@ describe('processFileTagsPath', () => { tagsFilePath, onBrokenTags: 'throw', }), - source: path.join(contentPath, 'hello.md'), + source: filePath, versionTagsPath: '/processFileTagsPath/tags', - frontMatterTags: ['tag1', 'tag2'], + frontMatterTags: frontMatter.tags, }); - console.log('process:', process); await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( - `"Broken tags found in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md [tag1,tag2] : "[0]" must be [open]"`, + `"Broken tags found in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md [hello,world] : "[0]" must be [open]"`, ); }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index a2a48c53c493..fef4fdc06fb3 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -109,12 +109,6 @@ export async function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; }): Promise { - // console.log('options:', options); - // console.log('====================================================='); - // console.log('contentPath:', contentPath); - // console.log('source:', source); - // console.log('frontMatterTags:', frontMatterTags); - // console.log('versionTagsPath:', versionTagsPath); if (!options.tagsFilePath || options.onBrokenTags === 'ignore') { return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } From 335cbeb54ef8685d826211f7b3f0cc09263324cd Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 15 May 2024 16:19:27 +0200 Subject: [PATCH 010/142] wip tests --- .../simple-tags/docusaurus.config.js | 26 ----- .../__fixtures__/simple-tags/good.md | 4 + .../simple-tags/{docs => }/tags.yml | 0 .../simple-tags/{docs/hello.md => wrong.md} | 0 .../src/__tests__/tags.test.ts | 105 ++++++++++++------ 5 files changed, 78 insertions(+), 57 deletions(-) delete mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md rename packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/{docs => }/tags.yml (100%) rename packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/{docs/hello.md => wrong.md} (100%) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js deleted file mode 100644 index bd7de0da9fcb..000000000000 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docusaurus.config.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * 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. - */ - -module.exports = { - title: 'My Site', - tagline: 'The tagline of my site', - url: 'https://your-docusaurus-site.example.com', - baseUrl: '/', - favicon: 'img/favicon.ico', - markdown: { - parseFrontMatter: async (params) => { - // Reuse the default parser - const result = await params.defaultParseFrontMatter(params); - if (result.frontMatter.last_update?.author) { - result.frontMatter.last_update.author = - result.frontMatter.last_update.author + - ' (processed by parseFrontMatter)'; - } - return result; - }, - }, -}; diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md new file mode 100644 index 000000000000..6f5aa6a901e2 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md @@ -0,0 +1,4 @@ +--- +id: test +tags: ['open'] +--- diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml similarity index 100% rename from packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/tags.yml rename to packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md similarity index 100% rename from packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md rename to packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 528dd3616f14..19a495d30ee8 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -12,41 +12,84 @@ import {parseMarkdownFile} from '@docusaurus/utils'; import {processFileTagsPath} from '../docs'; import {validateDocFrontMatter} from '../frontMatter'; +const createTest = async ({ + filePath, + onBrokenTags, +}: { + filePath: string; + onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw' | undefined; +}) => { + const contentPath = path.join(__dirname, '__fixtures__', 'simple-tags'); + const tagsFilePath = 'tags.yml'; + + const {frontMatter: unsafeFrontMatter} = await parseMarkdownFile({ + filePath, + fileContent: await fs.readFile(filePath, 'utf-8'), + parseFrontMatter: async (params) => { + const result = await params.defaultParseFrontMatter(params); + return {...result}; + }, + }); + const frontMatter = validateDocFrontMatter(unsafeFrontMatter); + + return processFileTagsPath({ + contentPath, + options: fromPartial({ + tagsFilePath, + onBrokenTags, + }), + source: filePath, + versionTagsPath: '/processFileTagsPath/tags', + frontMatterTags: frontMatter.tags, + }); +}; + describe('processFileTagsPath', () => { - it('docs with valid tags', async () => { - const contentPath = path.join( - __dirname, - '__fixtures__', - 'simple-tags', - 'docs', - ); + const testFolder = path.join(__dirname, '__fixtures__', 'simple-tags'); - const tagsFilePath = 'tags.yml'; - const filePath = path.join(contentPath, 'hello.md'); - const {frontMatter: unsafeFrontMatter} = await parseMarkdownFile({ - filePath, - fileContent: await fs.readFile(filePath, 'utf-8'), - parseFrontMatter: async (params) => { - const result = await params.defaultParseFrontMatter(params); - return { - ...result, - }; - }, - }); - const frontMatter = validateDocFrontMatter(unsafeFrontMatter); - - const process = processFileTagsPath({ - contentPath, - options: fromPartial({ - tagsFilePath, - onBrokenTags: 'throw', - }), - source: filePath, - versionTagsPath: '/processFileTagsPath/tags', - frontMatterTags: frontMatter.tags, + it('throw when docs has invalid tags', async () => { + const process = createTest({ + filePath: path.join(testFolder, 'wrong.md'), + onBrokenTags: 'throw', }); + await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( - `"Broken tags found in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/docs/hello.md [hello,world] : "[0]" must be [open]"`, + `"Broken tags found in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md [hello,world] : "[0]" must be [open]"`, ); }); + + it('warns when docs has invalid tags', async () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); + + const process = createTest({ + filePath: path.join(testFolder, 'wrong.md'), + onBrokenTags: 'warn', + }); + + await process; + + expect(consoleWarnSpy).toHaveBeenCalledTimes(1); + expect(consoleWarnSpy).toHaveBeenCalledWith( + expect.stringMatching( + /.*\[WARNING\].*Broken tags found in .*wrong\.md.*\[hello,world\] : "\[0\]" must be \[open\].*/, + ), + ); + consoleWarnSpy.mockRestore(); + }); + + it('ignore when docs has invalid tags', async () => { + const process = createTest({ + filePath: path.join(testFolder, 'wrong.md'), + onBrokenTags: 'ignore', + }); + await expect(process).resolves.toBeDefined(); + }); + + it('does not throw when docs has valid tags', async () => { + const process = createTest({ + filePath: path.join(testFolder, 'good.md'), + onBrokenTags: 'throw', + }); + await expect(process).resolves.toBeDefined(); + }); }); From 72cc7ad58cf702f5e5e9989eba53643f0bde21c5 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 15 May 2024 16:42:05 +0200 Subject: [PATCH 011/142] better naming --- .../src/docs.ts | 26 +++++++++++-------- .../src/tags.ts | 6 ++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index fef4fdc06fb3..0145a58bee54 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -27,7 +27,11 @@ import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; import {stripPathNumberPrefixes} from './numberPrefix'; import {toDocNavigationLink, toNavigationLink} from './sidebars/utils'; -import {createTagSchema, validateFrontMatterTags, validateTags} from './tags'; +import { + createTagSchema, + validateFrontMatterTags, + validateDefinedTags, +} from './tags'; import type {FrontMatterTag, Tag} from '@docusaurus/utils'; import type { MetadataOptions, @@ -79,21 +83,21 @@ export async function readVersionDocs( export type DocEnv = 'production' | 'development'; -async function getTagDefinition( +async function getDefinedTags( options: MetadataOptions, contentPath: string, ): Promise { - const tagsPath = path.join(contentPath, options.tagsFilePath); - const tagsFileContent = await fs.readFile(tagsPath, 'utf-8'); - const data = YAML.load(tagsFileContent); - const tags = validateTags(data); - if (tags.error) { + const tagDefinitionPath = path.join(contentPath, options.tagsFilePath); + const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); + const data = YAML.load(tagDefinitionContent); + const definedTags = validateDefinedTags(data); + if (definedTags.error) { throw new Error( - `There was an error extracting tags from file: ${tags.error.message}`, - {cause: tags}, + `There was an error extracting tags from file: ${definedTags.error.message}`, + {cause: definedTags}, ); } - return tags.value; + return definedTags.value; } export async function processFileTagsPath({ @@ -113,7 +117,7 @@ export async function processFileTagsPath({ return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } - const definedTags = await getTagDefinition(options, contentPath); + const definedTags = await getDefinedTags(options, contentPath); const validTagsSchema = createTagSchema(Object.keys(definedTags)); validateFrontMatterTags({ frontMatterTags, diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index a9e58e4a0e5d..b74bcbf38573 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -32,7 +32,7 @@ export function getVersionTags(docs: DocMetadata[]): VersionTags { }); } -export const tagSchema = Joi.object().pattern( +export const tagDefinitionSchema = Joi.object().pattern( Joi.string(), Joi.object({ label: Joi.string().required(), @@ -40,8 +40,8 @@ export const tagSchema = Joi.object().pattern( }), ); -export function validateTags(tags: unknown): Joi.ValidationResult { - return tagSchema.validate(tags); +export function validateDefinedTags(tags: unknown): Joi.ValidationResult { + return tagDefinitionSchema.validate(tags); } export function createTagSchema(tags: string[]): Joi.Schema { From 257564e051b39d642b77d29e5856b4fbfe340c1c Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 16 May 2024 15:47:59 +0200 Subject: [PATCH 012/142] wip --- packages/docusaurus-plugin-content-docs/src/docs.ts | 13 ++++++++++--- .../docusaurus-plugin-content-docs/src/options.ts | 11 +++++++---- .../src/plugin-content-docs.d.ts | 4 ++-- packages/docusaurus-plugin-content-docs/src/tags.ts | 2 +- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 0145a58bee54..6af3b3b0a53e 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -87,7 +87,10 @@ async function getDefinedTags( options: MetadataOptions, contentPath: string, ): Promise { - const tagDefinitionPath = path.join(contentPath, options.tagsFilePath); + const tagDefinitionPath = path.join( + contentPath, + options.tagsFilePath ? options.tagsFilePath : 'tags.yml', + ); const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); const data = YAML.load(tagDefinitionContent); const definedTags = validateDefinedTags(data); @@ -113,7 +116,11 @@ export async function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; }): Promise { - if (!options.tagsFilePath || options.onBrokenTags === 'ignore') { + if ( + options.tagsFilePath === false || + options.tagsFilePath === null || + options.onUnknownTags === 'ignore' + ) { return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } @@ -123,7 +130,7 @@ export async function processFileTagsPath({ frontMatterTags, validTagsSchema, source, - onBrokenTags: options.onBrokenTags, + onBrokenTags: options.onUnknownTags, }); const transformedTags = Object.entries(definedTags).map(([key, value]) => ({ label: value.label, diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index f2f4b43fa4c8..18180fc1948c 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -54,8 +54,8 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsible: true, sidebarCollapsed: true, breadcrumbs: true, - onBrokenTags: 'warn', - tagsFilePath: '', + onUnknownTags: 'warn', + tagsFilePath: 'tags.yml', }; const VersionOptionsSchema = Joi.object({ @@ -144,8 +144,11 @@ const OptionsSchema = Joi.object({ breadcrumbs: Joi.bool().default(DEFAULT_OPTIONS.breadcrumbs), onBrokenTags: Joi.string() .equal('ignore', 'log', 'warn', 'throw') - .default(DEFAULT_OPTIONS.onBrokenTags), - tagsFilePath: Joi.string().default(DEFAULT_OPTIONS.tagsFilePath), + .default(DEFAULT_OPTIONS.onUnknownTags), + tagsFilePath: Joi.string() + .allow(null, false, undefined) + .disallow('') + .default(DEFAULT_OPTIONS.tagsFilePath), }); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 3ff7a998fa4c..6c09758a5c40 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -101,8 +101,8 @@ declare module '@docusaurus/plugin-content-docs' { numberPrefixParser: NumberPrefixParser; /** Enable or disable the breadcrumbs on doc pages. */ breadcrumbs: boolean; - tagsFilePath: string; - onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw'; + tagsFilePath: string | null | undefined | false; + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type PathOptions = { diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index b74bcbf38573..388e8c963763 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -57,7 +57,7 @@ export function validateFrontMatterTags({ frontMatterTags: FrontMatterTag[] | undefined; validTagsSchema: Joi.Schema; source: string; - onBrokenTags: MetadataOptions['onBrokenTags']; + onBrokenTags: MetadataOptions['onUnknownTags']; }): void { if (frontMatterTags === undefined || !Array.isArray(frontMatterTags)) { return; From 8260feda3d6fbb210f84a39e02b0fbca9d4f86cf Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 16 May 2024 15:49:59 +0200 Subject: [PATCH 013/142] wip --- packages/docusaurus-plugin-content-docs/src/options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index 18180fc1948c..76eaedef09a0 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -54,7 +54,7 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsible: true, sidebarCollapsed: true, breadcrumbs: true, - onUnknownTags: 'warn', + onUnknownTags: 'throw', tagsFilePath: 'tags.yml', }; From cff68ee9bf6aabe835ce3da5f2cd1df1aa8402e0 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 16 May 2024 15:55:04 +0200 Subject: [PATCH 014/142] wip --- website/_dogfooding/_docs tests/tags.yml | 5 +++++ website/_dogfooding/dogfooding.config.ts | 2 ++ website/docs/installation.mdx | 1 - website/docs/tags.yml | 6 ------ website/docusaurus.config.ts | 2 -- website/versioned_docs/version-3.2.1/tags.yml | 6 ------ website/versioned_docs/version-3.3.2/tags.yml | 6 ------ 7 files changed, 7 insertions(+), 21 deletions(-) create mode 100644 website/_dogfooding/_docs tests/tags.yml delete mode 100644 website/docs/tags.yml delete mode 100644 website/versioned_docs/version-3.2.1/tags.yml delete mode 100644 website/versioned_docs/version-3.3.2/tags.yml diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml new file mode 100644 index 000000000000..2866666341a3 --- /dev/null +++ b/website/_dogfooding/_docs tests/tags.yml @@ -0,0 +1,5 @@ +open: + label: Open Source + description: Open source projects + # TODO add support for permalink + # permalink: /open diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index 7bcc7babea24..27693cc75f51 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -35,6 +35,8 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ id: 'docs-tests', routeBasePath: '/tests/docs', sidebarPath: '_dogfooding/docs-tests-sidebars.js', + tagsFilePath: 'tags.yml', + onUnknownTags: 'throw', versions: { current: { noIndex: true, diff --git a/website/docs/installation.mdx b/website/docs/installation.mdx index 8b398eac1ae4..f9f29dac424f 100644 --- a/website/docs/installation.mdx +++ b/website/docs/installation.mdx @@ -1,6 +1,5 @@ --- description: How to install Docusaurus locally, and start a Docusaurus site in no time. -tags: [installation, getting-started] --- # Installation diff --git a/website/docs/tags.yml b/website/docs/tags.yml deleted file mode 100644 index c4718703baae..000000000000 --- a/website/docs/tags.yml +++ /dev/null @@ -1,6 +0,0 @@ -getting-started: - description: Get started with the basics of using the API. - label: Getting Started -installation: - description: How to install the API. - label: installation diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 416700d6d64d..aae27b1a4d8e 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -466,8 +466,6 @@ export default async function createConfigAsync() { label: `${getNextVersionName()} 🚧`, }, }, - tagsFilePath: 'tags.yml', - onBrokenTags: 'throw', }, blog: { // routeBasePath: '/', diff --git a/website/versioned_docs/version-3.2.1/tags.yml b/website/versioned_docs/version-3.2.1/tags.yml deleted file mode 100644 index b5aea8df76cb..000000000000 --- a/website/versioned_docs/version-3.2.1/tags.yml +++ /dev/null @@ -1,6 +0,0 @@ -getting-started: - description: Get started with the basics of using the API. - label: Getting Started -introduction: - description: Learn about the basics of the API. - label: Introduction diff --git a/website/versioned_docs/version-3.3.2/tags.yml b/website/versioned_docs/version-3.3.2/tags.yml deleted file mode 100644 index b5aea8df76cb..000000000000 --- a/website/versioned_docs/version-3.3.2/tags.yml +++ /dev/null @@ -1,6 +0,0 @@ -getting-started: - description: Get started with the basics of using the API. - label: Getting Started -introduction: - description: Learn about the basics of the API. - label: Introduction From c9b2f2798a4bf3eb875d64c086ffedf02dc44f60 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 14:05:11 +0200 Subject: [PATCH 015/142] Revert "wip" This reverts commit cff68ee9bf6aabe835ce3da5f2cd1df1aa8402e0. --- website/_dogfooding/_docs tests/tags.yml | 5 ----- website/_dogfooding/dogfooding.config.ts | 2 -- website/docs/installation.mdx | 1 + website/docs/tags.yml | 6 ++++++ website/docusaurus.config.ts | 2 ++ website/versioned_docs/version-3.2.1/tags.yml | 6 ++++++ website/versioned_docs/version-3.3.2/tags.yml | 6 ++++++ 7 files changed, 21 insertions(+), 7 deletions(-) delete mode 100644 website/_dogfooding/_docs tests/tags.yml create mode 100644 website/docs/tags.yml create mode 100644 website/versioned_docs/version-3.2.1/tags.yml create mode 100644 website/versioned_docs/version-3.3.2/tags.yml diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml deleted file mode 100644 index 2866666341a3..000000000000 --- a/website/_dogfooding/_docs tests/tags.yml +++ /dev/null @@ -1,5 +0,0 @@ -open: - label: Open Source - description: Open source projects - # TODO add support for permalink - # permalink: /open diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index 27693cc75f51..7bcc7babea24 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -35,8 +35,6 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ id: 'docs-tests', routeBasePath: '/tests/docs', sidebarPath: '_dogfooding/docs-tests-sidebars.js', - tagsFilePath: 'tags.yml', - onUnknownTags: 'throw', versions: { current: { noIndex: true, diff --git a/website/docs/installation.mdx b/website/docs/installation.mdx index f9f29dac424f..8b398eac1ae4 100644 --- a/website/docs/installation.mdx +++ b/website/docs/installation.mdx @@ -1,5 +1,6 @@ --- description: How to install Docusaurus locally, and start a Docusaurus site in no time. +tags: [installation, getting-started] --- # Installation diff --git a/website/docs/tags.yml b/website/docs/tags.yml new file mode 100644 index 000000000000..c4718703baae --- /dev/null +++ b/website/docs/tags.yml @@ -0,0 +1,6 @@ +getting-started: + description: Get started with the basics of using the API. + label: Getting Started +installation: + description: How to install the API. + label: installation diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index aae27b1a4d8e..416700d6d64d 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -466,6 +466,8 @@ export default async function createConfigAsync() { label: `${getNextVersionName()} 🚧`, }, }, + tagsFilePath: 'tags.yml', + onBrokenTags: 'throw', }, blog: { // routeBasePath: '/', diff --git a/website/versioned_docs/version-3.2.1/tags.yml b/website/versioned_docs/version-3.2.1/tags.yml new file mode 100644 index 000000000000..b5aea8df76cb --- /dev/null +++ b/website/versioned_docs/version-3.2.1/tags.yml @@ -0,0 +1,6 @@ +getting-started: + description: Get started with the basics of using the API. + label: Getting Started +introduction: + description: Learn about the basics of the API. + label: Introduction diff --git a/website/versioned_docs/version-3.3.2/tags.yml b/website/versioned_docs/version-3.3.2/tags.yml new file mode 100644 index 000000000000..b5aea8df76cb --- /dev/null +++ b/website/versioned_docs/version-3.3.2/tags.yml @@ -0,0 +1,6 @@ +getting-started: + description: Get started with the basics of using the API. + label: Getting Started +introduction: + description: Learn about the basics of the API. + label: Introduction From 5145b45290f6eb94413bff0ebd02f765cc910841 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 14:05:20 +0200 Subject: [PATCH 016/142] Revert "wip" This reverts commit 8260feda3d6fbb210f84a39e02b0fbca9d4f86cf. --- packages/docusaurus-plugin-content-docs/src/options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index 76eaedef09a0..18180fc1948c 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -54,7 +54,7 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsible: true, sidebarCollapsed: true, breadcrumbs: true, - onUnknownTags: 'throw', + onUnknownTags: 'warn', tagsFilePath: 'tags.yml', }; From 217d4b06ab9ea83d562bf327d05b22b833e5aa19 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 14:05:25 +0200 Subject: [PATCH 017/142] Revert "wip" This reverts commit 257564e051b39d642b77d29e5856b4fbfe340c1c. --- packages/docusaurus-plugin-content-docs/src/docs.ts | 13 +++---------- .../docusaurus-plugin-content-docs/src/options.ts | 11 ++++------- .../src/plugin-content-docs.d.ts | 4 ++-- packages/docusaurus-plugin-content-docs/src/tags.ts | 2 +- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 6af3b3b0a53e..0145a58bee54 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -87,10 +87,7 @@ async function getDefinedTags( options: MetadataOptions, contentPath: string, ): Promise { - const tagDefinitionPath = path.join( - contentPath, - options.tagsFilePath ? options.tagsFilePath : 'tags.yml', - ); + const tagDefinitionPath = path.join(contentPath, options.tagsFilePath); const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); const data = YAML.load(tagDefinitionContent); const definedTags = validateDefinedTags(data); @@ -116,11 +113,7 @@ export async function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; }): Promise { - if ( - options.tagsFilePath === false || - options.tagsFilePath === null || - options.onUnknownTags === 'ignore' - ) { + if (!options.tagsFilePath || options.onBrokenTags === 'ignore') { return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } @@ -130,7 +123,7 @@ export async function processFileTagsPath({ frontMatterTags, validTagsSchema, source, - onBrokenTags: options.onUnknownTags, + onBrokenTags: options.onBrokenTags, }); const transformedTags = Object.entries(definedTags).map(([key, value]) => ({ label: value.label, diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index 18180fc1948c..f2f4b43fa4c8 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -54,8 +54,8 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsible: true, sidebarCollapsed: true, breadcrumbs: true, - onUnknownTags: 'warn', - tagsFilePath: 'tags.yml', + onBrokenTags: 'warn', + tagsFilePath: '', }; const VersionOptionsSchema = Joi.object({ @@ -144,11 +144,8 @@ const OptionsSchema = Joi.object({ breadcrumbs: Joi.bool().default(DEFAULT_OPTIONS.breadcrumbs), onBrokenTags: Joi.string() .equal('ignore', 'log', 'warn', 'throw') - .default(DEFAULT_OPTIONS.onUnknownTags), - tagsFilePath: Joi.string() - .allow(null, false, undefined) - .disallow('') - .default(DEFAULT_OPTIONS.tagsFilePath), + .default(DEFAULT_OPTIONS.onBrokenTags), + tagsFilePath: Joi.string().default(DEFAULT_OPTIONS.tagsFilePath), }); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 6c09758a5c40..3ff7a998fa4c 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -101,8 +101,8 @@ declare module '@docusaurus/plugin-content-docs' { numberPrefixParser: NumberPrefixParser; /** Enable or disable the breadcrumbs on doc pages. */ breadcrumbs: boolean; - tagsFilePath: string | null | undefined | false; - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; + tagsFilePath: string; + onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type PathOptions = { diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index 388e8c963763..b74bcbf38573 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -57,7 +57,7 @@ export function validateFrontMatterTags({ frontMatterTags: FrontMatterTag[] | undefined; validTagsSchema: Joi.Schema; source: string; - onBrokenTags: MetadataOptions['onUnknownTags']; + onBrokenTags: MetadataOptions['onBrokenTags']; }): void { if (frontMatterTags === undefined || !Array.isArray(frontMatterTags)) { return; From 4f3ca7886b7c58953becc4f724a1bdce65d77c0f Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 14:06:48 +0200 Subject: [PATCH 018/142] rename option name --- .../src/__tests__/tags.test.ts | 14 +++++++------- .../docusaurus-plugin-content-docs/src/docs.ts | 4 ++-- .../docusaurus-plugin-content-docs/src/options.ts | 6 +++--- .../src/plugin-content-docs.d.ts | 2 +- .../docusaurus-plugin-content-docs/src/tags.ts | 6 +++--- website/docusaurus.config.ts | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 19a495d30ee8..6a8c15089b3c 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -14,10 +14,10 @@ import {validateDocFrontMatter} from '../frontMatter'; const createTest = async ({ filePath, - onBrokenTags, + onUnknownTags, }: { filePath: string; - onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw' | undefined; + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw' | undefined; }) => { const contentPath = path.join(__dirname, '__fixtures__', 'simple-tags'); const tagsFilePath = 'tags.yml'; @@ -36,7 +36,7 @@ const createTest = async ({ contentPath, options: fromPartial({ tagsFilePath, - onBrokenTags, + onUnknownTags, }), source: filePath, versionTagsPath: '/processFileTagsPath/tags', @@ -50,7 +50,7 @@ describe('processFileTagsPath', () => { it('throw when docs has invalid tags', async () => { const process = createTest({ filePath: path.join(testFolder, 'wrong.md'), - onBrokenTags: 'throw', + onUnknownTags: 'throw', }); await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( @@ -63,7 +63,7 @@ describe('processFileTagsPath', () => { const process = createTest({ filePath: path.join(testFolder, 'wrong.md'), - onBrokenTags: 'warn', + onUnknownTags: 'warn', }); await process; @@ -80,7 +80,7 @@ describe('processFileTagsPath', () => { it('ignore when docs has invalid tags', async () => { const process = createTest({ filePath: path.join(testFolder, 'wrong.md'), - onBrokenTags: 'ignore', + onUnknownTags: 'ignore', }); await expect(process).resolves.toBeDefined(); }); @@ -88,7 +88,7 @@ describe('processFileTagsPath', () => { it('does not throw when docs has valid tags', async () => { const process = createTest({ filePath: path.join(testFolder, 'good.md'), - onBrokenTags: 'throw', + onUnknownTags: 'throw', }); await expect(process).resolves.toBeDefined(); }); diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 0145a58bee54..bda1f1ecd1dc 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -113,7 +113,7 @@ export async function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; }): Promise { - if (!options.tagsFilePath || options.onBrokenTags === 'ignore') { + if (!options.tagsFilePath || options.onUnknownTags === 'ignore') { return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } @@ -123,7 +123,7 @@ export async function processFileTagsPath({ frontMatterTags, validTagsSchema, source, - onBrokenTags: options.onBrokenTags, + onUnknownTags: options.onUnknownTags, }); const transformedTags = Object.entries(definedTags).map(([key, value]) => ({ label: value.label, diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index f2f4b43fa4c8..e82bc6403600 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -54,7 +54,7 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsible: true, sidebarCollapsed: true, breadcrumbs: true, - onBrokenTags: 'warn', + onUnknownTags: 'warn', tagsFilePath: '', }; @@ -142,9 +142,9 @@ const OptionsSchema = Joi.object({ lastVersion: Joi.string().optional(), versions: VersionsOptionsSchema, breadcrumbs: Joi.bool().default(DEFAULT_OPTIONS.breadcrumbs), - onBrokenTags: Joi.string() + onUnknownTags: Joi.string() .equal('ignore', 'log', 'warn', 'throw') - .default(DEFAULT_OPTIONS.onBrokenTags), + .default(DEFAULT_OPTIONS.onUnknownTags), tagsFilePath: Joi.string().default(DEFAULT_OPTIONS.tagsFilePath), }); diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 3ff7a998fa4c..35ee5d675f96 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -102,7 +102,7 @@ declare module '@docusaurus/plugin-content-docs' { /** Enable or disable the breadcrumbs on doc pages. */ breadcrumbs: boolean; tagsFilePath: string; - onBrokenTags: 'ignore' | 'log' | 'warn' | 'throw'; + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type PathOptions = { diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index b74bcbf38573..07843c8f220f 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -52,12 +52,12 @@ export function validateFrontMatterTags({ frontMatterTags, validTagsSchema, source, - onBrokenTags, + onUnknownTags, }: { frontMatterTags: FrontMatterTag[] | undefined; validTagsSchema: Joi.Schema; source: string; - onBrokenTags: MetadataOptions['onBrokenTags']; + onUnknownTags: MetadataOptions['onUnknownTags']; }): void { if (frontMatterTags === undefined || !Array.isArray(frontMatterTags)) { return; @@ -70,7 +70,7 @@ export function validateFrontMatterTags({ const tagList = validTagsSchema.validate(labels); if (tagList.error) { - logger.report(onBrokenTags)( + logger.report(onUnknownTags)( `Broken tags found in ${source} [${labels}] : ${tagList.error.message}`, ); } diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 416700d6d64d..b836d180c20b 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -467,7 +467,7 @@ export default async function createConfigAsync() { }, }, tagsFilePath: 'tags.yml', - onBrokenTags: 'throw', + onUnknownTags: 'throw', }, blog: { // routeBasePath: '/', From f4cc3ce7ea474e465328379ce593b8b81cc0adf7 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 14:40:51 +0200 Subject: [PATCH 019/142] read tags once per plugin --- .../docusaurus-plugin-content-docs/src/docs.ts | 12 +++++++----- .../docusaurus-plugin-content-docs/src/index.ts | 17 +++++++++++++++-- website/_dogfooding/_docs tests/tags.yml | 3 +++ website/_dogfooding/dogfooding.config.ts | 2 ++ website/community/tags.yml | 3 +++ website/docs/tags.yml | 9 +++------ website/docusaurus.config.ts | 4 +++- website/versioned_docs/version-3.2.1/tags.yml | 9 +++------ website/versioned_docs/version-3.3.2/tags.yml | 7 ++----- 9 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 website/_dogfooding/_docs tests/tags.yml create mode 100644 website/community/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index bda1f1ecd1dc..b49e365f34ea 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -83,7 +83,7 @@ export async function readVersionDocs( export type DocEnv = 'production' | 'development'; -async function getDefinedTags( +export async function getDefinedTags( options: MetadataOptions, contentPath: string, ): Promise { @@ -102,22 +102,21 @@ async function getDefinedTags( export async function processFileTagsPath({ options, - contentPath, source, frontMatterTags, versionTagsPath, + definedTags, }: { options: MetadataOptions; - contentPath: string; source: string; frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; + definedTags: Tag[]; }): Promise { if (!options.tagsFilePath || options.onUnknownTags === 'ignore') { return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } - const definedTags = await getDefinedTags(options, contentPath); const validTagsSchema = createTagSchema(Object.keys(definedTags)); validateFrontMatterTags({ frontMatterTags, @@ -139,12 +138,14 @@ async function doProcessDocMetadata({ context, options, env, + definedTags, }: { docFile: DocFile; versionMetadata: VersionMetadata; context: LoadContext; options: MetadataOptions; env: DocEnv; + definedTags: Tag[]; }): Promise { const {source, content, contentPath, filePath} = docFile; const { @@ -280,10 +281,10 @@ async function doProcessDocMetadata({ editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(), tags: await processFileTagsPath({ options, - contentPath, source, frontMatterTags: frontMatter.tags, versionTagsPath: versionMetadata.tagsPath, + definedTags, }), version: versionMetadata.versionName, lastUpdatedBy: lastUpdate.lastUpdatedBy, @@ -299,6 +300,7 @@ export async function processDocMetadata(args: { context: LoadContext; options: MetadataOptions; env: DocEnv; + definedTags: Tag[]; }): Promise { try { return await doProcessDocMetadata(args); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 18e43a7f6540..1237d1a91a61 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -17,7 +17,7 @@ import { addTrailingPathSeparator, createAbsoluteFilePathMatcher, createSlugger, - DEFAULT_PLUGIN_ID, + DEFAULT_PLUGIN_ID } from '@docusaurus/utils'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; @@ -27,6 +27,7 @@ import { addDocNavigation, type DocEnv, createDocsByIdIndex, + getDefinedTags, } from './docs'; import {readVersionsMetadata, toFullVersion} from './versions'; import {cliDocsVersionCommand} from './cli'; @@ -38,6 +39,8 @@ import { } from './translations'; import {createAllRoutes} from './routes'; import {createSidebarsUtils} from './sidebars/utils'; +import type { + Tag} from '@docusaurus/utils'; import type { PluginOptions, @@ -132,6 +135,7 @@ export default async function pluginContentDocs( async loadContent() { async function loadVersionDocsBase( versionMetadata: VersionMetadata, + definedTags: Tag[], ): Promise { const docFiles = await readVersionDocs(versionMetadata, options); if (docFiles.length === 0) { @@ -151,6 +155,7 @@ export default async function pluginContentDocs( context, options, env, + definedTags, }); } return Promise.all(docFiles.map(processVersionDoc)); @@ -158,9 +163,11 @@ export default async function pluginContentDocs( async function doLoadVersion( versionMetadata: VersionMetadata, + definedTags: Tag[], ): Promise { const docsBase: DocMetadataBase[] = await loadVersionDocsBase( versionMetadata, + definedTags, ); // TODO we only ever need draftIds in further code, not full draft items @@ -209,7 +216,13 @@ export default async function pluginContentDocs( async function loadVersion(versionMetadata: VersionMetadata) { try { - return await doLoadVersion(versionMetadata); + const definedTags = await getDefinedTags( + options, + versionMetadata.contentPath, + ); + console.log('versionMetadata:', versionMetadata); + console.log('definedTags:', definedTags); + return await doLoadVersion(versionMetadata, definedTags); } catch (err) { logger.error`Loading of version failed for version name=${versionMetadata.versionName}`; throw err; diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml new file mode 100644 index 000000000000..88ebec281879 --- /dev/null +++ b/website/_dogfooding/_docs tests/tags.yml @@ -0,0 +1,3 @@ +dogfood: + label: Dogfooding + description: Learn about dogfooding diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index 7bcc7babea24..c52247e591c9 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -40,6 +40,8 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ noIndex: true, }, }, + onUnknownTags: 'ignore', + tagsFilePath: 'tags.yml', // Using a _ prefix to test against an edge case regarding MDX partials: https://github.com/facebook/docusaurus/discussions/5181#discussioncomment-1018079 path: '_dogfooding/_docs tests', diff --git a/website/community/tags.yml b/website/community/tags.yml new file mode 100644 index 000000000000..e8e0d4857cc2 --- /dev/null +++ b/website/community/tags.yml @@ -0,0 +1,3 @@ +community: + description: Community folder + label: Getting Started diff --git a/website/docs/tags.yml b/website/docs/tags.yml index c4718703baae..b950995cf2f6 100644 --- a/website/docs/tags.yml +++ b/website/docs/tags.yml @@ -1,6 +1,3 @@ -getting-started: - description: Get started with the basics of using the API. - label: Getting Started -installation: - description: How to install the API. - label: installation +docs: + description: Docs website + label: docs diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index b836d180c20b..db47f94c6d18 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -306,6 +306,8 @@ export default async function createConfigAsync() { sidebarPath: './sidebarsCommunity.js', showLastUpdateAuthor: true, showLastUpdateTime: true, + onUnknownTags: 'ignore', + tagsFilePath: 'tags.yml', } satisfies DocsOptions, ], [ @@ -467,7 +469,7 @@ export default async function createConfigAsync() { }, }, tagsFilePath: 'tags.yml', - onUnknownTags: 'throw', + onUnknownTags: 'ignore', }, blog: { // routeBasePath: '/', diff --git a/website/versioned_docs/version-3.2.1/tags.yml b/website/versioned_docs/version-3.2.1/tags.yml index b5aea8df76cb..7ffca89be1ed 100644 --- a/website/versioned_docs/version-3.2.1/tags.yml +++ b/website/versioned_docs/version-3.2.1/tags.yml @@ -1,6 +1,3 @@ -getting-started: - description: Get started with the basics of using the API. - label: Getting Started -introduction: - description: Learn about the basics of the API. - label: Introduction +docs: + description: Docs versoin 3.2.1 + label: Docs diff --git a/website/versioned_docs/version-3.3.2/tags.yml b/website/versioned_docs/version-3.3.2/tags.yml index b5aea8df76cb..a745ee5fc506 100644 --- a/website/versioned_docs/version-3.3.2/tags.yml +++ b/website/versioned_docs/version-3.3.2/tags.yml @@ -1,6 +1,3 @@ -getting-started: - description: Get started with the basics of using the API. +docs: + description: Docs version 3.2.2 label: Getting Started -introduction: - description: Learn about the basics of the API. - label: Introduction From 72fe1ec7eac878da5bc7f45b1ce749c755eeef9e Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Fri, 17 May 2024 12:45:59 +0000 Subject: [PATCH 020/142] refactor: apply lint autofix --- packages/docusaurus-plugin-content-docs/src/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 1237d1a91a61..76774c9caf79 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -17,7 +17,7 @@ import { addTrailingPathSeparator, createAbsoluteFilePathMatcher, createSlugger, - DEFAULT_PLUGIN_ID + DEFAULT_PLUGIN_ID, } from '@docusaurus/utils'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; @@ -39,8 +39,7 @@ import { } from './translations'; import {createAllRoutes} from './routes'; import {createSidebarsUtils} from './sidebars/utils'; -import type { - Tag} from '@docusaurus/utils'; +import type {Tag} from '@docusaurus/utils'; import type { PluginOptions, From 1a41ef26e298edb0879ba8e50bd48f43d8490496 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 15:05:52 +0200 Subject: [PATCH 021/142] optin & allow false null for filepath --- .../docusaurus-plugin-content-docs/src/docs.ts | 14 ++++++++++++-- .../docusaurus-plugin-content-docs/src/options.ts | 7 +++++-- .../src/plugin-content-docs.d.ts | 2 +- website/community/tags.yml | 3 --- website/docs/tags.yml | 3 --- website/docusaurus.config.ts | 2 -- website/versioned_docs/version-3.2.1/tags.yml | 3 --- website/versioned_docs/version-3.3.2/tags.yml | 3 --- 8 files changed, 18 insertions(+), 19 deletions(-) delete mode 100644 website/community/tags.yml delete mode 100644 website/docs/tags.yml delete mode 100644 website/versioned_docs/version-3.2.1/tags.yml delete mode 100644 website/versioned_docs/version-3.3.2/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index b49e365f34ea..2cc1f1c6ee89 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -87,7 +87,17 @@ export async function getDefinedTags( options: MetadataOptions, contentPath: string, ): Promise { - const tagDefinitionPath = path.join(contentPath, options.tagsFilePath); + if ( + options.tagsFilePath === false || + options.tagsFilePath === null || + options.onUnknownTags === 'ignore' + ) { + return []; + } + const tagDefinitionPath = path.join( + contentPath, + options.tagsFilePath ? options.tagsFilePath : 'tags.yml', + ); const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); const data = YAML.load(tagDefinitionContent); const definedTags = validateDefinedTags(data); @@ -113,7 +123,7 @@ export async function processFileTagsPath({ versionTagsPath: string; definedTags: Tag[]; }): Promise { - if (!options.tagsFilePath || options.onUnknownTags === 'ignore') { + if (definedTags.length === 0) { return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index e82bc6403600..abc53f582e26 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -55,7 +55,7 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsed: true, breadcrumbs: true, onUnknownTags: 'warn', - tagsFilePath: '', + tagsFilePath: false, }; const VersionOptionsSchema = Joi.object({ @@ -145,7 +145,10 @@ const OptionsSchema = Joi.object({ onUnknownTags: Joi.string() .equal('ignore', 'log', 'warn', 'throw') .default(DEFAULT_OPTIONS.onUnknownTags), - tagsFilePath: Joi.string().default(DEFAULT_OPTIONS.tagsFilePath), + tagsFilePath: Joi.string() + .disallow('') + .allow(null, false) + .default(DEFAULT_OPTIONS.tagsFilePath), }); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 35ee5d675f96..271965f85107 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -101,7 +101,7 @@ declare module '@docusaurus/plugin-content-docs' { numberPrefixParser: NumberPrefixParser; /** Enable or disable the breadcrumbs on doc pages. */ breadcrumbs: boolean; - tagsFilePath: string; + tagsFilePath: string | false | null | undefined; onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; }; diff --git a/website/community/tags.yml b/website/community/tags.yml deleted file mode 100644 index e8e0d4857cc2..000000000000 --- a/website/community/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -community: - description: Community folder - label: Getting Started diff --git a/website/docs/tags.yml b/website/docs/tags.yml deleted file mode 100644 index b950995cf2f6..000000000000 --- a/website/docs/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -docs: - description: Docs website - label: docs diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index db47f94c6d18..426b57f97f05 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -306,8 +306,6 @@ export default async function createConfigAsync() { sidebarPath: './sidebarsCommunity.js', showLastUpdateAuthor: true, showLastUpdateTime: true, - onUnknownTags: 'ignore', - tagsFilePath: 'tags.yml', } satisfies DocsOptions, ], [ diff --git a/website/versioned_docs/version-3.2.1/tags.yml b/website/versioned_docs/version-3.2.1/tags.yml deleted file mode 100644 index 7ffca89be1ed..000000000000 --- a/website/versioned_docs/version-3.2.1/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -docs: - description: Docs versoin 3.2.1 - label: Docs diff --git a/website/versioned_docs/version-3.3.2/tags.yml b/website/versioned_docs/version-3.3.2/tags.yml deleted file mode 100644 index a745ee5fc506..000000000000 --- a/website/versioned_docs/version-3.3.2/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -docs: - description: Docs version 3.2.2 - label: Getting Started From 0f9b397eb049fc6cc033f8c737311db403395df7 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 15:18:04 +0200 Subject: [PATCH 022/142] dogfood --- .../src/index.ts | 2 - website/_dogfooding/_docs tests/tags.yml | 39 +++++++++++++++++-- website/_dogfooding/dogfooding.config.ts | 2 +- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 76774c9caf79..8b5335bce1d3 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -219,8 +219,6 @@ export default async function pluginContentDocs( options, versionMetadata.contentPath, ); - console.log('versionMetadata:', versionMetadata); - console.log('definedTags:', definedTags); return await doLoadVersion(versionMetadata, definedTags); } catch (err) { logger.error`Loading of version failed for version name=${versionMetadata.versionName}`; diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml index 88ebec281879..4cb4d03e5670 100644 --- a/website/_dogfooding/_docs tests/tags.yml +++ b/website/_dogfooding/_docs tests/tags.yml @@ -1,3 +1,36 @@ -dogfood: - label: Dogfooding - description: Learn about dogfooding +a: + label: a + description: a +b: + label: b + description: b +c: + label: c + description: c +e: + label: e + description: e +some tag: + label: some tag + description: some tag +some-tag: + label: some-tag + description: some-tag +some_tag: + label: some_tag + description: some_tag +visibility: + label: visibility + description: visibility +draft: + label: draft + description: draft +listed: + label: listed + description: listed +unlisted: + label: unlisted + description: unlisted +d-custom-permalink: + label: d-custom-permalink + description: d-custom-permalink diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index c52247e591c9..3f9df2ab6185 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -40,7 +40,7 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ noIndex: true, }, }, - onUnknownTags: 'ignore', + onUnknownTags: 'warn', tagsFilePath: 'tags.yml', // Using a _ prefix to test against an edge case regarding MDX partials: https://github.com/facebook/docusaurus/discussions/5181#discussioncomment-1018079 From c1961d9ac80ad8e5e83550c310331047107698a0 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 15:41:17 +0200 Subject: [PATCH 023/142] check tags without joi --- .../docusaurus-plugin-content-docs/src/docs.ts | 10 +++------- .../docusaurus-plugin-content-docs/src/tags.ts | 17 ++++++++--------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 2cc1f1c6ee89..9c5beeb75a54 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -27,11 +27,7 @@ import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; import {stripPathNumberPrefixes} from './numberPrefix'; import {toDocNavigationLink, toNavigationLink} from './sidebars/utils'; -import { - createTagSchema, - validateFrontMatterTags, - validateDefinedTags, -} from './tags'; +import {validateFrontMatterTags, validateDefinedTags} from './tags'; import type {FrontMatterTag, Tag} from '@docusaurus/utils'; import type { MetadataOptions, @@ -127,13 +123,13 @@ export async function processFileTagsPath({ return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } - const validTagsSchema = createTagSchema(Object.keys(definedTags)); validateFrontMatterTags({ frontMatterTags, - validTagsSchema, + validTagList: Object.keys(definedTags), source, onUnknownTags: options.onUnknownTags, }); + const transformedTags = Object.entries(definedTags).map(([key, value]) => ({ label: value.label, permalink: key, diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index 07843c8f220f..ae3d468e6a03 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -37,6 +37,7 @@ export const tagDefinitionSchema = Joi.object().pattern( Joi.object({ label: Joi.string().required(), description: Joi.string().required(), + permalink: Joi.string(), }), ); @@ -44,18 +45,14 @@ export function validateDefinedTags(tags: unknown): Joi.ValidationResult { return tagDefinitionSchema.validate(tags); } -export function createTagSchema(tags: string[]): Joi.Schema { - return Joi.array().items(Joi.string().valid(...tags)); -} - export function validateFrontMatterTags({ frontMatterTags, - validTagsSchema, + validTagList, source, onUnknownTags, }: { frontMatterTags: FrontMatterTag[] | undefined; - validTagsSchema: Joi.Schema; + validTagList: string[]; source: string; onUnknownTags: MetadataOptions['onUnknownTags']; }): void { @@ -67,11 +64,13 @@ export function validateFrontMatterTags({ typeof tag === 'string' ? tag : tag.permalink, ); - const tagList = validTagsSchema.validate(labels); + const unknownTags = _.difference(labels, validTagList); - if (tagList.error) { + if (unknownTags.length > 0) { + const uniqueUnknownTags = [...new Set(unknownTags)]; + const tagListString = uniqueUnknownTags.join(', '); logger.report(onUnknownTags)( - `Broken tags found in ${source} [${labels}] : ${tagList.error.message}`, + `Tags [${tagListString}] used in ${source} are not defined in tags.yml`, ); } } From 9a4c40b4e56067f9798ec7e06e6a498de0297d10 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 15:51:14 +0200 Subject: [PATCH 024/142] add permalink support --- packages/docusaurus-plugin-content-docs/src/docs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 9c5beeb75a54..5810e4b7374a 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -132,7 +132,7 @@ export async function processFileTagsPath({ const transformedTags = Object.entries(definedTags).map(([key, value]) => ({ label: value.label, - permalink: key, + permalink: value.permalink ? value.permalink : key, })); return normalizeFrontMatterTags(versionTagsPath, transformedTags); From 4f24d5bb497f564e06daff15c7df46c01e851096 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 17 May 2024 16:55:14 +0200 Subject: [PATCH 025/142] update test --- .../src/__tests__/tags.test.ts | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 6a8c15089b3c..1081207d162e 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; import {fromPartial} from '@total-typescript/shoehorn'; import {parseMarkdownFile} from '@docusaurus/utils'; -import {processFileTagsPath} from '../docs'; +import {getDefinedTags, processFileTagsPath} from '../docs'; import {validateDocFrontMatter} from '../frontMatter'; const createTest = async ({ @@ -17,7 +17,7 @@ const createTest = async ({ onUnknownTags, }: { filePath: string; - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw' | undefined; + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; }) => { const contentPath = path.join(__dirname, '__fixtures__', 'simple-tags'); const tagsFilePath = 'tags.yml'; @@ -31,9 +31,16 @@ const createTest = async ({ }, }); const frontMatter = validateDocFrontMatter(unsafeFrontMatter); + const definedTags = await getDefinedTags( + fromPartial({ + onUnknownTags, + tagsFilePath, + }), + contentPath, + ); return processFileTagsPath({ - contentPath, + definedTags, options: fromPartial({ tagsFilePath, onUnknownTags, @@ -54,25 +61,21 @@ describe('processFileTagsPath', () => { }); await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( - `"Broken tags found in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md [hello,world] : "[0]" must be [open]"`, + `"Tags [hello, world] used in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md are not defined in tags.yml"`, ); }); it('warns when docs has invalid tags', async () => { const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); - const process = createTest({ + await createTest({ filePath: path.join(testFolder, 'wrong.md'), onUnknownTags: 'warn', }); - await process; - expect(consoleWarnSpy).toHaveBeenCalledTimes(1); expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringMatching( - /.*\[WARNING\].*Broken tags found in .*wrong\.md.*\[hello,world\] : "\[0\]" must be \[open\].*/, - ), + expect.stringMatching(/.*\[WARNING\].*Tags.*/), ); consoleWarnSpy.mockRestore(); }); From a65beb87b728a4e35eb443bf261e24e56577a0ce Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 17 May 2024 17:42:43 +0200 Subject: [PATCH 026/142] remove processFileTagsPath async --- packages/docusaurus-plugin-content-docs/src/docs.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 5810e4b7374a..ada5d05620a3 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -106,7 +106,7 @@ export async function getDefinedTags( return definedTags.value; } -export async function processFileTagsPath({ +export function processFileTagsPath({ options, source, frontMatterTags, @@ -118,7 +118,7 @@ export async function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; definedTags: Tag[]; -}): Promise { +}): Tag[] { if (definedTags.length === 0) { return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); } @@ -285,7 +285,7 @@ async function doProcessDocMetadata({ draft, unlisted, editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(), - tags: await processFileTagsPath({ + tags: processFileTagsPath({ options, source, frontMatterTags: frontMatter.tags, From 327dcd79814b47ed7ed76f25fbc2f7d567dc467d Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 17 May 2024 18:24:43 +0200 Subject: [PATCH 027/142] remove processFileTagsPath async --- .../src/__tests__/tags.test.ts | 6 +- .../src/docs.ts | 60 +++++++++---------- .../src/index.ts | 25 ++++---- .../src/tags.ts | 36 +++++------ packages/docusaurus-utils/src/index.ts | 2 + packages/docusaurus-utils/src/tags.ts | 48 +++++++++++++++ 6 files changed, 111 insertions(+), 66 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 1081207d162e..5e191ad6dadb 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; import {fromPartial} from '@total-typescript/shoehorn'; import {parseMarkdownFile} from '@docusaurus/utils'; -import {getDefinedTags, processFileTagsPath} from '../docs'; +import {getTagsFile, processFileTagsPath} from '../docs'; import {validateDocFrontMatter} from '../frontMatter'; const createTest = async ({ @@ -31,7 +31,7 @@ const createTest = async ({ }, }); const frontMatter = validateDocFrontMatter(unsafeFrontMatter); - const definedTags = await getDefinedTags( + const definedTags = await getTagsFile( fromPartial({ onUnknownTags, tagsFilePath, @@ -40,7 +40,7 @@ const createTest = async ({ ); return processFileTagsPath({ - definedTags, + tagsFile: definedTags, options: fromPartial({ tagsFilePath, onUnknownTags, diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index ada5d05620a3..6b7c5a2f3e4d 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -17,18 +17,18 @@ import { parseMarkdownFile, posixPath, Globby, - normalizeFrontMatterTags, isUnlisted, isDraft, readLastUpdateData, } from '@docusaurus/utils'; import YAML from 'js-yaml'; +import {normalizeTags} from '@docusaurus/utils/lib/tags'; import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; import {stripPathNumberPrefixes} from './numberPrefix'; import {toDocNavigationLink, toNavigationLink} from './sidebars/utils'; import {validateFrontMatterTags, validateDefinedTags} from './tags'; -import type {FrontMatterTag, Tag} from '@docusaurus/utils'; +import type {FrontMatterTag, TagsFile, NormalizedTag} from '@docusaurus/utils'; import type { MetadataOptions, PluginOptions, @@ -79,16 +79,16 @@ export async function readVersionDocs( export type DocEnv = 'production' | 'development'; -export async function getDefinedTags( +export async function getTagsFile( options: MetadataOptions, contentPath: string, -): Promise { +): Promise { if ( options.tagsFilePath === false || - options.tagsFilePath === null || - options.onUnknownTags === 'ignore' + options.tagsFilePath === null + // options.onUnknownTags === 'ignore' // TODO that looks wrong ) { - return []; + return {}; // TODO should return null } const tagDefinitionPath = path.join( contentPath, @@ -111,31 +111,27 @@ export function processFileTagsPath({ source, frontMatterTags, versionTagsPath, - definedTags, + tagsFile, }: { options: MetadataOptions; source: string; frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; - definedTags: Tag[]; -}): Tag[] { - if (definedTags.length === 0) { - return normalizeFrontMatterTags(versionTagsPath, frontMatterTags); - } + tagsFile: TagsFile | null; +}): NormalizedTag[] { + const tags = normalizeTags({ + versionTagsPath, + tagsFile, + frontMatterTags: frontMatterTags ?? [], + }); validateFrontMatterTags({ - frontMatterTags, - validTagList: Object.keys(definedTags), + tags, source, onUnknownTags: options.onUnknownTags, }); - const transformedTags = Object.entries(definedTags).map(([key, value]) => ({ - label: value.label, - permalink: value.permalink ? value.permalink : key, - })); - - return normalizeFrontMatterTags(versionTagsPath, transformedTags); + return tags; } async function doProcessDocMetadata({ @@ -144,14 +140,14 @@ async function doProcessDocMetadata({ context, options, env, - definedTags, + tagsFile, }: { docFile: DocFile; versionMetadata: VersionMetadata; context: LoadContext; options: MetadataOptions; env: DocEnv; - definedTags: Tag[]; + tagsFile: TagsFile; }): Promise { const {source, content, contentPath, filePath} = docFile; const { @@ -270,6 +266,14 @@ async function doProcessDocMetadata({ const draft = isDraft({env, frontMatter}); const unlisted = isUnlisted({env, frontMatter}); + const tags = processFileTagsPath({ + options, + source, + frontMatterTags: frontMatter.tags, + versionTagsPath: versionMetadata.tagsPath, + tagsFile, + }); + // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. // Adding properties to object after instantiation will cause hidden @@ -285,13 +289,7 @@ async function doProcessDocMetadata({ draft, unlisted, editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(), - tags: processFileTagsPath({ - options, - source, - frontMatterTags: frontMatter.tags, - versionTagsPath: versionMetadata.tagsPath, - definedTags, - }), + tags, version: versionMetadata.versionName, lastUpdatedBy: lastUpdate.lastUpdatedBy, lastUpdatedAt: lastUpdate.lastUpdatedAt, @@ -306,7 +304,7 @@ export async function processDocMetadata(args: { context: LoadContext; options: MetadataOptions; env: DocEnv; - definedTags: Tag[]; + tagsFile: TagsFile; }): Promise { try { return await doProcessDocMetadata(args); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 8b5335bce1d3..fd565e74bbc9 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -17,7 +17,7 @@ import { addTrailingPathSeparator, createAbsoluteFilePathMatcher, createSlugger, - DEFAULT_PLUGIN_ID, + DEFAULT_PLUGIN_ID } from '@docusaurus/utils'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; @@ -27,7 +27,7 @@ import { addDocNavigation, type DocEnv, createDocsByIdIndex, - getDefinedTags, + getTagsFile, } from './docs'; import {readVersionsMetadata, toFullVersion} from './versions'; import {cliDocsVersionCommand} from './cli'; @@ -39,7 +39,8 @@ import { } from './translations'; import {createAllRoutes} from './routes'; import {createSidebarsUtils} from './sidebars/utils'; -import type {Tag} from '@docusaurus/utils'; +import type { + TagsFile} from '@docusaurus/utils'; import type { PluginOptions, @@ -134,7 +135,7 @@ export default async function pluginContentDocs( async loadContent() { async function loadVersionDocsBase( versionMetadata: VersionMetadata, - definedTags: Tag[], + tagsFile: TagsFile, ): Promise { const docFiles = await readVersionDocs(versionMetadata, options); if (docFiles.length === 0) { @@ -154,7 +155,7 @@ export default async function pluginContentDocs( context, options, env, - definedTags, + tagsFile, }); } return Promise.all(docFiles.map(processVersionDoc)); @@ -162,11 +163,15 @@ export default async function pluginContentDocs( async function doLoadVersion( versionMetadata: VersionMetadata, - definedTags: Tag[], ): Promise { + const tagsFile = await getTagsFile( + options, + versionMetadata.contentPath, + ); + const docsBase: DocMetadataBase[] = await loadVersionDocsBase( versionMetadata, - definedTags, + tagsFile, ); // TODO we only ever need draftIds in further code, not full draft items @@ -215,11 +220,7 @@ export default async function pluginContentDocs( async function loadVersion(versionMetadata: VersionMetadata) { try { - const definedTags = await getDefinedTags( - options, - versionMetadata.contentPath, - ); - return await doLoadVersion(versionMetadata, definedTags); + return await doLoadVersion(versionMetadata); } catch (err) { logger.error`Loading of version failed for version name=${versionMetadata.versionName}`; throw err; diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index ae3d468e6a03..fe313e334acf 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -6,10 +6,15 @@ */ import _ from 'lodash'; -import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils'; +import { + getTagVisibility, + groupTaggedItems +} from '@docusaurus/utils'; import {Joi} from '@docusaurus/utils-validation'; import logger from '@docusaurus/logger'; -import type {FrontMatterTag} from '@docusaurus/utils'; +import type { + NormalizedTag, + TagsFile} from '@docusaurus/utils'; import type {VersionTags} from './types'; import type { DocMetadata, @@ -32,7 +37,7 @@ export function getVersionTags(docs: DocMetadata[]): VersionTags { }); } -export const tagDefinitionSchema = Joi.object().pattern( +export const tagDefinitionSchema = Joi.object().pattern( Joi.string(), Joi.object({ label: Joi.string().required(), @@ -41,33 +46,24 @@ export const tagDefinitionSchema = Joi.object().pattern( }), ); -export function validateDefinedTags(tags: unknown): Joi.ValidationResult { +export function validateDefinedTags( + tags: unknown, +): Joi.ValidationResult { return tagDefinitionSchema.validate(tags); } export function validateFrontMatterTags({ - frontMatterTags, - validTagList, + tags, source, onUnknownTags, }: { - frontMatterTags: FrontMatterTag[] | undefined; - validTagList: string[]; + tags: NormalizedTag[]; source: string; onUnknownTags: MetadataOptions['onUnknownTags']; }): void { - if (frontMatterTags === undefined || !Array.isArray(frontMatterTags)) { - return; - } - - const labels = frontMatterTags.map((tag) => - typeof tag === 'string' ? tag : tag.permalink, - ); - - const unknownTags = _.difference(labels, validTagList); - - if (unknownTags.length > 0) { - const uniqueUnknownTags = [...new Set(unknownTags)]; + const inlineTags = tags.filter((tag) => tag.inline); + if (inlineTags.length > 0 && onUnknownTags !== 'ignore') { + const uniqueUnknownTags = [...new Set(inlineTags)]; const tagListString = uniqueUnknownTags.join(', '); logger.report(onUnknownTags)( `Tags [${tagListString}] used in ${source} are not defined in tags.yml`, diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 405da5258dd4..8e982fe0edb5 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -52,6 +52,8 @@ export { export type {URLPath} from './urlUtils'; export { type Tag, + type TagsFile, + type NormalizedTag, type TagsListItem, type TagModule, type FrontMatterTag, diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 3560bde25e62..e52eefa9e289 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -8,6 +8,8 @@ import _ from 'lodash'; import {normalizeUrl} from './urlUtils'; +export type TagsFile = Record; + /** What the user configures. */ export type Tag = { label: string; @@ -15,6 +17,10 @@ export type Tag = { permalink: string; }; +export type NormalizedTag = Tag & { + inline: boolean; +}; + /** What the tags list page should know about each tag. */ export type TagsListItem = Tag & { /** Number of posts/docs with this tag. */ @@ -70,6 +76,7 @@ function normalizeFrontMatterTag( * The result will always be unique by permalinks. The behavior with colliding * permalinks is undetermined. */ +// TODO does this method still make sense? probably not export function normalizeFrontMatterTags( /** Base path to append the tag permalinks to. */ tagsPath: string, @@ -83,6 +90,47 @@ export function normalizeFrontMatterTags( return _.uniqBy(tags, (tag) => tag.permalink); } +export function normalizeTags({ + // versionTagsPath, + tagsFile, + frontMatterTags, +}: { + versionTagsPath: string; + tagsFile: TagsFile | null; + frontMatterTags: FrontMatterTag[]; +}): NormalizedTag[] { + // TODO do merge/normalization here + + function normalizeTag(tag: FrontMatterTag): NormalizedTag { + if (typeof tag === 'string') { + const tagDescription = tagsFile?.[tag]; + if (tagDescription) { + return { + label: tagDescription.label, + permalink: tagDescription.permalink, + inline: false, + }; + } else { + return { + // TODO Fix this, retro-compatible code + label: tag, + permalink: `/${tag}`, + inline: false, + }; + } + } + // legacy inline tag object, always inline + else { + return { + ...tag, + inline: true, + }; + } + } + + return frontMatterTags.map(normalizeTag); +} + type TaggedItemGroup = { tag: Tag; items: Item[]; From 4e306736ec1d18c6835b679e5720d2afdfd6f1b1 Mon Sep 17 00:00:00 2001 From: slorber Date: Fri, 17 May 2024 16:29:16 +0000 Subject: [PATCH 028/142] refactor: apply lint autofix --- packages/docusaurus-plugin-content-docs/src/index.ts | 5 ++--- packages/docusaurus-plugin-content-docs/src/tags.ts | 9 ++------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index fd565e74bbc9..d049e5d2c3e8 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -17,7 +17,7 @@ import { addTrailingPathSeparator, createAbsoluteFilePathMatcher, createSlugger, - DEFAULT_PLUGIN_ID + DEFAULT_PLUGIN_ID, } from '@docusaurus/utils'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; @@ -39,8 +39,7 @@ import { } from './translations'; import {createAllRoutes} from './routes'; import {createSidebarsUtils} from './sidebars/utils'; -import type { - TagsFile} from '@docusaurus/utils'; +import type {TagsFile} from '@docusaurus/utils'; import type { PluginOptions, diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index fe313e334acf..e465f1ffd3cf 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -6,15 +6,10 @@ */ import _ from 'lodash'; -import { - getTagVisibility, - groupTaggedItems -} from '@docusaurus/utils'; +import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils'; import {Joi} from '@docusaurus/utils-validation'; import logger from '@docusaurus/logger'; -import type { - NormalizedTag, - TagsFile} from '@docusaurus/utils'; +import type {NormalizedTag, TagsFile} from '@docusaurus/utils'; import type {VersionTags} from './types'; import type { DocMetadata, From 4ed4e98621c2f7d929358c7b1d61c940a6c8724c Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 21 May 2024 14:30:12 +0200 Subject: [PATCH 029/142] add null type --- .../src/__tests__/tags.test.ts | 1 + packages/docusaurus-plugin-content-docs/src/docs.ts | 8 ++++---- packages/docusaurus-plugin-content-docs/src/index.ts | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 5e191ad6dadb..4e71b50f1d62 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -12,6 +12,7 @@ import {parseMarkdownFile} from '@docusaurus/utils'; import {getTagsFile, processFileTagsPath} from '../docs'; import {validateDocFrontMatter} from '../frontMatter'; +// TODO remove fixtures and use inline strings const createTest = async ({ filePath, onUnknownTags, diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 6b7c5a2f3e4d..33034000e330 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -82,13 +82,13 @@ export type DocEnv = 'production' | 'development'; export async function getTagsFile( options: MetadataOptions, contentPath: string, -): Promise { +): Promise { if ( options.tagsFilePath === false || options.tagsFilePath === null // options.onUnknownTags === 'ignore' // TODO that looks wrong ) { - return {}; // TODO should return null + return null; } const tagDefinitionPath = path.join( contentPath, @@ -147,7 +147,7 @@ async function doProcessDocMetadata({ context: LoadContext; options: MetadataOptions; env: DocEnv; - tagsFile: TagsFile; + tagsFile: TagsFile | null; }): Promise { const {source, content, contentPath, filePath} = docFile; const { @@ -304,7 +304,7 @@ export async function processDocMetadata(args: { context: LoadContext; options: MetadataOptions; env: DocEnv; - tagsFile: TagsFile; + tagsFile: TagsFile | null; }): Promise { try { return await doProcessDocMetadata(args); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index d049e5d2c3e8..68a4f1e2c09b 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -134,7 +134,7 @@ export default async function pluginContentDocs( async loadContent() { async function loadVersionDocsBase( versionMetadata: VersionMetadata, - tagsFile: TagsFile, + tagsFile: TagsFile | null, ): Promise { const docFiles = await readVersionDocs(versionMetadata, options); if (docFiles.length === 0) { From 724b24eeb784acae21d1c389c718cf4afccf30a6 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 21 May 2024 14:51:40 +0200 Subject: [PATCH 030/142] add retro compatible code & update tests --- .../__snapshots__/index.test.ts.snap | 24 +++++++++++++++++++ .../src/__tests__/docs.test.ts | 15 ++++++++++++ .../src/plugin-content-docs.d.ts | 4 ++-- .../src/tags.ts | 1 + packages/docusaurus-utils/src/tags.ts | 5 ++-- 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index a19421255bc8..701317df30f9 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -85,10 +85,17 @@ exports[`simple website content 1`] = ` "sourceDirName": "foo", "tags": [ { + "inline": false, "label": "tag 1", "permalink": "/docs/tags/tag-1", }, { + "inline": false, + "label": "tag-1", + "permalink": "/docs/tags/tag-1", + }, + { + "inline": true, "label": "tag 2", "permalink": "/docs/tags/tag2-custom-permalink", }, @@ -130,10 +137,12 @@ exports[`simple website content 2`] = ` "sourceDirName": ".", "tags": [ { + "inline": false, "label": "tag-1", "permalink": "/docs/tags/tag-1", }, { + "inline": false, "label": "tag 3", "permalink": "/docs/tags/tag-3", }, @@ -594,10 +603,17 @@ exports[`simple website content: data 1`] = ` "sourceDirName": "foo", "tags": [ { + "inline": false, "label": "tag 1", "permalink": "/docs/tags/tag-1", }, { + "inline": false, + "label": "tag-1", + "permalink": "/docs/tags/tag-1", + }, + { + "inline": true, "label": "tag 2", "permalink": "/docs/tags/tag2-custom-permalink", }, @@ -663,10 +679,12 @@ exports[`simple website content: data 1`] = ` "sourceDirName": ".", "tags": [ { + "inline": false, "label": "tag-1", "permalink": "/docs/tags/tag-1", }, { + "inline": false, "label": "tag 3", "permalink": "/docs/tags/tag-3", }, @@ -3289,14 +3307,17 @@ exports[`versioned website content 1`] = ` "sourceDirName": "foo", "tags": [ { + "inline": false, "label": "barTag 1", "permalink": "/docs/next/tags/bar-tag-1", }, { + "inline": false, "label": "barTag-2", "permalink": "/docs/next/tags/bar-tag-2", }, { + "inline": true, "label": "barTag 3", "permalink": "/docs/next/tags/barTag-3-permalink", }, @@ -3558,14 +3579,17 @@ exports[`versioned website content: data 1`] = ` "sourceDirName": "foo", "tags": [ { + "inline": false, "label": "barTag 1", "permalink": "/docs/next/tags/bar-tag-1", }, { + "inline": false, "label": "barTag-2", "permalink": "/docs/next/tags/bar-tag-2", }, { + "inline": true, "label": "barTag 3", "permalink": "/docs/next/tags/barTag-3-permalink", }, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index ef2b03de79e3..e58298ab0650 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -93,6 +93,7 @@ function createTestUtils({ options, context, env, + tagsFile: null, }); } @@ -139,6 +140,7 @@ function createTestUtils({ context, options, env, + tagsFile: null, }); expect(metadata.permalink).toEqual(expectedPermalink); } @@ -159,6 +161,7 @@ function createTestUtils({ context, options, env, + tagsFile: null, }), ), ); @@ -296,6 +299,7 @@ describe('simple site', () => { slug: '/', title: 'Hello, World !', description: `Hi, Endilie here :)`, + sidebarPosition: undefined, frontMatter: { id: 'hello', title: 'Hello, World !', @@ -306,10 +310,12 @@ describe('simple site', () => { tags: [ { label: 'tag-1', + inline: false, permalink: '/docs/tags/tag-1', }, { label: 'tag 3', + inline: false, permalink: '/docs/tags/tag-3', }, ], @@ -339,6 +345,7 @@ describe('simple site', () => { permalink: '/docs/foo/bazSlug.html', slug: '/foo/bazSlug.html', title: 'baz', + sidebarPosition: undefined, editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/docs/foo/baz.md', description: 'Images', @@ -356,10 +363,12 @@ describe('simple site', () => { tags: [ { label: 'tag 1', + inline: false, permalink: '/docs/tags/tag-1', }, { label: 'tag 2', + inline: true, permalink: '/docs/tags/tag2-custom-permalink', }, ], @@ -416,6 +425,7 @@ describe('simple site', () => { title: 'baz', editUrl: hardcodedEditUrl, description: 'Images', + sidebarPosition: undefined, frontMatter: { id: 'baz', slug: 'bazSlug.html', @@ -430,10 +440,12 @@ describe('simple site', () => { tags: [ { label: 'tag 1', + inline: false, permalink: '/docs/tags/tag-1', }, { label: 'tag 2', + inline: true, permalink: '/docs/tags/tag2-custom-permalink', }, ], @@ -883,14 +895,17 @@ describe('versioned site', () => { tags: [ { label: 'barTag 1', + inline: false, permalink: '/docs/next/tags/bar-tag-1', }, { label: 'barTag-2', + inline: false, permalink: '/docs/next/tags/bar-tag-2', }, { label: 'barTag 3', + inline: true, permalink: '/docs/next/tags/barTag-3-permalink', }, ], diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 271965f85107..566aa8f054ff 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -15,9 +15,9 @@ declare module '@docusaurus/plugin-content-docs' { FrontMatterTag, TagsListItem, TagModule, - Tag, FrontMatterLastUpdate, LastUpdateData, + NormalizedTag, } from '@docusaurus/utils'; import type {Plugin, LoadContext} from '@docusaurus/types'; import type {Overwrite, Required} from 'utility-types'; @@ -448,7 +448,7 @@ declare module '@docusaurus/plugin-content-docs' { */ editUrl?: string | null; /** Tags, normalized. */ - tags: Tag[]; + tags: NormalizedTag[]; /** Front matter, as-is. */ frontMatter: DocFrontMatter & {[key: string]: unknown}; }; diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index e465f1ffd3cf..93681762ec4f 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -61,6 +61,7 @@ export function validateFrontMatterTags({ const uniqueUnknownTags = [...new Set(inlineTags)]; const tagListString = uniqueUnknownTags.join(', '); logger.report(onUnknownTags)( + // TODO tagListString is an object + change default file name tags.yml `Tags [${tagListString}] used in ${source} are not defined in tags.yml`, ); } diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index e52eefa9e289..0a9ff0aad051 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -91,7 +91,7 @@ export function normalizeFrontMatterTags( } export function normalizeTags({ - // versionTagsPath, + versionTagsPath, tagsFile, frontMatterTags, }: { @@ -114,7 +114,7 @@ export function normalizeTags({ return { // TODO Fix this, retro-compatible code label: tag, - permalink: `/${tag}`, + permalink: normalizeUrl([versionTagsPath, _.kebabCase(tag)]), inline: false, }; } @@ -123,6 +123,7 @@ export function normalizeTags({ else { return { ...tag, + permalink: normalizeUrl([versionTagsPath, tag.permalink]), inline: true, }; } From 82022c6998fae82486ecbbe33ff633ab95c55e82 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 21 May 2024 15:48:29 +0200 Subject: [PATCH 031/142] update tests --- .../__fixtures__/simple-tags/good.md | 4 - .../__fixtures__/simple-tags/wrong.md | 4 - .../src/__tests__/tags.test.ts | 78 ++++++++++++------- .../src/docs.ts | 2 +- .../src/tags.ts | 13 ++-- 5 files changed, 56 insertions(+), 45 deletions(-) delete mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md delete mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md deleted file mode 100644 index 6f5aa6a901e2..000000000000 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/good.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -id: test -tags: ['open'] ---- diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md deleted file mode 100644 index 76c74759f50d..000000000000 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -id: test -tags: ['hello', 'world'] ---- diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 4e71b50f1d62..5228b7b63dce 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -6,32 +6,24 @@ */ import path from 'path'; -import fs from 'fs-extra'; import {fromPartial} from '@total-typescript/shoehorn'; -import {parseMarkdownFile} from '@docusaurus/utils'; import {getTagsFile, processFileTagsPath} from '../docs'; -import {validateDocFrontMatter} from '../frontMatter'; +import {validateFrontMatterTags} from '../tags'; +import type {PluginOptions} from '@docusaurus/plugin-content-docs'; +import type {FrontMatterTag} from '@docusaurus/utils'; -// TODO remove fixtures and use inline strings const createTest = async ({ filePath, onUnknownTags, + tags, }: { filePath: string; - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; + onUnknownTags: PluginOptions['onUnknownTags']; + tags: FrontMatterTag[]; }) => { const contentPath = path.join(__dirname, '__fixtures__', 'simple-tags'); const tagsFilePath = 'tags.yml'; - const {frontMatter: unsafeFrontMatter} = await parseMarkdownFile({ - filePath, - fileContent: await fs.readFile(filePath, 'utf-8'), - parseFrontMatter: async (params) => { - const result = await params.defaultParseFrontMatter(params); - return {...result}; - }, - }); - const frontMatter = validateDocFrontMatter(unsafeFrontMatter); const definedTags = await getTagsFile( fromPartial({ onUnknownTags, @@ -48,31 +40,57 @@ const createTest = async ({ }), source: filePath, versionTagsPath: '/processFileTagsPath/tags', - frontMatterTags: frontMatter.tags, + frontMatterTags: tags, }); }; describe('processFileTagsPath', () => { - const testFolder = path.join(__dirname, '__fixtures__', 'simple-tags'); - it('throw when docs has invalid tags', async () => { - const process = createTest({ - filePath: path.join(testFolder, 'wrong.md'), - onUnknownTags: 'throw', - }); + const testFn = () => + validateFrontMatterTags( + fromPartial({ + tags: [ + { + label: 'hello', + permalink: 'hello', + inline: true, + }, + { + label: 'world', + permalink: 'world', + inline: true, + }, + ], + source: 'wrong.md', + options: {onUnknownTags: 'throw', tagsFilePath: 'tags.yml'}, + }), + ); - await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( - `"Tags [hello, world] used in /packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/wrong.md are not defined in tags.yml"`, + expect(testFn).toThrowErrorMatchingInlineSnapshot( + `"Tags [hello, world] used in wrong.md are not defined in tags.yml"`, ); }); it('warns when docs has invalid tags', async () => { const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); - await createTest({ - filePath: path.join(testFolder, 'wrong.md'), - onUnknownTags: 'warn', - }); + validateFrontMatterTags( + fromPartial({ + tags: [ + { + label: 'hello', + permalink: 'hello', + inline: true, + }, + { + label: 'world', + permalink: 'world', + inline: true, + }, + ], + options: {onUnknownTags: 'warn', tagsFilePath: 'tags.yml'}, + }), + ); expect(consoleWarnSpy).toHaveBeenCalledTimes(1); expect(consoleWarnSpy).toHaveBeenCalledWith( @@ -83,7 +101,8 @@ describe('processFileTagsPath', () => { it('ignore when docs has invalid tags', async () => { const process = createTest({ - filePath: path.join(testFolder, 'wrong.md'), + filePath: 'wrong.md', + tags: ['hello', 'world'], onUnknownTags: 'ignore', }); await expect(process).resolves.toBeDefined(); @@ -91,7 +110,8 @@ describe('processFileTagsPath', () => { it('does not throw when docs has valid tags', async () => { const process = createTest({ - filePath: path.join(testFolder, 'good.md'), + filePath: 'good.md', + tags: ['open'], onUnknownTags: 'throw', }); await expect(process).resolves.toBeDefined(); diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 33034000e330..17c0509c2fe8 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -128,7 +128,7 @@ export function processFileTagsPath({ validateFrontMatterTags({ tags, source, - onUnknownTags: options.onUnknownTags, + options, }); return tags; diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index 93681762ec4f..5d9a32d50f85 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -50,19 +50,18 @@ export function validateDefinedTags( export function validateFrontMatterTags({ tags, source, - onUnknownTags, + options, }: { tags: NormalizedTag[]; source: string; - onUnknownTags: MetadataOptions['onUnknownTags']; + options: MetadataOptions; }): void { const inlineTags = tags.filter((tag) => tag.inline); - if (inlineTags.length > 0 && onUnknownTags !== 'ignore') { - const uniqueUnknownTags = [...new Set(inlineTags)]; + if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { + const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; const tagListString = uniqueUnknownTags.join(', '); - logger.report(onUnknownTags)( - // TODO tagListString is an object + change default file name tags.yml - `Tags [${tagListString}] used in ${source} are not defined in tags.yml`, + logger.report(options.onUnknownTags)( + `Tags [${tagListString}] used in ${source} are not defined in ${options.tagsFilePath}`, ); } } From 7a914992f68a6fc4bedbe71757caf0e2012c2a69 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 21 May 2024 16:16:58 +0200 Subject: [PATCH 032/142] update wip tests --- .../src/__tests__/docs.test.ts | 15 +++++++++------ packages/docusaurus-utils/src/tags.ts | 9 ++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index e58298ab0650..27cec57aed5d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -310,12 +310,12 @@ describe('simple site', () => { tags: [ { label: 'tag-1', - inline: false, + inline: true, permalink: '/docs/tags/tag-1', }, { label: 'tag 3', - inline: false, + inline: true, permalink: '/docs/tags/tag-3', }, ], @@ -338,6 +338,7 @@ describe('simple site', () => { versionMetadata: currentVersion, }); + // TODO test recieves 2 times the tag 1 await testUtilsLocal.testMeta(path.join('foo', 'baz.md'), { version: 'current', id: 'foo/baz', @@ -363,7 +364,7 @@ describe('simple site', () => { tags: [ { label: 'tag 1', - inline: false, + inline: true, permalink: '/docs/tags/tag-1', }, { @@ -416,6 +417,7 @@ describe('simple site', () => { versionMetadata: currentVersion, }); + // TODO test recieves 2 times the tag 1 await testUtilsLocal.testMeta(path.join('foo', 'baz.md'), { version: 'current', id: 'foo/baz', @@ -440,7 +442,7 @@ describe('simple site', () => { tags: [ { label: 'tag 1', - inline: false, + inline: true, permalink: '/docs/tags/tag-1', }, { @@ -895,16 +897,17 @@ describe('versioned site', () => { tags: [ { label: 'barTag 1', - inline: false, + inline: true, permalink: '/docs/next/tags/bar-tag-1', }, { label: 'barTag-2', - inline: false, + inline: true, permalink: '/docs/next/tags/bar-tag-2', }, { label: 'barTag 3', + // TODO shouldn't it be false ? inline: true, permalink: '/docs/next/tags/barTag-3-permalink', }, diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 0a9ff0aad051..9f8a84d8563a 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -100,6 +100,9 @@ export function normalizeTags({ frontMatterTags: FrontMatterTag[]; }): NormalizedTag[] { // TODO do merge/normalization here + const normalizedFrontMatterTags = frontMatterTags.map((tag) => + normalizeFrontMatterTag(versionTagsPath, tag), + ); function normalizeTag(tag: FrontMatterTag): NormalizedTag { if (typeof tag === 'string') { @@ -114,7 +117,7 @@ export function normalizeTags({ return { // TODO Fix this, retro-compatible code label: tag, - permalink: normalizeUrl([versionTagsPath, _.kebabCase(tag)]), + permalink: _.kebabCase(tag), inline: false, }; } @@ -123,13 +126,13 @@ export function normalizeTags({ else { return { ...tag, - permalink: normalizeUrl([versionTagsPath, tag.permalink]), + permalink: tag.permalink, inline: true, }; } } - return frontMatterTags.map(normalizeTag); + return normalizedFrontMatterTags.map(normalizeTag); } type TaggedItemGroup = { From c6580da5e174c67658d8a81b804ae59caa692c39 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Tue, 21 May 2024 14:21:51 +0000 Subject: [PATCH 033/142] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index cc4e06e18cc5..c35a6799c988 100644 --- a/project-words.txt +++ b/project-words.txt @@ -283,6 +283,7 @@ rachelnabors Ramón reactjs rearchitecture +recieves recrawl redirections Redoc From e64d48d16e40214ee431b0aab680608b9f3d66e6 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 21 May 2024 17:16:00 +0200 Subject: [PATCH 034/142] auto lint fix --- .../docusaurus-plugin-content-docs/src/__tests__/docs.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index 27cec57aed5d..d319586e7ee5 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -338,7 +338,7 @@ describe('simple site', () => { versionMetadata: currentVersion, }); - // TODO test recieves 2 times the tag 1 + // TODO test receives 2 times the tag 1 await testUtilsLocal.testMeta(path.join('foo', 'baz.md'), { version: 'current', id: 'foo/baz', @@ -417,7 +417,7 @@ describe('simple site', () => { versionMetadata: currentVersion, }); - // TODO test recieves 2 times the tag 1 + // TODO test receives 2 times the tag 1 await testUtilsLocal.testMeta(path.join('foo', 'baz.md'), { version: 'current', id: 'foo/baz', From 2456a7f4302809cb7bc590576de3b8dd63519df3 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Tue, 21 May 2024 15:21:06 +0000 Subject: [PATCH 035/142] refactor: apply lint autofix --- project-words.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index c35a6799c988..cc4e06e18cc5 100644 --- a/project-words.txt +++ b/project-words.txt @@ -283,7 +283,6 @@ rachelnabors Ramón reactjs rearchitecture -recieves recrawl redirections Redoc From fd9c96631a50f51b2a289a49839d495d16b623dc Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 21 May 2024 19:36:52 +0200 Subject: [PATCH 036/142] wip --- .../__tests__/__snapshots__/index.test.ts.snap | 10 ---------- .../src/__tests__/docs.test.ts | 16 +++++++--------- packages/docusaurus-utils/src/tags.ts | 13 ++++--------- website/_dogfooding/_docs tests/tags.yml | 3 +++ 4 files changed, 14 insertions(+), 28 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index 701317df30f9..4d89278211fc 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -89,11 +89,6 @@ exports[`simple website content 1`] = ` "label": "tag 1", "permalink": "/docs/tags/tag-1", }, - { - "inline": false, - "label": "tag-1", - "permalink": "/docs/tags/tag-1", - }, { "inline": true, "label": "tag 2", @@ -607,11 +602,6 @@ exports[`simple website content: data 1`] = ` "label": "tag 1", "permalink": "/docs/tags/tag-1", }, - { - "inline": false, - "label": "tag-1", - "permalink": "/docs/tags/tag-1", - }, { "inline": true, "label": "tag 2", diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index d319586e7ee5..fd020ace9dd4 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -310,12 +310,12 @@ describe('simple site', () => { tags: [ { label: 'tag-1', - inline: true, + inline: false, permalink: '/docs/tags/tag-1', }, { label: 'tag 3', - inline: true, + inline: false, permalink: '/docs/tags/tag-3', }, ], @@ -338,7 +338,6 @@ describe('simple site', () => { versionMetadata: currentVersion, }); - // TODO test receives 2 times the tag 1 await testUtilsLocal.testMeta(path.join('foo', 'baz.md'), { version: 'current', id: 'foo/baz', @@ -364,7 +363,7 @@ describe('simple site', () => { tags: [ { label: 'tag 1', - inline: true, + inline: false, permalink: '/docs/tags/tag-1', }, { @@ -417,7 +416,6 @@ describe('simple site', () => { versionMetadata: currentVersion, }); - // TODO test receives 2 times the tag 1 await testUtilsLocal.testMeta(path.join('foo', 'baz.md'), { version: 'current', id: 'foo/baz', @@ -442,7 +440,7 @@ describe('simple site', () => { tags: [ { label: 'tag 1', - inline: true, + inline: false, permalink: '/docs/tags/tag-1', }, { @@ -883,6 +881,7 @@ describe('versioned site', () => { slug: '/foo/barSlug', title: 'bar', description: 'This is next version of bar.', + sidebarPosition: undefined, frontMatter: { slug: 'barSlug', tags: [ @@ -897,17 +896,16 @@ describe('versioned site', () => { tags: [ { label: 'barTag 1', - inline: true, + inline: false, permalink: '/docs/next/tags/bar-tag-1', }, { label: 'barTag-2', - inline: true, + inline: false, permalink: '/docs/next/tags/bar-tag-2', }, { label: 'barTag 3', - // TODO shouldn't it be false ? inline: true, permalink: '/docs/next/tags/barTag-3-permalink', }, diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 9f8a84d8563a..76e28cdc47b0 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -99,11 +99,6 @@ export function normalizeTags({ tagsFile: TagsFile | null; frontMatterTags: FrontMatterTag[]; }): NormalizedTag[] { - // TODO do merge/normalization here - const normalizedFrontMatterTags = frontMatterTags.map((tag) => - normalizeFrontMatterTag(versionTagsPath, tag), - ); - function normalizeTag(tag: FrontMatterTag): NormalizedTag { if (typeof tag === 'string') { const tagDescription = tagsFile?.[tag]; @@ -115,9 +110,8 @@ export function normalizeTags({ }; } else { return { - // TODO Fix this, retro-compatible code label: tag, - permalink: _.kebabCase(tag), + permalink: normalizeFrontMatterTag(versionTagsPath, tag).permalink, inline: false, }; } @@ -126,13 +120,14 @@ export function normalizeTags({ else { return { ...tag, - permalink: tag.permalink, + permalink: normalizeFrontMatterTag(versionTagsPath, tag).permalink, inline: true, }; } } - return normalizedFrontMatterTags.map(normalizeTag); + const tags = frontMatterTags.map(normalizeTag); + return _.uniqBy(tags, (tag) => tag.permalink); } type TaggedItemGroup = { diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml index 4cb4d03e5670..289e8fa9aa29 100644 --- a/website/_dogfooding/_docs tests/tags.yml +++ b/website/_dogfooding/_docs tests/tags.yml @@ -7,6 +7,9 @@ b: c: label: c description: c +d: + label: d + description: d e: label: e description: e From d0c3769c77ec1ab73e109380dd5ab2d793ce48f0 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 22 May 2024 15:00:25 +0200 Subject: [PATCH 037/142] wip fix --- packages/docusaurus-plugin-content-docs/src/docs.ts | 4 ++-- packages/docusaurus-utils/src/tags.ts | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 17c0509c2fe8..55a2001a1ab2 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -85,8 +85,8 @@ export async function getTagsFile( ): Promise { if ( options.tagsFilePath === false || - options.tagsFilePath === null - // options.onUnknownTags === 'ignore' // TODO that looks wrong + options.tagsFilePath === null || + options.onUnknownTags === 'ignore' // TODO that looks wrong ) { return null; } diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 76e28cdc47b0..e73c398dfdec 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -105,13 +105,13 @@ export function normalizeTags({ if (tagDescription) { return { label: tagDescription.label, - permalink: tagDescription.permalink, + permalink: + tagDescription.permalink ?? _.kebabCase(tagDescription.label), inline: false, }; } else { return { - label: tag, - permalink: normalizeFrontMatterTag(versionTagsPath, tag).permalink, + ...normalizeFrontMatterTag(versionTagsPath, tag), inline: false, }; } @@ -119,8 +119,7 @@ export function normalizeTags({ // legacy inline tag object, always inline else { return { - ...tag, - permalink: normalizeFrontMatterTag(versionTagsPath, tag).permalink, + ...normalizeFrontMatterTag(versionTagsPath, tag), inline: true, }; } From 4a63822ec5c139866c896096dc4edc58eee2934d Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 22 May 2024 15:45:25 +0200 Subject: [PATCH 038/142] wip --- .../__snapshots__/index.test.ts.snap | 20 +++++++++---------- .../src/__tests__/docs.test.ts | 12 +++++------ packages/docusaurus-utils/src/tags.ts | 10 +++++++--- website/_dogfooding/_docs tests/tags.yml | 3 --- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index 4d89278211fc..f0bd7eddf8e0 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -85,7 +85,7 @@ exports[`simple website content 1`] = ` "sourceDirName": "foo", "tags": [ { - "inline": false, + "inline": true, "label": "tag 1", "permalink": "/docs/tags/tag-1", }, @@ -132,12 +132,12 @@ exports[`simple website content 2`] = ` "sourceDirName": ".", "tags": [ { - "inline": false, + "inline": true, "label": "tag-1", "permalink": "/docs/tags/tag-1", }, { - "inline": false, + "inline": true, "label": "tag 3", "permalink": "/docs/tags/tag-3", }, @@ -598,7 +598,7 @@ exports[`simple website content: data 1`] = ` "sourceDirName": "foo", "tags": [ { - "inline": false, + "inline": true, "label": "tag 1", "permalink": "/docs/tags/tag-1", }, @@ -669,12 +669,12 @@ exports[`simple website content: data 1`] = ` "sourceDirName": ".", "tags": [ { - "inline": false, + "inline": true, "label": "tag-1", "permalink": "/docs/tags/tag-1", }, { - "inline": false, + "inline": true, "label": "tag 3", "permalink": "/docs/tags/tag-3", }, @@ -3297,12 +3297,12 @@ exports[`versioned website content 1`] = ` "sourceDirName": "foo", "tags": [ { - "inline": false, + "inline": true, "label": "barTag 1", "permalink": "/docs/next/tags/bar-tag-1", }, { - "inline": false, + "inline": true, "label": "barTag-2", "permalink": "/docs/next/tags/bar-tag-2", }, @@ -3569,12 +3569,12 @@ exports[`versioned website content: data 1`] = ` "sourceDirName": "foo", "tags": [ { - "inline": false, + "inline": true, "label": "barTag 1", "permalink": "/docs/next/tags/bar-tag-1", }, { - "inline": false, + "inline": true, "label": "barTag-2", "permalink": "/docs/next/tags/bar-tag-2", }, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index fd020ace9dd4..367ac625b897 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -310,12 +310,12 @@ describe('simple site', () => { tags: [ { label: 'tag-1', - inline: false, + inline: true, permalink: '/docs/tags/tag-1', }, { label: 'tag 3', - inline: false, + inline: true, permalink: '/docs/tags/tag-3', }, ], @@ -363,7 +363,7 @@ describe('simple site', () => { tags: [ { label: 'tag 1', - inline: false, + inline: true, permalink: '/docs/tags/tag-1', }, { @@ -440,7 +440,7 @@ describe('simple site', () => { tags: [ { label: 'tag 1', - inline: false, + inline: true, permalink: '/docs/tags/tag-1', }, { @@ -896,12 +896,12 @@ describe('versioned site', () => { tags: [ { label: 'barTag 1', - inline: false, + inline: true, permalink: '/docs/next/tags/bar-tag-1', }, { label: 'barTag-2', - inline: false, + inline: true, permalink: '/docs/next/tags/bar-tag-2', }, { diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index e73c398dfdec..8493dface277 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -103,20 +103,24 @@ export function normalizeTags({ if (typeof tag === 'string') { const tagDescription = tagsFile?.[tag]; if (tagDescription) { + // inline string known tag return { label: tagDescription.label, - permalink: + permalink: normalizeFrontMatterTag( + versionTagsPath, tagDescription.permalink ?? _.kebabCase(tagDescription.label), + ).permalink, inline: false, }; } else { + // inline string unknown tag return { ...normalizeFrontMatterTag(versionTagsPath, tag), - inline: false, + inline: true, }; } } - // legacy inline tag object, always inline + // legacy inline tag object, always inline, unknown because isn't a string else { return { ...normalizeFrontMatterTag(versionTagsPath, tag), diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml index 289e8fa9aa29..4cb4d03e5670 100644 --- a/website/_dogfooding/_docs tests/tags.yml +++ b/website/_dogfooding/_docs tests/tags.yml @@ -7,9 +7,6 @@ b: c: label: c description: c -d: - label: d - description: d e: label: e description: e From 89c14ac05170470056d75e3fee7ecf9c2cb3b11f Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 22 May 2024 16:58:59 +0200 Subject: [PATCH 039/142] wip more tests --- .../__fixtures__/simple-tags/tags.yml | 4 + .../src/__tests__/tags.test.ts | 96 +++++++++++++++++-- .../src/docs.ts | 2 + website/_dogfooding/_docs tests/index.mdx | 2 +- website/_dogfooding/_docs tests/more-test.mdx | 2 +- 5 files changed, 95 insertions(+), 11 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml index fd66420a585d..7adea9f791e4 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml @@ -1,3 +1,7 @@ open: label: Open Source description: Learn about the open source +test: + label: Test + description: Test + permalink: /custom-test diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 5228b7b63dce..acddc310b83e 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -7,29 +7,38 @@ import path from 'path'; import {fromPartial} from '@total-typescript/shoehorn'; +import {normalizeTags} from '@docusaurus/utils/lib/tags'; import {getTagsFile, processFileTagsPath} from '../docs'; import {validateFrontMatterTags} from '../tags'; import type {PluginOptions} from '@docusaurus/plugin-content-docs'; import type {FrontMatterTag} from '@docusaurus/utils'; +async function getTagsFileDefinition(options: PluginOptions) { + const contentPath = path.join(__dirname, '__fixtures__', 'simple-tags'); + + return getTagsFile( + fromPartial({ + onUnknownTags: options.onUnknownTags, + tagsFilePath: options.tagsFilePath, + }), + contentPath, + ); +} + const createTest = async ({ - filePath, onUnknownTags, tags, }: { - filePath: string; onUnknownTags: PluginOptions['onUnknownTags']; tags: FrontMatterTag[]; }) => { - const contentPath = path.join(__dirname, '__fixtures__', 'simple-tags'); const tagsFilePath = 'tags.yml'; - const definedTags = await getTagsFile( + const definedTags = await getTagsFileDefinition( fromPartial({ onUnknownTags, tagsFilePath, }), - contentPath, ); return processFileTagsPath({ @@ -38,7 +47,7 @@ const createTest = async ({ tagsFilePath, onUnknownTags, }), - source: filePath, + source: 'default.md', versionTagsPath: '/processFileTagsPath/tags', frontMatterTags: tags, }); @@ -101,19 +110,88 @@ describe('processFileTagsPath', () => { it('ignore when docs has invalid tags', async () => { const process = createTest({ - filePath: 'wrong.md', - tags: ['hello', 'world'], + tags: ['unknownTag'], onUnknownTags: 'ignore', }); await expect(process).resolves.toBeDefined(); }); + it('throw for unknown string and object tag', async () => { + const process = createTest({ + tags: [ + 'open', + 'world', + {label: 'hello', permalink: 'hello'}, + {label: 'open', permalink: 'open'}, + ], + onUnknownTags: 'throw', + }); + await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( + `"Tags [world, hello, open] used in default.md are not defined in tags.yml"`, + ); + }); + it('does not throw when docs has valid tags', async () => { const process = createTest({ - filePath: 'good.md', tags: ['open'], onUnknownTags: 'throw', }); await expect(process).resolves.toBeDefined(); }); }); + +describe('normalize tags', () => { + it('normalize tags', async () => { + const tagsFile = await getTagsFileDefinition( + fromPartial({ + onUnknownTags: 'throw', + tagsFilePath: 'tags.yml', + }), + ); + + const tags = [ + 'hello', + 'world', + {label: 'hello', permalink: 'hello'}, + {label: 'world', permalink: 'world'}, + 'hello', + 'open', + {label: 'open', permalink: 'open'}, + 'test', + ]; + + const normalizedTags = normalizeTags({ + versionTagsPath: '/tags', + tagsFile, + frontMatterTags: tags, + }); + + expect(normalizedTags).toEqual([ + { + label: 'hello', + permalink: '/tags/hello', + inline: true, + }, + { + label: 'world', + permalink: '/tags/world', + inline: true, + }, + { + label: 'Open Source', + permalink: '/tags/open-source', + inline: false, + }, + { + inline: true, + label: 'open', + permalink: '/tags/open', + }, + { + label: 'Test', + permalink: '/tags/custom-test', + inline: false, + }, + ]); + }); +}); diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 55a2001a1ab2..9cbbfd0ae128 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -86,12 +86,14 @@ export async function getTagsFile( if ( options.tagsFilePath === false || options.tagsFilePath === null || + // TODO doesn't work if not set options.onUnknownTags === 'ignore' // TODO that looks wrong ) { return null; } const tagDefinitionPath = path.join( contentPath, + // TODO default value isn't used ? options.tagsFilePath ? options.tagsFilePath : 'tags.yml', ); const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); diff --git a/website/_dogfooding/_docs tests/index.mdx b/website/_dogfooding/_docs tests/index.mdx index 64fcfb7eddbf..f4a7353116ae 100644 --- a/website/_dogfooding/_docs tests/index.mdx +++ b/website/_dogfooding/_docs tests/index.mdx @@ -1,6 +1,6 @@ --- slug: / -tags: [a, b, c, some tag] +tags: [{label: a, permalink: a}, a, b, c, some tag] unlisted: true # Makes the navbar link disappear in prod id: index sidebar_label: Docs tests # TODO why is this required? diff --git a/website/_dogfooding/_docs tests/more-test.mdx b/website/_dogfooding/_docs tests/more-test.mdx index 478082818a5e..74efd7c69cd9 100644 --- a/website/_dogfooding/_docs tests/more-test.mdx +++ b/website/_dogfooding/_docs tests/more-test.mdx @@ -1,5 +1,5 @@ --- -tags: [a, e, some-tag, some_tag] +tags: [{label: a, permalink: a}, e, some-tag, some_tag] --- # Another test page From d485fe5ba441f7245d36224606e86c7b089d272d Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 22 May 2024 21:06:36 +0200 Subject: [PATCH 040/142] ugly blog integration --- .../package.json | 1 + .../src/blogUtils.ts | 97 ++++++++++++++++++- .../src/frontMatter.ts | 18 +++- .../src/options.ts | 9 ++ .../src/plugin-content-blog.d.ts | 2 + website/_dogfooding/_blog tests/tags.yml | 36 +++++++ website/_dogfooding/dogfooding.config.ts | 2 + website/blog/tags.yml | 48 +++++++++ website/docusaurus.config.ts | 2 + 9 files changed, 211 insertions(+), 4 deletions(-) create mode 100644 website/_dogfooding/_blog tests/tags.yml create mode 100644 website/blog/tags.yml diff --git a/packages/docusaurus-plugin-content-blog/package.json b/packages/docusaurus-plugin-content-blog/package.json index 3476f4da66f5..efdd2f2f13b1 100644 --- a/packages/docusaurus-plugin-content-blog/package.json +++ b/packages/docusaurus-plugin-content-blog/package.json @@ -41,6 +41,7 @@ "cheerio": "^1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", "lodash": "^4.17.21", "reading-time": "^1.5.0", "srcset": "^4.0.0", diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index ff8b5b892915..fd0b778bf537 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -19,7 +19,7 @@ import { posixPath, replaceMarkdownLinks, Globby, - normalizeFrontMatterTags, + // normalizeFrontMatterTags, groupTaggedItems, getTagVisibility, getFileCommitDate, @@ -28,8 +28,11 @@ import { isDraft, readLastUpdateData, } from '@docusaurus/utils'; -import {validateBlogPostFrontMatter} from './frontMatter'; +import {normalizeTags} from '@docusaurus/utils/lib/tags'; +import YAML from 'js-yaml'; +import {validateBlogPostFrontMatter, validateDefinedTags} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; +import type {NormalizedTag, TagsFile, FrontMatterTag} from '@docusaurus/utils'; import type {LoadContext, ParseFrontMatter} from '@docusaurus/types'; import type { PluginOptions, @@ -193,11 +196,88 @@ async function parseBlogPostMarkdownFile({ const defaultReadingTime: ReadingTimeFunction = ({content, options}) => readingTime(content, options).minutes; +export async function getTagsFile( + options: PluginOptions, + contentPath: string, +): Promise { + if ( + options.tagsFilePath === false || + options.tagsFilePath === null || + // TODO doesn't work if not set + options.onUnknownTags === 'ignore' // TODO that looks wrong + ) { + return null; + } + const tagDefinitionPath = path.join( + contentPath, + // TODO default value isn't used ? + options.tagsFilePath ? options.tagsFilePath : 'tags.yml', + ); + const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); + const data = YAML.load(tagDefinitionContent); + const definedTags = validateDefinedTags(data); + if (definedTags.error) { + throw new Error( + `There was an error extracting tags from file: ${definedTags.error.message}`, + {cause: definedTags}, + ); + } + return definedTags.value; +} + +function validateFrontMatterTags({ + tags, + source, + options, +}: { + tags: NormalizedTag[]; + source: string; + options: PluginOptions; +}): void { + const inlineTags = tags.filter((tag) => tag.inline); + if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { + const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; + const tagListString = uniqueUnknownTags.join(', '); + logger.report(options.onUnknownTags)( + `Tags [${tagListString}] used in ${source} are not defined in ${options.tagsFilePath}`, + ); + } +} + +export function processFileTagsPath({ + options, + source, + frontMatterTags, + versionTagsPath, + tagsFile, +}: { + options: PluginOptions; + source: string; + frontMatterTags: FrontMatterTag[] | undefined; + versionTagsPath: string; + tagsFile: TagsFile | null; +}): NormalizedTag[] { + const tags = normalizeTags({ + versionTagsPath, + tagsFile, + frontMatterTags: frontMatterTags ?? [], + }); + + validateFrontMatterTags({ + tags, + source, + options, + }); + + return tags; +} + async function processBlogSourceFile( blogSourceRelative: string, contentPaths: BlogContentPaths, context: LoadContext, options: PluginOptions, + tagsFile: TagsFile | null, authorsMap?: AuthorsMap, ): Promise { const { @@ -323,6 +403,14 @@ async function processBlogSourceFile( ]); const authors = getBlogPostAuthors({authorsMap, frontMatter, baseUrl}); + const tags = processFileTagsPath({ + options, + source: blogSourceRelative, + frontMatterTags: frontMatter.tags, + versionTagsPath: tagsBasePath, + tagsFile, + }); + return { id: slug, metadata: { @@ -332,7 +420,8 @@ async function processBlogSourceFile( title, description, date, - tags: normalizeFrontMatterTags(tagsBasePath, frontMatter.tags), + tags, + // tags: normalizeFrontMatterTags(tagsBasePath, frontMatter.tags), readingTime: showReadingTime ? options.readingTime({ content, @@ -374,11 +463,13 @@ export async function generateBlogPosts( async function doProcessBlogSourceFile(blogSourceFile: string) { try { + const tagsFile = await getTagsFile(options, contentPaths.contentPath); return await processBlogSourceFile( blogSourceFile, contentPaths, context, options, + tagsFile, authorsMap, ); } catch (err) { diff --git a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts index 3c3f0f8883ee..d084e82c35bc 100644 --- a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts @@ -9,10 +9,11 @@ import { FrontMatterLastUpdateSchema, FrontMatterTOCHeadingLevels, FrontMatterTagsSchema, - JoiFrontMatter as Joi, // Custom instance for front matter + Joi, // Custom instance for front matter URISchema, validateFrontMatter, } from '@docusaurus/utils-validation'; +import type {TagsFile} from '@docusaurus/utils'; import type {BlogPostFrontMatter} from '@docusaurus/plugin-content-blog'; const BlogPostFrontMatterAuthorSchema = Joi.object({ @@ -82,3 +83,18 @@ export function validateBlogPostFrontMatter(frontMatter: { }): BlogPostFrontMatter { return validateFrontMatter(frontMatter, BlogFrontMatterSchema); } + +export const tagDefinitionSchema = Joi.object().pattern( + Joi.string(), + Joi.object({ + label: Joi.string().required(), + description: Joi.string().required(), + permalink: Joi.string(), + }), +); + +export function validateDefinedTags( + tags: unknown, +): Joi.ValidationResult { + return tagDefinitionSchema.validate(tags); +} diff --git a/packages/docusaurus-plugin-content-blog/src/options.ts b/packages/docusaurus-plugin-content-blog/src/options.ts index 86dcbbd4be4f..ea5ba788b4fc 100644 --- a/packages/docusaurus-plugin-content-blog/src/options.ts +++ b/packages/docusaurus-plugin-content-blog/src/options.ts @@ -54,6 +54,8 @@ export const DEFAULT_OPTIONS: PluginOptions = { showLastUpdateTime: false, showLastUpdateAuthor: false, processBlogPosts: async () => undefined, + onUnknownTags: 'warn', + tagsFilePath: false, }; const PluginOptionSchema = Joi.object({ @@ -144,6 +146,13 @@ const PluginOptionSchema = Joi.object({ processBlogPosts: Joi.function() .optional() .default(() => DEFAULT_OPTIONS.processBlogPosts), + onUnknownTags: Joi.string() + .equal('ignore', 'log', 'warn', 'throw') + .default(DEFAULT_OPTIONS.onUnknownTags), + tagsFilePath: Joi.string() + .disallow('') + .allow(null, false) + .default(DEFAULT_OPTIONS.tagsFilePath), }).default(DEFAULT_OPTIONS); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index a1f580466ebe..ee20b3f45c16 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -441,6 +441,8 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the * (filter, modify, delete, etc...). */ processBlogPosts: ProcessBlogPostsFn; + tagsFilePath: string | false | null | undefined; + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; }; /** diff --git a/website/_dogfooding/_blog tests/tags.yml b/website/_dogfooding/_blog tests/tags.yml new file mode 100644 index 000000000000..d921d71b7784 --- /dev/null +++ b/website/_dogfooding/_blog tests/tags.yml @@ -0,0 +1,36 @@ +paginated-tag: + label: Paginated Tag + description: paginated-tag +blog: + label: Blog + description: blog +docusaurus: + label: Docusaurus + description: docusaurus +long: + label: Long + description: long +long-long: + label: Long Long + description: long-long +long-long-long: + label: Long Long Long + description: long-long-long +long-long-long-long: + label: Long Long Long Long + description: long-long-long-long +long-long-long-long-long: + label: Long Long Long Long Long + description: long-long-long-long-long +visibility: + label: Visibility + description: visibility +unlisted: + label: Unlisted + description: unlisted +draft: + label: Draft + description: draft +new: + label: New + description: new diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index 3f9df2ab6185..a0c5ec375001 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -83,6 +83,8 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ frontMatter.hide_reading_time ? undefined : defaultReadingTime({content, options: {wordsPerMinute: 5}}), + onUnknownTags: 'warn', + tagsFilePath: 'tags.yml', } satisfies BlogOptions, ], diff --git a/website/blog/tags.yml b/website/blog/tags.yml new file mode 100644 index 000000000000..36fbae317636 --- /dev/null +++ b/website/blog/tags.yml @@ -0,0 +1,48 @@ +blog: + label: blog + description: blog +release: + label: Release + description: release +recap: + label: Recap + description: recap +birth: + label: Birth + description: birth +endi: + label: Endi + description: endi +tribute: + label: Tribute + description: tribute +i18n: + label: I18n + description: i18n +beta: + label: Beta + description: beta +search: + label: Search + description: search +maintenance: + label: Maintenance + description: maintenance +documentation: + label: Documentation + description: documentation +docusaurus: + label: Docusaurus + description: docusaurus +profilo: + label: Profilo + description: profilo +adoption: + label: Adoption + description: adoption +unlisted: + label: Unlisted + description: unlisted +new: + label: New + description: new diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 426b57f97f05..9b3785b3d838 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -490,6 +490,8 @@ export default async function createConfigAsync() { blogDescription: 'Read blog posts about Docusaurus from the team', blogSidebarCount: 'ALL', blogSidebarTitle: 'All our posts', + onUnknownTags: 'warn', + tagsFilePath: 'tags.yml', } satisfies BlogOptions, pages: { remarkPlugins: [npm2yarn], From 6f9c7b31ef16207b632154d9208af73e6d614f60 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 22 May 2024 23:19:43 +0200 Subject: [PATCH 041/142] shared code wip --- .../src/blogUtils.ts | 96 +++---------------- .../src/docs.ts | 67 +------------ .../src/index.ts | 8 +- .../src/tags.ts | 42 +------- .../docusaurus-utils-validation/src/index.ts | 1 + .../docusaurus-utils-validation/src/tags.ts | 24 +++++ packages/docusaurus-utils/src/tags.ts | 86 ++++++++++++++++- website/_dogfooding/_docs tests/index.mdx | 2 +- website/_dogfooding/_docs tests/more-test.mdx | 2 +- 9 files changed, 134 insertions(+), 194 deletions(-) create mode 100644 packages/docusaurus-utils-validation/src/tags.ts diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index fd0b778bf537..eee49964a256 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -19,7 +19,6 @@ import { posixPath, replaceMarkdownLinks, Globby, - // normalizeFrontMatterTags, groupTaggedItems, getTagVisibility, getFileCommitDate, @@ -28,11 +27,11 @@ import { isDraft, readLastUpdateData, } from '@docusaurus/utils'; -import {normalizeTags} from '@docusaurus/utils/lib/tags'; -import YAML from 'js-yaml'; -import {validateBlogPostFrontMatter, validateDefinedTags} from './frontMatter'; +import {getTagsFile, processFileTagsPath} from '@docusaurus/utils/lib/tags'; +import {validateDefinedTags} from '@docusaurus/utils-validation'; +import {validateBlogPostFrontMatter} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; -import type {NormalizedTag, TagsFile, FrontMatterTag} from '@docusaurus/utils'; +import type {TagsFile} from '@docusaurus/utils'; import type {LoadContext, ParseFrontMatter} from '@docusaurus/types'; import type { PluginOptions, @@ -196,88 +195,12 @@ async function parseBlogPostMarkdownFile({ const defaultReadingTime: ReadingTimeFunction = ({content, options}) => readingTime(content, options).minutes; -export async function getTagsFile( - options: PluginOptions, - contentPath: string, -): Promise { - if ( - options.tagsFilePath === false || - options.tagsFilePath === null || - // TODO doesn't work if not set - options.onUnknownTags === 'ignore' // TODO that looks wrong - ) { - return null; - } - const tagDefinitionPath = path.join( - contentPath, - // TODO default value isn't used ? - options.tagsFilePath ? options.tagsFilePath : 'tags.yml', - ); - const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); - const data = YAML.load(tagDefinitionContent); - const definedTags = validateDefinedTags(data); - if (definedTags.error) { - throw new Error( - `There was an error extracting tags from file: ${definedTags.error.message}`, - {cause: definedTags}, - ); - } - return definedTags.value; -} - -function validateFrontMatterTags({ - tags, - source, - options, -}: { - tags: NormalizedTag[]; - source: string; - options: PluginOptions; -}): void { - const inlineTags = tags.filter((tag) => tag.inline); - if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { - const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; - const tagListString = uniqueUnknownTags.join(', '); - logger.report(options.onUnknownTags)( - `Tags [${tagListString}] used in ${source} are not defined in ${options.tagsFilePath}`, - ); - } -} - -export function processFileTagsPath({ - options, - source, - frontMatterTags, - versionTagsPath, - tagsFile, -}: { - options: PluginOptions; - source: string; - frontMatterTags: FrontMatterTag[] | undefined; - versionTagsPath: string; - tagsFile: TagsFile | null; -}): NormalizedTag[] { - const tags = normalizeTags({ - versionTagsPath, - tagsFile, - frontMatterTags: frontMatterTags ?? [], - }); - - validateFrontMatterTags({ - tags, - source, - options, - }); - - return tags; -} - async function processBlogSourceFile( blogSourceRelative: string, contentPaths: BlogContentPaths, context: LoadContext, options: PluginOptions, - tagsFile: TagsFile | null, + tagsFile: TagsFile | undefined, authorsMap?: AuthorsMap, ): Promise { const { @@ -461,15 +384,20 @@ export async function generateBlogPosts( authorsMapPath: options.authorsMapPath, }); + const tagsFile = await getTagsFile( + options, + contentPaths.contentPath, + validateDefinedTags, + ); + async function doProcessBlogSourceFile(blogSourceFile: string) { try { - const tagsFile = await getTagsFile(options, contentPaths.contentPath); return await processBlogSourceFile( blogSourceFile, contentPaths, context, options, - tagsFile, + tagsFile?.value, authorsMap, ); } catch (err) { diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 9cbbfd0ae128..b75456081c5a 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -21,14 +21,12 @@ import { isDraft, readLastUpdateData, } from '@docusaurus/utils'; -import YAML from 'js-yaml'; -import {normalizeTags} from '@docusaurus/utils/lib/tags'; +import {processFileTagsPath} from '@docusaurus/utils/lib/tags'; import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; import {stripPathNumberPrefixes} from './numberPrefix'; import {toDocNavigationLink, toNavigationLink} from './sidebars/utils'; -import {validateFrontMatterTags, validateDefinedTags} from './tags'; -import type {FrontMatterTag, TagsFile, NormalizedTag} from '@docusaurus/utils'; +import type {TagsFile} from '@docusaurus/utils'; import type { MetadataOptions, PluginOptions, @@ -79,63 +77,6 @@ export async function readVersionDocs( export type DocEnv = 'production' | 'development'; -export async function getTagsFile( - options: MetadataOptions, - contentPath: string, -): Promise { - if ( - options.tagsFilePath === false || - options.tagsFilePath === null || - // TODO doesn't work if not set - options.onUnknownTags === 'ignore' // TODO that looks wrong - ) { - return null; - } - const tagDefinitionPath = path.join( - contentPath, - // TODO default value isn't used ? - options.tagsFilePath ? options.tagsFilePath : 'tags.yml', - ); - const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); - const data = YAML.load(tagDefinitionContent); - const definedTags = validateDefinedTags(data); - if (definedTags.error) { - throw new Error( - `There was an error extracting tags from file: ${definedTags.error.message}`, - {cause: definedTags}, - ); - } - return definedTags.value; -} - -export function processFileTagsPath({ - options, - source, - frontMatterTags, - versionTagsPath, - tagsFile, -}: { - options: MetadataOptions; - source: string; - frontMatterTags: FrontMatterTag[] | undefined; - versionTagsPath: string; - tagsFile: TagsFile | null; -}): NormalizedTag[] { - const tags = normalizeTags({ - versionTagsPath, - tagsFile, - frontMatterTags: frontMatterTags ?? [], - }); - - validateFrontMatterTags({ - tags, - source, - options, - }); - - return tags; -} - async function doProcessDocMetadata({ docFile, versionMetadata, @@ -149,7 +90,7 @@ async function doProcessDocMetadata({ context: LoadContext; options: MetadataOptions; env: DocEnv; - tagsFile: TagsFile | null; + tagsFile: TagsFile | undefined; }): Promise { const {source, content, contentPath, filePath} = docFile; const { @@ -306,7 +247,7 @@ export async function processDocMetadata(args: { context: LoadContext; options: MetadataOptions; env: DocEnv; - tagsFile: TagsFile | null; + tagsFile: TagsFile | undefined; }): Promise { try { return await doProcessDocMetadata(args); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 68a4f1e2c09b..9948d471959f 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -19,6 +19,8 @@ import { createSlugger, DEFAULT_PLUGIN_ID, } from '@docusaurus/utils'; +import {getTagsFile} from '@docusaurus/utils/lib/tags'; +import {validateDefinedTags} from '@docusaurus/utils-validation'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; import { @@ -27,7 +29,6 @@ import { addDocNavigation, type DocEnv, createDocsByIdIndex, - getTagsFile, } from './docs'; import {readVersionsMetadata, toFullVersion} from './versions'; import {cliDocsVersionCommand} from './cli'; @@ -134,7 +135,7 @@ export default async function pluginContentDocs( async loadContent() { async function loadVersionDocsBase( versionMetadata: VersionMetadata, - tagsFile: TagsFile | null, + tagsFile: TagsFile | undefined, ): Promise { const docFiles = await readVersionDocs(versionMetadata, options); if (docFiles.length === 0) { @@ -166,11 +167,12 @@ export default async function pluginContentDocs( const tagsFile = await getTagsFile( options, versionMetadata.contentPath, + validateDefinedTags, ); const docsBase: DocMetadataBase[] = await loadVersionDocsBase( versionMetadata, - tagsFile, + tagsFile?.value, ); // TODO we only ever need draftIds in further code, not full draft items diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts index 5d9a32d50f85..1fd784c213fa 100644 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ b/packages/docusaurus-plugin-content-docs/src/tags.ts @@ -7,14 +7,8 @@ import _ from 'lodash'; import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils'; -import {Joi} from '@docusaurus/utils-validation'; -import logger from '@docusaurus/logger'; -import type {NormalizedTag, TagsFile} from '@docusaurus/utils'; import type {VersionTags} from './types'; -import type { - DocMetadata, - MetadataOptions, -} from '@docusaurus/plugin-content-docs'; +import type {DocMetadata} from '@docusaurus/plugin-content-docs'; export function getVersionTags(docs: DocMetadata[]): VersionTags { const groups = groupTaggedItems(docs, (doc) => doc.tags); @@ -31,37 +25,3 @@ export function getVersionTags(docs: DocMetadata[]): VersionTags { }; }); } - -export const tagDefinitionSchema = Joi.object().pattern( - Joi.string(), - Joi.object({ - label: Joi.string().required(), - description: Joi.string().required(), - permalink: Joi.string(), - }), -); - -export function validateDefinedTags( - tags: unknown, -): Joi.ValidationResult { - return tagDefinitionSchema.validate(tags); -} - -export function validateFrontMatterTags({ - tags, - source, - options, -}: { - tags: NormalizedTag[]; - source: string; - options: MetadataOptions; -}): void { - const inlineTags = tags.filter((tag) => tag.inline); - if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { - const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; - const tagListString = uniqueUnknownTags.join(', '); - logger.report(options.onUnknownTags)( - `Tags [${tagListString}] used in ${source} are not defined in ${options.tagsFilePath}`, - ); - } -} diff --git a/packages/docusaurus-utils-validation/src/index.ts b/packages/docusaurus-utils-validation/src/index.ts index eff1cb28d24f..ee7e26432e06 100644 --- a/packages/docusaurus-utils-validation/src/index.ts +++ b/packages/docusaurus-utils-validation/src/index.ts @@ -29,3 +29,4 @@ export { FrontMatterLastUpdateErrorMessage, FrontMatterLastUpdateSchema, } from './validationSchemas'; +export {validateDefinedTags} from './tags'; diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts new file mode 100644 index 000000000000..d372b2e2c0f4 --- /dev/null +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -0,0 +1,24 @@ +/** + * 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 Joi from 'joi'; +import type {TagsFile} from '@docusaurus/utils'; + +export const tagDefinitionSchema = Joi.object().pattern( + Joi.string(), + Joi.object({ + label: Joi.string().required(), + description: Joi.string().required(), + permalink: Joi.string(), + }), +); + +export function validateDefinedTags( + tags: unknown, +): Joi.ValidationResult { + return tagDefinitionSchema.validate(tags); +} diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 8493dface277..dd2332830a79 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -5,8 +5,13 @@ * LICENSE file in the root directory of this source tree. */ +import path from 'path'; +import fs from 'fs-extra'; import _ from 'lodash'; +import logger from '@docusaurus/logger'; +import YAML from 'js-yaml'; import {normalizeUrl} from './urlUtils'; +import type {PluginOptions} from '@docusaurus/types'; export type TagsFile = Record; @@ -96,7 +101,7 @@ export function normalizeTags({ frontMatterTags, }: { versionTagsPath: string; - tagsFile: TagsFile | null; + tagsFile: TagsFile | undefined; frontMatterTags: FrontMatterTag[]; }): NormalizedTag[] { function normalizeTag(tag: FrontMatterTag): NormalizedTag { @@ -209,3 +214,82 @@ export function getTagVisibility({ listedItems: items.filter((item) => !isUnlisted(item)), }; } + +export function validateFrontMatterTags({ + tags, + source, + options, +}: { + tags: NormalizedTag[]; + source: string; + options: Pick; +}): void { + const inlineTags = tags.filter((tag) => tag.inline); + if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { + const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; + const tagListString = uniqueUnknownTags.join(', '); + // @ts-expect-error: onUnknownTags is not 'ignore' + logger.report(options.onUnknownTags)( + `Tags [${tagListString}] used in ${source} are not defined in ${options.tagsFilePath}`, + ); + } +} + +export function processFileTagsPath({ + options, + source, + frontMatterTags, + versionTagsPath, + tagsFile, +}: { + options: Pick; + source: string; + frontMatterTags: FrontMatterTag[] | undefined; + versionTagsPath: string; + tagsFile: TagsFile | undefined; +}): NormalizedTag[] { + const tags = normalizeTags({ + versionTagsPath, + tagsFile, + frontMatterTags: frontMatterTags ?? [], + }); + + validateFrontMatterTags({ + tags, + source, + options, + }); + + return tags; +} + +export async function getTagsFile( + options: Pick, + contentPath: string, + validateDefinedTags: (data: unknown) => T, +): Promise { + if ( + options.tagsFilePath === false || + options.tagsFilePath === null || + // TODO doesn't work if not set + options.onUnknownTags === 'ignore' // TODO that looks wrong + ) { + return null; + } + const tagDefinitionPath = path.join( + contentPath, + // TODO default value isn't used ? + // @ts-expect-error: tagsFilePath is not '' + options.tagsFilePath ? options.tagsFilePath : 'tags.yml', + ); + const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); + const data = YAML.load(tagDefinitionContent); + return validateDefinedTags(data); + // if (definedTags.error) { + // throw new Error( + // `There was an error extracting tags from file: ${definedTags.error.message}`, + // {cause: definedTags}, + // ); + // } + // return definedTags.value; +} diff --git a/website/_dogfooding/_docs tests/index.mdx b/website/_dogfooding/_docs tests/index.mdx index f4a7353116ae..64fcfb7eddbf 100644 --- a/website/_dogfooding/_docs tests/index.mdx +++ b/website/_dogfooding/_docs tests/index.mdx @@ -1,6 +1,6 @@ --- slug: / -tags: [{label: a, permalink: a}, a, b, c, some tag] +tags: [a, b, c, some tag] unlisted: true # Makes the navbar link disappear in prod id: index sidebar_label: Docs tests # TODO why is this required? diff --git a/website/_dogfooding/_docs tests/more-test.mdx b/website/_dogfooding/_docs tests/more-test.mdx index 74efd7c69cd9..478082818a5e 100644 --- a/website/_dogfooding/_docs tests/more-test.mdx +++ b/website/_dogfooding/_docs tests/more-test.mdx @@ -1,5 +1,5 @@ --- -tags: [{label: a, permalink: a}, e, some-tag, some_tag] +tags: [a, e, some-tag, some_tag] --- # Another test page From dd1778dd8e5065927e60a7e1ca401c6cacafd002 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 22 May 2024 23:22:21 +0200 Subject: [PATCH 042/142] remove dep --- packages/docusaurus-plugin-content-blog/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/docusaurus-plugin-content-blog/package.json b/packages/docusaurus-plugin-content-blog/package.json index efdd2f2f13b1..3476f4da66f5 100644 --- a/packages/docusaurus-plugin-content-blog/package.json +++ b/packages/docusaurus-plugin-content-blog/package.json @@ -41,7 +41,6 @@ "cheerio": "^1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", "lodash": "^4.17.21", "reading-time": "^1.5.0", "srcset": "^4.0.0", From 2944df6c1c6fa2160af4172228cded528edc10c1 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 22 May 2024 23:23:38 +0200 Subject: [PATCH 043/142] remove useless change --- website/docs/installation.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/website/docs/installation.mdx b/website/docs/installation.mdx index 8b398eac1ae4..f9f29dac424f 100644 --- a/website/docs/installation.mdx +++ b/website/docs/installation.mdx @@ -1,6 +1,5 @@ --- description: How to install Docusaurus locally, and start a Docusaurus site in no time. -tags: [installation, getting-started] --- # Installation From 6b03f2dd56c4b60d38e0ae72b4c3062cb31de43f Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 23 May 2024 14:04:55 +0200 Subject: [PATCH 044/142] refactor code & update tests --- .../__tests__/__snapshots__/index.test.ts.snap | 5 +++++ .../src/__tests__/feed.test.ts | 10 ++++++++++ .../src/__tests__/index.test.ts | 2 ++ .../src/blogUtils.ts | 3 ++- .../src/__tests__/tags.test.ts | 15 ++++++++++----- .../docusaurus-plugin-content-docs/src/docs.ts | 2 +- .../docusaurus-plugin-content-docs/src/index.ts | 2 +- packages/docusaurus-utils/src/index.ts | 7 +++++++ 8 files changed, 38 insertions(+), 8 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap index 983054187fee..85604591e4e7 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap @@ -148,6 +148,7 @@ exports[`blog plugin process blog posts load content 2`] = ` "source": "@site/blog/another-simple-slug-with-tags.md", "tags": [ { + "inline": true, "label": "tag1", "permalink": "/blog/tags/tag-1", }, @@ -189,10 +190,12 @@ exports[`blog plugin process blog posts load content 2`] = ` "source": "@site/blog/another-with-tags.md", "tags": [ { + "inline": true, "label": "tag1", "permalink": "/blog/tags/tag-1", }, { + "inline": true, "label": "tag2", "permalink": "/blog/tags/tag-2", }, @@ -230,10 +233,12 @@ exports[`blog plugin process blog posts load content 2`] = ` "source": "@site/blog/another-with-tags2.md", "tags": [ { + "inline": true, "label": "tag1", "permalink": "/blog/tags/tag-1", }, { + "inline": true, "label": "tag2", "permalink": "/blog/tags/tag-2", }, diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts index b900129c9bdc..8e91ef628a8d 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts @@ -100,6 +100,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, + onUnknownTags: 'ignore', + tagsFilePath: false, } as PluginOptions, ); @@ -141,6 +143,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, + onUnknownTags: 'ignore', + tagsFilePath: false, } as PluginOptions, ); @@ -194,6 +198,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, + onUnknownTags: 'ignore', + tagsFilePath: false, } as PluginOptions, ); @@ -238,6 +244,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, + onUnknownTags: 'ignore', + tagsFilePath: false, } as PluginOptions, ); @@ -282,6 +290,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, + onUnknownTags: 'ignore', + tagsFilePath: false, } as PluginOptions, ); diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index 3244150dc217..899aa3014abb 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -515,6 +515,8 @@ describe('blog plugin', () => { postsPerPage: 1, processBlogPosts: async ({blogPosts}) => blogPosts.filter((blog) => blog.metadata.tags[0]?.label === 'tag1'), + onUnknownTags: 'ignore', + tagsFilePath: false, }, DefaultI18N, ); diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index eee49964a256..6551ea87bb9b 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -26,8 +26,9 @@ import { isUnlisted, isDraft, readLastUpdateData, + getTagsFile, + processFileTagsPath, } from '@docusaurus/utils'; -import {getTagsFile, processFileTagsPath} from '@docusaurus/utils/lib/tags'; import {validateDefinedTags} from '@docusaurus/utils-validation'; import {validateBlogPostFrontMatter} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index acddc310b83e..adb3ae615ffc 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -7,9 +7,13 @@ import path from 'path'; import {fromPartial} from '@total-typescript/shoehorn'; -import {normalizeTags} from '@docusaurus/utils/lib/tags'; -import {getTagsFile, processFileTagsPath} from '../docs'; -import {validateFrontMatterTags} from '../tags'; +import {validateDefinedTags} from '@docusaurus/utils-validation'; +import { + getTagsFile, + normalizeTags, + processFileTagsPath, + validateFrontMatterTags, +} from '@docusaurus/utils'; import type {PluginOptions} from '@docusaurus/plugin-content-docs'; import type {FrontMatterTag} from '@docusaurus/utils'; @@ -22,6 +26,7 @@ async function getTagsFileDefinition(options: PluginOptions) { tagsFilePath: options.tagsFilePath, }), contentPath, + validateDefinedTags, ); } @@ -42,7 +47,7 @@ const createTest = async ({ ); return processFileTagsPath({ - tagsFile: definedTags, + tagsFile: definedTags?.value, options: fromPartial({ tagsFilePath, onUnknownTags, @@ -162,7 +167,7 @@ describe('normalize tags', () => { const normalizedTags = normalizeTags({ versionTagsPath: '/tags', - tagsFile, + tagsFile: tagsFile?.value, frontMatterTags: tags, }); diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index b75456081c5a..49b7ce158155 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -20,8 +20,8 @@ import { isUnlisted, isDraft, readLastUpdateData, + processFileTagsPath, } from '@docusaurus/utils'; -import {processFileTagsPath} from '@docusaurus/utils/lib/tags'; import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; import {stripPathNumberPrefixes} from './numberPrefix'; diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 9948d471959f..e3411a1d158d 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -18,8 +18,8 @@ import { createAbsoluteFilePathMatcher, createSlugger, DEFAULT_PLUGIN_ID, + getTagsFile, } from '@docusaurus/utils'; -import {getTagsFile} from '@docusaurus/utils/lib/tags'; import {validateDefinedTags} from '@docusaurus/utils-validation'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 8e982fe0edb5..4cfb743315d9 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -123,3 +123,10 @@ export { type LastUpdateData, type FrontMatterLastUpdate, } from './lastUpdateUtils'; + +export { + getTagsFile, + normalizeTags, + processFileTagsPath, + validateFrontMatterTags, +} from './tags'; From f2d458467bcd461a80ab9021ee270a6dc768c439 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 23 May 2024 14:20:23 +0200 Subject: [PATCH 045/142] chore: Add TagsFeature to docusaurus-types and use it in plugins --- .../src/plugin-content-blog.d.ts | 197 +++++++++--------- .../src/plugin-content-docs.d.ts | 6 +- packages/docusaurus-types/src/config.d.ts | 5 + packages/docusaurus-types/src/index.d.ts | 1 + packages/docusaurus-utils/src/tags.ts | 10 +- 5 files changed, 110 insertions(+), 109 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index ee20b3f45c16..708e7c075cd1 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -345,105 +345,104 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the /** * Plugin options after normalization. */ - export type PluginOptions = MDXOptions & { - /** Plugin ID. */ - id?: string; - /** - * Path to the blog content directory on the file system, relative to site - * directory. - */ - path: string; - /** - * URL route for the blog section of your site. **DO NOT** include a - * trailing slash. Use `/` to put the blog at root path. - */ - routeBasePath: string; - /** - * URL route for the tags section of your blog. Will be appended to - * `routeBasePath`. - */ - tagsBasePath: string; - /** - * URL route for the pages section of your blog. Will be appended to - * `routeBasePath`. - */ - pageBasePath: string; - /** - * URL route for the archive section of your blog. Will be appended to - * `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to - * disable generation of archive. - */ - archiveBasePath: string | null; - /** - * Array of glob patterns matching Markdown files to be built, relative to - * the content path. - */ - include: string[]; - /** - * Array of glob patterns matching Markdown files to be excluded. Serves as - * refinement based on the `include` option. - */ - exclude: string[]; - /** - * Number of posts to show per page in the listing page. Use `'ALL'` to - * display all posts on one listing page. - */ - postsPerPage: number | 'ALL'; - /** Root component of the blog listing page. */ - blogListComponent: string; - /** Root component of each blog post page. */ - blogPostComponent: string; - /** Root component of the tags list page. */ - blogTagsListComponent: string; - /** Root component of the "posts containing tag" page. */ - blogTagsPostsComponent: string; - /** Root component of the blog archive page. */ - blogArchiveComponent: string; - /** Blog page title for better SEO. */ - blogTitle: string; - /** Blog page meta description for better SEO. */ - blogDescription: string; - /** - * Number of blog post elements to show in the blog sidebar. `'ALL'` to show - * all blog posts; `0` to disable. - */ - blogSidebarCount: number | 'ALL'; - /** Title of the blog sidebar. */ - blogSidebarTitle: string; - /** Truncate marker marking where the summary ends. */ - truncateMarker: RegExp; - /** Show estimated reading time for the blog post. */ - showReadingTime: boolean; - /** Blog feed. */ - feedOptions: FeedOptions; - /** - * Base URL to edit your site. The final URL is computed by `editUrl + - * relativePostPath`. Using a function allows more nuanced control for each - * file. Omitting this variable entirely will disable edit links. - */ - editUrl?: string | EditUrlFunction; - /** - * The edit URL will target the localized file, instead of the original - * unlocalized file. Ignored when `editUrl` is a function. - */ - editLocalizedFiles?: boolean; - /** Path to the authors map file, relative to the blog content directory. */ - authorsMapPath: string; - /** A callback to customize the reading time number displayed. */ - readingTime: ReadingTimeFunctionOption; - /** Governs the direction of blog post sorting. */ - sortPosts: 'ascending' | 'descending'; - /** Whether to display the last date the doc was updated. */ - showLastUpdateTime: boolean; - /** Whether to display the author who last updated the doc. */ - showLastUpdateAuthor: boolean; - /** An optional function which can be used to transform blog posts - * (filter, modify, delete, etc...). - */ - processBlogPosts: ProcessBlogPostsFn; - tagsFilePath: string | false | null | undefined; - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; - }; + export type PluginOptions = TagsFeature & + MDXOptions & { + /** Plugin ID. */ + id?: string; + /** + * Path to the blog content directory on the file system, relative to site + * directory. + */ + path: string; + /** + * URL route for the blog section of your site. **DO NOT** include a + * trailing slash. Use `/` to put the blog at root path. + */ + routeBasePath: string; + /** + * URL route for the tags section of your blog. Will be appended to + * `routeBasePath`. + */ + tagsBasePath: string; + /** + * URL route for the pages section of your blog. Will be appended to + * `routeBasePath`. + */ + pageBasePath: string; + /** + * URL route for the archive section of your blog. Will be appended to + * `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to + * disable generation of archive. + */ + archiveBasePath: string | null; + /** + * Array of glob patterns matching Markdown files to be built, relative to + * the content path. + */ + include: string[]; + /** + * Array of glob patterns matching Markdown files to be excluded. Serves as + * refinement based on the `include` option. + */ + exclude: string[]; + /** + * Number of posts to show per page in the listing page. Use `'ALL'` to + * display all posts on one listing page. + */ + postsPerPage: number | 'ALL'; + /** Root component of the blog listing page. */ + blogListComponent: string; + /** Root component of each blog post page. */ + blogPostComponent: string; + /** Root component of the tags list page. */ + blogTagsListComponent: string; + /** Root component of the "posts containing tag" page. */ + blogTagsPostsComponent: string; + /** Root component of the blog archive page. */ + blogArchiveComponent: string; + /** Blog page title for better SEO. */ + blogTitle: string; + /** Blog page meta description for better SEO. */ + blogDescription: string; + /** + * Number of blog post elements to show in the blog sidebar. `'ALL'` to show + * all blog posts; `0` to disable. + */ + blogSidebarCount: number | 'ALL'; + /** Title of the blog sidebar. */ + blogSidebarTitle: string; + /** Truncate marker marking where the summary ends. */ + truncateMarker: RegExp; + /** Show estimated reading time for the blog post. */ + showReadingTime: boolean; + /** Blog feed. */ + feedOptions: FeedOptions; + /** + * Base URL to edit your site. The final URL is computed by `editUrl + + * relativePostPath`. Using a function allows more nuanced control for each + * file. Omitting this variable entirely will disable edit links. + */ + editUrl?: string | EditUrlFunction; + /** + * The edit URL will target the localized file, instead of the original + * unlocalized file. Ignored when `editUrl` is a function. + */ + editLocalizedFiles?: boolean; + /** Path to the authors map file, relative to the blog content directory. */ + authorsMapPath: string; + /** A callback to customize the reading time number displayed. */ + readingTime: ReadingTimeFunctionOption; + /** Governs the direction of blog post sorting. */ + sortPosts: 'ascending' | 'descending'; + /** Whether to display the last date the doc was updated. */ + showLastUpdateTime: boolean; + /** Whether to display the author who last updated the doc. */ + showLastUpdateAuthor: boolean; + /** An optional function which can be used to transform blog posts + * (filter, modify, delete, etc...). + */ + processBlogPosts: ProcessBlogPostsFn; + }; /** * Feed options, as provided by user config. `type` accepts `all` as shortcut diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 566aa8f054ff..53bb7df63574 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -19,7 +19,7 @@ declare module '@docusaurus/plugin-content-docs' { LastUpdateData, NormalizedTag, } from '@docusaurus/utils'; - import type {Plugin, LoadContext} from '@docusaurus/types'; + import type {Plugin, LoadContext, TagsFeature} from '@docusaurus/types'; import type {Overwrite, Required} from 'utility-types'; export type Assets = { @@ -64,7 +64,7 @@ declare module '@docusaurus/plugin-content-docs' { locale: string; }) => string | undefined; - export type MetadataOptions = { + export type MetadataOptions = TagsFeature & { /** * URL route for the docs section of your site. **DO NOT** include a * trailing slash. Use `/` for shipping docs without base path. @@ -101,8 +101,6 @@ declare module '@docusaurus/plugin-content-docs' { numberPrefixParser: NumberPrefixParser; /** Enable or disable the breadcrumbs on doc pages. */ breadcrumbs: boolean; - tagsFilePath: string | false | null | undefined; - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type PathOptions = { diff --git a/packages/docusaurus-types/src/config.d.ts b/packages/docusaurus-types/src/config.d.ts index 422ce7a574ee..2047d62b3fbc 100644 --- a/packages/docusaurus-types/src/config.d.ts +++ b/packages/docusaurus-types/src/config.d.ts @@ -125,6 +125,11 @@ export type FutureConfig = { experimental_storage: StorageConfig; }; +export type TagsFeature = { + tagsFilePath: string | false | null | undefined; + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; +}; + /** * Docusaurus config, after validation/normalization. */ diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 1504e6d03450..53eb91a55472 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -13,6 +13,7 @@ export { ParseFrontMatter, DocusaurusConfig, FutureConfig, + TagsFeature, StorageConfig, Config, } from './config'; diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index dd2332830a79..e4bbd2f4abc3 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -11,7 +11,7 @@ import _ from 'lodash'; import logger from '@docusaurus/logger'; import YAML from 'js-yaml'; import {normalizeUrl} from './urlUtils'; -import type {PluginOptions} from '@docusaurus/types'; +import type {TagsFeature} from '@docusaurus/types'; export type TagsFile = Record; @@ -222,13 +222,12 @@ export function validateFrontMatterTags({ }: { tags: NormalizedTag[]; source: string; - options: Pick; + options: TagsFeature; }): void { const inlineTags = tags.filter((tag) => tag.inline); if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; const tagListString = uniqueUnknownTags.join(', '); - // @ts-expect-error: onUnknownTags is not 'ignore' logger.report(options.onUnknownTags)( `Tags [${tagListString}] used in ${source} are not defined in ${options.tagsFilePath}`, ); @@ -242,7 +241,7 @@ export function processFileTagsPath({ versionTagsPath, tagsFile, }: { - options: Pick; + options: TagsFeature; source: string; frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; @@ -264,7 +263,7 @@ export function processFileTagsPath({ } export async function getTagsFile( - options: Pick, + options: TagsFeature, contentPath: string, validateDefinedTags: (data: unknown) => T, ): Promise { @@ -279,7 +278,6 @@ export async function getTagsFile( const tagDefinitionPath = path.join( contentPath, // TODO default value isn't used ? - // @ts-expect-error: tagsFilePath is not '' options.tagsFilePath ? options.tagsFilePath : 'tags.yml', ); const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); From 5af391831ee841eba7d84e9b02e54ae2107ed3ab Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 23 May 2024 14:33:57 +0200 Subject: [PATCH 046/142] fix ci ?? --- .../src/plugin-content-blog.d.ts | 197 +++++++++--------- 1 file changed, 99 insertions(+), 98 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 708e7c075cd1..26ed4abdaf91 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -345,104 +345,105 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the /** * Plugin options after normalization. */ - export type PluginOptions = TagsFeature & - MDXOptions & { - /** Plugin ID. */ - id?: string; - /** - * Path to the blog content directory on the file system, relative to site - * directory. - */ - path: string; - /** - * URL route for the blog section of your site. **DO NOT** include a - * trailing slash. Use `/` to put the blog at root path. - */ - routeBasePath: string; - /** - * URL route for the tags section of your blog. Will be appended to - * `routeBasePath`. - */ - tagsBasePath: string; - /** - * URL route for the pages section of your blog. Will be appended to - * `routeBasePath`. - */ - pageBasePath: string; - /** - * URL route for the archive section of your blog. Will be appended to - * `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to - * disable generation of archive. - */ - archiveBasePath: string | null; - /** - * Array of glob patterns matching Markdown files to be built, relative to - * the content path. - */ - include: string[]; - /** - * Array of glob patterns matching Markdown files to be excluded. Serves as - * refinement based on the `include` option. - */ - exclude: string[]; - /** - * Number of posts to show per page in the listing page. Use `'ALL'` to - * display all posts on one listing page. - */ - postsPerPage: number | 'ALL'; - /** Root component of the blog listing page. */ - blogListComponent: string; - /** Root component of each blog post page. */ - blogPostComponent: string; - /** Root component of the tags list page. */ - blogTagsListComponent: string; - /** Root component of the "posts containing tag" page. */ - blogTagsPostsComponent: string; - /** Root component of the blog archive page. */ - blogArchiveComponent: string; - /** Blog page title for better SEO. */ - blogTitle: string; - /** Blog page meta description for better SEO. */ - blogDescription: string; - /** - * Number of blog post elements to show in the blog sidebar. `'ALL'` to show - * all blog posts; `0` to disable. - */ - blogSidebarCount: number | 'ALL'; - /** Title of the blog sidebar. */ - blogSidebarTitle: string; - /** Truncate marker marking where the summary ends. */ - truncateMarker: RegExp; - /** Show estimated reading time for the blog post. */ - showReadingTime: boolean; - /** Blog feed. */ - feedOptions: FeedOptions; - /** - * Base URL to edit your site. The final URL is computed by `editUrl + - * relativePostPath`. Using a function allows more nuanced control for each - * file. Omitting this variable entirely will disable edit links. - */ - editUrl?: string | EditUrlFunction; - /** - * The edit URL will target the localized file, instead of the original - * unlocalized file. Ignored when `editUrl` is a function. - */ - editLocalizedFiles?: boolean; - /** Path to the authors map file, relative to the blog content directory. */ - authorsMapPath: string; - /** A callback to customize the reading time number displayed. */ - readingTime: ReadingTimeFunctionOption; - /** Governs the direction of blog post sorting. */ - sortPosts: 'ascending' | 'descending'; - /** Whether to display the last date the doc was updated. */ - showLastUpdateTime: boolean; - /** Whether to display the author who last updated the doc. */ - showLastUpdateAuthor: boolean; - /** An optional function which can be used to transform blog posts - * (filter, modify, delete, etc...). - */ - processBlogPosts: ProcessBlogPostsFn; - }; + export type PluginOptions = MDXOptions & { + /** Plugin ID. */ + id?: string; + /** + * Path to the blog content directory on the file system, relative to site + * directory. + */ + path: string; + /** + * URL route for the blog section of your site. **DO NOT** include a + * trailing slash. Use `/` to put the blog at root path. + */ + routeBasePath: string; + /** + * URL route for the tags section of your blog. Will be appended to + * `routeBasePath`. + */ + tagsBasePath: string; + /** + * URL route for the pages section of your blog. Will be appended to + * `routeBasePath`. + */ + pageBasePath: string; + /** + * URL route for the archive section of your blog. Will be appended to + * `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to + * disable generation of archive. + */ + archiveBasePath: string | null; + /** + * Array of glob patterns matching Markdown files to be built, relative to + * the content path. + */ + include: string[]; + /** + * Array of glob patterns matching Markdown files to be excluded. Serves as + * refinement based on the `include` option. + */ + exclude: string[]; + /** + * Number of posts to show per page in the listing page. Use `'ALL'` to + * display all posts on one listing page. + */ + postsPerPage: number | 'ALL'; + /** Root component of the blog listing page. */ + blogListComponent: string; + /** Root component of each blog post page. */ + blogPostComponent: string; + /** Root component of the tags list page. */ + blogTagsListComponent: string; + /** Root component of the "posts containing tag" page. */ + blogTagsPostsComponent: string; + /** Root component of the blog archive page. */ + blogArchiveComponent: string; + /** Blog page title for better SEO. */ + blogTitle: string; + /** Blog page meta description for better SEO. */ + blogDescription: string; + /** + * Number of blog post elements to show in the blog sidebar. `'ALL'` to show + * all blog posts; `0` to disable. + */ + blogSidebarCount: number | 'ALL'; + /** Title of the blog sidebar. */ + blogSidebarTitle: string; + /** Truncate marker marking where the summary ends. */ + truncateMarker: RegExp; + /** Show estimated reading time for the blog post. */ + showReadingTime: boolean; + /** Blog feed. */ + feedOptions: FeedOptions; + /** + * Base URL to edit your site. The final URL is computed by `editUrl + + * relativePostPath`. Using a function allows more nuanced control for each + * file. Omitting this variable entirely will disable edit links. + */ + editUrl?: string | EditUrlFunction; + /** + * The edit URL will target the localized file, instead of the original + * unlocalized file. Ignored when `editUrl` is a function. + */ + editLocalizedFiles?: boolean; + /** Path to the authors map file, relative to the blog content directory. */ + authorsMapPath: string; + /** A callback to customize the reading time number displayed. */ + readingTime: ReadingTimeFunctionOption; + /** Governs the direction of blog post sorting. */ + sortPosts: 'ascending' | 'descending'; + /** Whether to display the last date the doc was updated. */ + showLastUpdateTime: boolean; + /** Whether to display the author who last updated the doc. */ + showLastUpdateAuthor: boolean; + /** An optional function which can be used to transform blog posts + * (filter, modify, delete, etc...). + */ + processBlogPosts: ProcessBlogPostsFn; + onUnknownTags: TagsFeature['onUnknownTags']; + tagsFilePath: TagsFeature['tagsFilePath']; + }; /** * Feed options, as provided by user config. `type` accepts `all` as shortcut From 276d87704903a71abe6448f47763d18b58dbb135 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 23 May 2024 14:56:51 +0200 Subject: [PATCH 047/142] rename/move TagsFeature to TagsPluginOptions --- .../src/plugin-content-blog.d.ts | 199 +++++++++--------- .../src/plugin-content-docs.d.ts | 5 +- packages/docusaurus-types/src/config.d.ts | 5 - packages/docusaurus-types/src/index.d.ts | 1 - packages/docusaurus-utils/src/index.ts | 1 + packages/docusaurus-utils/src/tags.ts | 20 +- 6 files changed, 117 insertions(+), 114 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 26ed4abdaf91..a9e78d5c9b45 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ - /// declare module '@docusaurus/plugin-content-blog' { @@ -15,6 +14,7 @@ declare module '@docusaurus/plugin-content-blog' { Tag, LastUpdateData, FrontMatterLastUpdate, + TagsPluginOptions, } from '@docusaurus/utils'; import type {DocusaurusConfig, Plugin, LoadContext} from '@docusaurus/types'; import type {Item as FeedItem} from 'feed'; @@ -345,105 +345,104 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the /** * Plugin options after normalization. */ - export type PluginOptions = MDXOptions & { - /** Plugin ID. */ - id?: string; - /** - * Path to the blog content directory on the file system, relative to site - * directory. - */ - path: string; - /** - * URL route for the blog section of your site. **DO NOT** include a - * trailing slash. Use `/` to put the blog at root path. - */ - routeBasePath: string; - /** - * URL route for the tags section of your blog. Will be appended to - * `routeBasePath`. - */ - tagsBasePath: string; - /** - * URL route for the pages section of your blog. Will be appended to - * `routeBasePath`. - */ - pageBasePath: string; - /** - * URL route for the archive section of your blog. Will be appended to - * `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to - * disable generation of archive. - */ - archiveBasePath: string | null; - /** - * Array of glob patterns matching Markdown files to be built, relative to - * the content path. - */ - include: string[]; - /** - * Array of glob patterns matching Markdown files to be excluded. Serves as - * refinement based on the `include` option. - */ - exclude: string[]; - /** - * Number of posts to show per page in the listing page. Use `'ALL'` to - * display all posts on one listing page. - */ - postsPerPage: number | 'ALL'; - /** Root component of the blog listing page. */ - blogListComponent: string; - /** Root component of each blog post page. */ - blogPostComponent: string; - /** Root component of the tags list page. */ - blogTagsListComponent: string; - /** Root component of the "posts containing tag" page. */ - blogTagsPostsComponent: string; - /** Root component of the blog archive page. */ - blogArchiveComponent: string; - /** Blog page title for better SEO. */ - blogTitle: string; - /** Blog page meta description for better SEO. */ - blogDescription: string; - /** - * Number of blog post elements to show in the blog sidebar. `'ALL'` to show - * all blog posts; `0` to disable. - */ - blogSidebarCount: number | 'ALL'; - /** Title of the blog sidebar. */ - blogSidebarTitle: string; - /** Truncate marker marking where the summary ends. */ - truncateMarker: RegExp; - /** Show estimated reading time for the blog post. */ - showReadingTime: boolean; - /** Blog feed. */ - feedOptions: FeedOptions; - /** - * Base URL to edit your site. The final URL is computed by `editUrl + - * relativePostPath`. Using a function allows more nuanced control for each - * file. Omitting this variable entirely will disable edit links. - */ - editUrl?: string | EditUrlFunction; - /** - * The edit URL will target the localized file, instead of the original - * unlocalized file. Ignored when `editUrl` is a function. - */ - editLocalizedFiles?: boolean; - /** Path to the authors map file, relative to the blog content directory. */ - authorsMapPath: string; - /** A callback to customize the reading time number displayed. */ - readingTime: ReadingTimeFunctionOption; - /** Governs the direction of blog post sorting. */ - sortPosts: 'ascending' | 'descending'; - /** Whether to display the last date the doc was updated. */ - showLastUpdateTime: boolean; - /** Whether to display the author who last updated the doc. */ - showLastUpdateAuthor: boolean; - /** An optional function which can be used to transform blog posts - * (filter, modify, delete, etc...). - */ - processBlogPosts: ProcessBlogPostsFn; - onUnknownTags: TagsFeature['onUnknownTags']; - tagsFilePath: TagsFeature['tagsFilePath']; - }; + export type PluginOptions = MDXOptions & + TagsPluginOptions & { + /** Plugin ID. */ + id?: string; + /** + * Path to the blog content directory on the file system, relative to site + * directory. + */ + path: string; + /** + * URL route for the blog section of your site. **DO NOT** include a + * trailing slash. Use `/` to put the blog at root path. + */ + routeBasePath: string; + /** + * URL route for the tags section of your blog. Will be appended to + * `routeBasePath`. + */ + tagsBasePath: string; + /** + * URL route for the pages section of your blog. Will be appended to + * `routeBasePath`. + */ + pageBasePath: string; + /** + * URL route for the archive section of your blog. Will be appended to + * `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to + * disable generation of archive. + */ + archiveBasePath: string | null; + /** + * Array of glob patterns matching Markdown files to be built, relative to + * the content path. + */ + include: string[]; + /** + * Array of glob patterns matching Markdown files to be excluded. Serves as + * refinement based on the `include` option. + */ + exclude: string[]; + /** + * Number of posts to show per page in the listing page. Use `'ALL'` to + * display all posts on one listing page. + */ + postsPerPage: number | 'ALL'; + /** Root component of the blog listing page. */ + blogListComponent: string; + /** Root component of each blog post page. */ + blogPostComponent: string; + /** Root component of the tags list page. */ + blogTagsListComponent: string; + /** Root component of the "posts containing tag" page. */ + blogTagsPostsComponent: string; + /** Root component of the blog archive page. */ + blogArchiveComponent: string; + /** Blog page title for better SEO. */ + blogTitle: string; + /** Blog page meta description for better SEO. */ + blogDescription: string; + /** + * Number of blog post elements to show in the blog sidebar. `'ALL'` to show + * all blog posts; `0` to disable. + */ + blogSidebarCount: number | 'ALL'; + /** Title of the blog sidebar. */ + blogSidebarTitle: string; + /** Truncate marker marking where the summary ends. */ + truncateMarker: RegExp; + /** Show estimated reading time for the blog post. */ + showReadingTime: boolean; + /** Blog feed. */ + feedOptions: FeedOptions; + /** + * Base URL to edit your site. The final URL is computed by `editUrl + + * relativePostPath`. Using a function allows more nuanced control for each + * file. Omitting this variable entirely will disable edit links. + */ + editUrl?: string | EditUrlFunction; + /** + * The edit URL will target the localized file, instead of the original + * unlocalized file. Ignored when `editUrl` is a function. + */ + editLocalizedFiles?: boolean; + /** Path to the authors map file, relative to the blog content directory. */ + authorsMapPath: string; + /** A callback to customize the reading time number displayed. */ + readingTime: ReadingTimeFunctionOption; + /** Governs the direction of blog post sorting. */ + sortPosts: 'ascending' | 'descending'; + /** Whether to display the last date the doc was updated. */ + showLastUpdateTime: boolean; + /** Whether to display the author who last updated the doc. */ + showLastUpdateAuthor: boolean; + /** An optional function which can be used to transform blog posts + * (filter, modify, delete, etc...). + */ + processBlogPosts: ProcessBlogPostsFn; + }; /** * Feed options, as provided by user config. `type` accepts `all` as shortcut diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 53bb7df63574..5670fe7288b0 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -18,8 +18,9 @@ declare module '@docusaurus/plugin-content-docs' { FrontMatterLastUpdate, LastUpdateData, NormalizedTag, + TagsPluginOptions, } from '@docusaurus/utils'; - import type {Plugin, LoadContext, TagsFeature} from '@docusaurus/types'; + import type {Plugin, LoadContext} from '@docusaurus/types'; import type {Overwrite, Required} from 'utility-types'; export type Assets = { @@ -64,7 +65,7 @@ declare module '@docusaurus/plugin-content-docs' { locale: string; }) => string | undefined; - export type MetadataOptions = TagsFeature & { + export type MetadataOptions = TagsPluginOptions & { /** * URL route for the docs section of your site. **DO NOT** include a * trailing slash. Use `/` for shipping docs without base path. diff --git a/packages/docusaurus-types/src/config.d.ts b/packages/docusaurus-types/src/config.d.ts index 2047d62b3fbc..422ce7a574ee 100644 --- a/packages/docusaurus-types/src/config.d.ts +++ b/packages/docusaurus-types/src/config.d.ts @@ -125,11 +125,6 @@ export type FutureConfig = { experimental_storage: StorageConfig; }; -export type TagsFeature = { - tagsFilePath: string | false | null | undefined; - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; -}; - /** * Docusaurus config, after validation/normalization. */ diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 53eb91a55472..1504e6d03450 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -13,7 +13,6 @@ export { ParseFrontMatter, DocusaurusConfig, FutureConfig, - TagsFeature, StorageConfig, Config, } from './config'; diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 4cfb743315d9..e3c8e6262ac0 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -57,6 +57,7 @@ export { type TagsListItem, type TagModule, type FrontMatterTag, + type TagsPluginOptions, normalizeFrontMatterTags, groupTaggedItems, getTagVisibility, diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index e4bbd2f4abc3..4c326c8c48bd 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -11,9 +11,6 @@ import _ from 'lodash'; import logger from '@docusaurus/logger'; import YAML from 'js-yaml'; import {normalizeUrl} from './urlUtils'; -import type {TagsFeature} from '@docusaurus/types'; - -export type TagsFile = Record; /** What the user configures. */ export type Tag = { @@ -22,6 +19,17 @@ export type Tag = { permalink: string; }; +export type TagsFile = Record; + +// Tags plugins options shared between docs/blog +export type TagsPluginOptions = { + // TODO rename to tags? + // TODO allow option tags later? | TagsFile; + tagsFilePath: string | false | null | undefined; + // TODO rename to onInlineTags + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; +}; + export type NormalizedTag = Tag & { inline: boolean; }; @@ -222,7 +230,7 @@ export function validateFrontMatterTags({ }: { tags: NormalizedTag[]; source: string; - options: TagsFeature; + options: TagsPluginOptions; }): void { const inlineTags = tags.filter((tag) => tag.inline); if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { @@ -241,7 +249,7 @@ export function processFileTagsPath({ versionTagsPath, tagsFile, }: { - options: TagsFeature; + options: TagsPluginOptions; source: string; frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; @@ -263,7 +271,7 @@ export function processFileTagsPath({ } export async function getTagsFile( - options: TagsFeature, + options: TagsPluginOptions, contentPath: string, validateDefinedTags: (data: unknown) => T, ): Promise { From 13c3e821f01fcb40d91833665d6b377c5eaccec4 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 23 May 2024 15:10:53 +0200 Subject: [PATCH 048/142] remove useless method --- .../src/validationSchemas.ts | 2 ++ packages/docusaurus-utils/src/index.ts | 1 - packages/docusaurus-utils/src/tags.ts | 27 ++----------------- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/validationSchemas.ts b/packages/docusaurus-utils-validation/src/validationSchemas.ts index 69b4ff5c9996..26a3180398a5 100644 --- a/packages/docusaurus-utils-validation/src/validationSchemas.ts +++ b/packages/docusaurus-utils-validation/src/validationSchemas.ts @@ -113,6 +113,8 @@ export const RouteBasePathSchema = Joi const FrontMatterTagSchema = JoiFrontMatter.alternatives() .try( JoiFrontMatter.string().required(), + // TODO Docusaurus v4 remove this front matter tag form + // users should use tags.yml instead JoiFrontMatter.object({ label: JoiFrontMatter.string().required(), permalink: JoiFrontMatter.string().required(), diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index e3c8e6262ac0..313b5523984a 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -58,7 +58,6 @@ export { type TagModule, type FrontMatterTag, type TagsPluginOptions, - normalizeFrontMatterTags, groupTaggedItems, getTagVisibility, } from './tags'; diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 4c326c8c48bd..87e5e14f09b9 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -80,29 +80,6 @@ function normalizeFrontMatterTag( }; } -/** - * Takes tag objects as they are defined in front matter, and normalizes each - * into a standard tag object. The permalink is created by appending the - * sluggified label to `tagsPath`. Front matter tags already containing - * permalinks would still have `tagsPath` prepended. - * - * The result will always be unique by permalinks. The behavior with colliding - * permalinks is undetermined. - */ -// TODO does this method still make sense? probably not -export function normalizeFrontMatterTags( - /** Base path to append the tag permalinks to. */ - tagsPath: string, - /** Can be `undefined`, so that we can directly pipe in `frontMatter.tags`. */ - frontMatterTags: FrontMatterTag[] | undefined = [], -): Tag[] { - const tags = frontMatterTags.map((tag) => - normalizeFrontMatterTag(tagsPath, tag), - ); - - return _.uniqBy(tags, (tag) => tag.permalink); -} - export function normalizeTags({ versionTagsPath, tagsFile, @@ -116,7 +93,7 @@ export function normalizeTags({ if (typeof tag === 'string') { const tagDescription = tagsFile?.[tag]; if (tagDescription) { - // inline string known tag + // pre-defined tag from tags.yml return { label: tagDescription.label, permalink: normalizeFrontMatterTag( @@ -126,7 +103,7 @@ export function normalizeTags({ inline: false, }; } else { - // inline string unknown tag + // inline tag return { ...normalizeFrontMatterTag(versionTagsPath, tag), inline: true, From f2e990c212f7423e3b4b6e5f3445d45f81f13cc9 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 23 May 2024 16:08:30 +0200 Subject: [PATCH 049/142] refactor tags a bit + add todo --- .../__fixtures__/simple-tags/tags.yml | 7 - .../src/__tests__/tags.test.ts | 59 +----- .../src/__tests__/tags.test.ts | 200 ++++++++++-------- packages/docusaurus-utils/src/tags.ts | 122 ++++++----- 4 files changed, 182 insertions(+), 206 deletions(-) delete mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml deleted file mode 100644 index 7adea9f791e4..000000000000 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-tags/tags.yml +++ /dev/null @@ -1,7 +0,0 @@ -open: - label: Open Source - description: Learn about the open source -test: - label: Test - description: Test - permalink: /custom-test diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index adb3ae615ffc..1d5f4489884d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -10,7 +10,6 @@ import {fromPartial} from '@total-typescript/shoehorn'; import {validateDefinedTags} from '@docusaurus/utils-validation'; import { getTagsFile, - normalizeTags, processFileTagsPath, validateFrontMatterTags, } from '@docusaurus/utils'; @@ -47,7 +46,7 @@ const createTest = async ({ ); return processFileTagsPath({ - tagsFile: definedTags?.value, + tagsFile: definedTags?.value as any, // TODO options: fromPartial({ tagsFilePath, onUnknownTags, @@ -144,59 +143,3 @@ describe('processFileTagsPath', () => { await expect(process).resolves.toBeDefined(); }); }); - -describe('normalize tags', () => { - it('normalize tags', async () => { - const tagsFile = await getTagsFileDefinition( - fromPartial({ - onUnknownTags: 'throw', - tagsFilePath: 'tags.yml', - }), - ); - - const tags = [ - 'hello', - 'world', - {label: 'hello', permalink: 'hello'}, - {label: 'world', permalink: 'world'}, - 'hello', - 'open', - {label: 'open', permalink: 'open'}, - 'test', - ]; - - const normalizedTags = normalizeTags({ - versionTagsPath: '/tags', - tagsFile: tagsFile?.value, - frontMatterTags: tags, - }); - - expect(normalizedTags).toEqual([ - { - label: 'hello', - permalink: '/tags/hello', - inline: true, - }, - { - label: 'world', - permalink: '/tags/world', - inline: true, - }, - { - label: 'Open Source', - permalink: '/tags/open-source', - inline: false, - }, - { - inline: true, - label: 'open', - permalink: '/tags/open', - }, - { - label: 'Test', - permalink: '/tags/custom-test', - inline: false, - }, - ]); - }); -}); diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index cf8c52ec5335..ff7f775b891b 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -6,117 +6,131 @@ */ import { - normalizeFrontMatterTags, groupTaggedItems, - type Tag, getTagVisibility, + normalizeTags, + normalizeTag } from '../tags'; - -describe('normalizeFrontMatterTags', () => { - it('normalizes simple string tag', () => { - const tagsPath = '/all/tags'; - const input = 'tag'; - const expectedOutput = { - label: 'tag', - permalink: `${tagsPath}/tag`, - }; - expect(normalizeFrontMatterTags(tagsPath, [input])).toEqual([ - expectedOutput, - ]); - }); - - it('normalizes complex string tag', () => { - const tagsPath = '/all/tags'; - const input = 'some more Complex_tag'; - const expectedOutput = { - label: 'some more Complex_tag', - permalink: `${tagsPath}/some-more-complex-tag`, - }; - expect(normalizeFrontMatterTags(tagsPath, [input])).toEqual([ - expectedOutput, - ]); - }); - - it('normalizes simple object tag', () => { - const tagsPath = '/all/tags'; - const input = {label: 'tag', permalink: 'tagPermalink'}; - const expectedOutput = { - label: 'tag', - permalink: `${tagsPath}/tagPermalink`, +import type {TagsFile, Tag, + NormalizedTag, + FrontMatterTag} from '../tags'; + +describe('normalize tags', () => { + it('normalize tags', async () => { + const tagsFile: TagsFile = { + open: { + label: 'Open Source', + permalink: '/custom-open-source', + description: 'Learn about the open source', + }, + test: {label: 'Test', permalink: '/custom-test', description: 'Test'}, }; - expect(normalizeFrontMatterTags(tagsPath, [input])).toEqual([ - expectedOutput, - ]); - }); - it('normalizes complex string tag with object tag', () => { - const tagsPath = '/all/tags'; - const input = { - label: 'tag complex Label', - permalink: '/MoreComplex/Permalink', - }; - const expectedOutput = { - label: 'tag complex Label', - permalink: `${tagsPath}/MoreComplex/Permalink`, - }; - expect(normalizeFrontMatterTags(tagsPath, [input])).toEqual([ - expectedOutput, - ]); - }); + const tags = [ + 'hello', + 'world', + {label: 'hello', permalink: 'hello'}, + {label: 'world', permalink: 'world'}, + 'hello', + 'open', + {label: 'open', permalink: 'open'}, + 'test', + ]; - type Input = Parameters[1]; - type Output = ReturnType; + const normalizedTags = normalizeTags({ + tagsPath: '/tags', + tagsFile, + frontMatterTags: tags, + }); - it('normalizes string list', () => { - const tagsPath = '/all/tags'; - const input: Input = ['tag 1', 'tag-1', 'tag 3', 'tag1', 'tag-2']; - // Keep user input order but remove tags that lead to same permalink - const expectedOutput: Output = [ + const expected: NormalizedTag[] = [ { - label: 'tag 1', - permalink: `${tagsPath}/tag-1`, + inline: true, + label: 'hello', + permalink: '/tags/hello', }, { - label: 'tag 3', - permalink: `${tagsPath}/tag-3`, + inline: true, + label: 'world', + permalink: '/tags/world', }, { - label: 'tag-2', - permalink: `${tagsPath}/tag-2`, - }, - ]; - expect(normalizeFrontMatterTags(tagsPath, input)).toEqual(expectedOutput); - }); - - it('succeeds for empty list', () => { - expect(normalizeFrontMatterTags('/foo')).toEqual([]); - }); - - it('normalizes complex mixed list', () => { - const tagsPath = '/all/tags'; - const input: Input = [ - 'tag 1', - {label: 'tag-1', permalink: '/tag-1'}, - 'tag 3', - 'tag1', - {label: 'tag 4', permalink: '/tag4Permalink'}, - ]; - // Keep user input order but remove tags that lead to same permalink - const expectedOutput: Output = [ - { - label: 'tag 1', - permalink: `${tagsPath}/tag-1`, + inline: false, + label: 'Open Source', + permalink: '/tags/custom-open-source', + description: 'Learn about the open source', }, { - label: 'tag 3', - permalink: `${tagsPath}/tag-3`, + inline: true, + label: 'open', + permalink: '/tags/open', }, { - label: 'tag 4', - permalink: `${tagsPath}/tag4Permalink`, + inline: false, + label: 'Test', + permalink: '/tags/custom-test', + description: 'Test', }, ]; - expect(normalizeFrontMatterTags(tagsPath, input)).toEqual(expectedOutput); + + expect(normalizedTags).toEqual(expected); + }); +}); + +describe('normalizeFrontMatterTags', () => { + const tagsPath = '/all/tags'; + + describe('inline', () => { + it('normalizes simple string tag', () => { + const input: FrontMatterTag = 'tag'; + const expectedOutput: NormalizedTag = { + inline: true, + label: 'tag', + permalink: `${tagsPath}/tag`, + }; + expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( + expectedOutput, + ); + }); + + it('normalizes complex string tag', () => { + const input: FrontMatterTag = 'some more Complex_tag'; + const expectedOutput: NormalizedTag = { + inline: true, + label: 'some more Complex_tag', + permalink: `${tagsPath}/some-more-complex-tag`, + }; + expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( + expectedOutput, + ); + }); + + it('normalizes simple object tag', () => { + const input: FrontMatterTag = {label: 'tag', permalink: 'tagPermalink'}; + const expectedOutput: NormalizedTag = { + inline: true, + label: 'tag', + permalink: `${tagsPath}/tagPermalink`, + }; + expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( + expectedOutput, + ); + }); + + it('normalizes complex string tag with object tag', () => { + const input: FrontMatterTag = { + label: 'tag complex Label', + permalink: '/MoreComplex/Permalink', + }; + const expectedOutput: NormalizedTag = { + inline: true, + label: 'tag complex Label', + permalink: `${tagsPath}/MoreComplex/Permalink`, + }; + expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( + expectedOutput, + ); + }); }); }); diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 87e5e14f09b9..519bc01ff785 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -17,8 +17,14 @@ export type Tag = { label: string; /** Permalink to this tag's page, without the `/tags/` base path. */ permalink: string; + + // TODO do we use it in practice? + description?: string; }; +// TODO add TagsFileInput=>TagsFile transformation + unit tests +export type TagsFileInput = Record>; + export type TagsFile = Record; // Tags plugins options shared between docs/blog @@ -50,76 +56,90 @@ export type TagModule = TagsListItem & { export type FrontMatterTag = string | Tag; -function normalizeFrontMatterTag( +// TODO maybe make ensure the permalink is valid url path? +function normalizeTagPermalink({ + tagsPath, + permalink, +}: { + tagsPath: string; + permalink: string; +}): string { + // Note: we always apply tagsPath on purpose. For versioned docs, v1/doc.md + // and v2/doc.md tags with custom permalinks don't lead to the same created + // page. tagsPath is different for each doc version + return normalizeUrl([tagsPath, permalink]); +} + +// TODO old legacy method, to refactor +function normalizeInlineTag( tagsPath: string, frontMatterTag: FrontMatterTag, -): Tag { - function toTagObject(tagString: string): Tag { +): NormalizedTag { + function toTagObject(tagString: string): NormalizedTag { return { + inline: true, label: tagString, permalink: _.kebabCase(tagString), + description: undefined, }; } - // TODO maybe make ensure the permalink is valid url path? - function normalizeTagPermalink(permalink: string): string { - // Note: we always apply tagsPath on purpose. For versioned docs, v1/doc.md - // and v2/doc.md tags with custom permalinks don't lead to the same created - // page. tagsPath is different for each doc version - return normalizeUrl([tagsPath, permalink]); - } - const tag: Tag = typeof frontMatterTag === 'string' ? toTagObject(frontMatterTag) : frontMatterTag; return { + inline: true, label: tag.label, - permalink: normalizeTagPermalink(tag.permalink), + permalink: normalizeTagPermalink({permalink: tag.permalink, tagsPath}), + description: tag.description, }; } -export function normalizeTags({ - versionTagsPath, +export function normalizeTag({ + tag, tagsFile, - frontMatterTags, + tagsPath, }: { - versionTagsPath: string; + tag: FrontMatterTag; + tagsPath: string; tagsFile: TagsFile | undefined; - frontMatterTags: FrontMatterTag[]; -}): NormalizedTag[] { - function normalizeTag(tag: FrontMatterTag): NormalizedTag { - if (typeof tag === 'string') { - const tagDescription = tagsFile?.[tag]; - if (tagDescription) { - // pre-defined tag from tags.yml - return { - label: tagDescription.label, - permalink: normalizeFrontMatterTag( - versionTagsPath, - tagDescription.permalink ?? _.kebabCase(tagDescription.label), - ).permalink, - inline: false, - }; - } else { - // inline tag - return { - ...normalizeFrontMatterTag(versionTagsPath, tag), - inline: true, - }; - } - } - // legacy inline tag object, always inline, unknown because isn't a string - else { +}): NormalizedTag { + if (typeof tag === 'string') { + const tagDescription = tagsFile?.[tag]; + if (tagDescription) { + // pre-defined tag from tags.yml return { - ...normalizeFrontMatterTag(versionTagsPath, tag), - inline: true, + inline: false, + label: tagDescription.label, + permalink: normalizeTagPermalink({ + permalink: tagDescription.permalink, + tagsPath, + }), + description: tagDescription.description, }; } } + // legacy inline tag object, always inline, unknown because isn't a string + return normalizeInlineTag(tagsPath, tag); +} - const tags = frontMatterTags.map(normalizeTag); +export function normalizeTags({ + tagsPath, + tagsFile, + frontMatterTags, +}: { + tagsPath: string; + tagsFile: TagsFile | undefined; + frontMatterTags: FrontMatterTag[]; +}): NormalizedTag[] { + const tags = frontMatterTags.map((tag) => + normalizeTag({tag, tagsPath, tagsFile}), + ); + + // TODO old legacy behavior + // emit errors in case of conflicts instead return _.uniqBy(tags, (tag) => tag.permalink); } @@ -233,7 +253,7 @@ export function processFileTagsPath({ tagsFile: TagsFile | undefined; }): NormalizedTag[] { const tags = normalizeTags({ - versionTagsPath, + tagsPath: versionTagsPath, tagsFile, frontMatterTags: frontMatterTags ?? [], }); @@ -247,11 +267,13 @@ export function processFileTagsPath({ return tags; } -export async function getTagsFile( +// TODO move to utils-validation +export async function getTagsFile( options: TagsPluginOptions, contentPath: string, - validateDefinedTags: (data: unknown) => T, -): Promise { + // TODO find a better solution + validateDefinedTags: (data: unknown) => TagsFile, +): Promise { if ( options.tagsFilePath === false || options.tagsFilePath === null || @@ -268,6 +290,10 @@ export async function getTagsFile( const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); const data = YAML.load(tagDefinitionContent); return validateDefinedTags(data); + // TODO + normalize partial input => full input + // TODO unit tests covering all forms of partial inputs + // TODO handle conflicts, verify unique permalink etc + // if (definedTags.error) { // throw new Error( // `There was an error extracting tags from file: ${definedTags.error.message}`, From 9f7e89e1ca9286c112e87ac5483b06002d2c8adf Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 24 May 2024 12:55:48 +0200 Subject: [PATCH 050/142] move getTagsFile to utils-validation --- .../__snapshots__/index.test.ts.snap | 5 + .../src/blogUtils.ts | 14 +-- .../__snapshots__/index.test.ts.snap | 14 +++ .../src/__tests__/tags.test.ts | 9 +- .../src/docs.ts | 4 +- .../src/index.ts | 8 +- .../docusaurus-utils-validation/package.json | 1 + .../docusaurus-utils-validation/src/index.ts | 2 +- .../docusaurus-utils-validation/src/tags.ts | 93 +++++++++++++++++-- packages/docusaurus-utils/src/index.ts | 2 +- packages/docusaurus-utils/src/tags.ts | 47 +--------- yarn.lock | 39 ++------ 12 files changed, 129 insertions(+), 109 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap index 85604591e4e7..ab928b433c34 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap @@ -148,6 +148,7 @@ exports[`blog plugin process blog posts load content 2`] = ` "source": "@site/blog/another-simple-slug-with-tags.md", "tags": [ { + "description": undefined, "inline": true, "label": "tag1", "permalink": "/blog/tags/tag-1", @@ -190,11 +191,13 @@ exports[`blog plugin process blog posts load content 2`] = ` "source": "@site/blog/another-with-tags.md", "tags": [ { + "description": undefined, "inline": true, "label": "tag1", "permalink": "/blog/tags/tag-1", }, { + "description": undefined, "inline": true, "label": "tag2", "permalink": "/blog/tags/tag-2", @@ -233,11 +236,13 @@ exports[`blog plugin process blog posts load content 2`] = ` "source": "@site/blog/another-with-tags2.md", "tags": [ { + "description": undefined, "inline": true, "label": "tag1", "permalink": "/blog/tags/tag-1", }, { + "description": undefined, "inline": true, "label": "tag2", "permalink": "/blog/tags/tag-2", diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 6551ea87bb9b..3abeec583aee 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -26,10 +26,9 @@ import { isUnlisted, isDraft, readLastUpdateData, - getTagsFile, processFileTagsPath, } from '@docusaurus/utils'; -import {validateDefinedTags} from '@docusaurus/utils-validation'; +import {getTagsFile} from '@docusaurus/utils-validation'; import {validateBlogPostFrontMatter} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; import type {TagsFile} from '@docusaurus/utils'; @@ -201,7 +200,7 @@ async function processBlogSourceFile( contentPaths: BlogContentPaths, context: LoadContext, options: PluginOptions, - tagsFile: TagsFile | undefined, + tagsFile: TagsFile | null, authorsMap?: AuthorsMap, ): Promise { const { @@ -345,7 +344,6 @@ async function processBlogSourceFile( description, date, tags, - // tags: normalizeFrontMatterTags(tagsBasePath, frontMatter.tags), readingTime: showReadingTime ? options.readingTime({ content, @@ -385,11 +383,7 @@ export async function generateBlogPosts( authorsMapPath: options.authorsMapPath, }); - const tagsFile = await getTagsFile( - options, - contentPaths.contentPath, - validateDefinedTags, - ); + const tagsFile = await getTagsFile(options, contentPaths.contentPath); async function doProcessBlogSourceFile(blogSourceFile: string) { try { @@ -398,7 +392,7 @@ export async function generateBlogPosts( contentPaths, context, options, - tagsFile?.value, + tagsFile, authorsMap, ); } catch (err) { diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index f0bd7eddf8e0..bb4b21574e64 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -85,11 +85,13 @@ exports[`simple website content 1`] = ` "sourceDirName": "foo", "tags": [ { + "description": undefined, "inline": true, "label": "tag 1", "permalink": "/docs/tags/tag-1", }, { + "description": undefined, "inline": true, "label": "tag 2", "permalink": "/docs/tags/tag2-custom-permalink", @@ -132,11 +134,13 @@ exports[`simple website content 2`] = ` "sourceDirName": ".", "tags": [ { + "description": undefined, "inline": true, "label": "tag-1", "permalink": "/docs/tags/tag-1", }, { + "description": undefined, "inline": true, "label": "tag 3", "permalink": "/docs/tags/tag-3", @@ -598,11 +602,13 @@ exports[`simple website content: data 1`] = ` "sourceDirName": "foo", "tags": [ { + "description": undefined, "inline": true, "label": "tag 1", "permalink": "/docs/tags/tag-1", }, { + "description": undefined, "inline": true, "label": "tag 2", "permalink": "/docs/tags/tag2-custom-permalink", @@ -669,11 +675,13 @@ exports[`simple website content: data 1`] = ` "sourceDirName": ".", "tags": [ { + "description": undefined, "inline": true, "label": "tag-1", "permalink": "/docs/tags/tag-1", }, { + "description": undefined, "inline": true, "label": "tag 3", "permalink": "/docs/tags/tag-3", @@ -3297,16 +3305,19 @@ exports[`versioned website content 1`] = ` "sourceDirName": "foo", "tags": [ { + "description": undefined, "inline": true, "label": "barTag 1", "permalink": "/docs/next/tags/bar-tag-1", }, { + "description": undefined, "inline": true, "label": "barTag-2", "permalink": "/docs/next/tags/bar-tag-2", }, { + "description": undefined, "inline": true, "label": "barTag 3", "permalink": "/docs/next/tags/barTag-3-permalink", @@ -3569,16 +3580,19 @@ exports[`versioned website content: data 1`] = ` "sourceDirName": "foo", "tags": [ { + "description": undefined, "inline": true, "label": "barTag 1", "permalink": "/docs/next/tags/bar-tag-1", }, { + "description": undefined, "inline": true, "label": "barTag-2", "permalink": "/docs/next/tags/bar-tag-2", }, { + "description": undefined, "inline": true, "label": "barTag 3", "permalink": "/docs/next/tags/barTag-3-permalink", diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts index 1d5f4489884d..d5f50e6686a6 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts @@ -7,12 +7,8 @@ import path from 'path'; import {fromPartial} from '@total-typescript/shoehorn'; -import {validateDefinedTags} from '@docusaurus/utils-validation'; -import { - getTagsFile, - processFileTagsPath, - validateFrontMatterTags, -} from '@docusaurus/utils'; +import {getTagsFile} from '@docusaurus/utils-validation'; +import {processFileTagsPath, validateFrontMatterTags} from '@docusaurus/utils'; import type {PluginOptions} from '@docusaurus/plugin-content-docs'; import type {FrontMatterTag} from '@docusaurus/utils'; @@ -25,7 +21,6 @@ async function getTagsFileDefinition(options: PluginOptions) { tagsFilePath: options.tagsFilePath, }), contentPath, - validateDefinedTags, ); } diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 49b7ce158155..1f277c5a52d0 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -90,7 +90,7 @@ async function doProcessDocMetadata({ context: LoadContext; options: MetadataOptions; env: DocEnv; - tagsFile: TagsFile | undefined; + tagsFile: TagsFile | null; }): Promise { const {source, content, contentPath, filePath} = docFile; const { @@ -247,7 +247,7 @@ export async function processDocMetadata(args: { context: LoadContext; options: MetadataOptions; env: DocEnv; - tagsFile: TagsFile | undefined; + tagsFile: TagsFile | null; }): Promise { try { return await doProcessDocMetadata(args); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index e3411a1d158d..9193c8a9fe55 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -18,9 +18,8 @@ import { createAbsoluteFilePathMatcher, createSlugger, DEFAULT_PLUGIN_ID, - getTagsFile, } from '@docusaurus/utils'; -import {validateDefinedTags} from '@docusaurus/utils-validation'; +import {getTagsFile} from '@docusaurus/utils-validation'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; import { @@ -135,7 +134,7 @@ export default async function pluginContentDocs( async loadContent() { async function loadVersionDocsBase( versionMetadata: VersionMetadata, - tagsFile: TagsFile | undefined, + tagsFile: TagsFile | null, ): Promise { const docFiles = await readVersionDocs(versionMetadata, options); if (docFiles.length === 0) { @@ -167,12 +166,11 @@ export default async function pluginContentDocs( const tagsFile = await getTagsFile( options, versionMetadata.contentPath, - validateDefinedTags, ); const docsBase: DocMetadataBase[] = await loadVersionDocsBase( versionMetadata, - tagsFile?.value, + tagsFile, ); // TODO we only ever need draftIds in further code, not full draft items diff --git a/packages/docusaurus-utils-validation/package.json b/packages/docusaurus-utils-validation/package.json index 96279a3b30ee..f7f5ddfc26a5 100644 --- a/packages/docusaurus-utils-validation/package.json +++ b/packages/docusaurus-utils-validation/package.json @@ -21,6 +21,7 @@ "@docusaurus/logger": "3.3.2", "@docusaurus/utils": "3.3.2", "@docusaurus/utils-common": "3.3.2", + "fs-extra": "^11.2.0", "joi": "^17.9.2", "js-yaml": "^4.1.0", "tslib": "^2.6.0" diff --git a/packages/docusaurus-utils-validation/src/index.ts b/packages/docusaurus-utils-validation/src/index.ts index ee7e26432e06..c2f053dfd569 100644 --- a/packages/docusaurus-utils-validation/src/index.ts +++ b/packages/docusaurus-utils-validation/src/index.ts @@ -29,4 +29,4 @@ export { FrontMatterLastUpdateErrorMessage, FrontMatterLastUpdateSchema, } from './validationSchemas'; -export {validateDefinedTags} from './tags'; +export {getTagsFile} from './tags'; diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index d372b2e2c0f4..c46ff569e81a 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -5,20 +5,97 @@ * LICENSE file in the root directory of this source tree. */ +import path from 'path'; +import fs from 'fs-extra'; import Joi from 'joi'; -import type {TagsFile} from '@docusaurus/utils'; +import YAML from 'js-yaml'; +import type {Tag, TagsFile, TagsFileInput} from '@docusaurus/utils'; -export const tagDefinitionSchema = Joi.object().pattern( +// Tags plugins options shared between docs/blog +export type TagsPluginOptions = { + // TODO rename to tags? + // TODO allow option tags later? | TagsFile; + tagsFilePath: string | false | null | undefined; + // TODO rename to onInlineTags + onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; +}; + +const tagDefinitionSchema = Joi.object().pattern( Joi.string(), Joi.object({ - label: Joi.string().required(), - description: Joi.string().required(), + label: Joi.string(), + description: Joi.string(), permalink: Joi.string(), - }), + }).allow(null), ); -export function validateDefinedTags( - tags: unknown, -): Joi.ValidationResult { +function validateDefinedTags(tags: unknown): Joi.ValidationResult { return tagDefinitionSchema.validate(tags); } + +function ensureUniquePermalinks(tags: TagsFile) { + const permalinks = new Set(); + for (const [, tag] of Object.entries(tags)) { + const {permalink} = tag; + if (permalinks.has(permalink)) { + throw new Error(`Duplicate permalink found: ${permalink}`); + } + permalinks.add(permalink); + } +} + +function normalizeTags(data: TagsFileInput): TagsFile { + const normalizedData: TagsFile = {}; + for (const [key, tag] of Object.entries(data)) { + if (Object.prototype.hasOwnProperty.call(data, key)) { + // Use type assertion to tell TypeScript that tag is of type Partial + const partialTag = tag as Partial; + normalizedData[key] = { + label: partialTag.label || key, + description: partialTag.description || `${key} description`, + permalink: partialTag.permalink || `/${key}`, + }; + } + } + + return normalizedData; +} + +export async function getTagsFile( + options: TagsPluginOptions, + contentPath: string, + // TODO find a better solution +): Promise { + if ( + options.tagsFilePath === false || + options.tagsFilePath === null || + // TODO doesn't work if not set + options.onUnknownTags === 'ignore' // TODO that looks wrong + ) { + return null; + } + const tagDefinitionPath = path.join( + contentPath, + // TODO default value isn't used ? + options.tagsFilePath ? options.tagsFilePath : 'tags.yml', + ); + const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); + // TODO is it fine? + const data = YAML.load(tagDefinitionContent) as TagsFileInput; + const normalizedData = normalizeTags(data); + + // return validateDefinedTags(data); + // TODO + normalize partial input => full input + // TODO unit tests covering all forms of partial inputs + // TODO handle conflicts, verify unique permalink etc + const definedTags = validateDefinedTags(normalizedData); + if (definedTags.error) { + throw new Error( + `There was an error extracting tags from file: ${definedTags.error.message}`, + {cause: definedTags}, + ); + } + ensureUniquePermalinks(definedTags.value); + + return definedTags.value; +} diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 313b5523984a..578d1ec5bdb0 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -53,6 +53,7 @@ export type {URLPath} from './urlUtils'; export { type Tag, type TagsFile, + type TagsFileInput, type NormalizedTag, type TagsListItem, type TagModule, @@ -125,7 +126,6 @@ export { } from './lastUpdateUtils'; export { - getTagsFile, normalizeTags, processFileTagsPath, validateFrontMatterTags, diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 519bc01ff785..12dd6502e3a4 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -5,11 +5,8 @@ * LICENSE file in the root directory of this source tree. */ -import path from 'path'; -import fs from 'fs-extra'; import _ from 'lodash'; import logger from '@docusaurus/logger'; -import YAML from 'js-yaml'; import {normalizeUrl} from './urlUtils'; /** What the user configures. */ @@ -17,7 +14,6 @@ export type Tag = { label: string; /** Permalink to this tag's page, without the `/tags/` base path. */ permalink: string; - // TODO do we use it in practice? description?: string; }; @@ -104,7 +100,7 @@ export function normalizeTag({ }: { tag: FrontMatterTag; tagsPath: string; - tagsFile: TagsFile | undefined; + tagsFile: TagsFile | null; }): NormalizedTag { if (typeof tag === 'string') { const tagDescription = tagsFile?.[tag]; @@ -131,7 +127,7 @@ export function normalizeTags({ frontMatterTags, }: { tagsPath: string; - tagsFile: TagsFile | undefined; + tagsFile: TagsFile | null; frontMatterTags: FrontMatterTag[]; }): NormalizedTag[] { const tags = frontMatterTags.map((tag) => @@ -141,6 +137,7 @@ export function normalizeTags({ // TODO old legacy behavior // emit errors in case of conflicts instead return _.uniqBy(tags, (tag) => tag.permalink); + // return tags; } type TaggedItemGroup = { @@ -250,7 +247,7 @@ export function processFileTagsPath({ source: string; frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; - tagsFile: TagsFile | undefined; + tagsFile: TagsFile | null; }): NormalizedTag[] { const tags = normalizeTags({ tagsPath: versionTagsPath, @@ -266,39 +263,3 @@ export function processFileTagsPath({ return tags; } - -// TODO move to utils-validation -export async function getTagsFile( - options: TagsPluginOptions, - contentPath: string, - // TODO find a better solution - validateDefinedTags: (data: unknown) => TagsFile, -): Promise { - if ( - options.tagsFilePath === false || - options.tagsFilePath === null || - // TODO doesn't work if not set - options.onUnknownTags === 'ignore' // TODO that looks wrong - ) { - return null; - } - const tagDefinitionPath = path.join( - contentPath, - // TODO default value isn't used ? - options.tagsFilePath ? options.tagsFilePath : 'tags.yml', - ); - const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); - const data = YAML.load(tagDefinitionContent); - return validateDefinedTags(data); - // TODO + normalize partial input => full input - // TODO unit tests covering all forms of partial inputs - // TODO handle conflicts, verify unique permalink etc - - // if (definedTags.error) { - // throw new Error( - // `There was an error extracting tags from file: ${definedTags.error.message}`, - // {cause: definedTags}, - // ); - // } - // return definedTags.value; -} diff --git a/yarn.lock b/yarn.lock index 5b26ba4c4359..f20f2f15ef80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7847,10 +7847,10 @@ fs-extra@9.1.0, fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^11.1.0, fs-extra@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== +fs-extra@^11.1.0, fs-extra@^11.1.1, fs-extra@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -15205,16 +15205,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -15313,14 +15304,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -16990,7 +16974,7 @@ workbox-window@7.0.0, workbox-window@^7.0.0: "@types/trusted-types" "^2.0.2" workbox-core "7.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -17008,15 +16992,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From be4b7d078c8f7c2cad33070480bbf8083e65199e Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Fri, 24 May 2024 11:00:17 +0000 Subject: [PATCH 051/142] refactor: apply lint autofix --- packages/docusaurus-utils/src/__tests__/tags.test.ts | 6 ++---- project-words.txt | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index ff7f775b891b..530a81451f93 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -9,11 +9,9 @@ import { groupTaggedItems, getTagVisibility, normalizeTags, - normalizeTag + normalizeTag, } from '../tags'; -import type {TagsFile, Tag, - NormalizedTag, - FrontMatterTag} from '../tags'; +import type {TagsFile, Tag, NormalizedTag, FrontMatterTag} from '../tags'; describe('normalize tags', () => { it('normalize tags', async () => { diff --git a/project-words.txt b/project-words.txt index cc4e06e18cc5..1b0b7fc729b0 100644 --- a/project-words.txt +++ b/project-words.txt @@ -320,7 +320,6 @@ showinfo Sida Simen slorber -sluggified sluggifies sluggify solana From 834367cd1455c6cb41c858cccefe440f065e5279 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 24 May 2024 19:29:25 +0200 Subject: [PATCH 052/142] wip --- package.json | 3 +- .../__snapshots__/index.test.ts.snap | 12 ++ .../src/__tests__/tags.test.ts | 140 ------------------ .../docusaurus-utils-validation/src/tags.ts | 8 +- .../src/__tests__/tags.test.ts | 122 +++++++++++++++ packages/docusaurus-utils/src/tags.ts | 7 +- 6 files changed, 143 insertions(+), 149 deletions(-) delete mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts diff --git a/package.json b/package.json index c9abfeb1997c..26ec1372eb8f 100644 --- a/package.json +++ b/package.json @@ -116,5 +116,6 @@ "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "^29.0.0", "typescript": "~5.4.5" - } + }, + "packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72" } diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index bb4b21574e64..b675307ea080 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -90,6 +90,12 @@ exports[`simple website content 1`] = ` "label": "tag 1", "permalink": "/docs/tags/tag-1", }, + { + "description": undefined, + "inline": true, + "label": "tag-1", + "permalink": "/docs/tags/tag-1", + }, { "description": undefined, "inline": true, @@ -607,6 +613,12 @@ exports[`simple website content: data 1`] = ` "label": "tag 1", "permalink": "/docs/tags/tag-1", }, + { + "description": undefined, + "inline": true, + "label": "tag-1", + "permalink": "/docs/tags/tag-1", + }, { "description": undefined, "inline": true, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts deleted file mode 100644 index d5f50e6686a6..000000000000 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/tags.test.ts +++ /dev/null @@ -1,140 +0,0 @@ -/** - * 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 path from 'path'; -import {fromPartial} from '@total-typescript/shoehorn'; -import {getTagsFile} from '@docusaurus/utils-validation'; -import {processFileTagsPath, validateFrontMatterTags} from '@docusaurus/utils'; -import type {PluginOptions} from '@docusaurus/plugin-content-docs'; -import type {FrontMatterTag} from '@docusaurus/utils'; - -async function getTagsFileDefinition(options: PluginOptions) { - const contentPath = path.join(__dirname, '__fixtures__', 'simple-tags'); - - return getTagsFile( - fromPartial({ - onUnknownTags: options.onUnknownTags, - tagsFilePath: options.tagsFilePath, - }), - contentPath, - ); -} - -const createTest = async ({ - onUnknownTags, - tags, -}: { - onUnknownTags: PluginOptions['onUnknownTags']; - tags: FrontMatterTag[]; -}) => { - const tagsFilePath = 'tags.yml'; - - const definedTags = await getTagsFileDefinition( - fromPartial({ - onUnknownTags, - tagsFilePath, - }), - ); - - return processFileTagsPath({ - tagsFile: definedTags?.value as any, // TODO - options: fromPartial({ - tagsFilePath, - onUnknownTags, - }), - source: 'default.md', - versionTagsPath: '/processFileTagsPath/tags', - frontMatterTags: tags, - }); -}; - -describe('processFileTagsPath', () => { - it('throw when docs has invalid tags', async () => { - const testFn = () => - validateFrontMatterTags( - fromPartial({ - tags: [ - { - label: 'hello', - permalink: 'hello', - inline: true, - }, - { - label: 'world', - permalink: 'world', - inline: true, - }, - ], - source: 'wrong.md', - options: {onUnknownTags: 'throw', tagsFilePath: 'tags.yml'}, - }), - ); - - expect(testFn).toThrowErrorMatchingInlineSnapshot( - `"Tags [hello, world] used in wrong.md are not defined in tags.yml"`, - ); - }); - - it('warns when docs has invalid tags', async () => { - const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); - - validateFrontMatterTags( - fromPartial({ - tags: [ - { - label: 'hello', - permalink: 'hello', - inline: true, - }, - { - label: 'world', - permalink: 'world', - inline: true, - }, - ], - options: {onUnknownTags: 'warn', tagsFilePath: 'tags.yml'}, - }), - ); - - expect(consoleWarnSpy).toHaveBeenCalledTimes(1); - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringMatching(/.*\[WARNING\].*Tags.*/), - ); - consoleWarnSpy.mockRestore(); - }); - - it('ignore when docs has invalid tags', async () => { - const process = createTest({ - tags: ['unknownTag'], - onUnknownTags: 'ignore', - }); - await expect(process).resolves.toBeDefined(); - }); - - it('throw for unknown string and object tag', async () => { - const process = createTest({ - tags: [ - 'open', - 'world', - {label: 'hello', permalink: 'hello'}, - {label: 'open', permalink: 'open'}, - ], - onUnknownTags: 'throw', - }); - await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( - `"Tags [world, hello, open] used in default.md are not defined in tags.yml"`, - ); - }); - - it('does not throw when docs has valid tags', async () => { - const process = createTest({ - tags: ['open'], - onUnknownTags: 'throw', - }); - await expect(process).resolves.toBeDefined(); - }); -}); diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index c46ff569e81a..70cc77cb2fcb 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -33,7 +33,7 @@ function validateDefinedTags(tags: unknown): Joi.ValidationResult { return tagDefinitionSchema.validate(tags); } -function ensureUniquePermalinks(tags: TagsFile) { +function ensureUniquePermalinks(tags: TagsFile): void { const permalinks = new Set(); for (const [, tag] of Object.entries(tags)) { const {permalink} = tag; @@ -51,9 +51,9 @@ function normalizeTags(data: TagsFileInput): TagsFile { // Use type assertion to tell TypeScript that tag is of type Partial const partialTag = tag as Partial; normalizedData[key] = { - label: partialTag.label || key, - description: partialTag.description || `${key} description`, - permalink: partialTag.permalink || `/${key}`, + label: partialTag?.label || key, + description: partialTag?.description || `${key} description`, + permalink: partialTag?.permalink || `/${key}`, }; } } diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 530a81451f93..270c895eb824 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -5,12 +5,17 @@ * LICENSE file in the root directory of this source tree. */ +import path from 'path'; +import {fromPartial} from '@total-typescript/shoehorn'; +import {getTagsFile} from '@docusaurus/utils-validation'; +import {processFileTagsPath, validateFrontMatterTags} from '@docusaurus/utils'; import { groupTaggedItems, getTagVisibility, normalizeTags, normalizeTag, } from '../tags'; +import type {PluginOptions} from '@docusaurus/types'; import type {TagsFile, Tag, NormalizedTag, FrontMatterTag} from '../tags'; describe('normalize tags', () => { @@ -249,3 +254,120 @@ describe('getTagVisibility', () => { }); }); }); + +const createTest = async ({ + onUnknownTags, + tags, +}: { + onUnknownTags: PluginOptions['onUnknownTags']; + tags: FrontMatterTag[]; +}) => { + const tagsFilePath = 'tags.yml'; + const contentPath = path.join(__dirname, '__fixtures__', 'tags'); + + const definedTags = await getTagsFile( + fromPartial({ + onUnknownTags, + tagsFilePath, + }), + contentPath, + ); + + return processFileTagsPath({ + tagsFile: definedTags, + options: fromPartial({ + tagsFilePath, + onUnknownTags, + }), + source: 'default.md', + versionTagsPath: '/processFileTagsPath/tags', + frontMatterTags: tags, + }); +}; + +describe('processFileTagsPath', () => { + it('throw when docs has invalid tags', async () => { + const testFn = () => + validateFrontMatterTags( + fromPartial({ + tags: [ + { + label: 'hello', + permalink: 'hello', + inline: true, + }, + { + label: 'world', + permalink: 'world', + inline: true, + }, + ], + source: 'wrong.md', + options: {onUnknownTags: 'throw', tagsFilePath: 'tags.yml'}, + }), + ); + + expect(testFn).toThrowErrorMatchingInlineSnapshot( + `"Tags [hello, world] used in wrong.md are not defined in tags.yml"`, + ); + }); + + it('warns when docs has invalid tags', async () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); + + validateFrontMatterTags( + fromPartial({ + tags: [ + { + label: 'hello', + permalink: 'hello', + inline: true, + }, + { + label: 'world', + permalink: 'world', + inline: true, + }, + ], + options: {onUnknownTags: 'warn', tagsFilePath: 'tags.yml'}, + }), + ); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(1); + expect(consoleWarnSpy).toHaveBeenCalledWith( + expect.stringMatching(/.*\[WARNING\].*Tags.*/), + ); + consoleWarnSpy.mockRestore(); + }); + + it('ignore when docs has invalid tags', async () => { + const process = createTest({ + tags: ['unknownTag'], + onUnknownTags: 'ignore', + }); + await expect(process).resolves.toBeDefined(); + }); + + it('throw for unknown string and object tag', async () => { + const process = createTest({ + tags: [ + 'open', + 'world', + {label: 'hello', permalink: 'hello'}, + {label: 'open', permalink: 'open'}, + ], + onUnknownTags: 'throw', + }); + await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( + `"Tags [world, hello, open] used in default.md are not defined in tags.yml"`, + ); + }); + + it('does not throw when docs has valid tags', async () => { + const process = createTest({ + tags: ['open'], + onUnknownTags: 'throw', + }); + await expect(process).resolves.toBeDefined(); + }); +}); diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 12dd6502e3a4..28bddd231bad 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -134,10 +134,9 @@ export function normalizeTags({ normalizeTag({tag, tagsPath, tagsFile}), ); - // TODO old legacy behavior - // emit errors in case of conflicts instead - return _.uniqBy(tags, (tag) => tag.permalink); - // return tags; + return tags; + // TODO old legacy behavior emit errors in case of conflicts instead + // return _.uniqBy(tags, (tag) => tag.permalink); } type TaggedItemGroup = { From 38d4934434b6e2dd1afcfd23178e4afeb05ece88 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 13:34:56 +0200 Subject: [PATCH 053/142] wip --- .../docusaurus-utils-validation/package.json | 1 + .../docusaurus-utils-validation/src/tags.ts | 20 +++++------ .../src/__tests__/tags.test.ts | 34 +++++++------------ packages/docusaurus-utils/src/tags.ts | 4 +-- website/_dogfooding/_blog tests/tags.yml | 24 ------------- website/_dogfooding/_docs tests/index.mdx | 2 +- website/_dogfooding/_docs tests/more-test.mdx | 2 +- website/_dogfooding/_docs tests/tags.yml | 26 -------------- website/blog/tags.yml | 32 ----------------- 9 files changed, 26 insertions(+), 119 deletions(-) diff --git a/packages/docusaurus-utils-validation/package.json b/packages/docusaurus-utils-validation/package.json index f7f5ddfc26a5..21cccd26388f 100644 --- a/packages/docusaurus-utils-validation/package.json +++ b/packages/docusaurus-utils-validation/package.json @@ -24,6 +24,7 @@ "fs-extra": "^11.2.0", "joi": "^17.9.2", "js-yaml": "^4.1.0", + "lodash": "^4.17.21", "tslib": "^2.6.0" }, "engines": { diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index 70cc77cb2fcb..970a3c268125 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -7,6 +7,7 @@ import path from 'path'; import fs from 'fs-extra'; +import _ from 'lodash'; import Joi from 'joi'; import YAML from 'js-yaml'; import type {Tag, TagsFile, TagsFileInput} from '@docusaurus/utils'; @@ -33,7 +34,7 @@ function validateDefinedTags(tags: unknown): Joi.ValidationResult { return tagDefinitionSchema.validate(tags); } -function ensureUniquePermalinks(tags: TagsFile): void { +export function ensureUniquePermalinks(tags: TagsFile): void { const permalinks = new Set(); for (const [, tag] of Object.entries(tags)) { const {permalink} = tag; @@ -44,16 +45,16 @@ function ensureUniquePermalinks(tags: TagsFile): void { } } -function normalizeTags(data: TagsFileInput): TagsFile { +export function normalizeTags(data: TagsFileInput): TagsFile { const normalizedData: TagsFile = {}; for (const [key, tag] of Object.entries(data)) { if (Object.prototype.hasOwnProperty.call(data, key)) { // Use type assertion to tell TypeScript that tag is of type Partial const partialTag = tag as Partial; normalizedData[key] = { - label: partialTag?.label || key, + label: partialTag?.label || _.capitalize(key), description: partialTag?.description || `${key} description`, - permalink: partialTag?.permalink || `/${key}`, + permalink: partialTag?.permalink || `/${_.kebabCase(key)}`, }; } } @@ -64,7 +65,6 @@ function normalizeTags(data: TagsFileInput): TagsFile { export async function getTagsFile( options: TagsPluginOptions, contentPath: string, - // TODO find a better solution ): Promise { if ( options.tagsFilePath === false || @@ -82,20 +82,20 @@ export async function getTagsFile( const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); // TODO is it fine? const data = YAML.load(tagDefinitionContent) as TagsFileInput; - const normalizedData = normalizeTags(data); + const definedTags = validateDefinedTags(data); - // return validateDefinedTags(data); // TODO + normalize partial input => full input // TODO unit tests covering all forms of partial inputs // TODO handle conflicts, verify unique permalink etc - const definedTags = validateDefinedTags(normalizedData); if (definedTags.error) { throw new Error( `There was an error extracting tags from file: ${definedTags.error.message}`, {cause: definedTags}, ); } - ensureUniquePermalinks(definedTags.value); + const normalizedData = normalizeTags(definedTags.value); - return definedTags.value; + ensureUniquePermalinks(normalizedData); + + return normalizedData; } diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 270c895eb824..62e65e6eabfa 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -15,8 +15,13 @@ import { normalizeTags, normalizeTag, } from '../tags'; -import type {PluginOptions} from '@docusaurus/types'; -import type {TagsFile, Tag, NormalizedTag, FrontMatterTag} from '../tags'; +import type { + TagsFile, + Tag, + NormalizedTag, + FrontMatterTag, + TagsPluginOptions, +} from '../tags'; describe('normalize tags', () => { it('normalize tags', async () => { @@ -26,24 +31,18 @@ describe('normalize tags', () => { permalink: '/custom-open-source', description: 'Learn about the open source', }, - test: {label: 'Test', permalink: '/custom-test', description: 'Test'}, }; - const tags = [ + const frontMatterTags = [ 'hello', - 'world', - {label: 'hello', permalink: 'hello'}, {label: 'world', permalink: 'world'}, - 'hello', 'open', - {label: 'open', permalink: 'open'}, - 'test', ]; const normalizedTags = normalizeTags({ tagsPath: '/tags', tagsFile, - frontMatterTags: tags, + frontMatterTags, }); const expected: NormalizedTag[] = [ @@ -51,11 +50,13 @@ describe('normalize tags', () => { inline: true, label: 'hello', permalink: '/tags/hello', + description: undefined, }, { inline: true, label: 'world', permalink: '/tags/world', + description: undefined, }, { inline: false, @@ -63,17 +64,6 @@ describe('normalize tags', () => { permalink: '/tags/custom-open-source', description: 'Learn about the open source', }, - { - inline: true, - label: 'open', - permalink: '/tags/open', - }, - { - inline: false, - label: 'Test', - permalink: '/tags/custom-test', - description: 'Test', - }, ]; expect(normalizedTags).toEqual(expected); @@ -259,7 +249,7 @@ const createTest = async ({ onUnknownTags, tags, }: { - onUnknownTags: PluginOptions['onUnknownTags']; + onUnknownTags: TagsPluginOptions['onUnknownTags']; tags: FrontMatterTag[]; }) => { const tagsFilePath = 'tags.yml'; diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 28bddd231bad..9c2f85494334 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -19,7 +19,7 @@ export type Tag = { }; // TODO add TagsFileInput=>TagsFile transformation + unit tests -export type TagsFileInput = Record>; +export type TagsFileInput = Record | null>; export type TagsFile = Record; @@ -135,8 +135,6 @@ export function normalizeTags({ ); return tags; - // TODO old legacy behavior emit errors in case of conflicts instead - // return _.uniqBy(tags, (tag) => tag.permalink); } type TaggedItemGroup = { diff --git a/website/_dogfooding/_blog tests/tags.yml b/website/_dogfooding/_blog tests/tags.yml index d921d71b7784..34bcbdc0f95d 100644 --- a/website/_dogfooding/_blog tests/tags.yml +++ b/website/_dogfooding/_blog tests/tags.yml @@ -1,36 +1,12 @@ paginated-tag: - label: Paginated Tag - description: paginated-tag blog: - label: Blog - description: blog docusaurus: - label: Docusaurus - description: docusaurus long: - label: Long - description: long long-long: - label: Long Long - description: long-long long-long-long: - label: Long Long Long - description: long-long-long long-long-long-long: - label: Long Long Long Long - description: long-long-long-long long-long-long-long-long: - label: Long Long Long Long Long - description: long-long-long-long-long visibility: - label: Visibility - description: visibility unlisted: - label: Unlisted - description: unlisted draft: - label: Draft - description: draft new: - label: New - description: new diff --git a/website/_dogfooding/_docs tests/index.mdx b/website/_dogfooding/_docs tests/index.mdx index 64fcfb7eddbf..a97ed434eff9 100644 --- a/website/_dogfooding/_docs tests/index.mdx +++ b/website/_dogfooding/_docs tests/index.mdx @@ -1,6 +1,6 @@ --- slug: / -tags: [a, b, c, some tag] +tags: [a, b, c] unlisted: true # Makes the navbar link disappear in prod id: index sidebar_label: Docs tests # TODO why is this required? diff --git a/website/_dogfooding/_docs tests/more-test.mdx b/website/_dogfooding/_docs tests/more-test.mdx index 478082818a5e..b46d4e52b98c 100644 --- a/website/_dogfooding/_docs tests/more-test.mdx +++ b/website/_dogfooding/_docs tests/more-test.mdx @@ -1,5 +1,5 @@ --- -tags: [a, e, some-tag, some_tag] +tags: [a, e, some-tag] --- # Another test page diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml index 4cb4d03e5670..d1cc20a91bce 100644 --- a/website/_dogfooding/_docs tests/tags.yml +++ b/website/_dogfooding/_docs tests/tags.yml @@ -1,36 +1,10 @@ a: - label: a - description: a b: - label: b - description: b c: - label: c - description: c e: - label: e - description: e -some tag: - label: some tag - description: some tag some-tag: - label: some-tag - description: some-tag -some_tag: - label: some_tag - description: some_tag visibility: - label: visibility - description: visibility draft: - label: draft - description: draft listed: - label: listed - description: listed unlisted: - label: unlisted - description: unlisted d-custom-permalink: - label: d-custom-permalink - description: d-custom-permalink diff --git a/website/blog/tags.yml b/website/blog/tags.yml index 36fbae317636..1666e3c54c0b 100644 --- a/website/blog/tags.yml +++ b/website/blog/tags.yml @@ -1,48 +1,16 @@ blog: - label: blog - description: blog release: - label: Release - description: release recap: - label: Recap - description: recap birth: - label: Birth - description: birth endi: - label: Endi - description: endi tribute: - label: Tribute - description: tribute i18n: - label: I18n - description: i18n beta: - label: Beta - description: beta search: - label: Search - description: search maintenance: - label: Maintenance - description: maintenance documentation: - label: Documentation - description: documentation docusaurus: - label: Docusaurus - description: docusaurus profilo: - label: Profilo - description: profilo adoption: - label: Adoption - description: adoption unlisted: - label: Unlisted - description: unlisted new: - label: New - description: new From af278d4de3b635c148be96f5e3c2c5e70c25fb6f Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 13:41:14 +0200 Subject: [PATCH 054/142] wip --- .../src/__tests__/index.test.ts | 6 + .../src/__tests__/docs.test.ts | 18 ++- .../src/__tests__/tags.test.ts | 114 ++++++++++++++++++ .../src/__tests__/__fixtures__/tags/tags.yml | 7 ++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 packages/docusaurus-utils-validation/src/__tests__/tags.test.ts create mode 100644 packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index 899aa3014abb..c2dc1e9423eb 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -187,6 +187,8 @@ describe('blog plugin', () => { prevItem: undefined, tags: [ { + description: undefined, + inline: true, label: 'date', permalink: '/blog/tags/date', }, @@ -268,10 +270,14 @@ describe('blog plugin', () => { }, tags: [ { + description: undefined, + inline: true, label: 'date', permalink: '/blog/tags/date', }, { + description: undefined, + inline: true, label: 'complex', permalink: '/blog/tags/complex', }, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index 367ac625b897..8107e78f05ea 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -362,12 +362,20 @@ describe('simple site', () => { }, tags: [ { + description: undefined, + inline: true, label: 'tag 1', + permalink: '/docs/tags/tag-1', + }, + { + description: undefined, inline: true, + label: 'tag-1', permalink: '/docs/tags/tag-1', }, { label: 'tag 2', + description: undefined, inline: true, permalink: '/docs/tags/tag2-custom-permalink', }, @@ -439,13 +447,21 @@ describe('simple site', () => { }, tags: [ { + description: undefined, + inline: true, label: 'tag 1', + permalink: '/docs/tags/tag-1', + }, + { + description: undefined, inline: true, + label: 'tag-1', permalink: '/docs/tags/tag-1', }, { - label: 'tag 2', + description: undefined, inline: true, + label: 'tag 2', permalink: '/docs/tags/tag2-custom-permalink', }, ], diff --git a/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts new file mode 100644 index 000000000000..0377e18ecdd8 --- /dev/null +++ b/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts @@ -0,0 +1,114 @@ +/** + * 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 {ensureUniquePermalinks, normalizeTags} from '../../lib/tags'; + +describe('ensureUniquePermalinks', () => { + it('throw when duplicate permalink found', () => { + const definedTags = { + open: { + label: 'Open Source', + permalink: '/custom-open-source', + description: 'Learn about the open source', + }, + closed: { + label: 'Closed Source', + permalink: '/custom-open-source', + description: 'Learn about the closed source', + }, + world: { + label: 'World', + permalink: '/world', + description: 'Learn about the world', + }, + world2: { + label: 'World', + permalink: '/world', + description: 'Learn about the world', + }, + }; + + expect(() => + ensureUniquePermalinks(definedTags), + ).toThrowErrorMatchingInlineSnapshot( + `"Duplicate permalink found: /custom-open-source"`, + ); + }); +}); + +describe('normalizeTags', () => { + it('normalize null tag', () => { + const input = { + 'kebab case test': null, + }; + + const expectedOutput = { + 'kebab case test': { + description: 'kebab case test description', + label: 'Kebab case test', + permalink: '/kebab-case-test', + }, + }; + + expect(normalizeTags(input)).toEqual(expectedOutput); + }); + + it('normalize permalink and description', () => { + const input = { + world: {label: 'WORLD'}, + }; + + const expectedOutput = { + world: { + description: 'world description', + label: 'WORLD', + permalink: '/world', + }, + }; + + expect(normalizeTags(input)).toEqual(expectedOutput); + }); + + it('normalize kebab case permalink and capitalize label', () => { + const input = { + 'kebab case': null, + }; + + const expectedOutput = { + 'kebab case': { + description: 'kebab case description', + label: 'Kebab case', + permalink: '/kebab-case', + }, + }; + + expect(normalizeTags(input)).toEqual(expectedOutput); + }); + + it('normalize test', () => { + const input = { + world: {permalink: 'aze'}, + hello: {permalink: 'h e l l o'}, + }; + + const expectedOutput = { + world: { + description: 'world description', + label: 'World', + permalink: 'aze', + }, + hello: { + description: 'hello description', + label: 'Hello', + // TODO should we allow this ? + permalink: 'h e l l o', + }, + }; + + expect(normalizeTags(input)).toEqual(expectedOutput); + }); +}); diff --git a/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml b/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml new file mode 100644 index 000000000000..4cb3b2579d69 --- /dev/null +++ b/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml @@ -0,0 +1,7 @@ +hello: + permalink: /hellllo +test: + label: Test +testdesc: + description: Nothing to see +open: From 789574b0a6f5618f086a1fff3518857752dc0627 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 13:56:01 +0200 Subject: [PATCH 055/142] refactor unique permalinks --- .../src/__tests__/tags.test.ts | 2 +- packages/docusaurus-utils-validation/src/tags.ts | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts index 0377e18ecdd8..790f5cd4d2b0 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts @@ -35,7 +35,7 @@ describe('ensureUniquePermalinks', () => { expect(() => ensureUniquePermalinks(definedTags), ).toThrowErrorMatchingInlineSnapshot( - `"Duplicate permalink found: /custom-open-source"`, + `"Duplicate permalinks found: /custom-open-source, /world"`, ); }); }); diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index 970a3c268125..9cee1432fa2c 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -36,12 +36,21 @@ function validateDefinedTags(tags: unknown): Joi.ValidationResult { export function ensureUniquePermalinks(tags: TagsFile): void { const permalinks = new Set(); + const duplicates = new Set(); + for (const [, tag] of Object.entries(tags)) { const {permalink} = tag; if (permalinks.has(permalink)) { - throw new Error(`Duplicate permalink found: ${permalink}`); + duplicates.add(permalink); + } else { + permalinks.add(permalink); } - permalinks.add(permalink); + } + + if (duplicates.size > 0) { + throw new Error( + `Duplicate permalinks found: ${Array.from(duplicates).join(', ')}`, + ); } } From 89affc8665ba73006b90bfa3283955faa72e326b Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 14:09:26 +0200 Subject: [PATCH 056/142] remove unwanted change --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 26ec1372eb8f..c9abfeb1997c 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,5 @@ "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "^29.0.0", "typescript": "~5.4.5" - }, - "packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72" + } } From 13e8b32a01652ff0bf84c6d756012dc823e38efb Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 14:20:48 +0200 Subject: [PATCH 057/142] renaming --- .../src/__tests__/feed.test.ts | 20 +++++----- .../src/__tests__/index.test.ts | 4 +- .../src/options.ts | 12 +++--- .../src/options.ts | 12 +++--- .../docusaurus-utils-validation/src/tags.ts | 24 +++++------- .../src/__tests__/tags.test.ts | 37 ++++++++++--------- packages/docusaurus-utils/src/tags.ts | 14 +++---- website/_dogfooding/dogfooding.config.ts | 8 ++-- 8 files changed, 64 insertions(+), 67 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts index 8e91ef628a8d..9f76d72a144e 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts @@ -100,8 +100,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, - onUnknownTags: 'ignore', - tagsFilePath: false, + onInlineTags: 'ignore', + tags: false, } as PluginOptions, ); @@ -143,8 +143,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, - onUnknownTags: 'ignore', - tagsFilePath: false, + onInlineTags: 'ignore', + tags: false, } as PluginOptions, ); @@ -198,8 +198,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, - onUnknownTags: 'ignore', - tagsFilePath: false, + onInlineTags: 'ignore', + tags: false, } as PluginOptions, ); @@ -244,8 +244,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, - onUnknownTags: 'ignore', - tagsFilePath: false, + onInlineTags: 'ignore', + tags: false, } as PluginOptions, ); @@ -290,8 +290,8 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), truncateMarker: //, - onUnknownTags: 'ignore', - tagsFilePath: false, + onInlineTags: 'ignore', + tags: false, } as PluginOptions, ); diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index c2dc1e9423eb..a32b5b5a218f 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -521,8 +521,8 @@ describe('blog plugin', () => { postsPerPage: 1, processBlogPosts: async ({blogPosts}) => blogPosts.filter((blog) => blog.metadata.tags[0]?.label === 'tag1'), - onUnknownTags: 'ignore', - tagsFilePath: false, + onInlineTags: 'ignore', + tags: false, }, DefaultI18N, ); diff --git a/packages/docusaurus-plugin-content-blog/src/options.ts b/packages/docusaurus-plugin-content-blog/src/options.ts index ea5ba788b4fc..464a2f135c9d 100644 --- a/packages/docusaurus-plugin-content-blog/src/options.ts +++ b/packages/docusaurus-plugin-content-blog/src/options.ts @@ -54,8 +54,8 @@ export const DEFAULT_OPTIONS: PluginOptions = { showLastUpdateTime: false, showLastUpdateAuthor: false, processBlogPosts: async () => undefined, - onUnknownTags: 'warn', - tagsFilePath: false, + onInlineTags: 'warn', + tags: false, }; const PluginOptionSchema = Joi.object({ @@ -146,13 +146,13 @@ const PluginOptionSchema = Joi.object({ processBlogPosts: Joi.function() .optional() .default(() => DEFAULT_OPTIONS.processBlogPosts), - onUnknownTags: Joi.string() + onInlineTags: Joi.string() .equal('ignore', 'log', 'warn', 'throw') - .default(DEFAULT_OPTIONS.onUnknownTags), - tagsFilePath: Joi.string() + .default(DEFAULT_OPTIONS.onInlineTags), + tags: Joi.string() .disallow('') .allow(null, false) - .default(DEFAULT_OPTIONS.tagsFilePath), + .default(DEFAULT_OPTIONS.tags), }).default(DEFAULT_OPTIONS); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index abc53f582e26..50dc1f9f2319 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -54,8 +54,8 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsible: true, sidebarCollapsed: true, breadcrumbs: true, - onUnknownTags: 'warn', - tagsFilePath: false, + onInlineTags: 'warn', + tags: false, }; const VersionOptionsSchema = Joi.object({ @@ -142,13 +142,13 @@ const OptionsSchema = Joi.object({ lastVersion: Joi.string().optional(), versions: VersionsOptionsSchema, breadcrumbs: Joi.bool().default(DEFAULT_OPTIONS.breadcrumbs), - onUnknownTags: Joi.string() + onInlineTags: Joi.string() .equal('ignore', 'log', 'warn', 'throw') - .default(DEFAULT_OPTIONS.onUnknownTags), - tagsFilePath: Joi.string() + .default(DEFAULT_OPTIONS.onInlineTags), + tags: Joi.string() .disallow('') .allow(null, false) - .default(DEFAULT_OPTIONS.tagsFilePath), + .default(DEFAULT_OPTIONS.tags), }); export function validateOptions({ diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index 9cee1432fa2c..b136edfb6233 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -10,16 +10,12 @@ import fs from 'fs-extra'; import _ from 'lodash'; import Joi from 'joi'; import YAML from 'js-yaml'; -import type {Tag, TagsFile, TagsFileInput} from '@docusaurus/utils'; - -// Tags plugins options shared between docs/blog -export type TagsPluginOptions = { - // TODO rename to tags? - // TODO allow option tags later? | TagsFile; - tagsFilePath: string | false | null | undefined; - // TODO rename to onInlineTags - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; -}; +import type { + Tag, + TagsFile, + TagsFileInput, + TagsPluginOptions, +} from '@docusaurus/utils'; const tagDefinitionSchema = Joi.object().pattern( Joi.string(), @@ -76,17 +72,17 @@ export async function getTagsFile( contentPath: string, ): Promise { if ( - options.tagsFilePath === false || - options.tagsFilePath === null || + options.tags === false || + options.tags === null || // TODO doesn't work if not set - options.onUnknownTags === 'ignore' // TODO that looks wrong + options.onInlineTags === 'ignore' // TODO that looks wrong ) { return null; } const tagDefinitionPath = path.join( contentPath, // TODO default value isn't used ? - options.tagsFilePath ? options.tagsFilePath : 'tags.yml', + options.tags ? options.tags : 'tags.yml', ); const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); // TODO is it fine? diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 62e65e6eabfa..e486e3b0518f 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -23,6 +23,7 @@ import type { TagsPluginOptions, } from '../tags'; +// TODO one by one test small describe('normalize tags', () => { it('normalize tags', async () => { const tagsFile: TagsFile = { @@ -246,19 +247,19 @@ describe('getTagVisibility', () => { }); const createTest = async ({ - onUnknownTags, - tags, + onInlineTags, + frontMatterTags, }: { - onUnknownTags: TagsPluginOptions['onUnknownTags']; - tags: FrontMatterTag[]; + onInlineTags: TagsPluginOptions['onInlineTags']; + frontMatterTags: FrontMatterTag[]; }) => { - const tagsFilePath = 'tags.yml'; + const tagFile = 'tags.yml'; const contentPath = path.join(__dirname, '__fixtures__', 'tags'); const definedTags = await getTagsFile( fromPartial({ - onUnknownTags, - tagsFilePath, + onInlineTags, + tags: tagFile, }), contentPath, ); @@ -266,12 +267,12 @@ const createTest = async ({ return processFileTagsPath({ tagsFile: definedTags, options: fromPartial({ - tagsFilePath, - onUnknownTags, + tags: tagFile, + onInlineTags, }), source: 'default.md', versionTagsPath: '/processFileTagsPath/tags', - frontMatterTags: tags, + frontMatterTags, }); }; @@ -293,7 +294,7 @@ describe('processFileTagsPath', () => { }, ], source: 'wrong.md', - options: {onUnknownTags: 'throw', tagsFilePath: 'tags.yml'}, + options: {onInlineTags: 'throw', tags: 'tags.yml'}, }), ); @@ -319,7 +320,7 @@ describe('processFileTagsPath', () => { inline: true, }, ], - options: {onUnknownTags: 'warn', tagsFilePath: 'tags.yml'}, + options: {onInlineTags: 'warn', tags: 'tags.yml'}, }), ); @@ -332,21 +333,21 @@ describe('processFileTagsPath', () => { it('ignore when docs has invalid tags', async () => { const process = createTest({ - tags: ['unknownTag'], - onUnknownTags: 'ignore', + frontMatterTags: ['unknownTag'], + onInlineTags: 'ignore', }); await expect(process).resolves.toBeDefined(); }); it('throw for unknown string and object tag', async () => { const process = createTest({ - tags: [ + frontMatterTags: [ 'open', 'world', {label: 'hello', permalink: 'hello'}, {label: 'open', permalink: 'open'}, ], - onUnknownTags: 'throw', + onInlineTags: 'throw', }); await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( `"Tags [world, hello, open] used in default.md are not defined in tags.yml"`, @@ -355,8 +356,8 @@ describe('processFileTagsPath', () => { it('does not throw when docs has valid tags', async () => { const process = createTest({ - tags: ['open'], - onUnknownTags: 'throw', + frontMatterTags: ['open'], + onInlineTags: 'throw', }); await expect(process).resolves.toBeDefined(); }); diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 9c2f85494334..5963c2fee9a5 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -11,8 +11,10 @@ import {normalizeUrl} from './urlUtils'; /** What the user configures. */ export type Tag = { + // TODO isn't it also possibly undefiend ? (label?: string) label: string; /** Permalink to this tag's page, without the `/tags/` base path. */ + // TODO same as label comment? permalink: string; // TODO do we use it in practice? description?: string; @@ -25,11 +27,9 @@ export type TagsFile = Record; // Tags plugins options shared between docs/blog export type TagsPluginOptions = { - // TODO rename to tags? // TODO allow option tags later? | TagsFile; - tagsFilePath: string | false | null | undefined; - // TODO rename to onInlineTags - onUnknownTags: 'ignore' | 'log' | 'warn' | 'throw'; + tags: string | false | null | undefined; + onInlineTags: 'ignore' | 'log' | 'warn' | 'throw'; }; export type NormalizedTag = Tag & { @@ -224,11 +224,11 @@ export function validateFrontMatterTags({ options: TagsPluginOptions; }): void { const inlineTags = tags.filter((tag) => tag.inline); - if (inlineTags.length > 0 && options.onUnknownTags !== 'ignore') { + if (inlineTags.length > 0 && options.onInlineTags !== 'ignore') { const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; const tagListString = uniqueUnknownTags.join(', '); - logger.report(options.onUnknownTags)( - `Tags [${tagListString}] used in ${source} are not defined in ${options.tagsFilePath}`, + logger.report(options.onInlineTags)( + `Tags [${tagListString}] used in ${source} are not defined in ${options.tags}`, ); } } diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index a0c5ec375001..d751ced7ec0a 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -40,8 +40,8 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ noIndex: true, }, }, - onUnknownTags: 'warn', - tagsFilePath: 'tags.yml', + onInlineTags: 'warn', + tags: 'tags.yml', // Using a _ prefix to test against an edge case regarding MDX partials: https://github.com/facebook/docusaurus/discussions/5181#discussioncomment-1018079 path: '_dogfooding/_docs tests', @@ -83,8 +83,8 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ frontMatter.hide_reading_time ? undefined : defaultReadingTime({content, options: {wordsPerMinute: 5}}), - onUnknownTags: 'warn', - tagsFilePath: 'tags.yml', + onInlineTags: 'warn', + tags: 'tags.yml', } satisfies BlogOptions, ], From c473da682237752994735e992c23df431e45e65d Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 14:22:02 +0200 Subject: [PATCH 058/142] update config --- website/docusaurus.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 9b3785b3d838..3cd2f548b70a 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -466,8 +466,8 @@ export default async function createConfigAsync() { label: `${getNextVersionName()} 🚧`, }, }, - tagsFilePath: 'tags.yml', - onUnknownTags: 'ignore', + tags: 'tags.yml', + onInlineTags: 'ignore', }, blog: { // routeBasePath: '/', @@ -490,8 +490,8 @@ export default async function createConfigAsync() { blogDescription: 'Read blog posts about Docusaurus from the team', blogSidebarCount: 'ALL', blogSidebarTitle: 'All our posts', - onUnknownTags: 'warn', - tagsFilePath: 'tags.yml', + onInlineTags: 'warn', + tags: 'tags.yml', } satisfies BlogOptions, pages: { remarkPlugins: [npm2yarn], From 44659c0a51e2e6b7795d78611d72559855370e1f Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 15:08:32 +0200 Subject: [PATCH 059/142] refactor feature behavior based on options --- .../docusaurus-utils-validation/src/tags.ts | 51 +++++++++++-------- packages/docusaurus-utils/src/tags.ts | 10 +++- website/docusaurus.config.ts | 4 -- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index b136edfb6233..9b7d112d32a9 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -71,36 +71,43 @@ export async function getTagsFile( options: TagsPluginOptions, contentPath: string, ): Promise { + const filename = options.tags || 'tags.yml'; + const tagDefinitionPath = path.join(contentPath, filename); + const isFileExists = await fs.pathExists(tagDefinitionPath); + if ( - options.tags === false || - options.tags === null || - // TODO doesn't work if not set - options.onInlineTags === 'ignore' // TODO that looks wrong + (options.tags === false || + options.tags === null || + options.tags === undefined) && + !isFileExists ) { return null; } - const tagDefinitionPath = path.join( - contentPath, - // TODO default value isn't used ? - options.tags ? options.tags : 'tags.yml', - ); + const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); - // TODO is it fine? + if (!tagDefinitionContent.trim()) { + throw new Error(`Tags file at path ${tagDefinitionPath} is empty`); + } + // TODO is it fine to use as TagsFileInput? const data = YAML.load(tagDefinitionContent) as TagsFileInput; const definedTags = validateDefinedTags(data); - // TODO + normalize partial input => full input - // TODO unit tests covering all forms of partial inputs - // TODO handle conflicts, verify unique permalink etc - if (definedTags.error) { - throw new Error( - `There was an error extracting tags from file: ${definedTags.error.message}`, - {cause: definedTags}, - ); - } - const normalizedData = normalizeTags(definedTags.value); + if (options.onInlineTags !== 'ignore') { + // TODO + normalize partial input => full input + // TODO unit tests covering all forms of partial inputs + // TODO handle conflicts, verify unique permalink etc + if (definedTags.error) { + throw new Error( + `There was an error extracting tags from file: ${definedTags.error.message}`, + {cause: definedTags}, + ); + } + const normalizedData = normalizeTags(definedTags.value); - ensureUniquePermalinks(normalizedData); + ensureUniquePermalinks(normalizedData); - return normalizedData; + return normalizedData; + } + + return null; } diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 5963c2fee9a5..6ebd6ee18a20 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -245,7 +245,15 @@ export function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; tagsFile: TagsFile | null; -}): NormalizedTag[] { +}): NormalizedTag[] | FrontMatterTag[] { + if (tagsFile === null) { + return normalizeTags({ + tagsPath: versionTagsPath, + tagsFile: null, + frontMatterTags: frontMatterTags ?? [], + }); + } + const tags = normalizeTags({ tagsPath: versionTagsPath, tagsFile, diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 3cd2f548b70a..aae27b1a4d8e 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -466,8 +466,6 @@ export default async function createConfigAsync() { label: `${getNextVersionName()} 🚧`, }, }, - tags: 'tags.yml', - onInlineTags: 'ignore', }, blog: { // routeBasePath: '/', @@ -490,8 +488,6 @@ export default async function createConfigAsync() { blogDescription: 'Read blog posts about Docusaurus from the team', blogSidebarCount: 'ALL', blogSidebarTitle: 'All our posts', - onInlineTags: 'warn', - tags: 'tags.yml', } satisfies BlogOptions, pages: { remarkPlugins: [npm2yarn], From fcef89cf797041dfe7dde3da080446347dac20dd Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 15:24:09 +0200 Subject: [PATCH 060/142] TODO annotation for blog types --- .../docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index a9e78d5c9b45..69670ac2b463 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -97,6 +97,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the * Front matter tags, unnormalized. * @see {@link BlogPostMetadata.tags} */ + // TODO NormalizedTag ?? tags?: FrontMatterTag[]; /** Custom slug appended after `///` */ slug?: string; From 20ab63ecdd5effdc4f5305c8fc562311e866dd21 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 27 May 2024 15:33:01 +0200 Subject: [PATCH 061/142] fix types --- packages/docusaurus-utils/src/tags.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 6ebd6ee18a20..e2ff47d8317f 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -245,7 +245,7 @@ export function processFileTagsPath({ frontMatterTags: FrontMatterTag[] | undefined; versionTagsPath: string; tagsFile: TagsFile | null; -}): NormalizedTag[] | FrontMatterTag[] { +}): NormalizedTag[] { if (tagsFile === null) { return normalizeTags({ tagsPath: versionTagsPath, From ecda5c026091f4dbd310eb21c8509719386e41e1 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Mon, 27 May 2024 13:37:41 +0000 Subject: [PATCH 062/142] refactor: apply lint autofix --- project-words.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/project-words.txt b/project-words.txt index 1b0b7fc729b0..d3bbe445bd50 100644 --- a/project-words.txt +++ b/project-words.txt @@ -119,6 +119,7 @@ hasura Hasura Heavener Héctor +hellllo héllô hideable Hideable @@ -354,6 +355,7 @@ SVGR swizzlable Teik templating +testdesc Thanos Therox toolset @@ -373,6 +375,7 @@ typesafe typesense Typesense Unavatar +undefiend unlinkable unlisteds Unlisteds From 095a3916e7e9a592e8fca4a4274de32a4b5ce3a5 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 09:29:03 +0200 Subject: [PATCH 063/142] fix behavior --- .../src/options.ts | 4 ++-- .../src/options.ts | 4 ++-- .../docusaurus-utils-validation/src/tags.ts | 20 +++++++++---------- website/docusaurus.config.ts | 1 + 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/options.ts b/packages/docusaurus-plugin-content-blog/src/options.ts index 464a2f135c9d..5835c32fc18f 100644 --- a/packages/docusaurus-plugin-content-blog/src/options.ts +++ b/packages/docusaurus-plugin-content-blog/src/options.ts @@ -55,7 +55,7 @@ export const DEFAULT_OPTIONS: PluginOptions = { showLastUpdateAuthor: false, processBlogPosts: async () => undefined, onInlineTags: 'warn', - tags: false, + tags: undefined, }; const PluginOptionSchema = Joi.object({ @@ -152,7 +152,7 @@ const PluginOptionSchema = Joi.object({ tags: Joi.string() .disallow('') .allow(null, false) - .default(DEFAULT_OPTIONS.tags), + .default(() => DEFAULT_OPTIONS.tags), }).default(DEFAULT_OPTIONS); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index 50dc1f9f2319..329341b5e5f7 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -55,7 +55,7 @@ export const DEFAULT_OPTIONS: Omit = { sidebarCollapsed: true, breadcrumbs: true, onInlineTags: 'warn', - tags: false, + tags: undefined, }; const VersionOptionsSchema = Joi.object({ @@ -148,7 +148,7 @@ const OptionsSchema = Joi.object({ tags: Joi.string() .disallow('') .allow(null, false) - .default(DEFAULT_OPTIONS.tags), + .default(() => DEFAULT_OPTIONS.tags), }); export function validateOptions({ diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index 9b7d112d32a9..7937fd220cea 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -76,10 +76,9 @@ export async function getTagsFile( const isFileExists = await fs.pathExists(tagDefinitionPath); if ( - (options.tags === false || - options.tags === null || - options.tags === undefined) && - !isFileExists + options.tags === false || + options.tags === null || + (options.tags === undefined && !isFileExists) ) { return null; } @@ -92,16 +91,17 @@ export async function getTagsFile( const data = YAML.load(tagDefinitionContent) as TagsFileInput; const definedTags = validateDefinedTags(data); + if (definedTags.error) { + throw new Error( + `There was an error extracting tags from file: ${definedTags.error.message}`, + {cause: definedTags}, + ); + } + if (options.onInlineTags !== 'ignore') { // TODO + normalize partial input => full input // TODO unit tests covering all forms of partial inputs // TODO handle conflicts, verify unique permalink etc - if (definedTags.error) { - throw new Error( - `There was an error extracting tags from file: ${definedTags.error.message}`, - {cause: definedTags}, - ); - } const normalizedData = normalizeTags(definedTags.value); ensureUniquePermalinks(normalizedData); diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index f42da17542bd..f84786d10e73 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -492,6 +492,7 @@ export default async function createConfigAsync() { blogDescription: 'Read blog posts about Docusaurus from the team', blogSidebarCount: 'ALL', blogSidebarTitle: 'All our posts', + onInlineTags: 'throw', } satisfies BlogOptions, pages: { remarkPlugins: [npm2yarn], From 7e5eb8e5711b1a6623e79123f86fb2f1e7223329 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 10:07:57 +0200 Subject: [PATCH 064/142] wip tests --- .../src/__tests__/tags.test.ts | 150 +++++++++++++++--- .../docusaurus-utils-validation/src/tags.ts | 4 +- 2 files changed, 126 insertions(+), 28 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts index 790f5cd4d2b0..6fca7c40c400 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts @@ -6,10 +6,11 @@ */ import {ensureUniquePermalinks, normalizeTags} from '../../lib/tags'; +import type {TagsFile, TagsFileInput} from '@docusaurus/utils'; describe('ensureUniquePermalinks', () => { - it('throw when duplicate permalink found', () => { - const definedTags = { + it('throw when one duplicate permalink found', () => { + const definedTags: TagsFile = { open: { label: 'Open Source', permalink: '/custom-open-source', @@ -20,14 +21,35 @@ describe('ensureUniquePermalinks', () => { permalink: '/custom-open-source', description: 'Learn about the closed source', }, - world: { - label: 'World', - permalink: '/world', - description: 'Learn about the world', + }; + + expect(() => + ensureUniquePermalinks(definedTags), + ).toThrowErrorMatchingInlineSnapshot( + `"Duplicate permalinks found: /custom-open-source"`, + ); + }); + + it('throw when multiple duplicate permalink found', () => { + const definedTags: TagsFile = { + open: { + label: 'Open Source', + permalink: '/custom-open-source', + description: 'Learn about the open source', }, - world2: { - label: 'World', - permalink: '/world', + closed: { + label: 'Closed Source', + permalink: '/custom-open-source', + description: 'Learn about the closed source', + }, + hello: { + label: 'Hello', + permalink: '/hello', + description: 'Learn about the hello', + }, + world: { + label: 'Hello', + permalink: '/hello', description: 'Learn about the world', }, }; @@ -35,20 +57,37 @@ describe('ensureUniquePermalinks', () => { expect(() => ensureUniquePermalinks(definedTags), ).toThrowErrorMatchingInlineSnapshot( - `"Duplicate permalinks found: /custom-open-source, /world"`, + `"Duplicate permalinks found: /custom-open-source, /hello"`, ); }); + + it('do not throw when no duplicate permalink found', () => { + const definedTags: TagsFile = { + open: { + label: 'Open Source', + permalink: '/open-source', + description: 'Learn about the open source', + }, + closed: { + label: 'Closed Source', + permalink: '/closed-source', + description: 'Learn about the closed source', + }, + }; + + expect(() => ensureUniquePermalinks(definedTags)).not.toThrow(); + }); }); describe('normalizeTags', () => { it('normalize null tag', () => { - const input = { + const input: TagsFileInput = { 'kebab case test': null, }; const expectedOutput = { 'kebab case test': { - description: 'kebab case test description', + description: 'kebab case test default description', label: 'Kebab case test', permalink: '/kebab-case-test', }, @@ -57,14 +96,14 @@ describe('normalizeTags', () => { expect(normalizeTags(input)).toEqual(expectedOutput); }); - it('normalize permalink and description', () => { - const input = { + it('normalize partial tag with label', () => { + const input: TagsFileInput = { world: {label: 'WORLD'}, }; const expectedOutput = { world: { - description: 'world description', + description: 'world default description', label: 'WORLD', permalink: '/world', }, @@ -73,39 +112,98 @@ describe('normalizeTags', () => { expect(normalizeTags(input)).toEqual(expectedOutput); }); - it('normalize kebab case permalink and capitalize label', () => { + it('normalize partial tag with description', () => { + const input: TagsFileInput = { + world: {description: 'World description test'}, + }; + + const expectedOutput = { + world: { + description: 'World description test', + label: 'World', + permalink: '/world', + }, + }; + + expect(normalizeTags(input)).toEqual(expectedOutput); + }); + + it('normalize partial tag with permalink', () => { + const input: TagsFileInput = { + world: {permalink: 'world'}, + }; + + const expectedOutput = { + world: { + description: 'world default description', + label: 'World', + permalink: 'world', + }, + }; + + expect(normalizeTags(input)).toEqual(expectedOutput); + }); + + it('does not modify fully defined tags', () => { + const input = { + tag1: { + label: 'Custom Label', + description: 'Custom Description', + permalink: 'custom-permalink', + }, + }; + + expect(normalizeTags(input)).toEqual(input); + }); + + it('handle special characters in keys', () => { const input = { - 'kebab case': null, + 'special@char$!key': null, }; const expectedOutput = { - 'kebab case': { - description: 'kebab case description', - label: 'Kebab case', - permalink: '/kebab-case', + 'special@char$!key': { + description: 'special@char$!key default description', + label: 'Special@char$!key', + permalink: '/special-char-key', }, }; expect(normalizeTags(input)).toEqual(expectedOutput); }); - it('normalize test', () => { + it('handle special characters in keys with chinese characters', () => { const input = { + 特殊字符测试: null, + }; + + const expectedOutput = { + 特殊字符测试: { + description: '特殊字符测试 default description', + label: '特殊字符测试', + permalink: '/特殊字符测试', + }, + }; + + expect(normalizeTags(input)).toEqual(expectedOutput); + }); + + it('normalize test', () => { + const input: TagsFileInput = { world: {permalink: 'aze'}, hello: {permalink: 'h e l l o'}, }; const expectedOutput = { world: { - description: 'world description', + description: 'world default description', label: 'World', permalink: 'aze', }, hello: { - description: 'hello description', + description: 'hello default description', label: 'Hello', - // TODO should we allow this ? - permalink: 'h e l l o', + permalink: 'h-e-l-l-o', }, }; diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tags.ts index 7937fd220cea..ba8d5dc6a296 100644 --- a/packages/docusaurus-utils-validation/src/tags.ts +++ b/packages/docusaurus-utils-validation/src/tags.ts @@ -58,8 +58,8 @@ export function normalizeTags(data: TagsFileInput): TagsFile { const partialTag = tag as Partial; normalizedData[key] = { label: partialTag?.label || _.capitalize(key), - description: partialTag?.description || `${key} description`, - permalink: partialTag?.permalink || `/${_.kebabCase(key)}`, + description: partialTag?.description || `${key} default description`, + permalink: _.kebabCase(partialTag?.permalink) || `/${_.kebabCase(key)}`, }; } } From 27fff1928f928ca5c5378c2dac203ded910e71ab Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 10:56:57 +0200 Subject: [PATCH 065/142] wip tests --- .../src/__tests__/tags.test.ts | 68 +++++++++---------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index e486e3b0518f..72b1fbba5f28 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -6,7 +6,6 @@ */ import path from 'path'; -import {fromPartial} from '@total-typescript/shoehorn'; import {getTagsFile} from '@docusaurus/utils-validation'; import {processFileTagsPath, validateFrontMatterTags} from '@docusaurus/utils'; import { @@ -257,19 +256,19 @@ const createTest = async ({ const contentPath = path.join(__dirname, '__fixtures__', 'tags'); const definedTags = await getTagsFile( - fromPartial({ + { onInlineTags, tags: tagFile, - }), + }, contentPath, ); return processFileTagsPath({ tagsFile: definedTags, - options: fromPartial({ + options: { tags: tagFile, onInlineTags, - }), + }, source: 'default.md', versionTagsPath: '/processFileTagsPath/tags', frontMatterTags, @@ -279,35 +278,7 @@ const createTest = async ({ describe('processFileTagsPath', () => { it('throw when docs has invalid tags', async () => { const testFn = () => - validateFrontMatterTags( - fromPartial({ - tags: [ - { - label: 'hello', - permalink: 'hello', - inline: true, - }, - { - label: 'world', - permalink: 'world', - inline: true, - }, - ], - source: 'wrong.md', - options: {onInlineTags: 'throw', tags: 'tags.yml'}, - }), - ); - - expect(testFn).toThrowErrorMatchingInlineSnapshot( - `"Tags [hello, world] used in wrong.md are not defined in tags.yml"`, - ); - }); - - it('warns when docs has invalid tags', async () => { - const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); - - validateFrontMatterTags( - fromPartial({ + validateFrontMatterTags({ tags: [ { label: 'hello', @@ -320,9 +291,34 @@ describe('processFileTagsPath', () => { inline: true, }, ], - options: {onInlineTags: 'warn', tags: 'tags.yml'}, - }), + source: 'wrong.md', + options: {onInlineTags: 'throw', tags: 'tags.yml'}, + }); + + expect(testFn).toThrowErrorMatchingInlineSnapshot( + `"Tags [hello, world] used in wrong.md are not defined in tags.yml"`, ); + }); + + it('warns when docs has invalid tags', async () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); + + validateFrontMatterTags({ + tags: [ + { + label: 'hello', + permalink: 'hello', + inline: true, + }, + { + label: 'world', + permalink: 'world', + inline: true, + }, + ], + source: 'wrong.md', + options: {onInlineTags: 'warn', tags: 'tags.yml'}, + }); expect(consoleWarnSpy).toHaveBeenCalledTimes(1); expect(consoleWarnSpy).toHaveBeenCalledWith( From 976930938153a9fac9b5665c9c03c0ac9d6363db Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 13:59:02 +0200 Subject: [PATCH 066/142] add docs --- .../docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml | 3 --- packages/docusaurus-utils/src/tags.ts | 2 ++ website/docs/api/plugins/plugin-content-blog.mdx | 2 ++ website/docs/api/plugins/plugin-content-docs.mdx | 2 ++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml b/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml index 4cb3b2579d69..7ec9e4c8769a 100644 --- a/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml +++ b/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml @@ -1,7 +1,4 @@ hello: - permalink: /hellllo test: - label: Test testdesc: - description: Nothing to see open: diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index e2ff47d8317f..9dc3cd062b07 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -28,7 +28,9 @@ export type TagsFile = Record; // Tags plugins options shared between docs/blog export type TagsPluginOptions = { // TODO allow option tags later? | TagsFile; + /** Path to the tags file. */ tags: string | false | null | undefined; + /** The behavior of Docusaurus when it found inline tags. */ onInlineTags: 'ignore' | 'log' | 'warn' | 'throw'; }; diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index d97b834aa2a5..b6befbb2ba25 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -78,6 +78,8 @@ Accepted fields: | `processBlogPosts` | [ProcessBlogPostsFn](#ProcessBlogPostsFn) | `undefined` | An optional function which can be used to transform blog posts (filter, modify, delete, etc...). | | `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the blog post. | | `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the blog post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | +| `tags` | `string \| false \| null \| undefined` | `tags.yml` | A path to the file that defines tags. | +| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The behavior of Docusaurus when it found inline tags. | ```mdx-code-block diff --git a/website/docs/api/plugins/plugin-content-docs.mdx b/website/docs/api/plugins/plugin-content-docs.mdx index 09ce59a60e5e..c8cf86c8276e 100644 --- a/website/docs/api/plugins/plugin-content-docs.mdx +++ b/website/docs/api/plugins/plugin-content-docs.mdx @@ -65,6 +65,8 @@ Accepted fields: | `lastVersion` | `string` | First version in `versions.json` | The version navigated to in priority and displayed by default for docs navbar items. | | `onlyIncludeVersions` | `string[]` | All versions available | Only include a subset of all available versions. | | `versions` | [VersionsConfig](#VersionsConfig) | `{}` | Independent customization of each version's properties. | +| `tags` | `string \| false \| null \| undefined` | `tags.yml` | A path to the file that defines tags. | +| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The behavior of Docusaurus when it found inline tags. | ```mdx-code-block From d32635fcb35d8c377caaf204ec43e81dc24bcb9e Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Tue, 28 May 2024 12:03:40 +0000 Subject: [PATCH 067/142] refactor: apply lint autofix --- project-words.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index d3bbe445bd50..eb0a2f219e7e 100644 --- a/project-words.txt +++ b/project-words.txt @@ -119,7 +119,6 @@ hasura Hasura Heavener Héctor -hellllo héllô hideable Hideable From 08f7127c2c7328df2492ef7aaca6b3cb2d6b0af5 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 14:58:29 +0200 Subject: [PATCH 068/142] add tests --- .../src/__tests__/tags.test.ts | 90 +++++++++++++++---- 1 file changed, 74 insertions(+), 16 deletions(-) diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 72b1fbba5f28..067b228fd922 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -24,20 +24,38 @@ import type { // TODO one by one test small describe('normalize tags', () => { - it('normalize tags', async () => { + it('normalize single inline tag', async () => { + const tagsFile: TagsFile = {}; + + const frontMatterTags = ['hello']; + + const normalizedTags = normalizeTags({ + tagsPath: '/tags', + tagsFile, + frontMatterTags, + }); + + const expected: NormalizedTag[] = [ + { + inline: true, + label: 'hello', + permalink: '/tags/hello', + description: undefined, + }, + ]; + + expect(normalizedTags).toEqual(expected); + }); + + it('normalize single defined tag', async () => { const tagsFile: TagsFile = { - open: { - label: 'Open Source', - permalink: '/custom-open-source', - description: 'Learn about the open source', + hello: { + label: 'hello', + permalink: '/hello', }, }; - const frontMatterTags = [ - 'hello', - {label: 'world', permalink: 'world'}, - 'open', - ]; + const frontMatterTags = ['hello']; const normalizedTags = normalizeTags({ tagsPath: '/tags', @@ -47,22 +65,62 @@ describe('normalize tags', () => { const expected: NormalizedTag[] = [ { - inline: true, + inline: false, label: 'hello', permalink: '/tags/hello', description: undefined, }, + ]; + + expect(normalizedTags).toEqual(expected); + }); + + it('normalize single inline tag object', async () => { + const tagsFile: TagsFile = {}; + + const frontMatterTags = [{label: 'hello', permalink: 'hello'}]; + + const normalizedTags = normalizeTags({ + tagsPath: '/tags', + tagsFile, + frontMatterTags, + }); + + const expected: NormalizedTag[] = [ { inline: true, - label: 'world', - permalink: '/tags/world', + label: 'hello', + permalink: '/tags/hello', description: undefined, }, + ]; + + expect(normalizedTags).toEqual(expected); + }); + + it('normalize single defined tag with description', async () => { + const tagsFile: TagsFile = { + hello: { + label: 'hello', + permalink: '/hello', + description: 'hello description', + }, + }; + + const frontMatterTags = ['hello']; + + const normalizedTags = normalizeTags({ + tagsPath: '/tags', + tagsFile, + frontMatterTags, + }); + + const expected: NormalizedTag[] = [ { inline: false, - label: 'Open Source', - permalink: '/tags/custom-open-source', - description: 'Learn about the open source', + label: 'hello', + permalink: '/tags/hello', + description: 'hello description', }, ]; From 98d04f96deb6fccb42f3746e1de9fbefcec0749d Mon Sep 17 00:00:00 2001 From: ozaki <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 17:48:15 +0200 Subject: [PATCH 069/142] Update website/docs/api/plugins/plugin-content-blog.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Lorber --- website/docs/api/plugins/plugin-content-blog.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index b6befbb2ba25..c79f0d6d7fb3 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -78,7 +78,7 @@ Accepted fields: | `processBlogPosts` | [ProcessBlogPostsFn](#ProcessBlogPostsFn) | `undefined` | An optional function which can be used to transform blog posts (filter, modify, delete, etc...). | | `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the blog post. | | `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the blog post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | -| `tags` | `string \| false \| null \| undefined` | `tags.yml` | A path to the file that defines tags. | +| `tags` | `string \| false \| null \| undefined` | `tags.yml` | Path to the YAML tags file listing pre-defined tags. Relative to the blog content directory. | | `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The behavior of Docusaurus when it found inline tags. | ```mdx-code-block From d5eba15961e938aa20a34286e858e60a53f15683 Mon Sep 17 00:00:00 2001 From: ozaki <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 17:48:42 +0200 Subject: [PATCH 070/142] Update website/docs/api/plugins/plugin-content-blog.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Lorber --- website/docs/api/plugins/plugin-content-blog.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index c79f0d6d7fb3..1b8eb6ee7379 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -79,7 +79,7 @@ Accepted fields: | `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the blog post. | | `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the blog post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | | `tags` | `string \| false \| null \| undefined` | `tags.yml` | Path to the YAML tags file listing pre-defined tags. Relative to the blog content directory. | -| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The behavior of Docusaurus when it found inline tags. | +| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The plugin behavior when blog posts contain inline tags (not appearing in the list of pre-defined tags, usually `tags.yml`). | ```mdx-code-block From a7c1259894bbebe90cb257f2c5cba861e55e48b0 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 17:59:35 +0200 Subject: [PATCH 071/142] renaming --- .../src/blogUtils.ts | 4 +- .../src/docs.ts | 2 +- .../src/__tests__/__fixtures__/tags/tags.yml | 1 - .../src/__tests__/tags.test.ts | 50 +++++++++---------- packages/docusaurus-utils/src/index.ts | 6 +-- packages/docusaurus-utils/src/tags.ts | 46 +++++++++-------- 6 files changed, 53 insertions(+), 56 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 8f6fdb976d51..042ecbbce6fc 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -318,7 +318,7 @@ async function processBlogSourceFile( return undefined; } - const tagsBasePath = normalizeUrl([ + const tagsBaseRoutePath = normalizeUrl([ baseUrl, routeBasePath, tagsRouteBasePath, @@ -329,7 +329,7 @@ async function processBlogSourceFile( options, source: blogSourceRelative, frontMatterTags: frontMatter.tags, - versionTagsPath: tagsBasePath, + tagsBaseRoutePath, tagsFile, }); diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 1f277c5a52d0..160ce93a15a3 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -213,7 +213,7 @@ async function doProcessDocMetadata({ options, source, frontMatterTags: frontMatter.tags, - versionTagsPath: versionMetadata.tagsPath, + tagsBaseRoutePath: versionMetadata.tagsPath, tagsFile, }); diff --git a/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml b/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml index 7ec9e4c8769a..2db7c5574bc9 100644 --- a/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml +++ b/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml @@ -1,4 +1,3 @@ hello: test: -testdesc: open: diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 067b228fd922..d0bfd0e17b4b 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -7,7 +7,7 @@ import path from 'path'; import {getTagsFile} from '@docusaurus/utils-validation'; -import {processFileTagsPath, validateFrontMatterTags} from '@docusaurus/utils'; +import {processFileTagsPath, reportInlineTags} from '@docusaurus/utils'; import { groupTaggedItems, getTagVisibility, @@ -30,7 +30,7 @@ describe('normalize tags', () => { const frontMatterTags = ['hello']; const normalizedTags = normalizeTags({ - tagsPath: '/tags', + tagsBaseRoutePath: '/tags', tagsFile, frontMatterTags, }); @@ -58,7 +58,7 @@ describe('normalize tags', () => { const frontMatterTags = ['hello']; const normalizedTags = normalizeTags({ - tagsPath: '/tags', + tagsBaseRoutePath: '/tags', tagsFile, frontMatterTags, }); @@ -81,7 +81,7 @@ describe('normalize tags', () => { const frontMatterTags = [{label: 'hello', permalink: 'hello'}]; const normalizedTags = normalizeTags({ - tagsPath: '/tags', + tagsBaseRoutePath: '/tags', tagsFile, frontMatterTags, }); @@ -110,7 +110,7 @@ describe('normalize tags', () => { const frontMatterTags = ['hello']; const normalizedTags = normalizeTags({ - tagsPath: '/tags', + tagsBaseRoutePath: '/tags', tagsFile, frontMatterTags, }); @@ -129,7 +129,7 @@ describe('normalize tags', () => { }); describe('normalizeFrontMatterTags', () => { - const tagsPath = '/all/tags'; + const tagsBaseRoutePath = '/all/tags'; describe('inline', () => { it('normalizes simple string tag', () => { @@ -137,11 +137,11 @@ describe('normalizeFrontMatterTags', () => { const expectedOutput: NormalizedTag = { inline: true, label: 'tag', - permalink: `${tagsPath}/tag`, + permalink: `${tagsBaseRoutePath}/tag`, }; - expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( - expectedOutput, - ); + expect( + normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), + ).toEqual(expectedOutput); }); it('normalizes complex string tag', () => { @@ -149,11 +149,11 @@ describe('normalizeFrontMatterTags', () => { const expectedOutput: NormalizedTag = { inline: true, label: 'some more Complex_tag', - permalink: `${tagsPath}/some-more-complex-tag`, + permalink: `${tagsBaseRoutePath}/some-more-complex-tag`, }; - expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( - expectedOutput, - ); + expect( + normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), + ).toEqual(expectedOutput); }); it('normalizes simple object tag', () => { @@ -161,11 +161,11 @@ describe('normalizeFrontMatterTags', () => { const expectedOutput: NormalizedTag = { inline: true, label: 'tag', - permalink: `${tagsPath}/tagPermalink`, + permalink: `${tagsBaseRoutePath}/tagPermalink`, }; - expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( - expectedOutput, - ); + expect( + normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), + ).toEqual(expectedOutput); }); it('normalizes complex string tag with object tag', () => { @@ -176,11 +176,11 @@ describe('normalizeFrontMatterTags', () => { const expectedOutput: NormalizedTag = { inline: true, label: 'tag complex Label', - permalink: `${tagsPath}/MoreComplex/Permalink`, + permalink: `${tagsBaseRoutePath}/MoreComplex/Permalink`, }; - expect(normalizeTag({tagsPath, tagsFile: null, tag: input})).toEqual( - expectedOutput, - ); + expect( + normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), + ).toEqual(expectedOutput); }); }); }); @@ -328,7 +328,7 @@ const createTest = async ({ onInlineTags, }, source: 'default.md', - versionTagsPath: '/processFileTagsPath/tags', + tagsBaseRoutePath: '/processFileTagsPath/tags', frontMatterTags, }); }; @@ -336,7 +336,7 @@ const createTest = async ({ describe('processFileTagsPath', () => { it('throw when docs has invalid tags', async () => { const testFn = () => - validateFrontMatterTags({ + reportInlineTags({ tags: [ { label: 'hello', @@ -361,7 +361,7 @@ describe('processFileTagsPath', () => { it('warns when docs has invalid tags', async () => { const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); - validateFrontMatterTags({ + reportInlineTags({ tags: [ { label: 'hello', diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 7ee1e2ae57d9..a5b778b1db2c 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -124,8 +124,4 @@ export { type FrontMatterLastUpdate, } from './lastUpdateUtils'; -export { - normalizeTags, - processFileTagsPath, - validateFrontMatterTags, -} from './tags'; +export {normalizeTags, processFileTagsPath, reportInlineTags} from './tags'; diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 9dc3cd062b07..b456d2d04616 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -11,7 +11,7 @@ import {normalizeUrl} from './urlUtils'; /** What the user configures. */ export type Tag = { - // TODO isn't it also possibly undefiend ? (label?: string) + // TODO isn't it also possibly undefined ? (label?: string) label: string; /** Permalink to this tag's page, without the `/tags/` base path. */ // TODO same as label comment? @@ -56,21 +56,20 @@ export type FrontMatterTag = string | Tag; // TODO maybe make ensure the permalink is valid url path? function normalizeTagPermalink({ - tagsPath, + tagsBaseRoutePath, permalink, }: { - tagsPath: string; + tagsBaseRoutePath: string; permalink: string; }): string { - // Note: we always apply tagsPath on purpose. For versioned docs, v1/doc.md + // Note: we always apply tagsBaseRoutePath on purpose. For versioned docs, v1/doc.md // and v2/doc.md tags with custom permalinks don't lead to the same created - // page. tagsPath is different for each doc version - return normalizeUrl([tagsPath, permalink]); + // page. tagsBaseRoutePath is different for each doc version + return normalizeUrl([tagsBaseRoutePath, permalink]); } -// TODO old legacy method, to refactor function normalizeInlineTag( - tagsPath: string, + tagsBaseRoutePath: string, frontMatterTag: FrontMatterTag, ): NormalizedTag { function toTagObject(tagString: string): NormalizedTag { @@ -90,7 +89,10 @@ function normalizeInlineTag( return { inline: true, label: tag.label, - permalink: normalizeTagPermalink({permalink: tag.permalink, tagsPath}), + permalink: normalizeTagPermalink({ + permalink: tag.permalink, + tagsBaseRoutePath, + }), description: tag.description, }; } @@ -98,10 +100,10 @@ function normalizeInlineTag( export function normalizeTag({ tag, tagsFile, - tagsPath, + tagsBaseRoutePath, }: { tag: FrontMatterTag; - tagsPath: string; + tagsBaseRoutePath: string; tagsFile: TagsFile | null; }): NormalizedTag { if (typeof tag === 'string') { @@ -113,27 +115,27 @@ export function normalizeTag({ label: tagDescription.label, permalink: normalizeTagPermalink({ permalink: tagDescription.permalink, - tagsPath, + tagsBaseRoutePath, }), description: tagDescription.description, }; } } // legacy inline tag object, always inline, unknown because isn't a string - return normalizeInlineTag(tagsPath, tag); + return normalizeInlineTag(tagsBaseRoutePath, tag); } export function normalizeTags({ - tagsPath, + tagsBaseRoutePath, tagsFile, frontMatterTags, }: { - tagsPath: string; + tagsBaseRoutePath: string; tagsFile: TagsFile | null; frontMatterTags: FrontMatterTag[]; }): NormalizedTag[] { const tags = frontMatterTags.map((tag) => - normalizeTag({tag, tagsPath, tagsFile}), + normalizeTag({tag, tagsBaseRoutePath, tagsFile}), ); return tags; @@ -216,7 +218,7 @@ export function getTagVisibility({ }; } -export function validateFrontMatterTags({ +export function reportInlineTags({ tags, source, options, @@ -239,30 +241,30 @@ export function processFileTagsPath({ options, source, frontMatterTags, - versionTagsPath, + tagsBaseRoutePath, tagsFile, }: { options: TagsPluginOptions; source: string; frontMatterTags: FrontMatterTag[] | undefined; - versionTagsPath: string; + tagsBaseRoutePath: string; tagsFile: TagsFile | null; }): NormalizedTag[] { if (tagsFile === null) { return normalizeTags({ - tagsPath: versionTagsPath, + tagsBaseRoutePath, tagsFile: null, frontMatterTags: frontMatterTags ?? [], }); } const tags = normalizeTags({ - tagsPath: versionTagsPath, + tagsBaseRoutePath, tagsFile, frontMatterTags: frontMatterTags ?? [], }); - validateFrontMatterTags({ + reportInlineTags({ tags, source, options, From 4b6369b1b47b0df2a66c542e62e02277880eccdc Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:02:16 +0200 Subject: [PATCH 072/142] rename file --- packages/docusaurus-utils-validation/src/index.ts | 2 +- .../docusaurus-utils-validation/src/{tags.ts => tagsFile.ts.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/docusaurus-utils-validation/src/{tags.ts => tagsFile.ts.ts} (100%) diff --git a/packages/docusaurus-utils-validation/src/index.ts b/packages/docusaurus-utils-validation/src/index.ts index c2f053dfd569..819b6329fbcd 100644 --- a/packages/docusaurus-utils-validation/src/index.ts +++ b/packages/docusaurus-utils-validation/src/index.ts @@ -29,4 +29,4 @@ export { FrontMatterLastUpdateErrorMessage, FrontMatterLastUpdateSchema, } from './validationSchemas'; -export {getTagsFile} from './tags'; +export {getTagsFile} from './tagsFile.ts'; diff --git a/packages/docusaurus-utils-validation/src/tags.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts.ts similarity index 100% rename from packages/docusaurus-utils-validation/src/tags.ts rename to packages/docusaurus-utils-validation/src/tagsFile.ts.ts From 888f2cff4e3d81006fdb4520adb43beca02fffbf Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:07:37 +0200 Subject: [PATCH 073/142] rename things --- .../{tags.test.ts => tagsFile.test.ts} | 20 +++++++++---------- .../src/{tagsFile.ts.ts => tagsFile.ts} | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) rename packages/docusaurus-utils-validation/src/__tests__/{tags.test.ts => tagsFile.test.ts} (88%) rename packages/docusaurus-utils-validation/src/{tagsFile.ts.ts => tagsFile.ts} (95%) diff --git a/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts similarity index 88% rename from packages/docusaurus-utils-validation/src/__tests__/tags.test.ts rename to packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts index 6fca7c40c400..75bcd77ff037 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {ensureUniquePermalinks, normalizeTags} from '../../lib/tags'; +import {ensureUniquePermalinks, normalizeTagsFile} from '../tagsFile'; import type {TagsFile, TagsFileInput} from '@docusaurus/utils'; describe('ensureUniquePermalinks', () => { @@ -79,7 +79,7 @@ describe('ensureUniquePermalinks', () => { }); }); -describe('normalizeTags', () => { +describe('normalizeTagsFile', () => { it('normalize null tag', () => { const input: TagsFileInput = { 'kebab case test': null, @@ -93,7 +93,7 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(expectedOutput); + expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); it('normalize partial tag with label', () => { @@ -109,7 +109,7 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(expectedOutput); + expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); it('normalize partial tag with description', () => { @@ -125,7 +125,7 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(expectedOutput); + expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); it('normalize partial tag with permalink', () => { @@ -141,7 +141,7 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(expectedOutput); + expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); it('does not modify fully defined tags', () => { @@ -153,7 +153,7 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(input); + expect(normalizeTagsFile(input)).toEqual(input); }); it('handle special characters in keys', () => { @@ -169,7 +169,7 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(expectedOutput); + expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); it('handle special characters in keys with chinese characters', () => { @@ -185,7 +185,7 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(expectedOutput); + expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); it('normalize test', () => { @@ -207,6 +207,6 @@ describe('normalizeTags', () => { }, }; - expect(normalizeTags(input)).toEqual(expectedOutput); + expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); }); diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts similarity index 95% rename from packages/docusaurus-utils-validation/src/tagsFile.ts.ts rename to packages/docusaurus-utils-validation/src/tagsFile.ts index ba8d5dc6a296..01667b34694e 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -50,7 +50,7 @@ export function ensureUniquePermalinks(tags: TagsFile): void { } } -export function normalizeTags(data: TagsFileInput): TagsFile { +export function normalizeTagsFile(data: TagsFileInput): TagsFile { const normalizedData: TagsFile = {}; for (const [key, tag] of Object.entries(data)) { if (Object.prototype.hasOwnProperty.call(data, key)) { @@ -102,7 +102,7 @@ export async function getTagsFile( // TODO + normalize partial input => full input // TODO unit tests covering all forms of partial inputs // TODO handle conflicts, verify unique permalink etc - const normalizedData = normalizeTags(definedTags.value); + const normalizedData = normalizeTagsFile(definedTags.value); ensureUniquePermalinks(normalizedData); From 4c61ab675884c5458ec243b2444a4add5d08a400 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:08:59 +0200 Subject: [PATCH 074/142] behavior change --- packages/docusaurus-utils-validation/src/tagsFile.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 01667b34694e..b1e16edf6920 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -71,15 +71,15 @@ export async function getTagsFile( options: TagsPluginOptions, contentPath: string, ): Promise { + if (options.tags === false || options.tags === null) { + return null; + } + const filename = options.tags || 'tags.yml'; const tagDefinitionPath = path.join(contentPath, filename); const isFileExists = await fs.pathExists(tagDefinitionPath); - if ( - options.tags === false || - options.tags === null || - (options.tags === undefined && !isFileExists) - ) { + if (options.tags === undefined && !isFileExists) { return null; } From 23dafc02fb888037e2c57f5337b4f65cc97fd9a5 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:09:33 +0200 Subject: [PATCH 075/142] fix name --- packages/docusaurus-utils-validation/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-utils-validation/src/index.ts b/packages/docusaurus-utils-validation/src/index.ts index 819b6329fbcd..f08134849aea 100644 --- a/packages/docusaurus-utils-validation/src/index.ts +++ b/packages/docusaurus-utils-validation/src/index.ts @@ -29,4 +29,4 @@ export { FrontMatterLastUpdateErrorMessage, FrontMatterLastUpdateSchema, } from './validationSchemas'; -export {getTagsFile} from './tagsFile.ts'; +export {getTagsFile} from './tagsFile'; From fb43efa28c9954b8b8a7bd4cbb70079b16a82481 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:10:52 +0200 Subject: [PATCH 076/142] remove as --- packages/docusaurus-utils-validation/src/tagsFile.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index b1e16edf6920..fe730ac63f14 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -87,8 +87,7 @@ export async function getTagsFile( if (!tagDefinitionContent.trim()) { throw new Error(`Tags file at path ${tagDefinitionPath} is empty`); } - // TODO is it fine to use as TagsFileInput? - const data = YAML.load(tagDefinitionContent) as TagsFileInput; + const data = YAML.load(tagDefinitionContent); const definedTags = validateDefinedTags(data); if (definedTags.error) { From 60e20c82842e06b3621385e574f4f4f88b37a3b1 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:12:17 +0200 Subject: [PATCH 077/142] remove Partial --- packages/docusaurus-utils-validation/src/tagsFile.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index fe730ac63f14..5831a8de753f 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -11,7 +11,6 @@ import _ from 'lodash'; import Joi from 'joi'; import YAML from 'js-yaml'; import type { - Tag, TagsFile, TagsFileInput, TagsPluginOptions, @@ -54,8 +53,7 @@ export function normalizeTagsFile(data: TagsFileInput): TagsFile { const normalizedData: TagsFile = {}; for (const [key, tag] of Object.entries(data)) { if (Object.prototype.hasOwnProperty.call(data, key)) { - // Use type assertion to tell TypeScript that tag is of type Partial - const partialTag = tag as Partial; + const partialTag = tag; normalizedData[key] = { label: partialTag?.label || _.capitalize(key), description: partialTag?.description || `${key} default description`, From d725aa5cd238de9a165983ca0d29a77704e892a2 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:14:11 +0200 Subject: [PATCH 078/142] change description default to undefined --- .../src/__tests__/tagsFile.test.ts | 14 +++++++------- .../docusaurus-utils-validation/src/tagsFile.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts index 75bcd77ff037..41893c8deef3 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts @@ -87,7 +87,7 @@ describe('normalizeTagsFile', () => { const expectedOutput = { 'kebab case test': { - description: 'kebab case test default description', + description: undefined, label: 'Kebab case test', permalink: '/kebab-case-test', }, @@ -103,7 +103,7 @@ describe('normalizeTagsFile', () => { const expectedOutput = { world: { - description: 'world default description', + description: undefined, label: 'WORLD', permalink: '/world', }, @@ -135,7 +135,7 @@ describe('normalizeTagsFile', () => { const expectedOutput = { world: { - description: 'world default description', + description: undefined, label: 'World', permalink: 'world', }, @@ -163,7 +163,7 @@ describe('normalizeTagsFile', () => { const expectedOutput = { 'special@char$!key': { - description: 'special@char$!key default description', + description: undefined, label: 'Special@char$!key', permalink: '/special-char-key', }, @@ -179,7 +179,7 @@ describe('normalizeTagsFile', () => { const expectedOutput = { 特殊字符测试: { - description: '特殊字符测试 default description', + description: undefined, label: '特殊字符测试', permalink: '/特殊字符测试', }, @@ -196,12 +196,12 @@ describe('normalizeTagsFile', () => { const expectedOutput = { world: { - description: 'world default description', + description: undefined, label: 'World', permalink: 'aze', }, hello: { - description: 'hello default description', + description: undefined, label: 'Hello', permalink: 'h-e-l-l-o', }, diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 5831a8de753f..57894b0c488d 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -56,7 +56,7 @@ export function normalizeTagsFile(data: TagsFileInput): TagsFile { const partialTag = tag; normalizedData[key] = { label: partialTag?.label || _.capitalize(key), - description: partialTag?.description || `${key} default description`, + description: partialTag?.description, permalink: _.kebabCase(partialTag?.permalink) || `/${_.kebabCase(key)}`, }; } From 70f56db0ba12f85d4421bba0b81e81d6952668c1 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:16:37 +0200 Subject: [PATCH 079/142] remove useless check for ts --- .../docusaurus-utils-validation/src/tagsFile.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 57894b0c488d..68b47dd24d89 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -52,14 +52,12 @@ export function ensureUniquePermalinks(tags: TagsFile): void { export function normalizeTagsFile(data: TagsFileInput): TagsFile { const normalizedData: TagsFile = {}; for (const [key, tag] of Object.entries(data)) { - if (Object.prototype.hasOwnProperty.call(data, key)) { - const partialTag = tag; - normalizedData[key] = { - label: partialTag?.label || _.capitalize(key), - description: partialTag?.description, - permalink: _.kebabCase(partialTag?.permalink) || `/${_.kebabCase(key)}`, - }; - } + const partialTag = tag; + normalizedData[key] = { + label: partialTag?.label || _.capitalize(key), + description: partialTag?.description, + permalink: _.kebabCase(partialTag?.permalink) || `/${_.kebabCase(key)}`, + }; } return normalizedData; From d53fb5c8426174101392b4cb306bebf9e888b9ef Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Tue, 28 May 2024 16:21:32 +0000 Subject: [PATCH 080/142] refactor: apply lint autofix --- project-words.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/project-words.txt b/project-words.txt index eb0a2f219e7e..1b0b7fc729b0 100644 --- a/project-words.txt +++ b/project-words.txt @@ -354,7 +354,6 @@ SVGR swizzlable Teik templating -testdesc Thanos Therox toolset @@ -374,7 +373,6 @@ typesafe typesense Typesense Unavatar -undefiend unlinkable unlisteds Unlisteds From 04b2c0943907380cc88385894dbcd47315202a4e Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:18:24 +0200 Subject: [PATCH 081/142] use lodash mapValues --- package.json | 3 ++- .../docusaurus-utils-validation/src/tagsFile.ts | 16 ++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index c9abfeb1997c..26ec1372eb8f 100644 --- a/package.json +++ b/package.json @@ -116,5 +116,6 @@ "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "^29.0.0", "typescript": "~5.4.5" - } + }, + "packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72" } diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 68b47dd24d89..656227bc5a9e 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -50,17 +50,13 @@ export function ensureUniquePermalinks(tags: TagsFile): void { } export function normalizeTagsFile(data: TagsFileInput): TagsFile { - const normalizedData: TagsFile = {}; - for (const [key, tag] of Object.entries(data)) { - const partialTag = tag; - normalizedData[key] = { - label: partialTag?.label || _.capitalize(key), - description: partialTag?.description, - permalink: _.kebabCase(partialTag?.permalink) || `/${_.kebabCase(key)}`, + return _.mapValues(data, (tag, key) => { + return { + label: tag?.label || _.capitalize(key), + description: tag?.description, + permalink: _.kebabCase(tag?.permalink) || `/${_.kebabCase(key)}`, }; - } - - return normalizedData; + }); } export async function getTagsFile( From e24bc4f57e702c244ab9857e5b93a59ebcad0534 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:19:00 +0200 Subject: [PATCH 082/142] do not kebab case user permalink --- packages/docusaurus-utils-validation/src/tagsFile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 656227bc5a9e..3a7316e0fed3 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -54,7 +54,7 @@ export function normalizeTagsFile(data: TagsFileInput): TagsFile { return { label: tag?.label || _.capitalize(key), description: tag?.description, - permalink: _.kebabCase(tag?.permalink) || `/${_.kebabCase(key)}`, + permalink: tag?.permalink || `/${_.kebabCase(key)}`, }; }); } From 70a776f535ffd4a529af9a419df02135fad654e6 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:24:08 +0200 Subject: [PATCH 083/142] improve error log --- .../src/__tests__/tagsFile.test.ts | 23 ++++++++++--------- .../src/tagsFile.ts | 5 +++- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts index 41893c8deef3..3ef18cb198c0 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts @@ -23,11 +23,11 @@ describe('ensureUniquePermalinks', () => { }, }; - expect(() => - ensureUniquePermalinks(definedTags), - ).toThrowErrorMatchingInlineSnapshot( - `"Duplicate permalinks found: /custom-open-source"`, - ); + expect(() => ensureUniquePermalinks(definedTags)) + .toThrowErrorMatchingInlineSnapshot(` + "Duplicate permalinks found in tags file: + - /custom-open-source" + `); }); it('throw when multiple duplicate permalink found', () => { @@ -54,11 +54,12 @@ describe('ensureUniquePermalinks', () => { }, }; - expect(() => - ensureUniquePermalinks(definedTags), - ).toThrowErrorMatchingInlineSnapshot( - `"Duplicate permalinks found: /custom-open-source, /hello"`, - ); + expect(() => ensureUniquePermalinks(definedTags)) + .toThrowErrorMatchingInlineSnapshot(` + "Duplicate permalinks found in tags file: + - /custom-open-source + - /hello" + `); }); it('do not throw when no duplicate permalink found', () => { @@ -203,7 +204,7 @@ describe('normalizeTagsFile', () => { hello: { description: undefined, label: 'Hello', - permalink: 'h-e-l-l-o', + permalink: 'h e l l o', }, }; diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 3a7316e0fed3..d7c2dd583af8 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -43,8 +43,11 @@ export function ensureUniquePermalinks(tags: TagsFile): void { } if (duplicates.size > 0) { + const duplicateList = Array.from(duplicates) + .map((permalink) => ` - ${permalink}`) + .join('\n'); throw new Error( - `Duplicate permalinks found: ${Array.from(duplicates).join(', ')}`, + `Duplicate permalinks found in tags file:\n${duplicateList}`, ); } } From 94bff22af300015931cf940c9aa15e638ae5a4f5 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:27:04 +0200 Subject: [PATCH 084/142] use TagsFileInput for schemas --- packages/docusaurus-utils-validation/src/tagsFile.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index d7c2dd583af8..67a63e086310 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -16,7 +16,7 @@ import type { TagsPluginOptions, } from '@docusaurus/utils'; -const tagDefinitionSchema = Joi.object().pattern( +const tagDefinitionSchema = Joi.object().pattern( Joi.string(), Joi.object({ label: Joi.string(), @@ -25,7 +25,9 @@ const tagDefinitionSchema = Joi.object().pattern( }).allow(null), ); -function validateDefinedTags(tags: unknown): Joi.ValidationResult { +function validateDefinedTags( + tags: unknown, +): Joi.ValidationResult { return tagDefinitionSchema.validate(tags); } From f1514c68faa41a48c166c6a46071229cfb6d1da1 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:29:12 +0200 Subject: [PATCH 085/142] change behavior when oninlinetags is ignore --- packages/docusaurus-utils-validation/src/tagsFile.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 67a63e086310..4830d983d361 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -94,14 +94,10 @@ export async function getTagsFile( ); } - if (options.onInlineTags !== 'ignore') { - // TODO + normalize partial input => full input - // TODO unit tests covering all forms of partial inputs - // TODO handle conflicts, verify unique permalink etc - const normalizedData = normalizeTagsFile(definedTags.value); - - ensureUniquePermalinks(normalizedData); + const normalizedData = normalizeTagsFile(definedTags.value); + ensureUniquePermalinks(normalizedData); + if (options.onInlineTags !== 'ignore') { return normalizedData; } From f5facae8ca7aaae3d7b71aec15fe7045e3eee957 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:31:59 +0200 Subject: [PATCH 086/142] use ternary --- packages/docusaurus-utils-validation/src/tagsFile.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 4830d983d361..b2e56600aaa7 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -97,9 +97,5 @@ export async function getTagsFile( const normalizedData = normalizeTagsFile(definedTags.value); ensureUniquePermalinks(normalizedData); - if (options.onInlineTags !== 'ignore') { - return normalizedData; - } - - return null; + return options.onInlineTags !== 'ignore' ? normalizedData : null; } From aeb3cf409e96adbadbd712b4137835595ac392bf Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:36:26 +0200 Subject: [PATCH 087/142] remove comments --- packages/docusaurus-utils/src/tags.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index b456d2d04616..067d44c15ec9 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -11,16 +11,12 @@ import {normalizeUrl} from './urlUtils'; /** What the user configures. */ export type Tag = { - // TODO isn't it also possibly undefined ? (label?: string) label: string; /** Permalink to this tag's page, without the `/tags/` base path. */ - // TODO same as label comment? permalink: string; - // TODO do we use it in practice? description?: string; }; -// TODO add TagsFileInput=>TagsFile transformation + unit tests export type TagsFileInput = Record | null>; export type TagsFile = Record; From 450dcef82b7e7847a16f9d87b6173021907ff695 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:47:19 +0200 Subject: [PATCH 088/142] try remove function normalizeTags --- .../src/__tests__/tags.test.ts | 216 +++++++++--------- packages/docusaurus-utils/src/index.ts | 2 +- packages/docusaurus-utils/src/tags.ts | 40 +--- 3 files changed, 115 insertions(+), 143 deletions(-) diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index d0bfd0e17b4b..16059e018e00 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -8,14 +8,8 @@ import path from 'path'; import {getTagsFile} from '@docusaurus/utils-validation'; import {processFileTagsPath, reportInlineTags} from '@docusaurus/utils'; -import { - groupTaggedItems, - getTagVisibility, - normalizeTags, - normalizeTag, -} from '../tags'; +import {groupTaggedItems, getTagVisibility, normalizeTag} from '../tags'; import type { - TagsFile, Tag, NormalizedTag, FrontMatterTag, @@ -23,110 +17,110 @@ import type { } from '../tags'; // TODO one by one test small -describe('normalize tags', () => { - it('normalize single inline tag', async () => { - const tagsFile: TagsFile = {}; - - const frontMatterTags = ['hello']; - - const normalizedTags = normalizeTags({ - tagsBaseRoutePath: '/tags', - tagsFile, - frontMatterTags, - }); - - const expected: NormalizedTag[] = [ - { - inline: true, - label: 'hello', - permalink: '/tags/hello', - description: undefined, - }, - ]; - - expect(normalizedTags).toEqual(expected); - }); - - it('normalize single defined tag', async () => { - const tagsFile: TagsFile = { - hello: { - label: 'hello', - permalink: '/hello', - }, - }; - - const frontMatterTags = ['hello']; - - const normalizedTags = normalizeTags({ - tagsBaseRoutePath: '/tags', - tagsFile, - frontMatterTags, - }); - - const expected: NormalizedTag[] = [ - { - inline: false, - label: 'hello', - permalink: '/tags/hello', - description: undefined, - }, - ]; - - expect(normalizedTags).toEqual(expected); - }); - - it('normalize single inline tag object', async () => { - const tagsFile: TagsFile = {}; - - const frontMatterTags = [{label: 'hello', permalink: 'hello'}]; - - const normalizedTags = normalizeTags({ - tagsBaseRoutePath: '/tags', - tagsFile, - frontMatterTags, - }); - - const expected: NormalizedTag[] = [ - { - inline: true, - label: 'hello', - permalink: '/tags/hello', - description: undefined, - }, - ]; - - expect(normalizedTags).toEqual(expected); - }); - - it('normalize single defined tag with description', async () => { - const tagsFile: TagsFile = { - hello: { - label: 'hello', - permalink: '/hello', - description: 'hello description', - }, - }; - - const frontMatterTags = ['hello']; - - const normalizedTags = normalizeTags({ - tagsBaseRoutePath: '/tags', - tagsFile, - frontMatterTags, - }); - - const expected: NormalizedTag[] = [ - { - inline: false, - label: 'hello', - permalink: '/tags/hello', - description: 'hello description', - }, - ]; - - expect(normalizedTags).toEqual(expected); - }); -}); +// describe('normalize tags', () => { +// it('normalize single inline tag', async () => { +// const tagsFile: TagsFile = {}; + +// const frontMatterTags = ['hello']; + +// const normalizedTags = normalizeTags({ +// tagsBaseRoutePath: '/tags', +// tagsFile, +// frontMatterTags, +// }); + +// const expected: NormalizedTag[] = [ +// { +// inline: true, +// label: 'hello', +// permalink: '/tags/hello', +// description: undefined, +// }, +// ]; + +// expect(normalizedTags).toEqual(expected); +// }); + +// it('normalize single defined tag', async () => { +// const tagsFile: TagsFile = { +// hello: { +// label: 'hello', +// permalink: '/hello', +// }, +// }; + +// const frontMatterTags = ['hello']; + +// const normalizedTags = normalizeTags({ +// tagsBaseRoutePath: '/tags', +// tagsFile, +// frontMatterTags, +// }); + +// const expected: NormalizedTag[] = [ +// { +// inline: false, +// label: 'hello', +// permalink: '/tags/hello', +// description: undefined, +// }, +// ]; + +// expect(normalizedTags).toEqual(expected); +// }); + +// it('normalize single inline tag object', async () => { +// const tagsFile: TagsFile = {}; + +// const frontMatterTags = [{label: 'hello', permalink: 'hello'}]; + +// const normalizedTags = normalizeTags({ +// tagsBaseRoutePath: '/tags', +// tagsFile, +// frontMatterTags, +// }); + +// const expected: NormalizedTag[] = [ +// { +// inline: true, +// label: 'hello', +// permalink: '/tags/hello', +// description: undefined, +// }, +// ]; + +// expect(normalizedTags).toEqual(expected); +// }); + +// it('normalize single defined tag with description', async () => { +// const tagsFile: TagsFile = { +// hello: { +// label: 'hello', +// permalink: '/hello', +// description: 'hello description', +// }, +// }; + +// const frontMatterTags = ['hello']; + +// const normalizedTags = normalizeTags({ +// tagsBaseRoutePath: '/tags', +// tagsFile, +// frontMatterTags, +// }); + +// const expected: NormalizedTag[] = [ +// { +// inline: false, +// label: 'hello', +// permalink: '/tags/hello', +// description: 'hello description', +// }, +// ]; + +// expect(normalizedTags).toEqual(expected); +// }); +// }); describe('normalizeFrontMatterTags', () => { const tagsBaseRoutePath = '/all/tags'; diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index a5b778b1db2c..e8e6fb07ebb5 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -124,4 +124,4 @@ export { type FrontMatterLastUpdate, } from './lastUpdateUtils'; -export {normalizeTags, processFileTagsPath, reportInlineTags} from './tags'; +export {processFileTagsPath, reportInlineTags} from './tags'; diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 067d44c15ec9..ed8fb6d2a897 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -121,22 +121,6 @@ export function normalizeTag({ return normalizeInlineTag(tagsBaseRoutePath, tag); } -export function normalizeTags({ - tagsBaseRoutePath, - tagsFile, - frontMatterTags, -}: { - tagsBaseRoutePath: string; - tagsFile: TagsFile | null; - frontMatterTags: FrontMatterTag[]; -}): NormalizedTag[] { - const tags = frontMatterTags.map((tag) => - normalizeTag({tag, tagsBaseRoutePath, tagsFile}), - ); - - return tags; -} - type TaggedItemGroup = { tag: Tag; items: Item[]; @@ -246,25 +230,19 @@ export function processFileTagsPath({ tagsBaseRoutePath: string; tagsFile: TagsFile | null; }): NormalizedTag[] { + const normalizedFrontMatterTags = frontMatterTags ?? []; + if (tagsFile === null) { - return normalizeTags({ - tagsBaseRoutePath, - tagsFile: null, - frontMatterTags: frontMatterTags ?? [], - }); + return normalizedFrontMatterTags.map((tag) => + normalizeTag({tag, tagsBaseRoutePath, tagsFile}), + ); } - const tags = normalizeTags({ - tagsBaseRoutePath, - tagsFile, - frontMatterTags: frontMatterTags ?? [], - }); + const tags = normalizedFrontMatterTags.map((tag) => + normalizeTag({tag, tagsBaseRoutePath, tagsFile}), + ); - reportInlineTags({ - tags, - source, - options, - }); + reportInlineTags({tags, source, options}); return tags; } From a3317466d0a20d8adfb544f4073cb54dee7e3179 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:49:29 +0200 Subject: [PATCH 089/142] rename processFileTagsPath to normalizeTags --- packages/docusaurus-plugin-content-blog/src/blogUtils.ts | 4 ++-- packages/docusaurus-plugin-content-docs/src/docs.ts | 4 ++-- packages/docusaurus-utils/src/__tests__/tags.test.ts | 8 ++++---- packages/docusaurus-utils/src/index.ts | 2 +- packages/docusaurus-utils/src/tags.ts | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 042ecbbce6fc..cf0834d096f8 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -25,7 +25,7 @@ import { isUnlisted, isDraft, readLastUpdateData, - processFileTagsPath, + normalizeTags, } from '@docusaurus/utils'; import {getTagsFile} from '@docusaurus/utils-validation'; import {validateBlogPostFrontMatter} from './frontMatter'; @@ -325,7 +325,7 @@ async function processBlogSourceFile( ]); const authors = getBlogPostAuthors({authorsMap, frontMatter, baseUrl}); - const tags = processFileTagsPath({ + const tags = normalizeTags({ options, source: blogSourceRelative, frontMatterTags: frontMatter.tags, diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 160ce93a15a3..e3eb7cc47f45 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -20,7 +20,7 @@ import { isUnlisted, isDraft, readLastUpdateData, - processFileTagsPath, + normalizeTags, } from '@docusaurus/utils'; import {validateDocFrontMatter} from './frontMatter'; import getSlug from './slug'; @@ -209,7 +209,7 @@ async function doProcessDocMetadata({ const draft = isDraft({env, frontMatter}); const unlisted = isUnlisted({env, frontMatter}); - const tags = processFileTagsPath({ + const tags = normalizeTags({ options, source, frontMatterTags: frontMatter.tags, diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 16059e018e00..13cfd369bd1c 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -7,7 +7,7 @@ import path from 'path'; import {getTagsFile} from '@docusaurus/utils-validation'; -import {processFileTagsPath, reportInlineTags} from '@docusaurus/utils'; +import {normalizeTags, reportInlineTags} from '@docusaurus/utils'; import {groupTaggedItems, getTagVisibility, normalizeTag} from '../tags'; import type { Tag, @@ -315,19 +315,19 @@ const createTest = async ({ contentPath, ); - return processFileTagsPath({ + return normalizeTags({ tagsFile: definedTags, options: { tags: tagFile, onInlineTags, }, source: 'default.md', - tagsBaseRoutePath: '/processFileTagsPath/tags', + tagsBaseRoutePath: '/normalizeTags/tags', frontMatterTags, }); }; -describe('processFileTagsPath', () => { +describe('normalizeTags', () => { it('throw when docs has invalid tags', async () => { const testFn = () => reportInlineTags({ diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index e8e6fb07ebb5..7a638cdd867f 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -124,4 +124,4 @@ export { type FrontMatterLastUpdate, } from './lastUpdateUtils'; -export {processFileTagsPath, reportInlineTags} from './tags'; +export {normalizeTags, reportInlineTags} from './tags'; diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index ed8fb6d2a897..b2bd7909921b 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -217,7 +217,7 @@ export function reportInlineTags({ } } -export function processFileTagsPath({ +export function normalizeTags({ options, source, frontMatterTags, From 54a6106d4874a211d4d6f0cce6199c8acd85251f Mon Sep 17 00:00:00 2001 From: ozaki <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:59:03 +0200 Subject: [PATCH 090/142] Update website/docs/api/plugins/plugin-content-docs.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Lorber --- website/docs/api/plugins/plugin-content-docs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/api/plugins/plugin-content-docs.mdx b/website/docs/api/plugins/plugin-content-docs.mdx index c8cf86c8276e..b090a72db6f7 100644 --- a/website/docs/api/plugins/plugin-content-docs.mdx +++ b/website/docs/api/plugins/plugin-content-docs.mdx @@ -66,7 +66,7 @@ Accepted fields: | `onlyIncludeVersions` | `string[]` | All versions available | Only include a subset of all available versions. | | `versions` | [VersionsConfig](#VersionsConfig) | `{}` | Independent customization of each version's properties. | | `tags` | `string \| false \| null \| undefined` | `tags.yml` | A path to the file that defines tags. | -| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The behavior of Docusaurus when it found inline tags. | +| `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The plugin behavior when docs contain inline tags (not appearing in the list of pre-defined tags, usually `docs/tags.yml`). | ```mdx-code-block From 2ed5d9c3d953727e003b3d58041f5dcab12a25e7 Mon Sep 17 00:00:00 2001 From: ozaki <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:59:22 +0200 Subject: [PATCH 091/142] Update website/docs/api/plugins/plugin-content-docs.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Lorber --- website/docs/api/plugins/plugin-content-docs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/api/plugins/plugin-content-docs.mdx b/website/docs/api/plugins/plugin-content-docs.mdx index b090a72db6f7..935bb1cd3b0d 100644 --- a/website/docs/api/plugins/plugin-content-docs.mdx +++ b/website/docs/api/plugins/plugin-content-docs.mdx @@ -65,7 +65,7 @@ Accepted fields: | `lastVersion` | `string` | First version in `versions.json` | The version navigated to in priority and displayed by default for docs navbar items. | | `onlyIncludeVersions` | `string[]` | All versions available | Only include a subset of all available versions. | | `versions` | [VersionsConfig](#VersionsConfig) | `{}` | Independent customization of each version's properties. | -| `tags` | `string \| false \| null \| undefined` | `tags.yml` | A path to the file that defines tags. | +| `tags` | `string \| false \| null \| undefined` | `tags.yml` | Path to a YAML file listing pre-defined tags. Relative to the docs version content directories. | | `onInlineTags` | `'ignore' \| 'log' \| 'warn' \| 'throw'` | `warn` | The plugin behavior when docs contain inline tags (not appearing in the list of pre-defined tags, usually `docs/tags.yml`). | ```mdx-code-block From 2a1821e15d0fe356c7a99f493ec0b3d5686d65be Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 28 May 2024 18:58:51 +0200 Subject: [PATCH 092/142] refactor logic --- packages/docusaurus-utils/src/tags.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index b2bd7909921b..45a7d6638ee3 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -232,17 +232,13 @@ export function normalizeTags({ }): NormalizedTag[] { const normalizedFrontMatterTags = frontMatterTags ?? []; - if (tagsFile === null) { - return normalizedFrontMatterTags.map((tag) => - normalizeTag({tag, tagsBaseRoutePath, tagsFile}), - ); - } - const tags = normalizedFrontMatterTags.map((tag) => normalizeTag({tag, tagsBaseRoutePath, tagsFile}), ); - reportInlineTags({tags, source, options}); + if (tagsFile !== null) { + reportInlineTags({tags, source, options}); + } return tags; } From 2d4f725d3bf289037d55cc679e84791a58e45a03 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 29 May 2024 16:40:41 +0200 Subject: [PATCH 093/142] add tags.yml in template --- .../create-docusaurus/templates/shared/blog/tags.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 packages/create-docusaurus/templates/shared/blog/tags.yml diff --git a/packages/create-docusaurus/templates/shared/blog/tags.yml b/packages/create-docusaurus/templates/shared/blog/tags.yml new file mode 100644 index 000000000000..12838dc23cb2 --- /dev/null +++ b/packages/create-docusaurus/templates/shared/blog/tags.yml @@ -0,0 +1,12 @@ +facebook: + label: Facebook + permalink: /facebook +hello: + label: Hello + permalink: /hello +docusaurus: + label: Docusaurus + permalink: /docusaurus +hola: + label: Hola + permalink: /hola From b6e34491f0bec4e5dbc25baf036e567b8e560e24 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Wed, 29 May 2024 14:45:19 +0000 Subject: [PATCH 094/142] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index 1b0b7fc729b0..aed1f66a43ed 100644 --- a/project-words.txt +++ b/project-words.txt @@ -123,6 +123,7 @@ héllô hideable Hideable hola +Hola Hostman hoverable Husain From cff6948c6afddaf71cda4824a91ffbcef53d0d2f Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 29 May 2024 18:12:30 +0200 Subject: [PATCH 095/142] feat(theme): poc with description --- packages/docusaurus-plugin-content-blog/src/blogUtils.ts | 1 + packages/docusaurus-plugin-content-blog/src/props.ts | 2 ++ .../src/theme/BlogTagsPostsPage/index.tsx | 1 + .../src/theme/TagsListByLetter/index.tsx | 1 + website/blog/tags.yml | 2 ++ 5 files changed, 7 insertions(+) diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index cf0834d096f8..e75b085168ff 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -130,6 +130,7 @@ export function getBlogTags({ label: tag.label, items: tagVisibility.listedItems.map((item) => item.id), permalink: tag.permalink, + description: tag.description, pages: paginateBlogPosts({ blogPosts: tagVisibility.listedItems, basePageUrl: tag.permalink, diff --git a/packages/docusaurus-plugin-content-blog/src/props.ts b/packages/docusaurus-plugin-content-blog/src/props.ts index 8946bc15d580..517cd4a5f820 100644 --- a/packages/docusaurus-plugin-content-blog/src/props.ts +++ b/packages/docusaurus-plugin-content-blog/src/props.ts @@ -13,6 +13,7 @@ export function toTagsProp({blogTags}: {blogTags: BlogTags}): TagsListItem[] { .map((tag) => ({ label: tag.label, permalink: tag.permalink, + description: tag.description, count: tag.items.length, })); } @@ -27,6 +28,7 @@ export function toTagProp({ return { label: tag.label, permalink: tag.permalink, + description: tag.description, allTagsPath: blogTagsListPath, count: tag.items.length, unlisted: tag.unlisted, diff --git a/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx index c93074a3a300..b81c3ab14851 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx @@ -75,6 +75,7 @@ function BlogTagsPostsPageContent({ {tag.unlisted && }
{title} + {tag.description &&

{tag.description}

} (
  • + {tag.description}
  • ))} diff --git a/website/blog/tags.yml b/website/blog/tags.yml index 1666e3c54c0b..2cc6c501f01d 100644 --- a/website/blog/tags.yml +++ b/website/blog/tags.yml @@ -1,6 +1,8 @@ blog: release: + description: "Blog posts about Docusaurus' new releases" recap: + description: "Blog posts about Docusaurus' year recaps" birth: endi: tribute: From b1e7c3429448b1b26805b4f483d92d574341a561 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 29 May 2024 18:15:27 +0200 Subject: [PATCH 096/142] Remove unused code & fix tests --- .../__tests__/__snapshots__/index.test.ts.snap | 8 ++++++++ .../src/frontMatter.ts | 18 +----------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap index ab928b433c34..dfeec789f8d0 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap @@ -3,6 +3,7 @@ exports[`blog plugin process blog posts load content 1`] = ` { "/blog/tags/tag-1": { + "description": undefined, "items": [ "/simple/slug/another", "/another/tags", @@ -63,6 +64,7 @@ exports[`blog plugin process blog posts load content 1`] = ` "unlisted": false, }, "/blog/tags/tag-2": { + "description": undefined, "items": [ "/another/tags", "/another/tags2", @@ -258,6 +260,7 @@ exports[`blog plugin process blog posts load content 2`] = ` exports[`blog plugin works on blog tags without pagination 1`] = ` { "/blog/tags/tag-1": { + "description": undefined, "items": [ "/simple/slug/another", "/another/tags", @@ -288,6 +291,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = ` "unlisted": false, }, "/blog/tags/tag-2": { + "description": undefined, "items": [ "/another/tags", "/another/tags2", @@ -316,6 +320,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = ` "unlisted": false, }, "/blog/tags/unlisted": { + "description": undefined, "items": [ "/another/blog-with-tags-unlisted", ], @@ -347,6 +352,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = ` exports[`blog plugin works with blog tags 1`] = ` { "/blog/tags/tag-1": { + "description": undefined, "items": [ "/simple/slug/another", "/another/tags", @@ -392,6 +398,7 @@ exports[`blog plugin works with blog tags 1`] = ` "unlisted": false, }, "/blog/tags/tag-2": { + "description": undefined, "items": [ "/another/tags", "/another/tags2", @@ -420,6 +427,7 @@ exports[`blog plugin works with blog tags 1`] = ` "unlisted": false, }, "/blog/tags/unlisted": { + "description": undefined, "items": [ "/another/blog-with-tags-unlisted", ], diff --git a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts index d084e82c35bc..3c3f0f8883ee 100644 --- a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts @@ -9,11 +9,10 @@ import { FrontMatterLastUpdateSchema, FrontMatterTOCHeadingLevels, FrontMatterTagsSchema, - Joi, // Custom instance for front matter + JoiFrontMatter as Joi, // Custom instance for front matter URISchema, validateFrontMatter, } from '@docusaurus/utils-validation'; -import type {TagsFile} from '@docusaurus/utils'; import type {BlogPostFrontMatter} from '@docusaurus/plugin-content-blog'; const BlogPostFrontMatterAuthorSchema = Joi.object({ @@ -83,18 +82,3 @@ export function validateBlogPostFrontMatter(frontMatter: { }): BlogPostFrontMatter { return validateFrontMatter(frontMatter, BlogFrontMatterSchema); } - -export const tagDefinitionSchema = Joi.object().pattern( - Joi.string(), - Joi.object({ - label: Joi.string().required(), - description: Joi.string().required(), - permalink: Joi.string(), - }), -); - -export function validateDefinedTags( - tags: unknown, -): Joi.ValidationResult { - return tagDefinitionSchema.validate(tags); -} From b351bc1e101dca05f4d6744f20a9fd4d588975fb Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 30 May 2024 12:07:47 +0200 Subject: [PATCH 097/142] refactor test --- .../src/__tests__/tags.test.ts | 263 ++++++------------ 1 file changed, 80 insertions(+), 183 deletions(-) diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 13cfd369bd1c..7dedfd26df8a 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -5,124 +5,15 @@ * LICENSE file in the root directory of this source tree. */ -import path from 'path'; -import {getTagsFile} from '@docusaurus/utils-validation'; -import {normalizeTags, reportInlineTags} from '@docusaurus/utils'; -import {groupTaggedItems, getTagVisibility, normalizeTag} from '../tags'; -import type { - Tag, - NormalizedTag, - FrontMatterTag, - TagsPluginOptions, -} from '../tags'; - -// TODO one by one test small -// describe('normalize tags', () => { -// it('normalize single inline tag', async () => { -// const tagsFile: TagsFile = {}; - -// const frontMatterTags = ['hello']; - -// const normalizedTags = normalizeTags({ -// tagsBaseRoutePath: '/tags', -// tagsFile, -// frontMatterTags, -// }); - -// const expected: NormalizedTag[] = [ -// { -// inline: true, -// label: 'hello', -// permalink: '/tags/hello', -// description: undefined, -// }, -// ]; - -// expect(normalizedTags).toEqual(expected); -// }); - -// it('normalize single defined tag', async () => { -// const tagsFile: TagsFile = { -// hello: { -// label: 'hello', -// permalink: '/hello', -// }, -// }; - -// const frontMatterTags = ['hello']; - -// const normalizedTags = normalizeTags({ -// tagsBaseRoutePath: '/tags', -// tagsFile, -// frontMatterTags, -// }); - -// const expected: NormalizedTag[] = [ -// { -// inline: false, -// label: 'hello', -// permalink: '/tags/hello', -// description: undefined, -// }, -// ]; - -// expect(normalizedTags).toEqual(expected); -// }); - -// it('normalize single inline tag object', async () => { -// const tagsFile: TagsFile = {}; - -// const frontMatterTags = [{label: 'hello', permalink: 'hello'}]; - -// const normalizedTags = normalizeTags({ -// tagsBaseRoutePath: '/tags', -// tagsFile, -// frontMatterTags, -// }); - -// const expected: NormalizedTag[] = [ -// { -// inline: true, -// label: 'hello', -// permalink: '/tags/hello', -// description: undefined, -// }, -// ]; - -// expect(normalizedTags).toEqual(expected); -// }); - -// it('normalize single defined tag with description', async () => { -// const tagsFile: TagsFile = { -// hello: { -// label: 'hello', -// permalink: '/hello', -// description: 'hello description', -// }, -// }; - -// const frontMatterTags = ['hello']; - -// const normalizedTags = normalizeTags({ -// tagsBaseRoutePath: '/tags', -// tagsFile, -// frontMatterTags, -// }); - -// const expected: NormalizedTag[] = [ -// { -// inline: false, -// label: 'hello', -// permalink: '/tags/hello', -// description: 'hello description', -// }, -// ]; - -// expect(normalizedTags).toEqual(expected); -// }); -// }); - -describe('normalizeFrontMatterTags', () => { +import { + reportInlineTags, + groupTaggedItems, + getTagVisibility, +} from '@docusaurus/utils'; +import {normalizeTag} from '../tags'; +import type {Tag, NormalizedTag, FrontMatterTag} from '../tags'; + +describe('normalizeTag', () => { const tagsBaseRoutePath = '/all/tags'; describe('inline', () => { @@ -297,38 +188,26 @@ describe('getTagVisibility', () => { }); }); -const createTest = async ({ - onInlineTags, - frontMatterTags, -}: { - onInlineTags: TagsPluginOptions['onInlineTags']; - frontMatterTags: FrontMatterTag[]; -}) => { - const tagFile = 'tags.yml'; - const contentPath = path.join(__dirname, '__fixtures__', 'tags'); - - const definedTags = await getTagsFile( - { - onInlineTags, - tags: tagFile, +describe('reportInlineTags', () => { + const tagsFile = { + hello: { + label: 'Hello', + permalink: '/hello', + description: undefined, }, - contentPath, - ); - - return normalizeTags({ - tagsFile: definedTags, - options: { - tags: tagFile, - onInlineTags, + test: { + label: 'Test', + permalink: '/test', + description: undefined, }, - source: 'default.md', - tagsBaseRoutePath: '/normalizeTags/tags', - frontMatterTags, - }); -}; + open: { + label: 'Open Source', + permalink: '/open', + description: undefined, + }, + }; -describe('normalizeTags', () => { - it('throw when docs has invalid tags', async () => { + it('throw when inline tags found', () => { const testFn = () => reportInlineTags({ tags: [ @@ -352,15 +231,17 @@ describe('normalizeTags', () => { ); }); - it('warns when docs has invalid tags', async () => { - const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); + it('ignore when docs has invalid tags', () => { + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); - reportInlineTags({ + const testFn = reportInlineTags({ tags: [ { label: 'hello', permalink: 'hello', - inline: true, + inline: false, }, { label: 'world', @@ -369,44 +250,60 @@ describe('normalizeTags', () => { }, ], source: 'wrong.md', - options: {onInlineTags: 'warn', tags: 'tags.yml'}, + options: {onInlineTags: 'ignore', tags: 'tags.yml'}, }); - - expect(consoleWarnSpy).toHaveBeenCalledTimes(1); - expect(consoleWarnSpy).toHaveBeenCalledWith( - expect.stringMatching(/.*\[WARNING\].*Tags.*/), - ); - consoleWarnSpy.mockRestore(); + expect(testFn).toBeUndefined(); + expect(errorSpy).not.toHaveBeenCalled(); + expect(warnSpy).not.toHaveBeenCalled(); + expect(logSpy).not.toHaveBeenCalled(); + + errorSpy.mockRestore(); + warnSpy.mockRestore(); + logSpy.mockRestore(); }); - it('ignore when docs has invalid tags', async () => { - const process = createTest({ - frontMatterTags: ['unknownTag'], - onInlineTags: 'ignore', - }); - await expect(process).resolves.toBeDefined(); - }); + it('throw for unknown string and object tag', () => { + const frontmatter = ['open', 'world']; + const tags = frontmatter.map((tag) => + normalizeTag({ + tagsBaseRoutePath: '/tags', + tagsFile, + tag, + }), + ); - it('throw for unknown string and object tag', async () => { - const process = createTest({ - frontMatterTags: [ - 'open', - 'world', - {label: 'hello', permalink: 'hello'}, - {label: 'open', permalink: 'open'}, - ], - onInlineTags: 'throw', - }); - await expect(process).rejects.toThrowErrorMatchingInlineSnapshot( - `"Tags [world, hello, open] used in default.md are not defined in tags.yml"`, + const testFn = () => + reportInlineTags({ + tags, + source: 'default.md', + options: { + onInlineTags: 'throw', + tags: 'tags.yml', + }, + }); + expect(testFn).toThrowErrorMatchingInlineSnapshot( + `"Tags [world] used in default.md are not defined in tags.yml"`, ); }); - it('does not throw when docs has valid tags', async () => { - const process = createTest({ - frontMatterTags: ['open'], - onInlineTags: 'throw', - }); - await expect(process).resolves.toBeDefined(); + it('does not throw when docs has valid tags', () => { + const frontmatter = ['open']; + const tags = frontmatter.map((tag) => + normalizeTag({ + tagsBaseRoutePath: '/tags', + tagsFile, + tag, + }), + ); + const testFn = () => + reportInlineTags({ + tags, + source: 'wrong.md', + options: { + onInlineTags: 'throw', + tags: 'tags.yml', + }, + }); + expect(testFn).not.toThrow(); }); }); From 6fa49d4a2c4f67f11b341df9d7143a56888ac605 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 30 May 2024 15:05:34 +0200 Subject: [PATCH 098/142] create doc --- .../api/plugins/_tags-partials-example.mdx | 13 +++++++++ .../docs/api/plugins/plugin-content-blog.mdx | 8 +++-- .../docs/api/plugins/plugin-content-docs.mdx | 7 ++++- website/docs/blog.mdx | 29 +++++++++++++++++++ website/docs/guides/docs/docs-create-doc.mdx | 13 +++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 website/docs/api/plugins/_tags-partials-example.mdx diff --git a/website/docs/api/plugins/_tags-partials-example.mdx b/website/docs/api/plugins/_tags-partials-example.mdx new file mode 100644 index 000000000000..2d94c2e843a6 --- /dev/null +++ b/website/docs/api/plugins/_tags-partials-example.mdx @@ -0,0 +1,13 @@ +Example: + +```yml title="tags.yml" +tag: +tag1: null +# both tag above are equivalent +docusaurus: # what you'll be using in the front matter + label: Docusaurus + permalink: /docusaurus + description: Things related to Docusaurus +``` + +Only the key are required. If values are not provided the label will be set to the key Capitalized and the permalink will be set to the key kebab-cased. diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index 1b8eb6ee7379..75c5d9f7b551 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -226,7 +226,7 @@ Accepted fields: | `author_title` | `string` | `undefined` | ⚠️ Prefer using `authors`. A description of the author. | | `title` | `string` | Markdown title | The blog post title. | | `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. | -| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. | +| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. Strings can be a reference to keys in `tags.yml` | | `draft` | `boolean` | `false` | Draft blog posts will only be available during development. | | `unlisted` | `boolean` | `false` | Unlisted blog posts will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. | | `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. | @@ -274,7 +274,7 @@ authors: title: Co-creator of Docusaurus 1 url: https://github.com/JoelMarcey image_url: https://github.com/JoelMarcey.png -tags: [hello, docusaurus-v2] +tags: [hello, docusaurus] description: This is my first post on Docusaurus. image: https://i.imgur.com/mErPwqL.png hide_table_of_contents: false @@ -283,6 +283,10 @@ hide_table_of_contents: false A Markdown blog post ``` +import TagsFile from './_tags-partials-example.mdx'; + + + ## i18n {#i18n} Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first. diff --git a/website/docs/api/plugins/plugin-content-docs.mdx b/website/docs/api/plugins/plugin-content-docs.mdx index 935bb1cd3b0d..6cb127cebab6 100644 --- a/website/docs/api/plugins/plugin-content-docs.mdx +++ b/website/docs/api/plugins/plugin-content-docs.mdx @@ -295,7 +295,7 @@ Accepted fields: | `description` | `string` | The first line of Markdown content | The description of your document, which will become the `` and `` in ``, used by search engines. | | `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `` in the ``, enhancing link previews on social media and messaging platforms. | | `slug` | `string` | File path | Allows to customize the document URL (`//`). Support multiple patterns: `slug: my-doc`, `slug: /my/path/myDoc`, `slug: /`. | -| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. | +| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. Strings can be a reference to keys in `tags.yml` | | `draft` | `boolean` | `false` | Draft documents will only be available during development. | | `unlisted` | `boolean` | `false` | Unlisted documents will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. | | `last_update` | `FrontMatterLastUpdate` | `undefined` | Allows overriding the last update author/date. Date can be any [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). | @@ -326,6 +326,7 @@ description: How do I find you when I cannot solve this problem keywords: - docs - docusaurus +tags: [docusaurus] image: https://i.imgur.com/mErPwqL.png slug: /myDoc last_update: @@ -338,6 +339,10 @@ last_update: My Document Markdown content ``` +import TagsFile from './_tags-partials-example.mdx'; + + + ## i18n {#i18n} Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first. diff --git a/website/docs/blog.mdx b/website/docs/blog.mdx index 1fb3ace11c1b..276234cd8dea 100644 --- a/website/docs/blog.mdx +++ b/website/docs/blog.mdx @@ -380,6 +380,35 @@ An author, either declared through front matter or through the authors map, need ::: +## Blog post tags {#blog-post-tags} + +Use the `tags` front matter field use tags declared in `tags.yml`. Tags are a way to categorize your blog posts. + +### Inline tags {#inline-tags} + +Blog post tags can be declared directly inside the front matter: + +```md title="my-blog-post.md" +--- +tags: [hello, docusaurus-v2] +--- +``` + +### Global tags {#global-tags} + +For regular blog post tags, it can be tedious to maintain tags inlined in each blog post. + +It is possible to declare those tags globally in a configuration file: + +```yml title="website/blog/tags.yml" +tag: + hello: null + docusaurus-v2: + label: Docusaurus v2 + permalink: /docusaurus-v2 + description: Docusaurus v2 related posts +``` + ## Reading time {#reading-time} Docusaurus generates a reading time estimation for each blog post based on word count. We provide an option to customize this. diff --git a/website/docs/guides/docs/docs-create-doc.mdx b/website/docs/guides/docs/docs-create-doc.mdx index 86fc7c2a8e4a..947948b9c1f3 100644 --- a/website/docs/guides/docs/docs-create-doc.mdx +++ b/website/docs/guides/docs/docs-create-doc.mdx @@ -72,6 +72,19 @@ tags: --- ``` +You can use pre defined tags in docs with `tags.yml` file. For example, if you have a `tags.yml` file with the following content: + +```yml title="tags.yml" +tag: + Demo: null + Getting started: + label: Getting started + permalink: /getting-started + description: Things to get you started +``` + +Depending on the configuration of onInlineTags in `docusaurus.config.js`, you can throw, warn, log or ignore if a tag is not defined in `tags.yml`: + :::tip Tags can also be declared with `tags: [Demo, Getting started]`. From 93865aa5a30721b4f409118be812134ae712d764 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 30 May 2024 15:51:59 +0200 Subject: [PATCH 099/142] update docs --- .../api/plugins/_tags-partials-example.mdx | 6 ++-- .../docs/api/plugins/plugin-content-blog.mdx | 2 +- website/docs/blog.mdx | 29 ++++++++------- website/docs/guides/docs/docs-create-doc.mdx | 35 +++++++++++-------- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/website/docs/api/plugins/_tags-partials-example.mdx b/website/docs/api/plugins/_tags-partials-example.mdx index 2d94c2e843a6..738b0d4c296c 100644 --- a/website/docs/api/plugins/_tags-partials-example.mdx +++ b/website/docs/api/plugins/_tags-partials-example.mdx @@ -1,13 +1,13 @@ Example: ```yml title="tags.yml" -tag: -tag1: null +hello: +hello: null # both tag above are equivalent docusaurus: # what you'll be using in the front matter label: Docusaurus permalink: /docusaurus - description: Things related to Docusaurus + description: Docusaurus related posts ``` Only the key are required. If values are not provided the label will be set to the key Capitalized and the permalink will be set to the key kebab-cased. diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index 75c5d9f7b551..4d6a34238409 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -274,7 +274,7 @@ authors: title: Co-creator of Docusaurus 1 url: https://github.com/JoelMarcey image_url: https://github.com/JoelMarcey.png -tags: [hello, docusaurus] +tags: [docusaurus] description: This is my first post on Docusaurus. image: https://i.imgur.com/mErPwqL.png hide_table_of_contents: false diff --git a/website/docs/blog.mdx b/website/docs/blog.mdx index 276234cd8dea..2e4e3a1f8f34 100644 --- a/website/docs/blog.mdx +++ b/website/docs/blog.mdx @@ -386,28 +386,31 @@ Use the `tags` front matter field use tags declared in `tags.yml`. Tags are a wa ### Inline tags {#inline-tags} -Blog post tags can be declared directly inside the front matter: +Tags are considered inline when they are not defined in a global configuration file. They will be reported as per the `onInlineTags` configuration in `docusaurus.config.js`. + +Blog post tags can be declared directly inside the front matter in different ways: ```md title="my-blog-post.md" --- -tags: [hello, docusaurus-v2] +tags: [hello, docusaurus, {label: 'Open Source', permalink: '/open-source'}] --- ``` -### Global tags {#global-tags} +```md title="my-blog-post.md" +--- +tags: + - hello + - docusaurus + - label: Open Source + permalink: /open-source +--- +``` -For regular blog post tags, it can be tedious to maintain tags inlined in each blog post. +### Global tags {#global-tags} -It is possible to declare those tags globally in a configuration file: +Global tags are declared in a configuration file which then tag's key can be referenced in the blog post front matter. -```yml title="website/blog/tags.yml" -tag: - hello: null - docusaurus-v2: - label: Docusaurus v2 - permalink: /docusaurus-v2 - description: Docusaurus v2 related posts -``` +See [the API documentation](./api/plugins/plugin-content-blog.mdx#markdown-front-matter) to learn about `tags.yml`. ## Reading time {#reading-time} diff --git a/website/docs/guides/docs/docs-create-doc.mdx b/website/docs/guides/docs/docs-create-doc.mdx index 947948b9c1f3..102d2cbb24c6 100644 --- a/website/docs/guides/docs/docs-create-doc.mdx +++ b/website/docs/guides/docs/docs-create-doc.mdx @@ -62,26 +62,33 @@ The [front matter](../markdown-features/markdown-features-intro.mdx#front-matter Optionally, you can add tags to your doc pages, which introduces another dimension of categorization in addition to the [docs sidebar](./sidebar/index.mdx). Tags are passed in the front matter as a list of labels: -```md "your-doc-page.md" +### Inline tags {#inline-tags} + +Tags are considered inline when they are not defined in a global configuration file. They will be reported as per the `onInlineTags` configuration in `docusaurus.config.js`. + +Blog post tags can be declared directly inside the front matter in different ways: + +```md title="my-blog-post.md" +--- +tags: [hello, docusaurus, {label: 'Open Source', permalink: '/open-source'}] +--- +``` + +```md title="my-blog-post.md" --- -id: doc-with-tags -title: A doc with tags tags: - - Demo - - Getting started + - hello + - docusaurus + - label: Open Source + permalink: /open-source --- ``` -You can use pre defined tags in docs with `tags.yml` file. For example, if you have a `tags.yml` file with the following content: +### Global tags {#global-tags} -```yml title="tags.yml" -tag: - Demo: null - Getting started: - label: Getting started - permalink: /getting-started - description: Things to get you started -``` +Global tags are declared in a configuration file which then tag's key can be referenced in the blog post front matter. + +See [the API documentation](../../api/plugins/plugin-content-docs.mdx#markdown-front-matter) to learn about `tags.yml`. Depending on the configuration of onInlineTags in `docusaurus.config.js`, you can throw, warn, log or ignore if a tag is not defined in `tags.yml`: From 1f3da01539758e7cc95ea0224fc19a076942adad Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 30 May 2024 16:12:44 +0200 Subject: [PATCH 100/142] update doc --- website/docs/blog.mdx | 8 +++----- website/docs/guides/docs/docs-create-doc.mdx | 14 +++++--------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/website/docs/blog.mdx b/website/docs/blog.mdx index 2e4e3a1f8f34..f0c58045a823 100644 --- a/website/docs/blog.mdx +++ b/website/docs/blog.mdx @@ -382,17 +382,17 @@ An author, either declared through front matter or through the authors map, need ## Blog post tags {#blog-post-tags} -Use the `tags` front matter field use tags declared in `tags.yml`. Tags are a way to categorize your blog posts. +Optionally, you can add tags to your blog pages. Tags are passed in the front matter as a list of labels: ### Inline tags {#inline-tags} -Tags are considered inline when they are not defined in a global configuration file. They will be reported as per the `onInlineTags` configuration in `docusaurus.config.js`. +Tags are considered inline when they are not defined in a global configuration file. You can configure how to report inline tags with [`onInlineTags`](./api/plugins/plugin-content-blog.mdx#onInlineTags). Blog post tags can be declared directly inside the front matter in different ways: ```md title="my-blog-post.md" --- -tags: [hello, docusaurus, {label: 'Open Source', permalink: '/open-source'}] +tags: [hello, docusaurus] --- ``` @@ -401,8 +401,6 @@ tags: [hello, docusaurus, {label: 'Open Source', permalink: '/open-source'}] tags: - hello - docusaurus - - label: Open Source - permalink: /open-source --- ``` diff --git a/website/docs/guides/docs/docs-create-doc.mdx b/website/docs/guides/docs/docs-create-doc.mdx index 102d2cbb24c6..4645670982bb 100644 --- a/website/docs/guides/docs/docs-create-doc.mdx +++ b/website/docs/guides/docs/docs-create-doc.mdx @@ -64,34 +64,30 @@ Optionally, you can add tags to your doc pages, which introduces another dimensi ### Inline tags {#inline-tags} -Tags are considered inline when they are not defined in a global configuration file. They will be reported as per the `onInlineTags` configuration in `docusaurus.config.js`. +Tags are considered inline when they are not defined in a global configuration file. You can configure how to report inline tags with [`onInlineTags`](../../api/plugins/plugin-content-blog.mdx#onInlineTags). Blog post tags can be declared directly inside the front matter in different ways: -```md title="my-blog-post.md" +```md title="my-doc.md" --- -tags: [hello, docusaurus, {label: 'Open Source', permalink: '/open-source'}] +tags: [hello, docusaurus] --- ``` -```md title="my-blog-post.md" +```md title="my-doc.md" --- tags: - hello - docusaurus - - label: Open Source - permalink: /open-source --- ``` ### Global tags {#global-tags} -Global tags are declared in a configuration file which then tag's key can be referenced in the blog post front matter. +Global tags are declared in a configuration file which then tag's key can be referenced in the front matter. See [the API documentation](../../api/plugins/plugin-content-docs.mdx#markdown-front-matter) to learn about `tags.yml`. -Depending on the configuration of onInlineTags in `docusaurus.config.js`, you can throw, warn, log or ignore if a tag is not defined in `tags.yml`: - :::tip Tags can also be declared with `tags: [Demo, Getting started]`. From dc8be49f660d1caf19a53707f008ebeda638aa4a Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 30 May 2024 16:21:18 +0200 Subject: [PATCH 101/142] put description in title --- packages/docusaurus-theme-classic/src/theme/Tag/index.tsx | 8 +++++++- .../src/theme/TagsListByLetter/index.tsx | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/Tag/index.tsx b/packages/docusaurus-theme-classic/src/theme/Tag/index.tsx index 3b04395d3954..aeae26e594e6 100644 --- a/packages/docusaurus-theme-classic/src/theme/Tag/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Tag/index.tsx @@ -12,10 +12,16 @@ import type {Props} from '@theme/Tag'; import styles from './styles.module.css'; -export default function Tag({permalink, label, count}: Props): JSX.Element { +export default function Tag({ + permalink, + label, + count, + description, +}: Props): JSX.Element { return ( (
  • - {tag.description}
  • ))} From 9dc52515caaee26bf71028099c787d85fc8841be Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 16:39:14 +0200 Subject: [PATCH 102/142] wire doc description to docs plugin UI --- .../src/props.ts | 2 ++ .../src/routes.ts | 26 +++++++++++++++--- .../src/tags.ts | 27 ------------------- .../src/theme/BlogTagsPostsPage/index.tsx | 2 +- packages/docusaurus-utils/src/tags.ts | 2 +- website/_dogfooding/_docs tests/tags.yml | 1 + 6 files changed, 27 insertions(+), 33 deletions(-) delete mode 100644 packages/docusaurus-plugin-content-docs/src/tags.ts diff --git a/packages/docusaurus-plugin-content-docs/src/props.ts b/packages/docusaurus-plugin-content-docs/src/props.ts index 464ebc5e9001..c34211fad172 100644 --- a/packages/docusaurus-plugin-content-docs/src/props.ts +++ b/packages/docusaurus-plugin-content-docs/src/props.ts @@ -206,6 +206,7 @@ export function toTagDocListProp({ return { label: tag.label, permalink: tag.permalink, + description: tag.description, allTagsPath, count: tag.docIds.length, items: toDocListProp(), @@ -221,6 +222,7 @@ export function toTagsListTagsProp( .map((tagValue) => ({ label: tagValue.label, permalink: tagValue.permalink, + description: tagValue.description, count: tagValue.docIds.length, })); } diff --git a/packages/docusaurus-plugin-content-docs/src/routes.ts b/packages/docusaurus-plugin-content-docs/src/routes.ts index 14c55f154039..28031966ce92 100644 --- a/packages/docusaurus-plugin-content-docs/src/routes.ts +++ b/packages/docusaurus-plugin-content-docs/src/routes.ts @@ -11,19 +11,20 @@ import { docuHash, normalizeUrl, aliasedSitePathToRelativePath, + groupTaggedItems, + getTagVisibility, } from '@docusaurus/utils'; import { toTagDocListProp, toTagsListTagsProp, toVersionMetadataProp, } from './props'; -import {getVersionTags} from './tags'; import type { PluginContentLoadedActions, RouteConfig, RouteMetadata, } from '@docusaurus/types'; -import type {FullVersion, VersionTag} from './types'; +import type {FullVersion, VersionTag, VersionTags} from './types'; import type { CategoryGeneratedIndexMetadata, DocMetadata, @@ -112,6 +113,22 @@ async function buildVersionSidebarRoute(param: BuildVersionRoutesParam) { routes: subRoutes, }; } +function getVersionTags(docs: DocMetadata[]): VersionTags { + const groups = groupTaggedItems(docs, (doc) => doc.tags); + return _.mapValues(groups, ({tag, items: tagDocs}) => { + const tagVisibility = getTagVisibility({ + items: tagDocs, + isUnlisted: (item) => item.unlisted, + }); + return { + label: tag.label, + docIds: tagVisibility.listedItems.map((item) => item.id), + permalink: tag.permalink, + description: tag.description, + unlisted: tagVisibility.unlisted, + }; + }); +} async function buildVersionTagsRoutes( param: BuildVersionRoutesParam, @@ -120,8 +137,9 @@ async function buildVersionTagsRoutes( const versionTags = getVersionTags(version.docs); async function buildTagsListRoute(): Promise { + const tags = toTagsListTagsProp(versionTags); // Don't create a tags list page if there's no tag - if (Object.keys(versionTags).length === 0) { + if (tags.length === 0) { return null; } return { @@ -129,7 +147,7 @@ async function buildVersionTagsRoutes( exact: true, component: options.docTagsListComponent, props: { - tags: toTagsListTagsProp(versionTags), + tags, }, }; } diff --git a/packages/docusaurus-plugin-content-docs/src/tags.ts b/packages/docusaurus-plugin-content-docs/src/tags.ts deleted file mode 100644 index 1fd784c213fa..000000000000 --- a/packages/docusaurus-plugin-content-docs/src/tags.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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 _ from 'lodash'; -import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils'; -import type {VersionTags} from './types'; -import type {DocMetadata} from '@docusaurus/plugin-content-docs'; - -export function getVersionTags(docs: DocMetadata[]): VersionTags { - const groups = groupTaggedItems(docs, (doc) => doc.tags); - return _.mapValues(groups, ({tag, items: tagDocs}) => { - const tagVisibility = getTagVisibility({ - items: tagDocs, - isUnlisted: (item) => item.unlisted, - }); - return { - label: tag.label, - docIds: tagVisibility.listedItems.map((item) => item.id), - permalink: tag.permalink, - unlisted: tagVisibility.unlisted, - }; - }); -} diff --git a/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx index b81c3ab14851..45f71008db29 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx @@ -57,7 +57,7 @@ function BlogTagsPostsPageMetadata({tag}: Props): JSX.Element { const title = useBlogTagsPostsPageTitle(tag); return ( <> - + ); diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 45a7d6638ee3..895f149adbcb 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -14,7 +14,7 @@ export type Tag = { label: string; /** Permalink to this tag's page, without the `/tags/` base path. */ permalink: string; - description?: string; + description: string | undefined; }; export type TagsFileInput = Record | null>; diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml index d1cc20a91bce..1f902ca36015 100644 --- a/website/_dogfooding/_docs tests/tags.yml +++ b/website/_dogfooding/_docs tests/tags.yml @@ -1,4 +1,5 @@ a: + description: 'Description for tag a' b: c: e: From 29f81ec8f0253c95e66db93e61f4138886d7da82 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 16:44:35 +0200 Subject: [PATCH 103/142] cleanup package.json --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 26ec1372eb8f..c9abfeb1997c 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,5 @@ "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "^29.0.0", "typescript": "~5.4.5" - }, - "packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72" + } } From f465a75c23e7f3300e7dd4eef0b9d308ed8a4c96 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 16:48:17 +0200 Subject: [PATCH 104/142] Add tags descriptions to the init template --- packages/create-docusaurus/templates/shared/blog/tags.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/create-docusaurus/templates/shared/blog/tags.yml b/packages/create-docusaurus/templates/shared/blog/tags.yml index 12838dc23cb2..f71dd739318b 100644 --- a/packages/create-docusaurus/templates/shared/blog/tags.yml +++ b/packages/create-docusaurus/templates/shared/blog/tags.yml @@ -1,12 +1,16 @@ facebook: label: Facebook permalink: /facebook + description: Facebook tag description hello: label: Hello permalink: /hello + description: Hello tag description docusaurus: label: Docusaurus permalink: /docusaurus + description: Docusaurus tag description hola: label: Hola permalink: /hola + description: Hola tag description From 8884806992b606591d2af3e9b33b2776791316b0 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 16:53:02 +0200 Subject: [PATCH 105/142] TagsListInline should render tag description --- .../src/theme/TagsListInline/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/TagsListInline/index.tsx b/packages/docusaurus-theme-classic/src/theme/TagsListInline/index.tsx index b0b6fdaff5eb..2962283c933a 100644 --- a/packages/docusaurus-theme-classic/src/theme/TagsListInline/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/TagsListInline/index.tsx @@ -24,9 +24,9 @@ export default function TagsListInline({tags}: Props): JSX.Element {
      - {tags.map(({label, permalink: tagPermalink}) => ( -
    • - + {tags.map((tag) => ( +
    • +
    • ))}
    From 0b67e5fe81c64b51213ccd94fd134828b0573fdc Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 16:56:29 +0200 Subject: [PATCH 106/142] dogfood add more docs tags attributes --- website/_dogfooding/_docs tests/tags.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/_dogfooding/_docs tests/tags.yml b/website/_dogfooding/_docs tests/tags.yml index 1f902ca36015..548ba5e7d862 100644 --- a/website/_dogfooding/_docs tests/tags.yml +++ b/website/_dogfooding/_docs tests/tags.yml @@ -1,8 +1,13 @@ a: description: 'Description for tag a' b: + label: 'Label for tag b' c: + permalink: '/permalink-for-tag-c' e: + label: 'Label for tag e' + description: 'Description for tag e' + permalink: '/permalink-for-tag-e' some-tag: visibility: draft: From 44bd57592e29613a9030ce8bb0aec165a14c9081 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 16:56:43 +0200 Subject: [PATCH 107/142] fix DocTagDocListPage not showing doc tag description --- .../src/theme/DocTagDocListPage/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx index aa90c75abfe0..c08cf342dc87 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx @@ -85,6 +85,7 @@ function DocTagDocListPageContent({ {tag.unlisted && }
    {title} + {tag.description &&

    {tag.description}

    } Date: Thu, 30 May 2024 17:09:41 +0200 Subject: [PATCH 108/142] Minor tags.ts refactors --- .../src/__tests__/__fixtures__/tags/tags.yml | 3 - packages/docusaurus-utils/src/tags.ts | 91 +++++++++---------- 2 files changed, 45 insertions(+), 49 deletions(-) delete mode 100644 packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml diff --git a/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml b/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml deleted file mode 100644 index 2db7c5574bc9..000000000000 --- a/packages/docusaurus-utils/src/__tests__/__fixtures__/tags/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -hello: -test: -open: diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 895f149adbcb..344f392d48d0 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -50,7 +50,6 @@ export type TagModule = TagsListItem & { export type FrontMatterTag = string | Tag; -// TODO maybe make ensure the permalink is valid url path? function normalizeTagPermalink({ tagsBaseRoutePath, permalink, @@ -121,6 +120,51 @@ export function normalizeTag({ return normalizeInlineTag(tagsBaseRoutePath, tag); } +export function reportInlineTags({ + tags, + source, + options, +}: { + tags: NormalizedTag[]; + source: string; + options: TagsPluginOptions; +}): void { + const inlineTags = tags.filter((tag) => tag.inline); + if (inlineTags.length > 0 && options.onInlineTags !== 'ignore') { + const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; + const tagListString = uniqueUnknownTags.join(', '); + logger.report(options.onInlineTags)( + `Tags [${tagListString}] used in ${source} are not defined in ${options.tags}`, + ); + } +} + +export function normalizeTags({ + options, + source, + frontMatterTags, + tagsBaseRoutePath, + tagsFile, +}: { + options: TagsPluginOptions; + source: string; + frontMatterTags: FrontMatterTag[] | undefined; + tagsBaseRoutePath: string; + tagsFile: TagsFile | null; +}): NormalizedTag[] { + const normalizedFrontMatterTags = frontMatterTags ?? []; + + const tags = normalizedFrontMatterTags.map((tag) => + normalizeTag({tag, tagsBaseRoutePath, tagsFile}), + ); + + if (tagsFile !== null) { + reportInlineTags({tags, source, options}); + } + + return tags; +} + type TaggedItemGroup = { tag: Tag; items: Item[]; @@ -197,48 +241,3 @@ export function getTagVisibility({ listedItems: items.filter((item) => !isUnlisted(item)), }; } - -export function reportInlineTags({ - tags, - source, - options, -}: { - tags: NormalizedTag[]; - source: string; - options: TagsPluginOptions; -}): void { - const inlineTags = tags.filter((tag) => tag.inline); - if (inlineTags.length > 0 && options.onInlineTags !== 'ignore') { - const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; - const tagListString = uniqueUnknownTags.join(', '); - logger.report(options.onInlineTags)( - `Tags [${tagListString}] used in ${source} are not defined in ${options.tags}`, - ); - } -} - -export function normalizeTags({ - options, - source, - frontMatterTags, - tagsBaseRoutePath, - tagsFile, -}: { - options: TagsPluginOptions; - source: string; - frontMatterTags: FrontMatterTag[] | undefined; - tagsBaseRoutePath: string; - tagsFile: TagsFile | null; -}): NormalizedTag[] { - const normalizedFrontMatterTags = frontMatterTags ?? []; - - const tags = normalizedFrontMatterTags.map((tag) => - normalizeTag({tag, tagsBaseRoutePath, tagsFile}), - ); - - if (tagsFile !== null) { - reportInlineTags({tags, source, options}); - } - - return tags; -} From 88096ffd46e9d345e389dea1e6e20b6b3acf13c8 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 17:10:01 +0200 Subject: [PATCH 109/142] fix snapshots --- .../src/__tests__/__snapshots__/index.test.ts.snap | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index b675307ea080..496a7283579d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -1548,16 +1548,19 @@ exports[`simple website content: route config 1`] = ` "tags": [ { "count": 2, + "description": undefined, "label": "tag 1", "permalink": "/docs/tags/tag-1", }, { "count": 1, + "description": undefined, "label": "tag 2", "permalink": "/docs/tags/tag2-custom-permalink", }, { "count": 1, + "description": undefined, "label": "tag 3", "permalink": "/docs/tags/tag-3", }, @@ -1572,6 +1575,7 @@ exports[`simple website content: route config 1`] = ` "tag": { "allTagsPath": "/docs/tags", "count": 2, + "description": undefined, "items": [ { "description": "Images", @@ -1600,6 +1604,7 @@ exports[`simple website content: route config 1`] = ` "tag": { "allTagsPath": "/docs/tags", "count": 1, + "description": undefined, "items": [ { "description": "Hi, Endilie here :)", @@ -1622,6 +1627,7 @@ exports[`simple website content: route config 1`] = ` "tag": { "allTagsPath": "/docs/tags", "count": 1, + "description": undefined, "items": [ { "description": "Images", @@ -4470,16 +4476,19 @@ exports[`versioned website content: route config 1`] = ` "tags": [ { "count": 1, + "description": undefined, "label": "barTag 1", "permalink": "/docs/next/tags/bar-tag-1", }, { "count": 1, + "description": undefined, "label": "barTag-2", "permalink": "/docs/next/tags/bar-tag-2", }, { "count": 1, + "description": undefined, "label": "barTag 3", "permalink": "/docs/next/tags/barTag-3-permalink", }, @@ -4494,6 +4503,7 @@ exports[`versioned website content: route config 1`] = ` "tag": { "allTagsPath": "/docs/next/tags", "count": 1, + "description": undefined, "items": [ { "description": "This is next version of bar.", @@ -4516,6 +4526,7 @@ exports[`versioned website content: route config 1`] = ` "tag": { "allTagsPath": "/docs/next/tags", "count": 1, + "description": undefined, "items": [ { "description": "This is next version of bar.", @@ -4538,6 +4549,7 @@ exports[`versioned website content: route config 1`] = ` "tag": { "allTagsPath": "/docs/next/tags", "count": 1, + "description": undefined, "items": [ { "description": "This is next version of bar.", From 8d80c744a9d46c30aad75cb3aea1f9550f99a659 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 17:25:01 +0200 Subject: [PATCH 110/142] refactor tags tests --- .../src/validationSchemas.ts | 9 +- packages/docusaurus-utils/package.json | 1 + .../src/__tests__/tags.test.ts | 265 ++++++++++-------- packages/docusaurus-utils/src/tags.ts | 3 +- 4 files changed, 152 insertions(+), 126 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/validationSchemas.ts b/packages/docusaurus-utils-validation/src/validationSchemas.ts index 26a3180398a5..a8e356856c95 100644 --- a/packages/docusaurus-utils-validation/src/validationSchemas.ts +++ b/packages/docusaurus-utils-validation/src/validationSchemas.ts @@ -5,7 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -import {isValidPathname, DEFAULT_PLUGIN_ID, type Tag} from '@docusaurus/utils'; +import { + isValidPathname, + DEFAULT_PLUGIN_ID, + type FrontMatterTag, +} from '@docusaurus/utils'; import {addLeadingSlash} from '@docusaurus/utils-common'; import Joi from './Joi'; import {JoiFrontMatter} from './JoiFrontMatter'; @@ -115,9 +119,10 @@ const FrontMatterTagSchema = JoiFrontMatter.alternatives() JoiFrontMatter.string().required(), // TODO Docusaurus v4 remove this front matter tag form // users should use tags.yml instead - JoiFrontMatter.object({ + JoiFrontMatter.object({ label: JoiFrontMatter.string().required(), permalink: JoiFrontMatter.string().required(), + description: JoiFrontMatter.string().required(), }).required(), ) .messages({ diff --git a/packages/docusaurus-utils/package.json b/packages/docusaurus-utils/package.json index b249b4269173..bc983e669fe9 100644 --- a/packages/docusaurus-utils/package.json +++ b/packages/docusaurus-utils/package.json @@ -36,6 +36,7 @@ "shelljs": "^0.8.5", "tslib": "^2.6.0", "url-loader": "^4.1.1", + "utility-types": "^3.10.0", "webpack": "^5.88.1" }, "engines": { diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 7dedfd26df8a..f1ed8b80b2b8 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -11,7 +11,7 @@ import { getTagVisibility, } from '@docusaurus/utils'; import {normalizeTag} from '../tags'; -import type {Tag, NormalizedTag, FrontMatterTag} from '../tags'; +import type {Tag, NormalizedTag, FrontMatterTag, TagsFile} from '../tags'; describe('normalizeTag', () => { const tagsBaseRoutePath = '/all/tags'; @@ -23,6 +23,7 @@ describe('normalizeTag', () => { inline: true, label: 'tag', permalink: `${tagsBaseRoutePath}/tag`, + description: undefined, }; expect( normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), @@ -35,6 +36,7 @@ describe('normalizeTag', () => { inline: true, label: 'some more Complex_tag', permalink: `${tagsBaseRoutePath}/some-more-complex-tag`, + description: undefined, }; expect( normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), @@ -42,11 +44,15 @@ describe('normalizeTag', () => { }); it('normalizes simple object tag', () => { - const input: FrontMatterTag = {label: 'tag', permalink: 'tagPermalink'}; + const input: FrontMatterTag = { + label: 'tag', + permalink: 'tagPermalink', + }; const expectedOutput: NormalizedTag = { inline: true, label: 'tag', permalink: `${tagsBaseRoutePath}/tagPermalink`, + description: undefined, }; expect( normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), @@ -62,6 +68,7 @@ describe('normalizeTag', () => { inline: true, label: 'tag complex Label', permalink: `${tagsBaseRoutePath}/MoreComplex/Permalink`, + description: undefined, }; expect( normalizeTag({tagsBaseRoutePath, tagsFile: null, tag: input}), @@ -70,126 +77,8 @@ describe('normalizeTag', () => { }); }); -describe('groupTaggedItems', () => { - type SomeTaggedItem = { - id: string; - nested: { - tags: Tag[]; - }; - }; - function groupItems(items: SomeTaggedItem[]) { - return groupTaggedItems(items, (item) => item.nested.tags); - } - - type Input = Parameters[0]; - type Output = ReturnType; - - it('groups items by tag permalink', () => { - const tagGuide = {label: 'Guide', permalink: '/guide'}; - const tagTutorial = {label: 'Tutorial', permalink: '/tutorial'}; - const tagAPI = {label: 'API', permalink: '/api'}; - - // This one will be grouped under same permalink and label is ignored - const tagTutorialOtherLabel = { - label: 'TutorialOtherLabel', - permalink: '/tutorial', - }; - - const item1: SomeTaggedItem = { - id: '1', - nested: { - tags: [ - tagGuide, - tagTutorial, - tagAPI, - // Add some duplicates on purpose: they should be filtered - tagGuide, - tagTutorialOtherLabel, - ], - }, - }; - const item2: SomeTaggedItem = { - id: '2', - nested: { - tags: [tagAPI], - }, - }; - const item3: SomeTaggedItem = { - id: '3', - nested: { - tags: [tagTutorial], - }, - }; - const item4: SomeTaggedItem = { - id: '4', - nested: { - tags: [tagTutorialOtherLabel], - }, - }; - - const input: Input = [item1, item2, item3, item4]; - - const expectedOutput: Output = { - '/guide': {tag: tagGuide, items: [item1]}, - '/tutorial': {tag: tagTutorial, items: [item1, item3, item4]}, - '/api': {tag: tagAPI, items: [item1, item2]}, - }; - - expect(groupItems(input)).toEqual(expectedOutput); - }); -}); - -describe('getTagVisibility', () => { - type Item = {id: string; unlisted: boolean}; - - function isUnlisted(item: Item): boolean { - return item.unlisted; - } - - const item1: Item = {id: '1', unlisted: false}; - const item2: Item = {id: '2', unlisted: true}; - const item3: Item = {id: '3', unlisted: false}; - const item4: Item = {id: '4', unlisted: true}; - - it('works for some unlisted', () => { - expect( - getTagVisibility({ - items: [item1, item2, item3, item4], - isUnlisted, - }), - ).toEqual({ - listedItems: [item1, item3], - unlisted: false, - }); - }); - - it('works for all unlisted', () => { - expect( - getTagVisibility({ - items: [item2, item4], - isUnlisted, - }), - ).toEqual({ - listedItems: [item2, item4], - unlisted: true, - }); - }); - - it('works for all listed', () => { - expect( - getTagVisibility({ - items: [item1, item3], - isUnlisted, - }), - ).toEqual({ - listedItems: [item1, item3], - unlisted: false, - }); - }); -}); - describe('reportInlineTags', () => { - const tagsFile = { + const tagsFile: TagsFile = { hello: { label: 'Hello', permalink: '/hello', @@ -215,11 +104,13 @@ describe('reportInlineTags', () => { label: 'hello', permalink: 'hello', inline: true, + description: undefined, }, { label: 'world', permalink: 'world', inline: true, + description: undefined, }, ], source: 'wrong.md', @@ -236,23 +127,24 @@ describe('reportInlineTags', () => { const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); - const testFn = reportInlineTags({ + reportInlineTags({ tags: [ { label: 'hello', permalink: 'hello', inline: false, + description: undefined, }, { label: 'world', permalink: 'world', inline: true, + description: undefined, }, ], source: 'wrong.md', options: {onInlineTags: 'ignore', tags: 'tags.yml'}, }); - expect(testFn).toBeUndefined(); expect(errorSpy).not.toHaveBeenCalled(); expect(warnSpy).not.toHaveBeenCalled(); expect(logSpy).not.toHaveBeenCalled(); @@ -307,3 +199,130 @@ describe('reportInlineTags', () => { expect(testFn).not.toThrow(); }); }); + +describe('groupTaggedItems', () => { + type SomeTaggedItem = { + id: string; + nested: { + tags: Tag[]; + }; + }; + function groupItems(items: SomeTaggedItem[]) { + return groupTaggedItems(items, (item) => item.nested.tags); + } + + type Input = Parameters[0]; + type Output = ReturnType; + + it('groups items by tag permalink', () => { + const tagGuide = { + label: 'Guide', + permalink: '/guide', + description: undefined, + }; + const tagTutorial = { + label: 'Tutorial', + permalink: '/tutorial', + description: undefined, + }; + const tagAPI = {label: 'API', permalink: '/api', description: undefined}; + + // This one will be grouped under same permalink and label is ignored + const tagTutorialOtherLabel = { + label: 'TutorialOtherLabel', + permalink: '/tutorial', + description: undefined, + }; + + const item1: SomeTaggedItem = { + id: '1', + nested: { + tags: [ + tagGuide, + tagTutorial, + tagAPI, + // Add some duplicates on purpose: they should be filtered + tagGuide, + tagTutorialOtherLabel, + ], + }, + }; + const item2: SomeTaggedItem = { + id: '2', + nested: { + tags: [tagAPI], + }, + }; + const item3: SomeTaggedItem = { + id: '3', + nested: { + tags: [tagTutorial], + }, + }; + const item4: SomeTaggedItem = { + id: '4', + nested: { + tags: [tagTutorialOtherLabel], + }, + }; + + const input: Input = [item1, item2, item3, item4]; + + const expectedOutput: Output = { + '/guide': {tag: tagGuide, items: [item1]}, + '/tutorial': {tag: tagTutorial, items: [item1, item3, item4]}, + '/api': {tag: tagAPI, items: [item1, item2]}, + }; + + expect(groupItems(input)).toEqual(expectedOutput); + }); +}); + +describe('getTagVisibility', () => { + type Item = {id: string; unlisted: boolean}; + + function isUnlisted(item: Item): boolean { + return item.unlisted; + } + + const item1: Item = {id: '1', unlisted: false}; + const item2: Item = {id: '2', unlisted: true}; + const item3: Item = {id: '3', unlisted: false}; + const item4: Item = {id: '4', unlisted: true}; + + it('works for some unlisted', () => { + expect( + getTagVisibility({ + items: [item1, item2, item3, item4], + isUnlisted, + }), + ).toEqual({ + listedItems: [item1, item3], + unlisted: false, + }); + }); + + it('works for all unlisted', () => { + expect( + getTagVisibility({ + items: [item2, item4], + isUnlisted, + }), + ).toEqual({ + listedItems: [item2, item4], + unlisted: true, + }); + }); + + it('works for all listed', () => { + expect( + getTagVisibility({ + items: [item1, item3], + isUnlisted, + }), + ).toEqual({ + listedItems: [item1, item3], + unlisted: false, + }); + }); +}); diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 344f392d48d0..02a7d08c430c 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -8,6 +8,7 @@ import _ from 'lodash'; import logger from '@docusaurus/logger'; import {normalizeUrl} from './urlUtils'; +import type {Optional} from 'utility-types'; /** What the user configures. */ export type Tag = { @@ -48,7 +49,7 @@ export type TagModule = TagsListItem & { unlisted: boolean; }; -export type FrontMatterTag = string | Tag; +export type FrontMatterTag = string | Optional; function normalizeTagPermalink({ tagsBaseRoutePath, From 0a043c624830470d2773ffbf80adb27286fa401e Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 17:25:31 +0200 Subject: [PATCH 111/142] move comment --- packages/docusaurus-utils/src/tags.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 02a7d08c430c..ccb613028cdb 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -51,6 +51,9 @@ export type TagModule = TagsListItem & { export type FrontMatterTag = string | Optional; +// We always apply tagsBaseRoutePath on purpose. For versioned docs, v1/doc.md +// and v2/doc.md tags with custom permalinks don't lead to the same created +// page. tagsBaseRoutePath is different for each doc version function normalizeTagPermalink({ tagsBaseRoutePath, permalink, @@ -58,9 +61,6 @@ function normalizeTagPermalink({ tagsBaseRoutePath: string; permalink: string; }): string { - // Note: we always apply tagsBaseRoutePath on purpose. For versioned docs, v1/doc.md - // and v2/doc.md tags with custom permalinks don't lead to the same created - // page. tagsBaseRoutePath is different for each doc version return normalizeUrl([tagsBaseRoutePath, permalink]); } From e8cd65dab6a2abc903e9d6e6c4e3d4a6b92ef1eb Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 17:36:18 +0200 Subject: [PATCH 112/142] test normalizeTag() with tags from tagsFile --- .../src/__tests__/tags.test.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index f1ed8b80b2b8..4cedebee1c96 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -75,6 +75,60 @@ describe('normalizeTag', () => { ).toEqual(expectedOutput); }); }); + + describe('with tags file', () => { + const tagsFile: TagsFile = { + tag1: { + label: 'Tag 1 label', + permalink: 'tag-1-permalink', + description: 'Tag 1 description', + }, + tag2: { + label: 'Tag 2 label', + permalink: '/tag-2-permalink', + description: undefined, + }, + }; + + it('normalizes tag1 ref', () => { + const input: FrontMatterTag = 'tag1'; + const expectedOutput: NormalizedTag = { + inline: false, + label: tagsFile.tag1.label, + description: tagsFile.tag1.description, + permalink: `${tagsBaseRoutePath}/tag-1-permalink`, + }; + expect(normalizeTag({tagsBaseRoutePath, tagsFile, tag: input})).toEqual( + expectedOutput, + ); + }); + + it('normalizes tag2 ref', () => { + const input: FrontMatterTag = 'tag2'; + const expectedOutput: NormalizedTag = { + inline: false, + label: tagsFile.tag2.label, + description: tagsFile.tag2.description, + permalink: `${tagsBaseRoutePath}/tag-2-permalink`, + }; + expect(normalizeTag({tagsBaseRoutePath, tagsFile, tag: input})).toEqual( + expectedOutput, + ); + }); + + it('normalizes inline tag not declared in tags file', () => { + const input: FrontMatterTag = 'inlineTag'; + const expectedOutput: NormalizedTag = { + inline: true, + label: 'inlineTag', + description: undefined, + permalink: `${tagsBaseRoutePath}/inline-tag`, + }; + expect(normalizeTag({tagsBaseRoutePath, tagsFile, tag: input})).toEqual( + expectedOutput, + ); + }); + }); }); describe('reportInlineTags', () => { From 8fa31c581342bb0bc46dc172a3f9ca053dd136b5 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 17:37:34 +0200 Subject: [PATCH 113/142] fix little typing issue --- packages/docusaurus-utils/src/tags.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index ccb613028cdb..9f9c494f51e8 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -80,7 +80,7 @@ function normalizeInlineTag( const tag: Tag = typeof frontMatterTag === 'string' ? toTagObject(frontMatterTag) - : frontMatterTag; + : {...frontMatterTag, description: frontMatterTag.description}; return { inline: true, From 0af6b866e6f8a21967081fafc55ead34bd992ff6 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 18:02:02 +0200 Subject: [PATCH 114/142] add extra warn reportInlineTags test --- .../src/__tests__/tags.test.ts | 33 ++++++++++++ packages/docusaurus-utils/src/tags.ts | 52 ++++++++++--------- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 4cedebee1c96..739a4fe0ce9a 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -176,6 +176,39 @@ describe('reportInlineTags', () => { ); }); + it('warn when docs has invalid tags', () => { + const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); + + reportInlineTags({ + tags: [ + { + label: 'hello', + permalink: 'hello', + inline: false, + description: undefined, + }, + { + label: 'world', + permalink: 'world', + inline: true, + description: undefined, + }, + ], + source: 'wrong.md', + options: {onInlineTags: 'warn', tags: 'tags.yml'}, + }); + expect(warnSpy).toHaveBeenCalledTimes(1); + expect(warnSpy.mock.calls).toMatchInlineSnapshot(` + [ + [ + "[WARNING] Tags [world] used in wrong.md are not defined in tags.yml", + ], + ] + `); + + warnSpy.mockRestore(); + }); + it('ignore when docs has invalid tags', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 9f9c494f51e8..747892ac24d2 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -10,11 +10,12 @@ import logger from '@docusaurus/logger'; import {normalizeUrl} from './urlUtils'; import type {Optional} from 'utility-types'; -/** What the user configures. */ export type Tag = { + /** The display label of a tag */ label: string; /** Permalink to this tag's page, without the `/tags/` base path. */ permalink: string; + /** An optional description of the tag */ description: string | undefined; }; @@ -121,25 +122,6 @@ export function normalizeTag({ return normalizeInlineTag(tagsBaseRoutePath, tag); } -export function reportInlineTags({ - tags, - source, - options, -}: { - tags: NormalizedTag[]; - source: string; - options: TagsPluginOptions; -}): void { - const inlineTags = tags.filter((tag) => tag.inline); - if (inlineTags.length > 0 && options.onInlineTags !== 'ignore') { - const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; - const tagListString = uniqueUnknownTags.join(', '); - logger.report(options.onInlineTags)( - `Tags [${tagListString}] used in ${source} are not defined in ${options.tags}`, - ); - } -} - export function normalizeTags({ options, source, @@ -153,19 +135,39 @@ export function normalizeTags({ tagsBaseRoutePath: string; tagsFile: TagsFile | null; }): NormalizedTag[] { - const normalizedFrontMatterTags = frontMatterTags ?? []; - - const tags = normalizedFrontMatterTags.map((tag) => + const tags = (frontMatterTags ?? []).map((tag) => normalizeTag({tag, tagsBaseRoutePath, tagsFile}), ); - if (tagsFile !== null) { reportInlineTags({tags, source, options}); } - return tags; } +export function reportInlineTags({ + tags, + source, + options, +}: { + tags: NormalizedTag[]; + source: string; + options: TagsPluginOptions; +}): void { + if (options.onInlineTags === 'ignore') { + return; + } + const inlineTags = tags.filter((tag) => tag.inline); + if (inlineTags.length > 0) { + const uniqueUnknownTags = [...new Set(inlineTags.map((tag) => tag.label))]; + const tagListString = uniqueUnknownTags.join(', '); + logger.report(options.onInlineTags)( + `Tags [${tagListString}] used in ${source} are not defined in ${ + options.tags ?? 'tags.yml' + }`, + ); + } +} + type TaggedItemGroup = { tag: Tag; items: Item[]; From fa95a975c8b73f814e4a1cbcb50347b9c96189e6 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 18:07:38 +0200 Subject: [PATCH 115/142] remove schema typo --- packages/docusaurus-utils-validation/src/validationSchemas.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/validationSchemas.ts b/packages/docusaurus-utils-validation/src/validationSchemas.ts index a8e356856c95..706eaf676f5e 100644 --- a/packages/docusaurus-utils-validation/src/validationSchemas.ts +++ b/packages/docusaurus-utils-validation/src/validationSchemas.ts @@ -117,12 +117,11 @@ export const RouteBasePathSchema = Joi const FrontMatterTagSchema = JoiFrontMatter.alternatives() .try( JoiFrontMatter.string().required(), - // TODO Docusaurus v4 remove this front matter tag form + // TODO Docusaurus v4 remove this legacy front matter tag object form // users should use tags.yml instead JoiFrontMatter.object({ label: JoiFrontMatter.string().required(), permalink: JoiFrontMatter.string().required(), - description: JoiFrontMatter.string().required(), }).required(), ) .messages({ From d1052933e9a8f5923c1b185d47fc592068fcd7c1 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 18:34:31 +0200 Subject: [PATCH 116/142] tagsFile refactor --- .../src/__tests__/tagsFile.test.ts | 18 ++++++------- .../src/tagsFile.ts | 25 +++++++------------ 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts index 3ef18cb198c0..5bd3d3ec85db 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts @@ -86,7 +86,7 @@ describe('normalizeTagsFile', () => { 'kebab case test': null, }; - const expectedOutput = { + const expectedOutput: TagsFile = { 'kebab case test': { description: undefined, label: 'Kebab case test', @@ -102,7 +102,7 @@ describe('normalizeTagsFile', () => { world: {label: 'WORLD'}, }; - const expectedOutput = { + const expectedOutput: TagsFile = { world: { description: undefined, label: 'WORLD', @@ -118,7 +118,7 @@ describe('normalizeTagsFile', () => { world: {description: 'World description test'}, }; - const expectedOutput = { + const expectedOutput: TagsFile = { world: { description: 'World description test', label: 'World', @@ -134,7 +134,7 @@ describe('normalizeTagsFile', () => { world: {permalink: 'world'}, }; - const expectedOutput = { + const expectedOutput: TagsFile = { world: { description: undefined, label: 'World', @@ -146,7 +146,7 @@ describe('normalizeTagsFile', () => { }); it('does not modify fully defined tags', () => { - const input = { + const input: TagsFileInput = { tag1: { label: 'Custom Label', description: 'Custom Description', @@ -158,11 +158,11 @@ describe('normalizeTagsFile', () => { }); it('handle special characters in keys', () => { - const input = { + const input: TagsFileInput = { 'special@char$!key': null, }; - const expectedOutput = { + const expectedOutput: TagsFile = { 'special@char$!key': { description: undefined, label: 'Special@char$!key', @@ -174,11 +174,11 @@ describe('normalizeTagsFile', () => { }); it('handle special characters in keys with chinese characters', () => { - const input = { + const input: TagsFileInput = { 特殊字符测试: null, }; - const expectedOutput = { + const expectedOutput: TagsFile = { 特殊字符测试: { description: undefined, label: '特殊字符测试', diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index b2e56600aaa7..ef2c095976d8 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -16,7 +16,7 @@ import type { TagsPluginOptions, } from '@docusaurus/utils'; -const tagDefinitionSchema = Joi.object().pattern( +const TagsFileInputSchema = Joi.object().pattern( Joi.string(), Joi.object({ label: Joi.string(), @@ -25,12 +25,6 @@ const tagDefinitionSchema = Joi.object().pattern( }).allow(null), ); -function validateDefinedTags( - tags: unknown, -): Joi.ValidationResult { - return tagDefinitionSchema.validate(tags); -} - export function ensureUniquePermalinks(tags: TagsFile): void { const permalinks = new Set(); const duplicates = new Set(); @@ -84,18 +78,17 @@ export async function getTagsFile( if (!tagDefinitionContent.trim()) { throw new Error(`Tags file at path ${tagDefinitionPath} is empty`); } - const data = YAML.load(tagDefinitionContent); - const definedTags = validateDefinedTags(data); - - if (definedTags.error) { + const yamlContent = YAML.load(tagDefinitionContent); + const tagsFileInputResult = TagsFileInputSchema.validate(yamlContent); + if (tagsFileInputResult.error) { throw new Error( - `There was an error extracting tags from file: ${definedTags.error.message}`, - {cause: definedTags}, + `There was an error extracting tags from file: ${tagsFileInputResult.error.message}`, + {cause: tagsFileInputResult}, ); } - const normalizedData = normalizeTagsFile(definedTags.value); - ensureUniquePermalinks(normalizedData); + const tagsFile = normalizeTagsFile(tagsFileInputResult.value); + ensureUniquePermalinks(tagsFile); - return options.onInlineTags !== 'ignore' ? normalizedData : null; + return options.onInlineTags !== 'ignore' ? tagsFile : null; } From 5ec16a6d7f8f82a7a8bfcfe8782d030648cdaa94 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 19:08:11 +0200 Subject: [PATCH 117/142] Add proper getTagsFile() tests --- .../docusaurus-utils-validation/package.json | 3 + .../src/__tests__/tagsFile.test.ts | 181 +++++++++++++++++- .../src/tagsFile.ts | 27 ++- 3 files changed, 201 insertions(+), 10 deletions(-) diff --git a/packages/docusaurus-utils-validation/package.json b/packages/docusaurus-utils-validation/package.json index 21cccd26388f..9813db6cd6d1 100644 --- a/packages/docusaurus-utils-validation/package.json +++ b/packages/docusaurus-utils-validation/package.json @@ -27,6 +27,9 @@ "lodash": "^4.17.21", "tslib": "^2.6.0" }, + "devDependencies": { + "tmp-promise": "^3.0.3" + }, "engines": { "node": ">=18.0" } diff --git a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts index 5bd3d3ec85db..82f582c58adb 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts @@ -5,7 +5,15 @@ * LICENSE file in the root directory of this source tree. */ -import {ensureUniquePermalinks, normalizeTagsFile} from '../tagsFile'; +import * as path from 'path'; +import * as fs from 'fs-extra'; +import * as tmp from 'tmp-promise'; +import * as YAML from 'js-yaml'; +import { + ensureUniquePermalinks, + getTagsFile, + normalizeTagsFile, +} from '../tagsFile'; import type {TagsFile, TagsFileInput} from '@docusaurus/utils'; describe('ensureUniquePermalinks', () => { @@ -211,3 +219,174 @@ describe('normalizeTagsFile', () => { expect(normalizeTagsFile(input)).toEqual(expectedOutput); }); }); + +describe('getTagsFile', () => { + async function createTestTagsFile({ + filePath, + tagsFileInput, + }: { + filePath: string; + tagsFileInput: TagsFileInput; + }): Promise<{contentPath: string}> { + async function createTmpDir() { + return ( + await tmp.dir({ + prefix: 'jest-createTmpSiteDir', + }) + ).path; + } + const contentPath = await createTmpDir(); + const finalFilePath = path.join(contentPath, filePath); + const fileContent = YAML.dump(tagsFileInput); + await fs.writeFile(finalFilePath, fileContent); + return {contentPath}; + } + + type Params = Parameters[0]; + + it('reads tags file - regular', async () => { + const {contentPath} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: { + tag1: {label: 'Tag1 Label'}, + tag2: {description: 'Tag2 Description'}, + tag3: { + label: 'Tag3 Label', + permalink: '/tag-3', + description: 'Tag3 Description', + }, + }, + }); + + const params: Params = {contentPath, tags: 'tags.yml'}; + + await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` + { + "tag1": { + "description": undefined, + "label": "Tag1 Label", + "permalink": "/tag-1", + }, + "tag2": { + "description": "Tag2 Description", + "label": "Tag2", + "permalink": "/tag-2", + }, + "tag3": { + "description": "Tag3 Description", + "label": "Tag3 Label", + "permalink": "/tag-3", + }, + } + `); + }); + + it('reads tags file - only keys', async () => { + const {contentPath} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: { + tagKey: null, + }, + }); + + const params: Params = {contentPath, tags: 'tags.yml'}; + + await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` + { + "tagKey": { + "description": undefined, + "label": "Tagkey", + "permalink": "/tag-key", + }, + } + `); + }); + + it('reads tags file - tags option undefined', async () => { + const {contentPath} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: { + tag: {label: 'tag label'}, + }, + }); + + const params: Params = {contentPath, tags: undefined}; + + await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` + { + "tag": { + "description": undefined, + "label": "tag label", + "permalink": "/tag", + }, + } + `); + }); + + it('reads tags file - empty file', async () => { + const {contentPath} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: {}, + }); + + const params: Params = {contentPath, tags: undefined}; + + await expect(getTagsFile(params)).resolves.toEqual({}); + }); + + it('reads tags file - custom tags file path', async () => { + const {contentPath} = await createTestTagsFile({ + filePath: 'custom-tags-path.yml', + tagsFileInput: { + tag: {label: 'tag label'}, + }, + }); + + const params: Params = {contentPath, tags: 'custom-tags-path.yml'}; + + await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` + { + "tag": { + "description": undefined, + "label": "tag label", + "permalink": "/tag", + }, + } + `); + }); + + it('throws if custom tags file path does not exist', async () => { + const params: Params = {contentPath: 'any', tags: 'custom-tags-path.yml'}; + + await expect( + getTagsFile(params), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"No tags file could be found at path any/custom-tags-path.yml"`, + ); + }); + + it('does not read tags file - tags option null/false', async () => { + const {contentPath} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: { + tag: {label: 'tag label'}, + }, + }); + + await expect(getTagsFile({contentPath, tags: null})).resolves.toBeNull(); + await expect(getTagsFile({contentPath, tags: false})).resolves.toBeNull(); + }); + + it('does not read tags file - tags files has non-default name', async () => { + const {contentPath} = await createTestTagsFile({ + filePath: 'bad-tags-file-name.yml', + tagsFileInput: { + tag: {label: 'tag label'}, + }, + }); + + await expect( + getTagsFile({contentPath, tags: undefined}), + ).resolves.toBeNull(); + }); +}); diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index ef2c095976d8..540859062e97 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -58,26 +58,35 @@ export function normalizeTagsFile(data: TagsFileInput): TagsFile { }); } -export async function getTagsFile( - options: TagsPluginOptions, - contentPath: string, -): Promise { - if (options.tags === false || options.tags === null) { +export async function getTagsFile({ + contentPath, + tags, +}: { + tags: TagsPluginOptions['tags']; + contentPath: string; +}): Promise { + if (tags === false || tags === null) { return null; } - const filename = options.tags || 'tags.yml'; + const defaultFileName = 'tags.yml'; + + const filename = tags || defaultFileName; const tagDefinitionPath = path.join(contentPath, filename); const isFileExists = await fs.pathExists(tagDefinitionPath); - if (options.tags === undefined && !isFileExists) { + if (tags === undefined && !isFileExists) { return null; } + if (!isFileExists) { + throw new Error(`No tags file could be found at path ${tagDefinitionPath}`); + } const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); if (!tagDefinitionContent.trim()) { - throw new Error(`Tags file at path ${tagDefinitionPath} is empty`); + return {}; } + const yamlContent = YAML.load(tagDefinitionContent); const tagsFileInputResult = TagsFileInputSchema.validate(yamlContent); if (tagsFileInputResult.error) { @@ -90,5 +99,5 @@ export async function getTagsFile( const tagsFile = normalizeTagsFile(tagsFileInputResult.value); ensureUniquePermalinks(tagsFile); - return options.onInlineTags !== 'ignore' ? tagsFile : null; + return tagsFile; } From 6451e8bd46916963010e5f0bf6952d131802bb53 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 19:29:07 +0200 Subject: [PATCH 118/142] Add proper getTagsFile() tests --- .../src/__tests__/tagsFile.test.ts | 133 ++++++++++++++---- .../src/tagsFile.ts | 31 ++-- 2 files changed, 128 insertions(+), 36 deletions(-) diff --git a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts index 82f582c58adb..8832b81ef760 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts @@ -227,7 +227,7 @@ describe('getTagsFile', () => { }: { filePath: string; tagsFileInput: TagsFileInput; - }): Promise<{contentPath: string}> { + }): Promise<{dir: string}> { async function createTmpDir() { return ( await tmp.dir({ @@ -239,13 +239,13 @@ describe('getTagsFile', () => { const finalFilePath = path.join(contentPath, filePath); const fileContent = YAML.dump(tagsFileInput); await fs.writeFile(finalFilePath, fileContent); - return {contentPath}; + return {dir: contentPath}; } type Params = Parameters[0]; it('reads tags file - regular', async () => { - const {contentPath} = await createTestTagsFile({ + const {dir} = await createTestTagsFile({ filePath: 'tags.yml', tagsFileInput: { tag1: {label: 'Tag1 Label'}, @@ -258,7 +258,10 @@ describe('getTagsFile', () => { }, }); - const params: Params = {contentPath, tags: 'tags.yml'}; + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: 'tags.yml', + }; await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` { @@ -282,14 +285,17 @@ describe('getTagsFile', () => { }); it('reads tags file - only keys', async () => { - const {contentPath} = await createTestTagsFile({ + const {dir} = await createTestTagsFile({ filePath: 'tags.yml', tagsFileInput: { tagKey: null, }, }); - const params: Params = {contentPath, tags: 'tags.yml'}; + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: 'tags.yml', + }; await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` { @@ -303,14 +309,17 @@ describe('getTagsFile', () => { }); it('reads tags file - tags option undefined', async () => { - const {contentPath} = await createTestTagsFile({ + const {dir} = await createTestTagsFile({ filePath: 'tags.yml', tagsFileInput: { tag: {label: 'tag label'}, }, }); - const params: Params = {contentPath, tags: undefined}; + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: undefined, + }; await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` { @@ -324,25 +333,62 @@ describe('getTagsFile', () => { }); it('reads tags file - empty file', async () => { - const {contentPath} = await createTestTagsFile({ + const {dir} = await createTestTagsFile({ filePath: 'tags.yml', tagsFileInput: {}, }); - const params: Params = {contentPath, tags: undefined}; + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: undefined, + }; await expect(getTagsFile(params)).resolves.toEqual({}); }); + it('reads tags file - prioritizes reading from localized content path', async () => { + const {dir} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: { + tag: {label: 'tag label'}, + }, + }); + + const {dir: dirLocalized} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: { + tag: {label: 'tag label (localized)'}, + }, + }); + + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dirLocalized}, + tags: undefined, + }; + + await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` + { + "tag": { + "description": undefined, + "label": "tag label (localized)", + "permalink": "/tag", + }, + } + `); + }); + it('reads tags file - custom tags file path', async () => { - const {contentPath} = await createTestTagsFile({ + const {dir} = await createTestTagsFile({ filePath: 'custom-tags-path.yml', tagsFileInput: { tag: {label: 'tag label'}, }, }); - const params: Params = {contentPath, tags: 'custom-tags-path.yml'}; + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: 'custom-tags-path.yml', + }; await expect(getTagsFile(params)).resolves.toMatchInlineSnapshot(` { @@ -355,38 +401,75 @@ describe('getTagsFile', () => { `); }); + it('throws if duplicate permalink', async () => { + const {dir} = await createTestTagsFile({ + filePath: 'tags.yml', + tagsFileInput: { + tag1: {permalink: '/duplicate'}, + tag2: {permalink: '/duplicate'}, + }, + }); + + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: undefined, + }; + + await expect(getTagsFile(params)).rejects.toMatchInlineSnapshot(` + [Error: Duplicate permalinks found in tags file: + - /duplicate] + `); + }); + it('throws if custom tags file path does not exist', async () => { - const params: Params = {contentPath: 'any', tags: 'custom-tags-path.yml'}; + const params: Params = { + contentPaths: {contentPath: 'any', contentPathLocalized: 'localizedAny'}, + tags: 'custom-tags-path.yml', + }; - await expect( - getTagsFile(params), - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"No tags file could be found at path any/custom-tags-path.yml"`, - ); + await expect(getTagsFile(params)).rejects + .toThrowErrorMatchingInlineSnapshot(` + "No tags file 'custom-tags-path.yml' could be found in any of those directories: + - localizedAny + - any" + `); }); it('does not read tags file - tags option null/false', async () => { - const {contentPath} = await createTestTagsFile({ + const {dir} = await createTestTagsFile({ filePath: 'tags.yml', tagsFileInput: { tag: {label: 'tag label'}, }, }); - await expect(getTagsFile({contentPath, tags: null})).resolves.toBeNull(); - await expect(getTagsFile({contentPath, tags: false})).resolves.toBeNull(); + await expect( + getTagsFile({ + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: null, + }), + ).resolves.toBeNull(); + await expect( + getTagsFile({ + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: false, + }), + ).resolves.toBeNull(); }); it('does not read tags file - tags files has non-default name', async () => { - const {contentPath} = await createTestTagsFile({ + const {dir} = await createTestTagsFile({ filePath: 'bad-tags-file-name.yml', tagsFileInput: { tag: {label: 'tag label'}, }, }); - await expect( - getTagsFile({contentPath, tags: undefined}), - ).resolves.toBeNull(); + const params: Params = { + contentPaths: {contentPath: dir, contentPathLocalized: dir}, + tags: undefined, + }; + + await expect(getTagsFile(params)).resolves.toBeNull(); }); }); diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 540859062e97..b32a16ec50f4 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -5,12 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -import path from 'path'; import fs from 'fs-extra'; import _ from 'lodash'; import Joi from 'joi'; import YAML from 'js-yaml'; +import {getContentPathList, getDataFilePath} from '@docusaurus/utils'; import type { + ContentPaths, TagsFile, TagsFileInput, TagsPluginOptions, @@ -59,30 +60,38 @@ export function normalizeTagsFile(data: TagsFileInput): TagsFile { } export async function getTagsFile({ - contentPath, tags, + contentPaths, }: { tags: TagsPluginOptions['tags']; - contentPath: string; + contentPaths: ContentPaths; }): Promise { if (tags === false || tags === null) { return null; } - const defaultFileName = 'tags.yml'; + const relativeFilePath = tags || 'tags.yml'; - const filename = tags || defaultFileName; - const tagDefinitionPath = path.join(contentPath, filename); - const isFileExists = await fs.pathExists(tagDefinitionPath); + // if returned path is defined, the file exists (localized or not) + const yamlFilePath = await getDataFilePath({ + contentPaths, + filePath: relativeFilePath, + }); - if (tags === undefined && !isFileExists) { + // If the tags option is undefined, don't throw when the file does not exist + // Retro-compatible behavior: existing sites do not yet have tags.yml + if (tags === undefined && !yamlFilePath) { return null; } - if (!isFileExists) { - throw new Error(`No tags file could be found at path ${tagDefinitionPath}`); + if (!yamlFilePath) { + throw new Error( + `No tags file '${relativeFilePath}' could be found in any of those directories:\n- ${getContentPathList( + contentPaths, + ).join('\n- ')}`, + ); } - const tagDefinitionContent = await fs.readFile(tagDefinitionPath, 'utf-8'); + const tagDefinitionContent = await fs.readFile(yamlFilePath, 'utf-8'); if (!tagDefinitionContent.trim()) { return {}; } From e91e03c16444651e2e8eb4bd84e47ddbdfbff9e6 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 30 May 2024 19:30:21 +0200 Subject: [PATCH 119/142] fix getTagsFile usage in blog + docs --- packages/docusaurus-plugin-content-blog/src/blogUtils.ts | 2 +- packages/docusaurus-plugin-content-docs/src/index.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index e75b085168ff..24510dbc80d3 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -383,7 +383,7 @@ export async function generateBlogPosts( authorsMapPath: options.authorsMapPath, }); - const tagsFile = await getTagsFile(options, contentPaths.contentPath); + const tagsFile = await getTagsFile({contentPaths, tags: options.tags}); async function doProcessBlogSourceFile(blogSourceFile: string) { try { diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index c867f381a54f..2807acf4faed 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -164,10 +164,10 @@ export default async function pluginContentDocs( async function doLoadVersion( versionMetadata: VersionMetadata, ): Promise { - const tagsFile = await getTagsFile( - options, - versionMetadata.contentPath, - ); + const tagsFile = await getTagsFile({ + contentPaths: versionMetadata, + tags: options.tags, + }); const docsBase: DocMetadataBase[] = await loadVersionDocsBase( versionMetadata, From 11f1c3149dfb8100c6fa072c2b9ba430655e2afa Mon Sep 17 00:00:00 2001 From: slorber Date: Thu, 30 May 2024 17:35:00 +0000 Subject: [PATCH 120/142] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index aed1f66a43ed..0125953ec975 100644 --- a/project-words.txt +++ b/project-words.txt @@ -353,6 +353,7 @@ Supabase svgr SVGR swizzlable +Tagkey Teik templating Thanos From f36c468609277c9240b68ceb2919c4349e9cbe88 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 11:44:43 +0200 Subject: [PATCH 121/142] DocTagDocListPageMetadata, add missing description seo meta --- .../src/theme/DocTagDocListPage/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx index c08cf342dc87..aa56a14ef31d 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx @@ -63,10 +63,11 @@ function DocItem({doc}: {doc: Props['tag']['items'][number]}): JSX.Element { function DocTagDocListPageMetadata({ title, + tag, }: Props & {title: string}): JSX.Element { return ( <> - + ); From bea279f1ddd165dc8105d5db47b7189edb23421a Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 11:54:07 +0200 Subject: [PATCH 122/142] add docs plugin option tests for tags options --- .../src/__tests__/options.test.ts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts index 260eaccb22d5..db43660088bf 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts @@ -70,6 +70,8 @@ describe('normalizeDocsPluginOptions', () => { disableVersioning: true, editCurrentVersion: true, editLocalizedFiles: true, + tags: 'docsTags.yml', + onInlineTags: 'throw', versions: { current: { path: 'next', @@ -266,4 +268,68 @@ describe('normalizeDocsPluginOptions', () => { }).sidebarCollapsed, ).toBe(false); }); + + describe('tags', () => { + it('accepts tags - undefined', () => { + expect(testValidate({tags: undefined}).tags).toBeUndefined(); + }); + + it('accepts tags - null', () => { + expect(testValidate({tags: null}).tags).toBeNull(); + }); + + it('accepts tags - false', () => { + expect(testValidate({tags: false}).tags).toBeFalsy(); + }); + + it('accepts tags - customTags.yml', () => { + expect(testValidate({tags: 'customTags.yml'}).tags).toBe( + 'customTags.yml', + ); + }); + + it('rejects tags - 42', () => { + // @ts-expect-error: test + expect(() => testValidate({tags: 42})).toThrowErrorMatchingInlineSnapshot( + `""tags" must be a string"`, + ); + }); + }); + + describe('onInlineTags', () => { + it('accepts onInlineTags - undefined', () => { + expect(testValidate({onInlineTags: undefined}).onInlineTags).toBe('warn'); + }); + + it('accepts onInlineTags - "throw"', () => { + expect(testValidate({onInlineTags: 'throw'}).onInlineTags).toBe('throw'); + }); + + it('rejects onInlineTags - "trace"', () => { + expect(() => + // @ts-expect-error: test + testValidate({onInlineTags: 'trace'}), + ).toThrowErrorMatchingInlineSnapshot( + `""onInlineTags" must be one of [ignore, log, warn, throw]"`, + ); + }); + + it('rejects onInlineTags - null', () => { + expect(() => + // @ts-expect-error: test + testValidate({onInlineTags: 42}), + ).toThrowErrorMatchingInlineSnapshot( + `""onInlineTags" must be one of [ignore, log, warn, throw]"`, + ); + }); + + it('rejects onInlineTags - 42', () => { + expect(() => + // @ts-expect-error: test + testValidate({onInlineTags: 42}), + ).toThrowErrorMatchingInlineSnapshot( + `""onInlineTags" must be one of [ignore, log, warn, throw]"`, + ); + }); + }); }); From 7edec838c662636fed6f3930ece69be792466559 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 12:05:32 +0200 Subject: [PATCH 123/142] docs tests: make createTestUtils async --- .../src/__tests__/docs.test.ts | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index 8107e78f05ea..db27d743a462 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -6,7 +6,7 @@ */ import {jest} from '@jest/globals'; -import path from 'path'; +import * as path from 'path'; import {loadContext} from '@docusaurus/core/src/server/site'; import { createSlugger, @@ -14,6 +14,7 @@ import { DEFAULT_PLUGIN_ID, LAST_UPDATE_FALLBACK, } from '@docusaurus/utils'; +import {getTagsFile} from '@docusaurus/utils-validation'; import {createSidebarsUtils} from '../sidebars/utils'; import { processDocMetadata, @@ -73,13 +74,18 @@ type TestUtilsArg = { env?: DocEnv; }; -function createTestUtils({ +async function createTestUtils({ siteDir, context, versionMetadata, options, env = 'production', }: TestUtilsArg) { + const tagsFile = await getTagsFile({ + contentPaths: versionMetadata, + tags: options.tags, + }); + async function readDoc(docFileSource: string) { return readDocFile(versionMetadata, docFileSource); } @@ -93,7 +99,7 @@ function createTestUtils({ options, context, env, - tagsFile: null, + tagsFile, }); } @@ -184,7 +190,6 @@ function createTestUtils({ pagination: addDocNavigation({ docs: rawDocs, sidebarsUtils, - sidebarFilePath: versionMetadata.sidebarFilePath as string, }).map((doc) => ({prev: doc.previous, next: doc.next, id: doc.id})), sidebars, }; @@ -217,7 +222,7 @@ describe('simple site', () => { expect(versionsMetadata).toHaveLength(1); const currentVersion = versionsMetadata[0]!; - function createTestUtilsPartial(args: Partial) { + async function createTestUtilsPartial(args: Partial) { return createTestUtils({ siteDir, context, @@ -227,7 +232,7 @@ describe('simple site', () => { }); } - const defaultTestUtils = createTestUtilsPartial({}); + const defaultTestUtils = await createTestUtilsPartial({}); return { siteDir, @@ -312,11 +317,13 @@ describe('simple site', () => { label: 'tag-1', inline: true, permalink: '/docs/tags/tag-1', + description: undefined, }, { label: 'tag 3', inline: true, permalink: '/docs/tags/tag-3', + description: undefined, }, ], unlisted: false, @@ -331,7 +338,7 @@ describe('simple site', () => { }, }); - const testUtilsLocal = createTestUtilsPartial({ + const testUtilsLocal = await createTestUtilsPartial({ siteDir, context, options, @@ -417,7 +424,7 @@ describe('simple site', () => { }, }); - const testUtilsLocal = createTestUtilsPartial({ + const testUtilsLocal = await createTestUtilsPartial({ siteDir, context, options, @@ -487,7 +494,7 @@ describe('simple site', () => { }, }); - const testUtilsLocal = createTestUtilsPartial({ + const testUtilsLocal = await createTestUtilsPartial({ siteDir, context, options, @@ -517,7 +524,7 @@ describe('simple site', () => { it('docs with draft frontmatter', async () => { const {createTestUtilsPartial} = await loadSite(); - const testUtilsProd = createTestUtilsPartial({ + const testUtilsProd = await createTestUtilsPartial({ env: 'production', }); await expect( @@ -526,7 +533,7 @@ describe('simple site', () => { draft: true, }); - const testUtilsDev = createTestUtilsPartial({ + const testUtilsDev = await createTestUtilsPartial({ env: 'development', }); await expect( @@ -554,7 +561,7 @@ describe('simple site', () => { tags: [], }; - const testUtilsProd = createTestUtilsPartial({ + const testUtilsProd = await createTestUtilsPartial({ env: 'production', }); @@ -563,7 +570,7 @@ describe('simple site', () => { unlisted: true, }); - const testUtilsDev = createTestUtilsPartial({ + const testUtilsDev = await createTestUtilsPartial({ env: 'development', }); @@ -582,7 +589,7 @@ describe('simple site', () => { }, }); - const testUtilsLocal = createTestUtilsPartial({ + const testUtilsLocal = await createTestUtilsPartial({ siteDir, context, options, @@ -621,7 +628,7 @@ describe('simple site', () => { }, }); - const testUtilsLocal = createTestUtilsPartial({ + const testUtilsLocal = await createTestUtilsPartial({ siteDir, context, options, @@ -659,7 +666,7 @@ describe('simple site', () => { }, }); - const testUtilsLocal = createTestUtilsPartial({ + const testUtilsLocal = await createTestUtilsPartial({ siteDir, context, options, @@ -697,7 +704,7 @@ describe('simple site', () => { }, }); - const testUtilsLocal = createTestUtilsPartial({ + const testUtilsLocal = await createTestUtilsPartial({ siteDir, context, options, @@ -789,7 +796,7 @@ describe('simple site', () => { it('custom pagination - production', async () => { const {createTestUtilsPartial, options, versionsMetadata} = await loadSite(); - const testUtils = createTestUtilsPartial({env: 'production'}); + const testUtils = await createTestUtilsPartial({env: 'production'}); const docs = await readVersionDocs(versionsMetadata[0]!, options); await expect(testUtils.generateNavigation(docs)).resolves.toMatchSnapshot(); }); @@ -797,7 +804,7 @@ describe('simple site', () => { it('custom pagination - development', async () => { const {createTestUtilsPartial, options, versionsMetadata} = await loadSite(); - const testUtils = createTestUtilsPartial({env: 'development'}); + const testUtils = await createTestUtilsPartial({env: 'development'}); const docs = await readVersionDocs(versionsMetadata[0]!, options); await expect(testUtils.generateNavigation(docs)).resolves.toMatchSnapshot(); }); @@ -846,27 +853,27 @@ describe('versioned site', () => { const version100 = versionsMetadata[2]!; const versionWithSlugs = versionsMetadata[3]!; - const currentVersionTestUtils = createTestUtils({ + const currentVersionTestUtils = await createTestUtils({ siteDir, context, options, versionMetadata: currentVersion, }); - const version101TestUtils = createTestUtils({ + const version101TestUtils = await createTestUtils({ siteDir, context, options, versionMetadata: version101, }); - const version100TestUtils = createTestUtils({ + const version100TestUtils = await createTestUtils({ siteDir, context, options, versionMetadata: version100, }); - const versionWithSlugsTestUtils = createTestUtils({ + const versionWithSlugsTestUtils = await createTestUtils({ siteDir, context, options, @@ -914,16 +921,19 @@ describe('versioned site', () => { label: 'barTag 1', inline: true, permalink: '/docs/next/tags/bar-tag-1', + description: undefined, }, { label: 'barTag-2', inline: true, permalink: '/docs/next/tags/bar-tag-2', + description: undefined, }, { label: 'barTag 3', inline: true, permalink: '/docs/next/tags/barTag-3-permalink', + description: undefined, }, ], unlisted: false, @@ -1073,7 +1083,7 @@ describe('versioned site', () => { }, }); - const testUtilsLocal = createTestUtils({ + const testUtilsLocal = await createTestUtils({ siteDir, context, options, @@ -1115,7 +1125,7 @@ describe('versioned site', () => { }, }); - const testUtilsLocal = createTestUtils({ + const testUtilsLocal = await createTestUtils({ siteDir, context, options, @@ -1150,7 +1160,7 @@ describe('versioned site', () => { }, }); - const testUtilsLocal = createTestUtils({ + const testUtilsLocal = await createTestUtils({ siteDir, context, options, @@ -1186,7 +1196,7 @@ describe('versioned site', () => { locale: 'fr', }); - const testUtilsLocal = createTestUtils({ + const testUtilsLocal = await createTestUtils({ siteDir, context, options, @@ -1223,7 +1233,7 @@ describe('versioned site', () => { locale: 'fr', }); - const testUtilsLocal = createTestUtils({ + const testUtilsLocal = await createTestUtils({ siteDir, context, options, From c0b28ae54c82622cfd3fd42a1e1bedbbdfa955c4 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 12:09:35 +0200 Subject: [PATCH 124/142] tests: ensure docs can read global tags --- .../__fixtures__/simple-site/docs/foo/baz.md | 1 + .../__fixtures__/simple-site/docs/tags.yml | 5 +++++ .../src/__tests__/docs.test.ts | 14 ++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md index c3f676e276ad..de766e7cb1a4 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md @@ -5,6 +5,7 @@ slug: bazSlug.html pagination_label: baz pagination_label tags: - tag 1 + - globalTag1 - tag-1 - label: tag 2 permalink: tag2-custom-permalink diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/tags.yml new file mode 100644 index 000000000000..1a12f092670c --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/docs/tags.yml @@ -0,0 +1,5 @@ + +globalTag1: + label: 'Global Tag 1 label' + description: 'Global Tag 1 description' + permalink: 'global-tag-1-permalink' diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index db27d743a462..e6488f1723f6 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -363,6 +363,7 @@ describe('simple site', () => { pagination_label: 'baz pagination_label', tags: [ 'tag 1', + 'globalTag1', 'tag-1', {label: 'tag 2', permalink: 'tag2-custom-permalink'}, ], @@ -374,6 +375,12 @@ describe('simple site', () => { label: 'tag 1', permalink: '/docs/tags/tag-1', }, + { + description: 'Global Tag 1 description', + inline: false, + label: 'Global Tag 1 label', + permalink: '/docs/tags/global-tag-1-permalink', + }, { description: undefined, inline: true, @@ -448,6 +455,7 @@ describe('simple site', () => { pagination_label: 'baz pagination_label', tags: [ 'tag 1', + 'globalTag1', 'tag-1', {label: 'tag 2', permalink: 'tag2-custom-permalink'}, ], @@ -459,6 +467,12 @@ describe('simple site', () => { label: 'tag 1', permalink: '/docs/tags/tag-1', }, + { + description: 'Global Tag 1 description', + inline: false, + label: 'Global Tag 1 label', + permalink: '/docs/tags/global-tag-1-permalink', + }, { description: undefined, inline: true, From a09f643399e8d123ceb1259b9bc9673cacde9361 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 12:13:10 +0200 Subject: [PATCH 125/142] tests: ensure docs can read versioned tags --- .../versioned_docs/version-1.0.1/hello.md | 2 ++ .../versioned_docs/version-1.0.1/tags.yml | 5 +++++ .../src/__tests__/docs.test.ts | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md index a9950ade90f6..fdb26f67c035 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md @@ -1,4 +1,6 @@ --- slug: / +tags: [inlineTag, globalTag-v1.0.1] --- + Hello `1.0.1` ! diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/tags.yml new file mode 100644 index 000000000000..e483ca75d45d --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/tags.yml @@ -0,0 +1,5 @@ + +globalTag-v1.0.1: + label: 'globalTag-v1.0.1 label' + description: 'globalTag-v1.0.1 description' + permalink: 'globalTag-v1.0.1 permalink' diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index e6488f1723f6..e45a4d997f95 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -1021,8 +1021,22 @@ describe('versioned site', () => { version: '1.0.1', frontMatter: { slug: '/', + tags: ['inlineTag', 'globalTag-v1.0.1'], }, - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag', + permalink: '/docs/tags/inline-tag', + }, + { + description: 'globalTag-v1.0.1 description', + inline: false, + label: 'globalTag-v1.0.1 label', + permalink: '/docs/tags/globalTag-v1.0.1 permalink', + }, + ], unlisted: false, }); }); From b74f731e5f959ec049e62601229f69c60aeada56 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 12:29:46 +0200 Subject: [PATCH 126/142] docs test, ensure tags file works with versioning and i18n --- .../version-1.0.0/hello.md | 2 + .../version-1.0.0/tags.yml | 5 + .../version-1.0.0/hello.md | 2 + .../version-1.0.0/tags.yml | 5 + .../versioned_docs/version-1.0.0/hello.md | 2 + .../versioned_docs/version-1.0.0/tags.yml | 5 + .../versioned_docs/version-1.0.1/hello.md | 2 +- .../src/__tests__/docs.test.ts | 102 ++++++++++++++++-- 8 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/tags.yml create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/tags.yml create mode 100644 packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/tags.yml diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md index 6940424b1919..7fed3dbd343c 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md @@ -1,4 +1,6 @@ --- slug: / +tags: [inlineTag-v1.0.0, globalTag-v1.0.0] --- + Hello `1.0.0` ! (translated en) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/tags.yml new file mode 100644 index 000000000000..60368a293593 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/tags.yml @@ -0,0 +1,5 @@ + +globalTag-v1.0.0: + label: 'globalTag-v1.0.0 label (en)' + description: 'globalTag-v1.0.0 description (en)' + permalink: 'globalTag-v1.0.0 permalink (en)' diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md index 5cf148d17a50..0e2a3969e4d0 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md @@ -1,4 +1,6 @@ --- slug: / +tags: [inlineTag-v1.0.0, globalTag-v1.0.0] --- + Hello `1.0.0` ! (translated fr) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/tags.yml new file mode 100644 index 000000000000..7b72346f9c4e --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/tags.yml @@ -0,0 +1,5 @@ + +globalTag-v1.0.0: + label: 'globalTag-v1.0.0 label (fr)' + description: 'globalTag-v1.0.0 description (fr)' + permalink: 'globalTag-v1.0.0 permalink (fr)' diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md index db13f1d75bad..b535fbbfbf72 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md @@ -1,4 +1,6 @@ --- slug: / +tags: [inlineTag-v1.0.0, globalTag-v1.0.0] --- + Hello `1.0.0` ! diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/tags.yml b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/tags.yml new file mode 100644 index 000000000000..a348b603d04b --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/tags.yml @@ -0,0 +1,5 @@ + +globalTag-v1.0.0: + label: 'globalTag-v1.0.0 label' + description: 'globalTag-v1.0.0 description' + permalink: 'globalTag-v1.0.0 permalink' diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md index fdb26f67c035..60a7a3c869b2 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md @@ -1,6 +1,6 @@ --- slug: / -tags: [inlineTag, globalTag-v1.0.1] +tags: [inlineTag-v1.0.1, globalTag-v1.0.1] --- Hello `1.0.1` ! diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index e45a4d997f95..2e033b2f1c7b 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -992,11 +992,25 @@ describe('versioned site', () => { description: 'Hello 1.0.0 ! (translated en)', frontMatter: { slug: '/', + tags: ['inlineTag-v1.0.0', 'globalTag-v1.0.0'], }, version: '1.0.0', source: '@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md', - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag-v1.0.0', + permalink: '/docs/1.0.0/tags/inline-tag-v-1-0-0', + }, + { + description: 'globalTag-v1.0.0 description (en)', + inline: false, + label: 'globalTag-v1.0.0 label (en)', + permalink: '/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)', + }, + ], unlisted: false, }); await version101TestUtils.testMeta(path.join('foo', 'bar.md'), { @@ -1021,14 +1035,14 @@ describe('versioned site', () => { version: '1.0.1', frontMatter: { slug: '/', - tags: ['inlineTag', 'globalTag-v1.0.1'], + tags: ['inlineTag-v1.0.1', 'globalTag-v1.0.1'], }, tags: [ { description: undefined, inline: true, - label: 'inlineTag', - permalink: '/docs/tags/inline-tag', + label: 'inlineTag-v1.0.1', + permalink: '/docs/tags/inline-tag-v-1-0-1', }, { description: 'globalTag-v1.0.1 description', @@ -1127,12 +1141,26 @@ describe('versioned site', () => { description: 'Hello 1.0.0 ! (translated en)', frontMatter: { slug: '/', + tags: ['inlineTag-v1.0.0', 'globalTag-v1.0.0'], }, version: '1.0.0', source: '@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md', editUrl: hardcodedEditUrl, - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag-v1.0.0', + permalink: '/docs/1.0.0/tags/inline-tag-v-1-0-0', + }, + { + description: 'globalTag-v1.0.0 description (en)', + inline: false, + label: 'globalTag-v1.0.0 label (en)', + permalink: '/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)', + }, + ], unlisted: false, }); @@ -1169,13 +1197,27 @@ describe('versioned site', () => { description: 'Hello 1.0.0 ! (translated en)', frontMatter: { slug: '/', + tags: ['inlineTag-v1.0.0', 'globalTag-v1.0.0'], }, version: '1.0.0', source: '@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md', editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/versioned_docs/version-1.0.0/hello.md', - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag-v1.0.0', + permalink: '/docs/1.0.0/tags/inline-tag-v-1-0-0', + }, + { + description: 'globalTag-v1.0.0 description (en)', + inline: false, + label: 'globalTag-v1.0.0 label (en)', + permalink: '/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)', + }, + ], unlisted: false, }); }); @@ -1204,13 +1246,27 @@ describe('versioned site', () => { description: 'Hello 1.0.0 ! (translated en)', frontMatter: { slug: '/', + tags: ['inlineTag-v1.0.0', 'globalTag-v1.0.0'], }, version: '1.0.0', source: '@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md', editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/docs/hello.md', - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag-v1.0.0', + permalink: '/docs/1.0.0/tags/inline-tag-v-1-0-0', + }, + { + description: 'globalTag-v1.0.0 description (en)', + inline: false, + label: 'globalTag-v1.0.0 label (en)', + permalink: '/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)', + }, + ], unlisted: false, }); }); @@ -1240,13 +1296,27 @@ describe('versioned site', () => { description: 'Hello 1.0.0 ! (translated fr)', frontMatter: { slug: '/', + tags: ['inlineTag-v1.0.0', 'globalTag-v1.0.0'], }, version: '1.0.0', source: '@site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md', editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md', - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag-v1.0.0', + permalink: '/fr/docs/1.0.0/tags/inline-tag-v-1-0-0', + }, + { + description: 'globalTag-v1.0.0 description (fr)', + inline: false, + label: 'globalTag-v1.0.0 label (fr)', + permalink: '/fr/docs/1.0.0/tags/globalTag-v1.0.0 permalink (fr)', + }, + ], unlisted: false, }); }); @@ -1277,13 +1347,27 @@ describe('versioned site', () => { description: 'Hello 1.0.0 ! (translated fr)', frontMatter: { slug: '/', + tags: ['inlineTag-v1.0.0', 'globalTag-v1.0.0'], }, version: '1.0.0', source: '@site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md', editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/i18n/fr/docusaurus-plugin-content-docs/current/hello.md', - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag-v1.0.0', + permalink: '/fr/docs/1.0.0/tags/inline-tag-v-1-0-0', + }, + { + description: 'globalTag-v1.0.0 description (fr)', + inline: false, + label: 'globalTag-v1.0.0 label (fr)', + permalink: '/fr/docs/1.0.0/tags/globalTag-v1.0.0 permalink (fr)', + }, + ], unlisted: false, }); }); From 68e5444e3dbbca8166e4e2f19be2a51f856ddbc2 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 12:37:30 +0200 Subject: [PATCH 127/142] add blog options tests --- .../src/__tests__/options.test.ts | 68 ++++++++++++++++++- .../src/plugin-content-blog.d.ts | 1 - 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts index 8133d10df1fb..3e925cf10687 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts @@ -36,13 +36,15 @@ describe('validateOptions', () => { }); it('accepts correctly defined user options', () => { - const userOptions = { + const userOptions: Options = { ...defaultOptions, feedOptions: {type: 'rss' as const, title: 'myTitle'}, path: 'not_blog', routeBasePath: '/myBlog', postsPerPage: 5, include: ['api/*', 'docs/*'], + tags: 'customTags.yml', + onInlineTags: 'warn', }; expect(testValidate(userOptions)).toEqual({ ...userOptions, @@ -172,4 +174,68 @@ describe('validateOptions', () => { `""blogSidebarTitle" must be a string"`, ); }); + + describe('tags', () => { + it('accepts tags - undefined', () => { + expect(testValidate({tags: undefined}).tags).toBeUndefined(); + }); + + it('accepts tags - null', () => { + expect(testValidate({tags: null}).tags).toBeNull(); + }); + + it('accepts tags - false', () => { + expect(testValidate({tags: false}).tags).toBeFalsy(); + }); + + it('accepts tags - customTags.yml', () => { + expect(testValidate({tags: 'customTags.yml'}).tags).toBe( + 'customTags.yml', + ); + }); + + it('rejects tags - 42', () => { + // @ts-expect-error: test + expect(() => testValidate({tags: 42})).toThrowErrorMatchingInlineSnapshot( + `""tags" must be a string"`, + ); + }); + }); + + describe('onInlineTags', () => { + it('accepts onInlineTags - undefined', () => { + expect(testValidate({onInlineTags: undefined}).onInlineTags).toBe('warn'); + }); + + it('accepts onInlineTags - "throw"', () => { + expect(testValidate({onInlineTags: 'throw'}).onInlineTags).toBe('throw'); + }); + + it('rejects onInlineTags - "trace"', () => { + expect(() => + // @ts-expect-error: test + testValidate({onInlineTags: 'trace'}), + ).toThrowErrorMatchingInlineSnapshot( + `""onInlineTags" must be one of [ignore, log, warn, throw]"`, + ); + }); + + it('rejects onInlineTags - null', () => { + expect(() => + // @ts-expect-error: test + testValidate({onInlineTags: 42}), + ).toThrowErrorMatchingInlineSnapshot( + `""onInlineTags" must be one of [ignore, log, warn, throw]"`, + ); + }); + + it('rejects onInlineTags - 42', () => { + expect(() => + // @ts-expect-error: test + testValidate({onInlineTags: 42}), + ).toThrowErrorMatchingInlineSnapshot( + `""onInlineTags" must be one of [ignore, log, warn, throw]"`, + ); + }); + }); }); diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 69670ac2b463..a9e78d5c9b45 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -97,7 +97,6 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the * Front matter tags, unnormalized. * @see {@link BlogPostMetadata.tags} */ - // TODO NormalizedTag ?? tags?: FrontMatterTag[]; /** Custom slug appended after `///` */ slug?: string; From 42723f8016c92a0c5f8a41a4b4b89ae4992e460d Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 12:48:17 +0200 Subject: [PATCH 128/142] tests: ensure blog can use tags files with i18n support --- .../2018-12-14-Happy-First-Birthday-Slash.md | 2 +- .../__tests__/__fixtures__/website/blog/tags.yml | 5 +++++ .../2018-12-14-Happy-First-Birthday-Slash.md | 1 + .../en/docusaurus-plugin-content-blog/tags.yml | 5 +++++ .../src/__tests__/index.test.ts | 16 +++++++++++++++- 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/tags.yml create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/tags.yml 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 02350da6d298..10ba9373aa47 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 @@ -3,7 +3,7 @@ title: Happy 1st Birthday Slash! authors: - name: Yangshun Tay - slorber -tags: [birthday] +tags: [birthday,inlineTag,globalTag] --- Happy birthday! diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/tags.yml b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/tags.yml new file mode 100644 index 000000000000..04d2fbef7028 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/tags.yml @@ -0,0 +1,5 @@ + +globalTag: + label: 'Global Tag label' + description: 'Global Tag description' + permalink: '/tags/global-tag-permalink' diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/2018-12-14-Happy-First-Birthday-Slash.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/2018-12-14-Happy-First-Birthday-Slash.md index b015e77fb557..7b25e16ce1fa 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/2018-12-14-Happy-First-Birthday-Slash.md +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/2018-12-14-Happy-First-Birthday-Slash.md @@ -3,6 +3,7 @@ title: Happy 1st Birthday Slash! (translated) authors: - name: Yangshun Tay (translated) - slorber +tags: [inlineTag,globalTag] --- Happy birthday! (translated) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/tags.yml b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/tags.yml new file mode 100644 index 000000000000..6b826f7bf78e --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/tags.yml @@ -0,0 +1,5 @@ + +globalTag: + label: 'Global Tag label (en)' + description: 'Global Tag description (en)' + permalink: 'global-tag-permalink (en)' diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index 624846fd2f26..a12e581062e3 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -234,9 +234,23 @@ describe('blog plugin', () => { }, 'slorber', ], + tags: ['inlineTag', 'globalTag'], title: 'Happy 1st Birthday Slash! (translated)', }, - tags: [], + tags: [ + { + description: undefined, + inline: true, + label: 'inlineTag', + permalink: '/blog/tags/inline-tag', + }, + { + description: 'Global Tag description (en)', + inline: false, + label: 'Global Tag label (en)', + permalink: '/blog/tags/global-tag-permalink (en)', + }, + ], prevItem: { permalink: '/blog/date-matter', title: 'date-matter', From b345c22e592f21f8bc147a344b913e96f4ce9af1 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 13:10:16 +0200 Subject: [PATCH 129/142] wire hot reload for tags file --- .../src/index.ts | 14 ++++- .../src/index.ts | 9 ++- .../src/__tests__/tagsFile.test.ts | 63 +++++++++++++++++++ .../docusaurus-utils-validation/src/index.ts | 2 +- .../src/tagsFile.ts | 29 +++++++-- 5 files changed, 107 insertions(+), 10 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index dc64b8b45155..19dfb1a5d2ad 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -20,6 +20,7 @@ import { DEFAULT_PLUGIN_ID, resolveMarkdownLinkPathname, } from '@docusaurus/utils'; +import {getTagsFilePathsToWatch} from '@docusaurus/utils-validation'; import { getSourceToPermalink, getBlogTags, @@ -104,9 +105,16 @@ export default async function pluginContentBlog( (contentPath) => include.map((pattern) => `${contentPath}/${pattern}`), ); - return [authorsMapFilePath, ...contentMarkdownGlobs].filter( - Boolean, - ) as string[]; + const tagsFilePaths = getTagsFilePathsToWatch({ + contentPaths, + tags: options.tags, + }); + + return [ + authorsMapFilePath, + ...tagsFilePaths, + ...contentMarkdownGlobs, + ].filter(Boolean) as string[]; }, getTranslationFiles() { diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 2807acf4faed..0f0ae32458ee 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -20,7 +20,10 @@ import { resolveMarkdownLinkPathname, DEFAULT_PLUGIN_ID, } from '@docusaurus/utils'; -import {getTagsFile} from '@docusaurus/utils-validation'; +import { + getTagsFile, + getTagsFilePathsToWatch, +} from '@docusaurus/utils-validation'; import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {CategoryMetadataFilenamePattern} from './sidebars/generator'; import { @@ -121,6 +124,10 @@ export default async function pluginContentDocs( (docsDirPath) => `${docsDirPath}/${pattern}`, ), ), + ...getTagsFilePathsToWatch({ + contentPaths: version, + tags: options.tags, + }), `${version.contentPath}/**/${CategoryMetadataFilenamePattern}`, ]; if (typeof version.sidebarFilePath === 'string') { diff --git a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts index 8832b81ef760..149c56a14274 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/tagsFile.test.ts @@ -12,6 +12,7 @@ import * as YAML from 'js-yaml'; import { ensureUniquePermalinks, getTagsFile, + getTagsFilePathsToWatch, normalizeTagsFile, } from '../tagsFile'; import type {TagsFile, TagsFileInput} from '@docusaurus/utils'; @@ -220,6 +221,68 @@ describe('normalizeTagsFile', () => { }); }); +describe('getTagsFilePathsToWatch', () => { + it('returns tags file paths - tags undefined', () => { + expect( + getTagsFilePathsToWatch({ + tags: undefined, + contentPaths: { + contentPath: '/user/blog', + contentPathLocalized: '/i18n/blog', + }, + }), + ).toEqual(['/i18n/blog/tags.yml', '/user/blog/tags.yml']); + }); + + it('returns tags file paths - tags.yml', () => { + expect( + getTagsFilePathsToWatch({ + tags: 'tags.yml', + contentPaths: { + contentPath: '/user/blog', + contentPathLocalized: '/i18n/blog', + }, + }), + ).toEqual(['/i18n/blog/tags.yml', '/user/blog/tags.yml']); + }); + + it('returns tags file paths - customTags.yml', () => { + expect( + getTagsFilePathsToWatch({ + tags: 'customTags.yml', + contentPaths: { + contentPath: '/user/blog', + contentPathLocalized: '/i18n/blog', + }, + }), + ).toEqual(['/i18n/blog/customTags.yml', '/user/blog/customTags.yml']); + }); + + it('returns [] - tags: null', () => { + expect( + getTagsFilePathsToWatch({ + tags: null, + contentPaths: { + contentPath: '/user/blog', + contentPathLocalized: '/i18n/blog', + }, + }), + ).toEqual([]); + }); + + it('returns [] - tags: false', () => { + expect( + getTagsFilePathsToWatch({ + tags: false, + contentPaths: { + contentPath: '/user/blog', + contentPathLocalized: '/i18n/blog', + }, + }), + ).toEqual([]); + }); +}); + describe('getTagsFile', () => { async function createTestTagsFile({ filePath, diff --git a/packages/docusaurus-utils-validation/src/index.ts b/packages/docusaurus-utils-validation/src/index.ts index f08134849aea..426e78db8caa 100644 --- a/packages/docusaurus-utils-validation/src/index.ts +++ b/packages/docusaurus-utils-validation/src/index.ts @@ -29,4 +29,4 @@ export { FrontMatterLastUpdateErrorMessage, FrontMatterLastUpdateSchema, } from './validationSchemas'; -export {getTagsFile} from './tagsFile'; +export {getTagsFilePathsToWatch, getTagsFile} from './tagsFile'; diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index b32a16ec50f4..a865acce45b3 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -6,6 +6,7 @@ */ import fs from 'fs-extra'; +import path from 'node:path'; import _ from 'lodash'; import Joi from 'joi'; import YAML from 'js-yaml'; @@ -59,18 +60,36 @@ export function normalizeTagsFile(data: TagsFileInput): TagsFile { }); } +type GetTagsFileParams = { + tags: TagsPluginOptions['tags']; + contentPaths: ContentPaths; +}; + +const DefaultTagsFileName = 'tags.yml'; + +export function getTagsFilePathsToWatch({ + tags, + contentPaths, +}: GetTagsFileParams): string[] { + if (tags === false || tags === null) { + return []; + } + const relativeFilePath = tags ?? DefaultTagsFileName; + + return getContentPathList(contentPaths).map((contentPath) => + path.join(contentPath, relativeFilePath), + ); +} + export async function getTagsFile({ tags, contentPaths, -}: { - tags: TagsPluginOptions['tags']; - contentPaths: ContentPaths; -}): Promise { +}: GetTagsFileParams): Promise { if (tags === false || tags === null) { return null; } - const relativeFilePath = tags || 'tags.yml'; + const relativeFilePath = tags ?? DefaultTagsFileName; // if returned path is defined, the file exists (localized or not) const yamlFilePath = await getDataFilePath({ From 891755c7c9586823ce2094c169c76f8cc94d910b Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 14:39:34 +0200 Subject: [PATCH 130/142] blog getPathsToWatch test --- .../docusaurus-plugin-content-blog/src/__tests__/index.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index a12e581062e3..5280a72c18c8 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -160,6 +160,8 @@ describe('blog plugin', () => { ); expect(relativePathsToWatch).toEqual([ 'i18n/en/docusaurus-plugin-content-blog/authors.yml', + 'i18n/en/docusaurus-plugin-content-blog/tags.yml', + 'blog/tags.yml', 'i18n/en/docusaurus-plugin-content-blog/**/*.{md,mdx}', 'blog/**/*.{md,mdx}', ]); From 58e24ce6ab331aeda983bc376864cfc7ab97f4af Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 14:39:45 +0200 Subject: [PATCH 131/142] update docs snapshots --- .../__snapshots__/index.test.ts.snap | 248 +++++++++++++++++- 1 file changed, 245 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index 496a7283579d..048e97aaee03 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -58,6 +58,7 @@ exports[`simple website content 1`] = ` "slug": "bazSlug.html", "tags": [ "tag 1", + "globalTag1", "tag-1", { "label": "tag 2", @@ -90,6 +91,12 @@ exports[`simple website content 1`] = ` "label": "tag 1", "permalink": "/docs/tags/tag-1", }, + { + "description": "Global Tag 1 description", + "inline": false, + "label": "Global Tag 1 label", + "permalink": "/docs/tags/global-tag-1-permalink", + }, { "description": undefined, "inline": true, @@ -581,6 +588,7 @@ exports[`simple website content: data 1`] = ` "slug": "bazSlug.html", "tags": [ "tag 1", + "globalTag1", "tag-1", { "label": "tag 2", @@ -613,6 +621,12 @@ exports[`simple website content: data 1`] = ` "label": "tag 1", "permalink": "/docs/tags/tag-1", }, + { + "description": "Global Tag 1 description", + "inline": false, + "label": "Global Tag 1 label", + "permalink": "/docs/tags/global-tag-1-permalink", + }, { "description": undefined, "inline": true, @@ -1552,6 +1566,12 @@ exports[`simple website content: route config 1`] = ` "label": "tag 1", "permalink": "/docs/tags/tag-1", }, + { + "count": 1, + "description": "Global Tag 1 description", + "label": "Global Tag 1 label", + "permalink": "/docs/tags/global-tag-1-permalink", + }, { "count": 1, "description": undefined, @@ -1567,6 +1587,29 @@ exports[`simple website content: route config 1`] = ` ], }, }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "path": "/docs/tags/global-tag-1-permalink", + "props": { + "tag": { + "allTagsPath": "/docs/tags", + "count": 1, + "description": "Global Tag 1 description", + "items": [ + { + "description": "Images", + "id": "foo/baz", + "permalink": "/docs/foo/bazSlug.html", + "title": "baz", + }, + ], + "label": "Global Tag 1 label", + "permalink": "/docs/tags/global-tag-1-permalink", + "unlisted": false, + }, + }, + }, { "component": "@theme/DocTagDocListPage", "exact": true, @@ -1963,6 +2006,8 @@ exports[`simple website getPathToWatch 1`] = ` "sidebars.json", "i18n/en/docusaurus-plugin-content-docs/current/**/*.{md,mdx}", "docs/**/*.{md,mdx}", + "i18n/en/docusaurus-plugin-content-docs/current/tags.yml", + "docs/tags.yml", "docs/**/_category_.{json,yml,yaml}", ] `; @@ -3283,10 +3328,14 @@ exports[`versioned website (community) getPathToWatch 1`] = ` "community_sidebars.json", "i18n/en/docusaurus-plugin-content-docs-community/current/**/*.{md,mdx}", "community/**/*.{md,mdx}", + "i18n/en/docusaurus-plugin-content-docs-community/current/tags.yml", + "community/tags.yml", "community/**/_category_.{json,yml,yaml}", "community_versioned_sidebars/version-1.0.0-sidebars.json", "i18n/en/docusaurus-plugin-content-docs-community/version-1.0.0/**/*.{md,mdx}", "community_versioned_docs/version-1.0.0/**/*.{md,mdx}", + "i18n/en/docusaurus-plugin-content-docs-community/version-1.0.0/tags.yml", + "community_versioned_docs/version-1.0.0/tags.yml", "community_versioned_docs/version-1.0.0/**/_category_.{json,yml,yaml}", ] `; @@ -3410,6 +3459,10 @@ exports[`versioned website content 4`] = ` "editUrl": undefined, "frontMatter": { "slug": "/", + "tags": [ + "inlineTag-v1.0.1", + "globalTag-v1.0.1", + ], }, "id": "hello", "lastUpdatedAt": undefined, @@ -3425,7 +3478,20 @@ exports[`versioned website content 4`] = ` "slug": "/", "source": "@site/versioned_docs/version-1.0.1/hello.md", "sourceDirName": ".", - "tags": [], + "tags": [ + { + "description": undefined, + "inline": true, + "label": "inlineTag-v1.0.1", + "permalink": "/docs/tags/inline-tag-v-1-0-1", + }, + { + "description": "globalTag-v1.0.1 description", + "inline": false, + "label": "globalTag-v1.0.1 label", + "permalink": "/docs/tags/globalTag-v1.0.1 permalink", + }, + ], "title": "hello", "unlisted": false, "version": "1.0.1", @@ -3744,6 +3810,10 @@ exports[`versioned website content: data 1`] = ` "editUrl": undefined, "frontMatter": { "slug": "/", + "tags": [ + "inlineTag-v1.0.0", + "globalTag-v1.0.0", + ], }, "id": "hello", "lastUpdatedAt": undefined, @@ -3759,7 +3829,20 @@ exports[`versioned website content: data 1`] = ` "slug": "/", "source": "@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md", "sourceDirName": ".", - "tags": [], + "tags": [ + { + "description": undefined, + "inline": true, + "label": "inlineTag-v1.0.0", + "permalink": "/docs/1.0.0/tags/inline-tag-v-1-0-0", + }, + { + "description": "globalTag-v1.0.0 description (en)", + "inline": false, + "label": "globalTag-v1.0.0 label (en)", + "permalink": "/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)", + }, + ], "title": "hello", "unlisted": false, "version": "1.0.0", @@ -3847,6 +3930,10 @@ exports[`versioned website content: data 1`] = ` "editUrl": undefined, "frontMatter": { "slug": "/", + "tags": [ + "inlineTag-v1.0.1", + "globalTag-v1.0.1", + ], }, "id": "hello", "lastUpdatedAt": undefined, @@ -3862,7 +3949,20 @@ exports[`versioned website content: data 1`] = ` "slug": "/", "source": "@site/versioned_docs/version-1.0.1/hello.md", "sourceDirName": ".", - "tags": [], + "tags": [ + { + "description": undefined, + "inline": true, + "label": "inlineTag-v1.0.1", + "permalink": "/docs/tags/inline-tag-v-1-0-1", + }, + { + "description": "globalTag-v1.0.1 description", + "inline": false, + "label": "globalTag-v1.0.1 label", + "permalink": "/docs/tags/globalTag-v1.0.1 permalink", + }, + ], "title": "hello", "unlisted": false, "version": "1.0.1", @@ -4326,6 +4426,73 @@ exports[`versioned website content: route config 1`] = ` }, }, "routes": [ + { + "component": "@theme/DocTagsListPage", + "exact": true, + "path": "/docs/1.0.0/tags", + "props": { + "tags": [ + { + "count": 1, + "description": undefined, + "label": "inlineTag-v1.0.0", + "permalink": "/docs/1.0.0/tags/inline-tag-v-1-0-0", + }, + { + "count": 1, + "description": "globalTag-v1.0.0 description (en)", + "label": "globalTag-v1.0.0 label (en)", + "permalink": "/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)", + }, + ], + }, + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "path": "/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)", + "props": { + "tag": { + "allTagsPath": "/docs/1.0.0/tags", + "count": 1, + "description": "globalTag-v1.0.0 description (en)", + "items": [ + { + "description": "Hello 1.0.0 ! (translated en)", + "id": "hello", + "permalink": "/docs/1.0.0/", + "title": "hello", + }, + ], + "label": "globalTag-v1.0.0 label (en)", + "permalink": "/docs/1.0.0/tags/globalTag-v1.0.0 permalink (en)", + "unlisted": false, + }, + }, + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "path": "/docs/1.0.0/tags/inline-tag-v-1-0-0", + "props": { + "tag": { + "allTagsPath": "/docs/1.0.0/tags", + "count": 1, + "description": undefined, + "items": [ + { + "description": "Hello 1.0.0 ! (translated en)", + "id": "hello", + "permalink": "/docs/1.0.0/", + "title": "hello", + }, + ], + "label": "inlineTag-v1.0.0", + "permalink": "/docs/1.0.0/tags/inline-tag-v-1-0-0", + "unlisted": false, + }, + }, + }, { "component": "@theme/DocRoot", "exact": false, @@ -4912,6 +5079,73 @@ exports[`versioned website content: route config 1`] = ` }, }, "routes": [ + { + "component": "@theme/DocTagsListPage", + "exact": true, + "path": "/docs/tags", + "props": { + "tags": [ + { + "count": 1, + "description": undefined, + "label": "inlineTag-v1.0.1", + "permalink": "/docs/tags/inline-tag-v-1-0-1", + }, + { + "count": 1, + "description": "globalTag-v1.0.1 description", + "label": "globalTag-v1.0.1 label", + "permalink": "/docs/tags/globalTag-v1.0.1 permalink", + }, + ], + }, + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "path": "/docs/tags/globalTag-v1.0.1 permalink", + "props": { + "tag": { + "allTagsPath": "/docs/tags", + "count": 1, + "description": "globalTag-v1.0.1 description", + "items": [ + { + "description": "Hello 1.0.1 !", + "id": "hello", + "permalink": "/docs/", + "title": "hello", + }, + ], + "label": "globalTag-v1.0.1 label", + "permalink": "/docs/tags/globalTag-v1.0.1 permalink", + "unlisted": false, + }, + }, + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "path": "/docs/tags/inline-tag-v-1-0-1", + "props": { + "tag": { + "allTagsPath": "/docs/tags", + "count": 1, + "description": undefined, + "items": [ + { + "description": "Hello 1.0.1 !", + "id": "hello", + "permalink": "/docs/", + "title": "hello", + }, + ], + "label": "inlineTag-v1.0.1", + "permalink": "/docs/tags/inline-tag-v-1-0-1", + "unlisted": false, + }, + }, + }, { "component": "@theme/DocRoot", "exact": false, @@ -4977,18 +5211,26 @@ exports[`versioned website getPathToWatch 1`] = ` "sidebars.json", "i18n/en/docusaurus-plugin-content-docs/current/**/*.{md,mdx}", "docs/**/*.{md,mdx}", + "i18n/en/docusaurus-plugin-content-docs/current/tags.yml", + "docs/tags.yml", "docs/**/_category_.{json,yml,yaml}", "versioned_sidebars/version-1.0.1-sidebars.json", "i18n/en/docusaurus-plugin-content-docs/version-1.0.1/**/*.{md,mdx}", "versioned_docs/version-1.0.1/**/*.{md,mdx}", + "i18n/en/docusaurus-plugin-content-docs/version-1.0.1/tags.yml", + "versioned_docs/version-1.0.1/tags.yml", "versioned_docs/version-1.0.1/**/_category_.{json,yml,yaml}", "versioned_sidebars/version-1.0.0-sidebars.json", "i18n/en/docusaurus-plugin-content-docs/version-1.0.0/**/*.{md,mdx}", "versioned_docs/version-1.0.0/**/*.{md,mdx}", + "i18n/en/docusaurus-plugin-content-docs/version-1.0.0/tags.yml", + "versioned_docs/version-1.0.0/tags.yml", "versioned_docs/version-1.0.0/**/_category_.{json,yml,yaml}", "versioned_sidebars/version-withSlugs-sidebars.json", "i18n/en/docusaurus-plugin-content-docs/version-withSlugs/**/*.{md,mdx}", "versioned_docs/version-withSlugs/**/*.{md,mdx}", + "i18n/en/docusaurus-plugin-content-docs/version-withSlugs/tags.yml", + "versioned_docs/version-withSlugs/tags.yml", "versioned_docs/version-withSlugs/**/_category_.{json,yml,yaml}", ] `; From a70df92a670a15f3cd235264bf8ed84ba0d93182 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 14:50:49 +0200 Subject: [PATCH 132/142] fix blog RSS feed tests --- .../__tests__/__snapshots__/feed.test.ts.snap | 286 +++++++++--------- .../src/__tests__/feed.test.ts | 5 - .../src/plugin-content-blog.d.ts | 4 +- 3 files changed, 152 insertions(+), 143 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap index b207a23623b9..6b693d83fb2e 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap @@ -92,29 +92,29 @@ exports[`atom filters to the first two entries using limit 1`] = ` ] `; -exports[`atom has feed item for each post 1`] = ` +exports[`atom has feed item for each post - with trailing slash 1`] = ` [ " - https://docusaurus.io/myBaseUrl/blog + https://docusaurus.io/myBaseUrl/blog/ Hello Blog 2023-07-23T00:00:00.000Z https://github.com/jpmonette/feed - + Hello Blog https://docusaurus.io/myBaseUrl/image/favicon.ico Copyright <![CDATA[test links]]> - https://docusaurus.io/myBaseUrl/blog/blog-with-links - + https://docusaurus.io/myBaseUrl/blog/blog-with-links/ + 2023-07-23T00:00:00.000Z absolute full url

    absolute pathname

    relative pathname

    md link

    -

    anchor

    +

    anchor

    relative pathname + anchor

    @@ -123,8 +123,8 @@ exports[`atom has feed item for each post 1`] = `
    <![CDATA[MDX Blog Sample with require calls]]> - https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post - + https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/ + 2021-03-06T00:00:00.000Z Test MDX with require calls

    @@ -136,8 +136,8 @@ exports[`atom has feed item for each post 1`] = `
    <![CDATA[Full Blog Sample]]> - https://docusaurus.io/myBaseUrl/blog/mdx-blog-post - + https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/ + 2021-03-05T00:00:00.000Z HTML Heading 1 @@ -147,10 +147,10 @@ exports[`atom has feed item for each post 1`] = `

    Import DOM

    Heading 1

    -

    Heading 2​

    -

    Heading 3​

    -

    Heading 4​

    -
    Heading 5​
    +

    Heading 2​

    +

    Heading 3​

    +

    Heading 4​

    +
    Heading 5​
    • list1
    • list2
    • @@ -166,8 +166,8 @@ exports[`atom has feed item for each post 1`] = ` <![CDATA[Complex Slug]]> - https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´ - + https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´/ + 2020-08-16T00:00:00.000Z complex url slug

      ]]>
      @@ -176,8 +176,8 @@ exports[`atom has feed item for each post 1`] = `
      <![CDATA[Simple Slug]]> - https://docusaurus.io/myBaseUrl/blog/simple/slug - + https://docusaurus.io/myBaseUrl/blog/simple/slug/ + 2020-08-15T00:00:00.000Z simple url slug

      ]]>
      @@ -188,14 +188,14 @@ exports[`atom has feed item for each post 1`] = `
      <![CDATA[some heading]]> - https://docusaurus.io/myBaseUrl/blog/heading-as-title - + https://docusaurus.io/myBaseUrl/blog/heading-as-title/ + 2019-01-02T00:00:00.000Z <![CDATA[date-matter]]> - https://docusaurus.io/myBaseUrl/blog/date-matter - + https://docusaurus.io/myBaseUrl/blog/date-matter/ + 2019-01-01T00:00:00.000Z date inside front matter

      ]]>
      @@ -203,8 +203,8 @@ exports[`atom has feed item for each post 1`] = `
      <![CDATA[Happy 1st Birthday Slash! (translated)]]> - https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash - + https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/ + 2018-12-14T00:00:00.000Z Happy birthday! (translated)

      ]]>
      @@ -215,34 +215,36 @@ exports[`atom has feed item for each post 1`] = ` SĂ©bastien Lorber (translated) lorber.sebastien@gmail.com + +
      ", ] `; -exports[`atom has feed item for each post - with trailing slash 1`] = ` +exports[`atom has feed item for each post 1`] = ` [ " - https://docusaurus.io/myBaseUrl/blog/ + https://docusaurus.io/myBaseUrl/blog Hello Blog 2023-07-23T00:00:00.000Z https://github.com/jpmonette/feed - + Hello Blog https://docusaurus.io/myBaseUrl/image/favicon.ico Copyright <![CDATA[test links]]> - https://docusaurus.io/myBaseUrl/blog/blog-with-links/ - + https://docusaurus.io/myBaseUrl/blog/blog-with-links + 2023-07-23T00:00:00.000Z absolute full url

      absolute pathname

      relative pathname

      md link

      -

      anchor

      +

      anchor

      relative pathname + anchor

      @@ -251,8 +253,8 @@ exports[`atom has feed item for each post - with trailing slash 1`] = `
      <![CDATA[MDX Blog Sample with require calls]]> - https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/ - + https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post + 2021-03-06T00:00:00.000Z Test MDX with require calls

      @@ -264,8 +266,8 @@ exports[`atom has feed item for each post - with trailing slash 1`] = `
      <![CDATA[Full Blog Sample]]> - https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/ - + https://docusaurus.io/myBaseUrl/blog/mdx-blog-post + 2021-03-05T00:00:00.000Z HTML Heading 1 @@ -275,10 +277,10 @@ exports[`atom has feed item for each post - with trailing slash 1`] = `

      Import DOM

      Heading 1

      -

      Heading 2​

      -

      Heading 3​

      -

      Heading 4​

      -
      Heading 5​
      +

      Heading 2​

      +

      Heading 3​

      +

      Heading 4​

      +
      Heading 5​
      • list1
      • list2
      • @@ -294,8 +296,8 @@ exports[`atom has feed item for each post - with trailing slash 1`] = ` <![CDATA[Complex Slug]]> - https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´/ - + https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´ + 2020-08-16T00:00:00.000Z complex url slug

        ]]>
        @@ -304,8 +306,8 @@ exports[`atom has feed item for each post - with trailing slash 1`] = `
        <![CDATA[Simple Slug]]> - https://docusaurus.io/myBaseUrl/blog/simple/slug/ - + https://docusaurus.io/myBaseUrl/blog/simple/slug + 2020-08-15T00:00:00.000Z simple url slug

        ]]>
        @@ -316,14 +318,14 @@ exports[`atom has feed item for each post - with trailing slash 1`] = `
        <![CDATA[some heading]]> - https://docusaurus.io/myBaseUrl/blog/heading-as-title/ - + https://docusaurus.io/myBaseUrl/blog/heading-as-title + 2019-01-02T00:00:00.000Z <![CDATA[date-matter]]> - https://docusaurus.io/myBaseUrl/blog/date-matter/ - + https://docusaurus.io/myBaseUrl/blog/date-matter + 2019-01-01T00:00:00.000Z date inside front matter

        ]]>
        @@ -331,8 +333,8 @@ exports[`atom has feed item for each post - with trailing slash 1`] = `
        <![CDATA[Happy 1st Birthday Slash! (translated)]]> - https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/ - + https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash + 2018-12-14T00:00:00.000Z Happy birthday! (translated)

        ]]>
        @@ -343,6 +345,8 @@ exports[`atom has feed item for each post - with trailing slash 1`] = ` SĂ©bastien Lorber (translated) lorber.sebastien@gmail.com + +
        ", ] @@ -410,45 +414,45 @@ exports[`json filters to the first two entries using limit 1`] = ` ] `; -exports[`json has feed item for each post 1`] = ` +exports[`json has feed item for each post - with trailing slash 1`] = ` [ "{ "version": "https://jsonfeed.org/version/1", "title": "Hello Blog", - "home_page_url": "https://docusaurus.io/myBaseUrl/blog", + "home_page_url": "https://docusaurus.io/myBaseUrl/blog/", "description": "Hello Blog", "items": [ { - "id": "https://docusaurus.io/myBaseUrl/blog/blog-with-links", - "content_html": "

        absolute full url

        /n

        absolute pathname

        /n

        relative pathname

        /n

        md link

        /n

        anchor

        /n

        relative pathname + anchor

        /n

        /n

        \\"\\"

        /n/n", - "url": "https://docusaurus.io/myBaseUrl/blog/blog-with-links", + "id": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/", + "content_html": "

        absolute full url

        /n

        absolute pathname

        /n

        relative pathname

        /n

        md link

        /n

        anchor

        /n

        relative pathname + anchor

        /n

        /n

        \\"\\"

        /n/n", + "url": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/", "title": "test links", "summary": "absolute full url", "date_modified": "2023-07-23T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post", + "id": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/", "content_html": "

        Test MDX with require calls

        /n/n/n/n/n", - "url": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post", + "url": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/", "title": "MDX Blog Sample with require calls", "summary": "Test MDX with require calls", "date_modified": "2021-03-06T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post", - "content_html": "

        HTML Heading 1

        /n

        HTML Heading 2

        /n

        HTML Paragraph

        /n/n/n

        Import DOM

        /n

        Heading 1

        /n

        Heading 2​

        /n

        Heading 3​

        /n

        Heading 4​

        /n
        Heading 5​
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n

        Normal Text Italics Text Bold Text

        /n

        link \\"image\\"

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post", + "id": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/", + "content_html": "

        HTML Heading 1

        /n

        HTML Heading 2

        /n

        HTML Paragraph

        /n/n/n

        Import DOM

        /n

        Heading 1

        /n

        Heading 2​

        /n

        Heading 3​

        /n

        Heading 4​

        /n
        Heading 5​
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n

        Normal Text Italics Text Bold Text

        /n

        link \\"image\\"

        ", + "url": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/", "title": "Full Blog Sample", "summary": "HTML Heading 1", "date_modified": "2021-03-05T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô", + "id": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/", "content_html": "

        complex url slug

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô", + "url": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/", "title": "Complex Slug", "summary": "complex url slug", "date_modified": "2020-08-16T00:00:00.000Z", @@ -458,9 +462,9 @@ exports[`json has feed item for each post 1`] = ` ] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/simple/slug", + "id": "https://docusaurus.io/myBaseUrl/blog/simple/slug/", "content_html": "

        simple url slug

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/simple/slug", + "url": "https://docusaurus.io/myBaseUrl/blog/simple/slug/", "title": "Simple Slug", "summary": "simple url slug", "date_modified": "2020-08-15T00:00:00.000Z", @@ -471,17 +475,17 @@ exports[`json has feed item for each post 1`] = ` "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/heading-as-title", + "id": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/", "content_html": "", - "url": "https://docusaurus.io/myBaseUrl/blog/heading-as-title", + "url": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/", "title": "some heading", "date_modified": "2019-01-02T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/date-matter", + "id": "https://docusaurus.io/myBaseUrl/blog/date-matter/", "content_html": "

        date inside front matter

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/date-matter", + "url": "https://docusaurus.io/myBaseUrl/blog/date-matter/", "title": "date-matter", "summary": "date inside front matter", "date_modified": "2019-01-01T00:00:00.000Z", @@ -490,61 +494,64 @@ exports[`json has feed item for each post 1`] = ` ] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash", + "id": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/", "content_html": "

        Happy birthday! (translated)

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash", + "url": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/", "title": "Happy 1st Birthday Slash! (translated)", "summary": "Happy birthday! (translated)", "date_modified": "2018-12-14T00:00:00.000Z", "author": { "name": "Yangshun Tay (translated)" }, - "tags": [] + "tags": [ + "inlineTag", + "Global Tag label (en)" + ] } ] }", ] `; -exports[`json has feed item for each post - with trailing slash 1`] = ` +exports[`json has feed item for each post 1`] = ` [ "{ "version": "https://jsonfeed.org/version/1", "title": "Hello Blog", - "home_page_url": "https://docusaurus.io/myBaseUrl/blog/", + "home_page_url": "https://docusaurus.io/myBaseUrl/blog", "description": "Hello Blog", "items": [ { - "id": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/", - "content_html": "

        absolute full url

        /n

        absolute pathname

        /n

        relative pathname

        /n

        md link

        /n

        anchor

        /n

        relative pathname + anchor

        /n

        /n

        \\"\\"

        /n/n", - "url": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/", + "id": "https://docusaurus.io/myBaseUrl/blog/blog-with-links", + "content_html": "

        absolute full url

        /n

        absolute pathname

        /n

        relative pathname

        /n

        md link

        /n

        anchor

        /n

        relative pathname + anchor

        /n

        /n

        \\"\\"

        /n/n", + "url": "https://docusaurus.io/myBaseUrl/blog/blog-with-links", "title": "test links", "summary": "absolute full url", "date_modified": "2023-07-23T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/", + "id": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post", "content_html": "

        Test MDX with require calls

        /n/n/n/n/n", - "url": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/", + "url": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post", "title": "MDX Blog Sample with require calls", "summary": "Test MDX with require calls", "date_modified": "2021-03-06T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/", - "content_html": "

        HTML Heading 1

        /n

        HTML Heading 2

        /n

        HTML Paragraph

        /n/n/n

        Import DOM

        /n

        Heading 1

        /n

        Heading 2​

        /n

        Heading 3​

        /n

        Heading 4​

        /n
        Heading 5​
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n

        Normal Text Italics Text Bold Text

        /n

        link \\"image\\"

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/", + "id": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post", + "content_html": "

        HTML Heading 1

        /n

        HTML Heading 2

        /n

        HTML Paragraph

        /n/n/n

        Import DOM

        /n

        Heading 1

        /n

        Heading 2​

        /n

        Heading 3​

        /n

        Heading 4​

        /n
        Heading 5​
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n
          /n
        • list1
        • /n
        • list2
        • /n
        • list3
        • /n
        /n

        Normal Text Italics Text Bold Text

        /n

        link \\"image\\"

        ", + "url": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post", "title": "Full Blog Sample", "summary": "HTML Heading 1", "date_modified": "2021-03-05T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/", + "id": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô", "content_html": "

        complex url slug

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/", + "url": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô", "title": "Complex Slug", "summary": "complex url slug", "date_modified": "2020-08-16T00:00:00.000Z", @@ -554,9 +561,9 @@ exports[`json has feed item for each post - with trailing slash 1`] = ` ] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/simple/slug/", + "id": "https://docusaurus.io/myBaseUrl/blog/simple/slug", "content_html": "

        simple url slug

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/simple/slug/", + "url": "https://docusaurus.io/myBaseUrl/blog/simple/slug", "title": "Simple Slug", "summary": "simple url slug", "date_modified": "2020-08-15T00:00:00.000Z", @@ -567,17 +574,17 @@ exports[`json has feed item for each post - with trailing slash 1`] = ` "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/", + "id": "https://docusaurus.io/myBaseUrl/blog/heading-as-title", "content_html": "", - "url": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/", + "url": "https://docusaurus.io/myBaseUrl/blog/heading-as-title", "title": "some heading", "date_modified": "2019-01-02T00:00:00.000Z", "tags": [] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/date-matter/", + "id": "https://docusaurus.io/myBaseUrl/blog/date-matter", "content_html": "

        date inside front matter

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/date-matter/", + "url": "https://docusaurus.io/myBaseUrl/blog/date-matter", "title": "date-matter", "summary": "date inside front matter", "date_modified": "2019-01-01T00:00:00.000Z", @@ -586,16 +593,19 @@ exports[`json has feed item for each post - with trailing slash 1`] = ` ] }, { - "id": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/", + "id": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash", "content_html": "

        Happy birthday! (translated)

        ", - "url": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/", + "url": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash", "title": "Happy 1st Birthday Slash! (translated)", "summary": "Happy birthday! (translated)", "date_modified": "2018-12-14T00:00:00.000Z", "author": { "name": "Yangshun Tay (translated)" }, - "tags": [] + "tags": [ + "inlineTag", + "Global Tag label (en)" + ] } ] }", @@ -698,13 +708,13 @@ exports[`rss filters to the first two entries using limit 1`] = ` ] `; -exports[`rss has feed item for each post 1`] = ` +exports[`rss has feed item for each post - with trailing slash 1`] = ` [ " Hello Blog - https://docusaurus.io/myBaseUrl/blog + https://docusaurus.io/myBaseUrl/blog/ Hello Blog Sun, 23 Jul 2023 00:00:00 GMT https://validator.w3.org/feed/docs/rss2.html @@ -713,15 +723,15 @@ exports[`rss has feed item for each post 1`] = ` Copyright <![CDATA[test links]]> - https://docusaurus.io/myBaseUrl/blog/blog-with-links - https://docusaurus.io/myBaseUrl/blog/blog-with-links + https://docusaurus.io/myBaseUrl/blog/blog-with-links/ + https://docusaurus.io/myBaseUrl/blog/blog-with-links/ Sun, 23 Jul 2023 00:00:00 GMT absolute full url

        absolute pathname

        relative pathname

        md link

        -

        anchor

        +

        anchor

        relative pathname + anchor

        @@ -730,8 +740,8 @@ exports[`rss has feed item for each post 1`] = `
        <![CDATA[MDX Blog Sample with require calls]]> - https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post - https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post + https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/ + https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/ Sat, 06 Mar 2021 00:00:00 GMT Test MDX with require calls

        @@ -743,8 +753,8 @@ exports[`rss has feed item for each post 1`] = `
        <![CDATA[Full Blog Sample]]> - https://docusaurus.io/myBaseUrl/blog/mdx-blog-post - https://docusaurus.io/myBaseUrl/blog/mdx-blog-post + https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/ + https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/ Fri, 05 Mar 2021 00:00:00 GMT HTML Heading 1 @@ -754,10 +764,10 @@ exports[`rss has feed item for each post 1`] = `

        Import DOM

        Heading 1

        -

        Heading 2​

        -

        Heading 3​

        -

        Heading 4​

        -
        Heading 5​
        +

        Heading 2​

        +

        Heading 3​

        +

        Heading 4​

        +
        Heading 5​
        • list1
        • list2
        • @@ -773,8 +783,8 @@ exports[`rss has feed item for each post 1`] = ` <![CDATA[Complex Slug]]> - https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´ - https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´ + https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´/ + https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´/ Sun, 16 Aug 2020 00:00:00 GMT complex url slug

          ]]>
          @@ -783,22 +793,22 @@ exports[`rss has feed item for each post 1`] = `
          <![CDATA[Simple Slug]]> - https://docusaurus.io/myBaseUrl/blog/simple/slug - https://docusaurus.io/myBaseUrl/blog/simple/slug + https://docusaurus.io/myBaseUrl/blog/simple/slug/ + https://docusaurus.io/myBaseUrl/blog/simple/slug/ Sat, 15 Aug 2020 00:00:00 GMT simple url slug

          ]]>
          <![CDATA[some heading]]> - https://docusaurus.io/myBaseUrl/blog/heading-as-title - https://docusaurus.io/myBaseUrl/blog/heading-as-title + https://docusaurus.io/myBaseUrl/blog/heading-as-title/ + https://docusaurus.io/myBaseUrl/blog/heading-as-title/ Wed, 02 Jan 2019 00:00:00 GMT <![CDATA[date-matter]]> - https://docusaurus.io/myBaseUrl/blog/date-matter - https://docusaurus.io/myBaseUrl/blog/date-matter + https://docusaurus.io/myBaseUrl/blog/date-matter/ + https://docusaurus.io/myBaseUrl/blog/date-matter/ Tue, 01 Jan 2019 00:00:00 GMT date inside front matter

          ]]>
          @@ -806,25 +816,27 @@ exports[`rss has feed item for each post 1`] = `
          <![CDATA[Happy 1st Birthday Slash! (translated)]]> - https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash - https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash + https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/ + https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/ Fri, 14 Dec 2018 00:00:00 GMT Happy birthday! (translated)

          ]]>
          lorber.sebastien@gmail.com (SĂ©bastien Lorber (translated)) + inlineTag + Global Tag label (en)
          ", ] `; -exports[`rss has feed item for each post - with trailing slash 1`] = ` +exports[`rss has feed item for each post 1`] = ` [ " Hello Blog - https://docusaurus.io/myBaseUrl/blog/ + https://docusaurus.io/myBaseUrl/blog Hello Blog Sun, 23 Jul 2023 00:00:00 GMT https://validator.w3.org/feed/docs/rss2.html @@ -833,15 +845,15 @@ exports[`rss has feed item for each post - with trailing slash 1`] = ` Copyright <![CDATA[test links]]> - https://docusaurus.io/myBaseUrl/blog/blog-with-links/ - https://docusaurus.io/myBaseUrl/blog/blog-with-links/ + https://docusaurus.io/myBaseUrl/blog/blog-with-links + https://docusaurus.io/myBaseUrl/blog/blog-with-links Sun, 23 Jul 2023 00:00:00 GMT absolute full url

          absolute pathname

          relative pathname

          md link

          -

          anchor

          +

          anchor

          relative pathname + anchor

          @@ -850,8 +862,8 @@ exports[`rss has feed item for each post - with trailing slash 1`] = `
          <![CDATA[MDX Blog Sample with require calls]]> - https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/ - https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/ + https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post + https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post Sat, 06 Mar 2021 00:00:00 GMT Test MDX with require calls

          @@ -863,8 +875,8 @@ exports[`rss has feed item for each post - with trailing slash 1`] = `
          <![CDATA[Full Blog Sample]]> - https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/ - https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/ + https://docusaurus.io/myBaseUrl/blog/mdx-blog-post + https://docusaurus.io/myBaseUrl/blog/mdx-blog-post Fri, 05 Mar 2021 00:00:00 GMT HTML Heading 1 @@ -874,10 +886,10 @@ exports[`rss has feed item for each post - with trailing slash 1`] = `

          Import DOM

          Heading 1

          -

          Heading 2​

          -

          Heading 3​

          -

          Heading 4​

          -
          Heading 5​
          +

          Heading 2​

          +

          Heading 3​

          +

          Heading 4​

          +
          Heading 5​
          • list1
          • list2
          • @@ -893,8 +905,8 @@ exports[`rss has feed item for each post - with trailing slash 1`] = ` <![CDATA[Complex Slug]]> - https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´/ - https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´/ + https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´ + https://docusaurus.io/myBaseUrl/blog/hey/my super path/hĂ©llĂ´ Sun, 16 Aug 2020 00:00:00 GMT complex url slug

            ]]>
            @@ -903,22 +915,22 @@ exports[`rss has feed item for each post - with trailing slash 1`] = `
            <![CDATA[Simple Slug]]> - https://docusaurus.io/myBaseUrl/blog/simple/slug/ - https://docusaurus.io/myBaseUrl/blog/simple/slug/ + https://docusaurus.io/myBaseUrl/blog/simple/slug + https://docusaurus.io/myBaseUrl/blog/simple/slug Sat, 15 Aug 2020 00:00:00 GMT simple url slug

            ]]>
            <![CDATA[some heading]]> - https://docusaurus.io/myBaseUrl/blog/heading-as-title/ - https://docusaurus.io/myBaseUrl/blog/heading-as-title/ + https://docusaurus.io/myBaseUrl/blog/heading-as-title + https://docusaurus.io/myBaseUrl/blog/heading-as-title Wed, 02 Jan 2019 00:00:00 GMT <![CDATA[date-matter]]> - https://docusaurus.io/myBaseUrl/blog/date-matter/ - https://docusaurus.io/myBaseUrl/blog/date-matter/ + https://docusaurus.io/myBaseUrl/blog/date-matter + https://docusaurus.io/myBaseUrl/blog/date-matter Tue, 01 Jan 2019 00:00:00 GMT date inside front matter

            ]]>
            @@ -926,12 +938,14 @@ exports[`rss has feed item for each post - with trailing slash 1`] = `
            <![CDATA[Happy 1st Birthday Slash! (translated)]]> - https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/ - https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/ + https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash + https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash Fri, 14 Dec 2018 00:00:00 GMT Happy birthday! (translated)

            ]]>
            lorber.sebastien@gmail.com (SĂ©bastien Lorber (translated)) + inlineTag + Global Tag label (en)
            ", diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts index 9f76d72a144e..8c79310890af 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts @@ -101,7 +101,6 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { defaultReadingTime({content}), truncateMarker: //, onInlineTags: 'ignore', - tags: false, } as PluginOptions, ); @@ -144,7 +143,6 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { defaultReadingTime({content}), truncateMarker: //, onInlineTags: 'ignore', - tags: false, } as PluginOptions, ); @@ -199,7 +197,6 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { defaultReadingTime({content}), truncateMarker: //, onInlineTags: 'ignore', - tags: false, } as PluginOptions, ); @@ -245,7 +242,6 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { defaultReadingTime({content}), truncateMarker: //, onInlineTags: 'ignore', - tags: false, } as PluginOptions, ); @@ -291,7 +287,6 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { defaultReadingTime({content}), truncateMarker: //, onInlineTags: 'ignore', - tags: false, } as PluginOptions, ); diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index a9e78d5c9b45..b7e0506cbf86 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -11,7 +11,7 @@ declare module '@docusaurus/plugin-content-blog' { import type {MDXOptions} from '@docusaurus/mdx-loader'; import type { FrontMatterTag, - Tag, + NormalizedTag, LastUpdateData, FrontMatterLastUpdate, TagsPluginOptions, @@ -236,7 +236,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the /** Front matter, as-is. */ readonly frontMatter: BlogPostFrontMatter & {[key: string]: unknown}; /** Tags, normalized. */ - readonly tags: Tag[]; + readonly tags: NormalizedTag[]; /** * Marks the post as unlisted and visibly hides it unless directly accessed. */ From 7018d6d5b507d229f9af91b86a51ab5a98079a3f Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 15:05:34 +0200 Subject: [PATCH 133/142] rename NormalizedTag to TagMetadata --- .../src/plugin-content-blog.d.ts | 4 ++-- .../src/plugin-content-docs.d.ts | 4 ++-- .../docusaurus-utils/src/__tests__/tags.test.ts | 16 ++++++++-------- packages/docusaurus-utils/src/index.ts | 2 +- packages/docusaurus-utils/src/tags.ts | 12 ++++++------ 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index b7e0506cbf86..f4eb45bc6fd9 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -11,7 +11,7 @@ declare module '@docusaurus/plugin-content-blog' { import type {MDXOptions} from '@docusaurus/mdx-loader'; import type { FrontMatterTag, - NormalizedTag, + TagMetadata, LastUpdateData, FrontMatterLastUpdate, TagsPluginOptions, @@ -236,7 +236,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the /** Front matter, as-is. */ readonly frontMatter: BlogPostFrontMatter & {[key: string]: unknown}; /** Tags, normalized. */ - readonly tags: NormalizedTag[]; + readonly tags: TagMetadata[]; /** * Marks the post as unlisted and visibly hides it unless directly accessed. */ diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 5670fe7288b0..806cf280ce51 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -17,7 +17,7 @@ declare module '@docusaurus/plugin-content-docs' { TagModule, FrontMatterLastUpdate, LastUpdateData, - NormalizedTag, + TagMetadata, TagsPluginOptions, } from '@docusaurus/utils'; import type {Plugin, LoadContext} from '@docusaurus/types'; @@ -447,7 +447,7 @@ declare module '@docusaurus/plugin-content-docs' { */ editUrl?: string | null; /** Tags, normalized. */ - tags: NormalizedTag[]; + tags: TagMetadata[]; /** Front matter, as-is. */ frontMatter: DocFrontMatter & {[key: string]: unknown}; }; diff --git a/packages/docusaurus-utils/src/__tests__/tags.test.ts b/packages/docusaurus-utils/src/__tests__/tags.test.ts index 739a4fe0ce9a..a238c638169c 100644 --- a/packages/docusaurus-utils/src/__tests__/tags.test.ts +++ b/packages/docusaurus-utils/src/__tests__/tags.test.ts @@ -11,7 +11,7 @@ import { getTagVisibility, } from '@docusaurus/utils'; import {normalizeTag} from '../tags'; -import type {Tag, NormalizedTag, FrontMatterTag, TagsFile} from '../tags'; +import type {Tag, TagMetadata, FrontMatterTag, TagsFile} from '../tags'; describe('normalizeTag', () => { const tagsBaseRoutePath = '/all/tags'; @@ -19,7 +19,7 @@ describe('normalizeTag', () => { describe('inline', () => { it('normalizes simple string tag', () => { const input: FrontMatterTag = 'tag'; - const expectedOutput: NormalizedTag = { + const expectedOutput: TagMetadata = { inline: true, label: 'tag', permalink: `${tagsBaseRoutePath}/tag`, @@ -32,7 +32,7 @@ describe('normalizeTag', () => { it('normalizes complex string tag', () => { const input: FrontMatterTag = 'some more Complex_tag'; - const expectedOutput: NormalizedTag = { + const expectedOutput: TagMetadata = { inline: true, label: 'some more Complex_tag', permalink: `${tagsBaseRoutePath}/some-more-complex-tag`, @@ -48,7 +48,7 @@ describe('normalizeTag', () => { label: 'tag', permalink: 'tagPermalink', }; - const expectedOutput: NormalizedTag = { + const expectedOutput: TagMetadata = { inline: true, label: 'tag', permalink: `${tagsBaseRoutePath}/tagPermalink`, @@ -64,7 +64,7 @@ describe('normalizeTag', () => { label: 'tag complex Label', permalink: '/MoreComplex/Permalink', }; - const expectedOutput: NormalizedTag = { + const expectedOutput: TagMetadata = { inline: true, label: 'tag complex Label', permalink: `${tagsBaseRoutePath}/MoreComplex/Permalink`, @@ -92,7 +92,7 @@ describe('normalizeTag', () => { it('normalizes tag1 ref', () => { const input: FrontMatterTag = 'tag1'; - const expectedOutput: NormalizedTag = { + const expectedOutput: TagMetadata = { inline: false, label: tagsFile.tag1.label, description: tagsFile.tag1.description, @@ -105,7 +105,7 @@ describe('normalizeTag', () => { it('normalizes tag2 ref', () => { const input: FrontMatterTag = 'tag2'; - const expectedOutput: NormalizedTag = { + const expectedOutput: TagMetadata = { inline: false, label: tagsFile.tag2.label, description: tagsFile.tag2.description, @@ -118,7 +118,7 @@ describe('normalizeTag', () => { it('normalizes inline tag not declared in tags file', () => { const input: FrontMatterTag = 'inlineTag'; - const expectedOutput: NormalizedTag = { + const expectedOutput: TagMetadata = { inline: true, label: 'inlineTag', description: undefined, diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 7a638cdd867f..3dd23137f536 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -57,7 +57,7 @@ export { type Tag, type TagsFile, type TagsFileInput, - type NormalizedTag, + type TagMetadata, type TagsListItem, type TagModule, type FrontMatterTag, diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 747892ac24d2..16b708a7ccfe 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -32,7 +32,7 @@ export type TagsPluginOptions = { onInlineTags: 'ignore' | 'log' | 'warn' | 'throw'; }; -export type NormalizedTag = Tag & { +export type TagMetadata = Tag & { inline: boolean; }; @@ -68,8 +68,8 @@ function normalizeTagPermalink({ function normalizeInlineTag( tagsBaseRoutePath: string, frontMatterTag: FrontMatterTag, -): NormalizedTag { - function toTagObject(tagString: string): NormalizedTag { +): TagMetadata { + function toTagObject(tagString: string): TagMetadata { return { inline: true, label: tagString, @@ -102,7 +102,7 @@ export function normalizeTag({ tag: FrontMatterTag; tagsBaseRoutePath: string; tagsFile: TagsFile | null; -}): NormalizedTag { +}): TagMetadata { if (typeof tag === 'string') { const tagDescription = tagsFile?.[tag]; if (tagDescription) { @@ -134,7 +134,7 @@ export function normalizeTags({ frontMatterTags: FrontMatterTag[] | undefined; tagsBaseRoutePath: string; tagsFile: TagsFile | null; -}): NormalizedTag[] { +}): TagMetadata[] { const tags = (frontMatterTags ?? []).map((tag) => normalizeTag({tag, tagsBaseRoutePath, tagsFile}), ); @@ -149,7 +149,7 @@ export function reportInlineTags({ source, options, }: { - tags: NormalizedTag[]; + tags: TagMetadata[]; source: string; options: TagsPluginOptions; }): void { From 55ce8cef93f0355a4719de56f153e79dc2f748c6 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 15:21:56 +0200 Subject: [PATCH 134/142] blog/docsVersion tags aggregates should have TagMetadata type --- packages/docusaurus-plugin-content-blog/src/blogUtils.ts | 3 ++- .../src/plugin-content-blog.d.ts | 2 +- packages/docusaurus-plugin-content-docs/src/routes.ts | 3 ++- packages/docusaurus-plugin-content-docs/src/types.ts | 4 ++-- packages/docusaurus-utils/src/tags.ts | 4 ++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 24510dbc80d3..d4a9f275bc87 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -127,10 +127,11 @@ export function getBlogTags({ isUnlisted: (item) => item.metadata.unlisted, }); return { + inline: tag.inline, label: tag.label, - items: tagVisibility.listedItems.map((item) => item.id), permalink: tag.permalink, description: tag.description, + items: tagVisibility.listedItems.map((item) => item.id), pages: paginateBlogPosts({ blogPosts: tagVisibility.listedItems, basePageUrl: tag.permalink, diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index f4eb45bc6fd9..f4d4f135c061 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -495,7 +495,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the [permalink: string]: BlogTag; }; - export type BlogTag = Tag & { + export type BlogTag = TagMetadata & { /** Blog post permalinks. */ items: string[]; pages: BlogPaginated[]; diff --git a/packages/docusaurus-plugin-content-docs/src/routes.ts b/packages/docusaurus-plugin-content-docs/src/routes.ts index 28031966ce92..cde7d8831241 100644 --- a/packages/docusaurus-plugin-content-docs/src/routes.ts +++ b/packages/docusaurus-plugin-content-docs/src/routes.ts @@ -121,10 +121,11 @@ function getVersionTags(docs: DocMetadata[]): VersionTags { isUnlisted: (item) => item.unlisted, }); return { + inline: tag.inline, label: tag.label, - docIds: tagVisibility.listedItems.map((item) => item.id), permalink: tag.permalink, description: tag.description, + docIds: tagVisibility.listedItems.map((item) => item.id), unlisted: tagVisibility.unlisted, }; }); diff --git a/packages/docusaurus-plugin-content-docs/src/types.ts b/packages/docusaurus-plugin-content-docs/src/types.ts index c44c60896a80..208675c72adc 100644 --- a/packages/docusaurus-plugin-content-docs/src/types.ts +++ b/packages/docusaurus-plugin-content-docs/src/types.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import type {Tag} from '@docusaurus/utils'; +import type {TagMetadata} from '@docusaurus/utils'; import type { LoadedVersion, CategoryGeneratedIndexMetadata, @@ -23,7 +23,7 @@ export type SourceToPermalink = { [source: string]: string; }; -export type VersionTag = Tag & { +export type VersionTag = TagMetadata & { /** All doc ids having this tag. */ docIds: string[]; unlisted: boolean; diff --git a/packages/docusaurus-utils/src/tags.ts b/packages/docusaurus-utils/src/tags.ts index 16b708a7ccfe..1da758f9cd5d 100644 --- a/packages/docusaurus-utils/src/tags.ts +++ b/packages/docusaurus-utils/src/tags.ts @@ -169,7 +169,7 @@ export function reportInlineTags({ } type TaggedItemGroup = { - tag: Tag; + tag: TagMetadata; items: Item[]; }; @@ -187,7 +187,7 @@ export function groupTaggedItems( * A callback telling me how to get the tags list of the current item. Usually * simply getting it from some metadata of the current item. */ - getItemTags: (item: Item) => readonly Tag[], + getItemTags: (item: Item) => readonly TagMetadata[], ): {[permalink: string]: TaggedItemGroup} { const result: {[permalink: string]: TaggedItemGroup} = {}; From 768fa68bf4704f8377662ad6407ee2eeedc2a75f Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 15:56:29 +0200 Subject: [PATCH 135/142] api ref doc --- .../_partial-tags-file-api-ref-section.mdx | 52 +++++++++++++++++++ .../api/plugins/_tags-partials-example.mdx | 13 ----- .../docs/api/plugins/plugin-content-blog.mdx | 6 +-- .../docs/api/plugins/plugin-content-docs.mdx | 6 +-- 4 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx delete mode 100644 website/docs/api/plugins/_tags-partials-example.mdx diff --git a/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx b/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx new file mode 100644 index 000000000000..2597ec3f40d1 --- /dev/null +++ b/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx @@ -0,0 +1,52 @@ +## Tags File {#tags-file} + +Use the `[tags plugion option](#tags)` to configure the path of a YAML tags file. By convention, the plugin will read a `tags.yml` file at the root of your content folder(s). + +This file can contain a list of predefined tags. You can reference these tags by their keys in Markdown files thanks to the [`tags` front matter](#markdown-front-matter). + +:::tip Keeping tags consistent + +Using a tags file, you can ensure that your tags usage is consistent across your plugin content set. Use the [`onInlineTags: 'throw'`](#onInlineTags) plugin option to enforce this consistency and prevent usage of inline tags declared on the fly. + +::: + +### Types {#tags-file-types} + +The YAML content of the provided tags file should respect the following shape: + +```tsx +type Tag = { + label?: string; // Tag display label + permalink?: string; // Tag URL pathname segment + description?: string; // Tag description displayed in the tag page +}; + +type TagsFileInput = Record | null>; +``` + +### Example {#tags-file-example} + +```yml title="tags.yml" +releases: + label: 'Product releases' + permalink: '/product-releases' + description: 'Content related to product releases.' + +# A partial tag definition is also valid +announcements: + label: 'Announcements' + +# An empty tag definition is also valid +# Other attributes will be inferred from the key +emptyTag: +``` + +```md title="content.md" +--- +tags: [releases, announcements, emptyTag] +--- + +# Title + +Content +``` diff --git a/website/docs/api/plugins/_tags-partials-example.mdx b/website/docs/api/plugins/_tags-partials-example.mdx deleted file mode 100644 index 738b0d4c296c..000000000000 --- a/website/docs/api/plugins/_tags-partials-example.mdx +++ /dev/null @@ -1,13 +0,0 @@ -Example: - -```yml title="tags.yml" -hello: -hello: null -# both tag above are equivalent -docusaurus: # what you'll be using in the front matter - label: Docusaurus - permalink: /docusaurus - description: Docusaurus related posts -``` - -Only the key are required. If values are not provided the label will be set to the key Capitalized and the permalink will be set to the key kebab-cased. diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index 4d6a34238409..1521411dad78 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -226,7 +226,7 @@ Accepted fields: | `author_title` | `string` | `undefined` | ⚠️ Prefer using `authors`. A description of the author. | | `title` | `string` | Markdown title | The blog post title. | | `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. | -| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. Strings can be a reference to keys in `tags.yml` | +| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. Strings can be a reference to keys of a [tags file](#tags-file) (usually `tags.yml`) | | `draft` | `boolean` | `false` | Draft blog posts will only be available during development. | | `unlisted` | `boolean` | `false` | Unlisted blog posts will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. | | `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. | @@ -283,9 +283,9 @@ hide_table_of_contents: false A Markdown blog post ``` -import TagsFile from './_tags-partials-example.mdx'; +import TagsFileApiRefSection from './_partial-tags-file-api-ref-section.mdx'; - + ## i18n {#i18n} diff --git a/website/docs/api/plugins/plugin-content-docs.mdx b/website/docs/api/plugins/plugin-content-docs.mdx index 6cb127cebab6..1a9dcc370758 100644 --- a/website/docs/api/plugins/plugin-content-docs.mdx +++ b/website/docs/api/plugins/plugin-content-docs.mdx @@ -295,7 +295,7 @@ Accepted fields: | `description` | `string` | The first line of Markdown content | The description of your document, which will become the `` and `` in ``, used by search engines. | | `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `` in the ``, enhancing link previews on social media and messaging platforms. | | `slug` | `string` | File path | Allows to customize the document URL (`//`). Support multiple patterns: `slug: my-doc`, `slug: /my/path/myDoc`, `slug: /`. | -| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. Strings can be a reference to keys in `tags.yml` | +| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. Strings can be a reference to keys of a [tags file](#tags-file) (usually `tags.yml`) | | `draft` | `boolean` | `false` | Draft documents will only be available during development. | | `unlisted` | `boolean` | `false` | Unlisted documents will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. | | `last_update` | `FrontMatterLastUpdate` | `undefined` | Allows overriding the last update author/date. Date can be any [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). | @@ -339,9 +339,9 @@ last_update: My Document Markdown content ``` -import TagsFile from './_tags-partials-example.mdx'; +import TagsFileApiRefSection from './_partial-tags-file-api-ref-section.mdx'; - + ## i18n {#i18n} From 356f447b9fa4aa09c5b805e705b4c4a9240301be Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 16:12:14 +0200 Subject: [PATCH 136/142] simplify docs tags guide --- website/docs/guides/docs/docs-create-doc.mdx | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/website/docs/guides/docs/docs-create-doc.mdx b/website/docs/guides/docs/docs-create-doc.mdx index 4645670982bb..a0d2359a8870 100644 --- a/website/docs/guides/docs/docs-create-doc.mdx +++ b/website/docs/guides/docs/docs-create-doc.mdx @@ -60,33 +60,33 @@ The [front matter](../markdown-features/markdown-features-intro.mdx#front-matter ## Doc tags {#doc-tags} -Optionally, you can add tags to your doc pages, which introduces another dimension of categorization in addition to the [docs sidebar](./sidebar/index.mdx). Tags are passed in the front matter as a list of labels: +Tags are declared in the front matter and introduce another dimension of categorization in addition to the [docs sidebar](./sidebar/index.mdx). -### Inline tags {#inline-tags} +It is possible to define tags inline, or to reference predefined tags declared in a [`tags file`](../../api/plugins/plugin-content-blog.mdx#tags-file) (optional, usually `docs/tags.yml`). -Tags are considered inline when they are not defined in a global configuration file. You can configure how to report inline tags with [`onInlineTags`](../../api/plugins/plugin-content-blog.mdx#onInlineTags). +In the following example: -Blog post tags can be declared directly inside the front matter in different ways: - -```md title="my-doc.md" ---- -tags: [hello, docusaurus] ---- -``` +- `docusaurus` references a predefined tag key declared in `docs/tags.yml` +- `Releases` is an inline tag, because it does not exist in `docs/tags.yml` ```md title="my-doc.md" --- tags: - - hello + - Releases - docusaurus --- -``` -### Global tags {#global-tags} +# Title -Global tags are declared in a configuration file which then tag's key can be referenced in the front matter. +Content +``` -See [the API documentation](../../api/plugins/plugin-content-docs.mdx#markdown-front-matter) to learn about `tags.yml`. +```yml title="docs/tags.yml" +docusaurus: + label: 'Docusaurus' + permalink: '/docusaurus' + description: 'Docs related to the Docusaurus framework' +``` :::tip From 3e1666bf723379334931caa09325c95412527e1b Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 16:20:27 +0200 Subject: [PATCH 137/142] simplify docs tags guide --- .../_partial-tags-file-api-ref-section.mdx | 4 ++- website/docs/blog.mdx | 33 +++++++++---------- website/docs/guides/docs/docs-create-doc.mdx | 4 +-- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx b/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx index 2597ec3f40d1..2e74586a6e54 100644 --- a/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx +++ b/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx @@ -1,6 +1,8 @@ ## Tags File {#tags-file} -Use the `[tags plugion option](#tags)` to configure the path of a YAML tags file. By convention, the plugin will read a `tags.yml` file at the root of your content folder(s). +Use the [`tags` plugion option](#tags) to configure the path of a YAML tags file. + +By convention, the plugin will look for a `tags.yml` file at the root of your content folder(s). This file can contain a list of predefined tags. You can reference these tags by their keys in Markdown files thanks to the [`tags` front matter](#markdown-front-matter). diff --git a/website/docs/blog.mdx b/website/docs/blog.mdx index f0c58045a823..75e4fa09a978 100644 --- a/website/docs/blog.mdx +++ b/website/docs/blog.mdx @@ -382,33 +382,32 @@ An author, either declared through front matter or through the authors map, need ## Blog post tags {#blog-post-tags} -Optionally, you can add tags to your blog pages. Tags are passed in the front matter as a list of labels: +Tags are declared in the front matter and introduce another dimension of categorization. -### Inline tags {#inline-tags} +It is possible to define tags inline, or to reference predefined tags declared in a [`tags file`](api/plugins/plugin-content-blog.mdx#tags-file) (optional, usually `blog/tags.yml`). -Tags are considered inline when they are not defined in a global configuration file. You can configure how to report inline tags with [`onInlineTags`](./api/plugins/plugin-content-blog.mdx#onInlineTags). +In the following example: -Blog post tags can be declared directly inside the front matter in different ways: +- `docusaurus` references a predefined tag key declared in `blog/tags.yml` +- `Releases` is an inline tag, because it does not exist in `blog/tags.yml` -```md title="my-blog-post.md" ---- -tags: [hello, docusaurus] ---- -``` - -```md title="my-blog-post.md" +```md title="blog/my-post.md" --- +title: 'My blog post' tags: - - hello + - Releases - docusaurus --- -``` - -### Global tags {#global-tags} -Global tags are declared in a configuration file which then tag's key can be referenced in the blog post front matter. +Content +``` -See [the API documentation](./api/plugins/plugin-content-blog.mdx#markdown-front-matter) to learn about `tags.yml`. +```yml title="blog/tags.yml" +docusaurus: + label: 'Docusaurus' + permalink: '/docusaurus' + description: 'Blog posts related to the Docusaurus framework' +``` ## Reading time {#reading-time} diff --git a/website/docs/guides/docs/docs-create-doc.mdx b/website/docs/guides/docs/docs-create-doc.mdx index a0d2359a8870..caf8e2ea77b7 100644 --- a/website/docs/guides/docs/docs-create-doc.mdx +++ b/website/docs/guides/docs/docs-create-doc.mdx @@ -62,14 +62,14 @@ The [front matter](../markdown-features/markdown-features-intro.mdx#front-matter Tags are declared in the front matter and introduce another dimension of categorization in addition to the [docs sidebar](./sidebar/index.mdx). -It is possible to define tags inline, or to reference predefined tags declared in a [`tags file`](../../api/plugins/plugin-content-blog.mdx#tags-file) (optional, usually `docs/tags.yml`). +It is possible to define tags inline, or to reference predefined tags declared in a [`tags file`](../../api/plugins/plugin-content-docs.mdx#tags-file) (optional, usually `docs/tags.yml`). In the following example: - `docusaurus` references a predefined tag key declared in `docs/tags.yml` - `Releases` is an inline tag, because it does not exist in `docs/tags.yml` -```md title="my-doc.md" +```md title="docs/my-doc.md" --- tags: - Releases From 4032351070e64c2ea27acf494d46cba1eab064bd Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 16:21:20 +0200 Subject: [PATCH 138/142] update snapshots --- .../src/__tests__/__snapshots__/index.test.ts.snap | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap index dfeec789f8d0..a9ff614dbab4 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap @@ -4,6 +4,7 @@ exports[`blog plugin process blog posts load content 1`] = ` { "/blog/tags/tag-1": { "description": undefined, + "inline": true, "items": [ "/simple/slug/another", "/another/tags", @@ -65,6 +66,7 @@ exports[`blog plugin process blog posts load content 1`] = ` }, "/blog/tags/tag-2": { "description": undefined, + "inline": true, "items": [ "/another/tags", "/another/tags2", @@ -261,6 +263,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = ` { "/blog/tags/tag-1": { "description": undefined, + "inline": true, "items": [ "/simple/slug/another", "/another/tags", @@ -292,6 +295,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = ` }, "/blog/tags/tag-2": { "description": undefined, + "inline": true, "items": [ "/another/tags", "/another/tags2", @@ -321,6 +325,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = ` }, "/blog/tags/unlisted": { "description": undefined, + "inline": true, "items": [ "/another/blog-with-tags-unlisted", ], @@ -353,6 +358,7 @@ exports[`blog plugin works with blog tags 1`] = ` { "/blog/tags/tag-1": { "description": undefined, + "inline": true, "items": [ "/simple/slug/another", "/another/tags", @@ -399,6 +405,7 @@ exports[`blog plugin works with blog tags 1`] = ` }, "/blog/tags/tag-2": { "description": undefined, + "inline": true, "items": [ "/another/tags", "/another/tags2", @@ -428,6 +435,7 @@ exports[`blog plugin works with blog tags 1`] = ` }, "/blog/tags/unlisted": { "description": undefined, + "inline": true, "items": [ "/another/blog-with-tags-unlisted", ], From eba218f094554bb447c70934764215576adeb3d2 Mon Sep 17 00:00:00 2001 From: slorber Date: Fri, 31 May 2024 14:26:25 +0000 Subject: [PATCH 139/142] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index 0125953ec975..af2f7b0c9087 100644 --- a/project-words.txt +++ b/project-words.txt @@ -252,6 +252,7 @@ Pipeable playbtn pluggable Pluggable +plugion plushie Plushie plushies From 979f3d38d7227be579a26456e8e09ff1aca3ca42 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 16:29:10 +0200 Subject: [PATCH 140/142] empty From 7e6fe9185a45fd1a90d0caab79fea6b2da663558 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 16:32:29 +0200 Subject: [PATCH 141/142] typo --- project-words.txt | 1 - website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/project-words.txt b/project-words.txt index af2f7b0c9087..0125953ec975 100644 --- a/project-words.txt +++ b/project-words.txt @@ -252,7 +252,6 @@ Pipeable playbtn pluggable Pluggable -plugion plushie Plushie plushies diff --git a/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx b/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx index 2e74586a6e54..f6d247c70f29 100644 --- a/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx +++ b/website/docs/api/plugins/_partial-tags-file-api-ref-section.mdx @@ -1,6 +1,6 @@ ## Tags File {#tags-file} -Use the [`tags` plugion option](#tags) to configure the path of a YAML tags file. +Use the [`tags` plugin option](#tags) to configure the path of a YAML tags file. By convention, the plugin will look for a `tags.yml` file at the root of your content folder(s). From 389e0468d40d8f0ef2334109b6d4af373995cca4 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 31 May 2024 17:17:35 +0200 Subject: [PATCH 142/142] Use posix path join to make windows tests pass --- packages/docusaurus-utils-validation/src/tagsFile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index a865acce45b3..55f9550102ed 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -77,7 +77,7 @@ export function getTagsFilePathsToWatch({ const relativeFilePath = tags ?? DefaultTagsFileName; return getContentPathList(contentPaths).map((contentPath) => - path.join(contentPath, relativeFilePath), + path.posix.join(contentPath, relativeFilePath), ); }