From 1db787144686ef84e1cc057d1072a87c490c4985 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 May 2022 10:41:00 +0800 Subject: [PATCH 01/43] chore(deps): bump actions/dependency-review-action from 1.0.1 to 1.0.2 (#7476) Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/39e692fa323107ef86d8fdac0067ce647f239bd7...a9c83d3af6b9031e20feba03b904645bb23d1dab) --- updated-dependencies: - dependency-name: actions/dependency-review-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 32fc4d96a997..786484e2847d 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -15,4 +15,4 @@ jobs: - name: Checkout uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3 - name: Dependency Review - uses: actions/dependency-review-action@39e692fa323107ef86d8fdac0067ce647f239bd7 # v1 + uses: actions/dependency-review-action@a9c83d3af6b9031e20feba03b904645bb23d1dab # v1 From 222bf3c0919a17d8caebadc823021058dd3ac4ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 May 2022 10:41:17 +0800 Subject: [PATCH 02/43] chore(deps): bump github/codeql-action from 2.1.10 to 2.1.11 (#7475) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.1.10 to 2.1.11. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/2f58583a1b24a7d3c7034f6bf9fa506d23b1183b...a3a6c128d771b6b9bdebb1c9d0583ebd2728a108) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 91f6c42c4f64..639230777941 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,9 +34,9 @@ jobs: uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3 - name: Initialize CodeQL - uses: github/codeql-action/init@2f58583a1b24a7d3c7034f6bf9fa506d23b1183b # v2 + uses: github/codeql-action/init@a3a6c128d771b6b9bdebb1c9d0583ebd2728a108 # v2 with: languages: ${{ matrix.language }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2f58583a1b24a7d3c7034f6bf9fa506d23b1183b # v2 + uses: github/codeql-action/analyze@a3a6c128d771b6b9bdebb1c9d0583ebd2728a108 # v2 From bf1513a3e357025ab1cf4cdb4c09f21316b31cfd Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Tue, 24 May 2022 15:40:26 +0800 Subject: [PATCH 03/43] refactor: fix a lot of errors in type-aware linting (#7477) --- __tests__/validate-package-json.test.ts | 20 +++--- .../functions/codesandbox.ts | 5 +- .../new.docusaurus.io/functions/stackblitz.ts | 5 +- packages/create-docusaurus/src/index.ts | 41 ++++++------ packages/docusaurus-logger/src/index.ts | 4 +- packages/docusaurus-mdx-loader/src/index.ts | 2 +- packages/docusaurus-mdx-loader/src/loader.ts | 4 +- .../src/remark/headings/index.ts | 4 +- .../src/remark/transformLinks/index.ts | 5 +- .../src/remark/utils/index.ts | 2 +- .../src/__tests__/index.test.ts | 8 +-- .../docusaurus-migrate/src/frontMatter.ts | 7 +- packages/docusaurus-migrate/src/index.ts | 61 +++++++++--------- packages/docusaurus-migrate/src/sanitizeMD.ts | 2 +- .../src/index.d.ts | 2 +- .../src/__tests__/writeRedirectFiles.test.ts | 14 ++-- .../src/index.ts | 2 +- .../src/__tests__/feed.test.ts | 2 + .../src/__tests__/index.test.ts | 2 +- .../src/__tests__/translations.test.ts | 2 +- .../src/authors.ts | 6 +- .../src/blogUtils.ts | 4 +- .../src/index.ts | 10 +-- .../src/markdownLoader.ts | 2 +- .../src/options.ts | 5 +- .../__snapshots__/translations.test.ts.snap | 60 ++++++++++++----- .../src/__tests__/cli.test.ts | Bin 11382 -> 11378 bytes .../src/__tests__/docs.test.ts | 2 +- .../src/__tests__/index.test.ts | 4 +- .../src/__tests__/options.test.ts | 10 +-- .../src/__tests__/translations.test.ts | 6 +- .../src/client/docsClientUtils.ts | 2 +- .../src/client/index.ts | 8 ++- .../src/index.ts | 2 +- .../src/markdown/index.ts | 2 +- .../src/options.ts | 2 +- .../src/props.ts | 2 +- .../src/sidebars/__tests__/generator.test.ts | 4 +- .../src/sidebars/__tests__/processor.test.ts | 4 +- .../src/sidebars/__tests__/utils.test.ts | 20 +++--- .../src/sidebars/__tests__/validation.test.ts | 16 ++--- .../src/sidebars/generator.ts | 2 +- .../src/sidebars/postProcessor.ts | 2 +- .../src/sidebars/types.ts | 4 +- .../src/sidebars/utils.ts | 2 +- .../src/sidebars/validation.ts | 8 ++- .../src/slug.ts | 2 +- .../src/versions/__tests__/index.test.ts | 2 +- .../src/versions/validation.ts | 4 +- .../src/__tests__/index.test.ts | 4 +- .../src/index.ts | 4 +- .../src/markdownLoader.ts | 2 +- .../src/options.ts | 2 +- .../src/theme/DebugSiteMetadata/index.tsx | 2 +- .../src/index.ts | 2 +- .../src/index.ts | 2 +- .../src/theme/IdealImage/index.tsx | 8 +-- packages/docusaurus-plugin-pwa/src/index.ts | 8 +-- packages/docusaurus-plugin-pwa/src/options.ts | 4 +- .../docusaurus-plugin-pwa/src/registerSw.ts | 6 +- .../docusaurus-plugin-sitemap/src/options.ts | 3 +- .../src/index.ts | 4 +- .../docusaurus-theme-classic/src/index.ts | 2 +- .../src/theme-classic.d.ts | 4 +- .../src/theme/CodeBlock/Content/String.tsx | 2 +- .../src/theme/DocSidebarItem/Html/index.tsx | 2 +- .../theme/Footer/Links/MultiColumn/index.tsx | 2 +- .../src/components/Collapsible/index.tsx | 2 +- .../src/hooks/useSkipToContent.ts | 2 +- .../src/hooks/useTOCHighlight.ts | 7 +- .../src/utils/codeBlockUtils.ts | 4 +- .../src/utils/reactUtils.tsx | 2 +- .../src/utils/routesUtils.ts | 2 +- .../src/utils/scrollUtils.tsx | 6 +- .../src/utils/searchUtils.ts | 2 +- .../src/utils/tocUtils.ts | 2 +- .../src/utils/usePluralForm.ts | 6 +- .../src/validateThemeConfig.ts | 2 +- .../src/index.ts | 2 +- .../src/validateThemeConfig.ts | 2 +- .../src/index.ts | 4 +- .../src/JoiFrontMatter.ts | 2 +- packages/docusaurus-utils/src/pathUtils.ts | 2 +- packages/docusaurus-utils/src/urlUtils.ts | 6 +- packages/docusaurus/src/client/docusaurus.ts | 2 +- .../src/client/exports/useBaseUrl.ts | 2 +- packages/docusaurus/src/commands/serve.ts | 2 +- .../commands/swizzle/__tests__/config.test.ts | 12 ++-- .../src/commands/swizzle/actions.ts | 2 +- .../docusaurus/src/commands/swizzle/config.ts | 10 ++- .../docusaurus/src/commands/swizzle/themes.ts | 10 ++- .../src/commands/writeHeadingIds.ts | 4 +- packages/docusaurus/src/deps.d.ts | 4 +- .../docusaurus/src/server/plugins/configs.ts | 4 +- .../docusaurus/src/server/plugins/index.ts | 2 +- .../docusaurus/src/server/plugins/init.ts | 6 +- .../src/server/plugins/moduleShorthand.ts | 5 +- .../src/server/plugins/routeConfig.ts | 4 +- .../src/server/plugins/synthetic.ts | 2 +- packages/docusaurus/src/server/routes.ts | 2 +- .../translations/translationsExtractor.ts | 6 +- packages/docusaurus/src/webpack/base.ts | 2 +- .../src/webpack/plugins/CleanWebpackPlugin.ts | 13 ++-- packages/docusaurus/src/webpack/utils.ts | 14 ++-- packages/lqip-loader/src/index.ts | 4 +- packages/stylelint-copyright/src/index.ts | 5 +- website/_dogfooding/docs-tests-sidebars.js | 26 ++++++-- .../_dogfooding/testSwizzleThemeClassic.mjs | 13 ++-- website/delayCrowdin.mjs | 3 + website/docusaurus.config.js | 2 +- website/src/components/APITable/index.tsx | 4 +- .../src/components/ColorGenerator/index.tsx | 4 +- .../src/components/TeamProfileCards/index.tsx | 4 +- website/src/pages/index.tsx | 2 +- .../ShowcaseFilterToggle/index.tsx | 2 +- .../_components/ShowcaseTooltip/index.tsx | 6 +- website/src/pages/versions.tsx | 61 +++++++++--------- website/src/theme/ColorModeToggle.tsx | 4 +- website/testCSSOrder.mjs | 11 +++- website/waitForCrowdin.mjs | 3 + 120 files changed, 407 insertions(+), 364 deletions(-) diff --git a/__tests__/validate-package-json.test.ts b/__tests__/validate-package-json.test.ts index ef18176ecd92..b8dd9b78771e 100644 --- a/__tests__/validate-package-json.test.ts +++ b/__tests__/validate-package-json.test.ts @@ -70,17 +70,15 @@ describe('packages', () => { packageJsonFile.content.name?.startsWith('@'), ) .forEach((packageJsonFile) => { - if (packageJsonFile) { - // Unfortunately jest custom message do not exist in loops, - // so using an exception instead to show failing package file - // (see https://github.com/facebook/jest/issues/3293) - // expect(packageJsonFile.content.publishConfig?.access) - // .toEqual('public'); - if (packageJsonFile.content.publishConfig?.access !== 'public') { - throw new Error( - `Package ${packageJsonFile.file} does not have publishConfig.access: 'public'`, - ); - } + // Unfortunately jest custom message do not exist in loops, + // so using an exception instead to show failing package file + // (see https://github.com/facebook/jest/issues/3293) + // expect(packageJsonFile.content.publishConfig?.access) + // .toEqual('public'); + if (packageJsonFile.content.publishConfig?.access !== 'public') { + throw new Error( + `Package ${packageJsonFile.file} does not have publishConfig.access: 'public'`, + ); } }); }); diff --git a/admin/new.docusaurus.io/functions/codesandbox.ts b/admin/new.docusaurus.io/functions/codesandbox.ts index 650c45727e6b..6f7b8327decf 100644 --- a/admin/new.docusaurus.io/functions/codesandbox.ts +++ b/admin/new.docusaurus.io/functions/codesandbox.ts @@ -8,6 +8,5 @@ import {createPlaygroundResponse} from '../functionUtils/playgroundUtils'; import type {Handler} from '@netlify/functions'; -export const handler: Handler = async function handler() { - return createPlaygroundResponse('codesandbox'); -}; +export const handler: Handler = () => + Promise.resolve(createPlaygroundResponse('codesandbox')); diff --git a/admin/new.docusaurus.io/functions/stackblitz.ts b/admin/new.docusaurus.io/functions/stackblitz.ts index bc6a84d31f5a..6e69c2ade829 100644 --- a/admin/new.docusaurus.io/functions/stackblitz.ts +++ b/admin/new.docusaurus.io/functions/stackblitz.ts @@ -8,6 +8,5 @@ import {createPlaygroundResponse} from '../functionUtils/playgroundUtils'; import type {Handler} from '@netlify/functions'; -export const handler: Handler = async function handler() { - return createPlaygroundResponse('stackblitz'); -}; +export const handler: Handler = () => + Promise.resolve(createPlaygroundResponse('stackblitz')); diff --git a/packages/create-docusaurus/src/index.ts b/packages/create-docusaurus/src/index.ts index c1f592cefcd1..6523b9291766 100755 --- a/packages/create-docusaurus/src/index.ts +++ b/packages/create-docusaurus/src/index.ts @@ -65,20 +65,22 @@ async function askForPackageManagerChoice(): Promise { .map((p) => ({title: p, value: p})); return ( - (await prompts( - { - type: 'select', - name: 'packageManager', - message: 'Select a package manager...', - choices, - }, - { - onCancel() { - logger.info`Falling back to name=${defaultPackageManager}`; + ( + (await prompts( + { + type: 'select', + name: 'packageManager', + message: 'Select a package manager...', + choices, }, - }, - )) as {packageManager: PackageManager} - ).packageManager; + { + onCancel() { + logger.info`Falling back to name=${defaultPackageManager}`; + }, + }, + )) as {packageManager: PackageManager} + ).packageManager ?? defaultPackageManager + ); } async function getPackageManager( @@ -101,8 +103,7 @@ async function getPackageManager( (await findPackageManagerFromLockFile('.')) ?? findPackageManagerFromUserAgent() ?? // This only happens if the user has a global installation in PATH - (skipInstall ? defaultPackageManager : askForPackageManagerChoice()) ?? - defaultPackageManager + (skipInstall ? defaultPackageManager : askForPackageManagerChoice()) ); } @@ -215,7 +216,7 @@ async function getGitCommand(gitStrategy: GitStrategy): Promise { logger.info`Falling back to code=${'git clone'}`; }, }, - )) as {command: string}; + )) as {command?: string}; return command ?? 'git clone'; } case 'deep': @@ -362,7 +363,7 @@ async function getSource( )) as {gitRepoUrl: string}; let strategy = cliOptions.gitStrategy; if (!strategy) { - ({strategy} = await prompts( + ({strategy} = (await prompts( { type: 'select', name: 'strategy', @@ -385,7 +386,7 @@ async function getSource( logger.info`Falling back to name=${'deep'}`; }, }, - )); + )) as {strategy?: GitStrategy}); } return { type: 'git', @@ -426,13 +427,13 @@ async function getSource( } let useTS = cliOptions.typescript; if (!useTS && template.tsVariantPath) { - ({useTS} = await prompts({ + ({useTS} = (await prompts({ type: 'confirm', name: 'useTS', message: 'This template is available in TypeScript. Do you want to use the TS variant?', initial: false, - })); + })) as {useTS?: boolean}); } return { type: 'template', diff --git a/packages/docusaurus-logger/src/index.ts b/packages/docusaurus-logger/src/index.ts index 6db95cdd1531..768cb8f9a0c2 100644 --- a/packages/docusaurus-logger/src/index.ts +++ b/packages/docusaurus-logger/src/index.ts @@ -9,10 +9,10 @@ import chalk from 'chalk'; type InterpolatableValue = string | number | (string | number)[]; -const path = (msg: unknown): string => chalk.cyan.underline(`"${msg}"`); +const path = (msg: unknown): string => chalk.cyan.underline(`"${String(msg)}"`); const url = (msg: unknown): string => chalk.cyan.underline(msg); const name = (msg: unknown): string => chalk.blue.bold(msg); -const code = (msg: unknown): string => chalk.cyan(`\`${msg}\``); +const code = (msg: unknown): string => chalk.cyan(`\`${String(msg)}\``); const subdue = (msg: unknown): string => chalk.gray(msg); const num = (msg: unknown): string => chalk.yellow(msg); diff --git a/packages/docusaurus-mdx-loader/src/index.ts b/packages/docusaurus-mdx-loader/src/index.ts index ad7887dcc77c..1b7f2be72344 100644 --- a/packages/docusaurus-mdx-loader/src/index.ts +++ b/packages/docusaurus-mdx-loader/src/index.ts @@ -21,7 +21,7 @@ export type LoadedMDXContent = { /** As provided by the content plugin. */ readonly metadata: Metadata; /** A list of TOC items (headings). */ - readonly toc: readonly TOCItem[]; + readonly toc?: readonly TOCItem[]; /** First h1 title before any content. */ readonly contentTitle: string | undefined; /** diff --git a/packages/docusaurus-mdx-loader/src/loader.ts b/packages/docusaurus-mdx-loader/src/loader.ts index 88fa1ecd5bdc..638a62566724 100644 --- a/packages/docusaurus-mdx-loader/src/loader.ts +++ b/packages/docusaurus-mdx-loader/src/loader.ts @@ -55,7 +55,7 @@ export type MDXOptions = { beforeDefaultRehypePlugins: MDXPlugin[]; }; -export type Options = MDXOptions & { +export type Options = Partial & { staticDirs: string[]; siteDir: string; isMDXPartial?: (filePath: string) => boolean; @@ -138,7 +138,7 @@ export async function mdxLoader( ): Promise { const callback = this.async(); const filePath = this.resourcePath; - const reqOptions = this.getOptions() ?? {}; + const reqOptions = this.getOptions(); const {frontMatter, content: contentWithTitle} = parseFrontMatter(fileString); diff --git a/packages/docusaurus-mdx-loader/src/remark/headings/index.ts b/packages/docusaurus-mdx-loader/src/remark/headings/index.ts index 51b0cb6c7bbd..98aaa37f7552 100644 --- a/packages/docusaurus-mdx-loader/src/remark/headings/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/headings/index.ts @@ -17,7 +17,7 @@ export default function plugin(): Transformer { return (root) => { const slugs = createSlugger(); visit(root, 'heading', (headingNode: Heading) => { - const data = headingNode.data || (headingNode.data = {}); + const data = headingNode.data ?? (headingNode.data = {}); const properties = (data.hProperties || (data.hProperties = {})) as { id: string; }; @@ -36,7 +36,7 @@ export default function plugin(): Transformer { // Support explicit heading IDs const parsedHeading = parseMarkdownHeadingId(heading); - id = parsedHeading.id || slugs.slug(heading); + id = parsedHeading.id ?? slugs.slug(heading); if (parsedHeading.id) { // When there's an id, it is always in the last child node diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts index 9c9f2004ba7d..59e1b4117bf5 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts @@ -110,8 +110,9 @@ async function processLinkNode(node: Link, context: Context) { if (!node.url) { // Try to improve error feedback // see https://github.com/facebook/docusaurus/issues/3309#issuecomment-690371675 - const title = node.title || (node.children[0] as Literal)?.value || '?'; - const line = node?.position?.start?.line || '?'; + const title = + node.title ?? (node.children[0] as Literal | undefined)?.value ?? '?'; + const line = node.position?.start.line ?? '?'; throw new Error( `Markdown link URL is mandatory in "${toMessageRelativeFilePath( context.filePath, diff --git a/packages/docusaurus-mdx-loader/src/remark/utils/index.ts b/packages/docusaurus-mdx-loader/src/remark/utils/index.ts index b0314d7a2349..3bf275085bf5 100644 --- a/packages/docusaurus-mdx-loader/src/remark/utils/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/utils/index.ts @@ -15,7 +15,7 @@ export function stringifyContent(node: Parent): string { } export function toValue(node: PhrasingContent | Heading): string { - switch (node?.type) { + switch (node.type) { case 'text': return escapeHtml(node.value); case 'heading': diff --git a/packages/docusaurus-migrate/src/__tests__/index.test.ts b/packages/docusaurus-migrate/src/__tests__/index.test.ts index 8eea0cd15849..306f7e394a12 100644 --- a/packages/docusaurus-migrate/src/__tests__/index.test.ts +++ b/packages/docusaurus-migrate/src/__tests__/index.test.ts @@ -19,22 +19,22 @@ async function testMigration(siteDir: string, newDir: string) { await migrateDocusaurusProject(siteDir, newDir, true, true); expect( writeMock.mock.calls.sort((a, b) => - posixPath(a[0] as string).localeCompare(posixPath(b[0] as string)), + posixPath(a[0]).localeCompare(posixPath(b[0])), ), ).toMatchSnapshot('write'); expect( mkdirpMock.mock.calls.sort((a, b) => - posixPath(a[0] as string).localeCompare(posixPath(b[0] as string)), + posixPath(a[0]).localeCompare(posixPath(b[0])), ), ).toMatchSnapshot('mkdirp'); expect( mkdirsMock.mock.calls.sort((a, b) => - posixPath(a[0] as string).localeCompare(posixPath(b[0] as string)), + posixPath(a[0]).localeCompare(posixPath(b[0])), ), ).toMatchSnapshot('mkdirs'); expect( copyMock.mock.calls.sort((a, b) => - posixPath(a[0] as string).localeCompare(posixPath(b[0] as string)), + posixPath(a[0]).localeCompare(posixPath(b[0])), ), ).toMatchSnapshot('copy'); writeMock.mockRestore(); diff --git a/packages/docusaurus-migrate/src/frontMatter.ts b/packages/docusaurus-migrate/src/frontMatter.ts index 2d03fb0e40e5..6ec040296d74 100644 --- a/packages/docusaurus-migrate/src/frontMatter.ts +++ b/packages/docusaurus-migrate/src/frontMatter.ts @@ -40,12 +40,7 @@ export default function extractMetadata(content: string): Data { lines.slice(0, -1).forEach((line) => { const keyValue = line.split(':') as [string, ...string[]]; const key = keyValue[0].trim(); - let value = keyValue.slice(1).join(':').trim(); - try { - value = JSON.parse(value); - } catch (err) { - // Ignore the error as it means it's not a JSON value. - } + const value = keyValue.slice(1).join(':').trim(); metadata[key] = value; }); return {metadata, rawContent: both.content}; diff --git a/packages/docusaurus-migrate/src/index.ts b/packages/docusaurus-migrate/src/index.ts index 81f31e6b874c..165c7c2fd32f 100644 --- a/packages/docusaurus-migrate/src/index.ts +++ b/packages/docusaurus-migrate/src/index.ts @@ -474,7 +474,7 @@ async function migrateVersionedDocs( versions.reverse().map(async (version, index) => { if (index === 0) { await fs.copy( - path.join(siteDir, '..', context.v1Config.customDocsPath || 'docs'), + path.join(siteDir, '..', context.v1Config.customDocsPath ?? 'docs'), path.join(newDir, 'versioned_docs', `version-${version}`), ); await fs.copy( @@ -551,7 +551,9 @@ async function migrateVersionedSidebar( const newSidebar = Object.entries(sidebarEntries).reduce( (topLevel: SidebarEntries, value) => { const key = value[0].replace(versionRegex, ''); - topLevel[key] = Object.entries(value[1]).reduce((acc, val) => { + topLevel[key] = Object.entries(value[1]).reduce<{ + [key: string]: Array; + }>((acc, val) => { acc[val[0].replace(versionRegex, '')] = ( val[1] as SidebarEntry[] ).map((item) => { @@ -565,7 +567,7 @@ async function migrateVersionedSidebar( }; }); return acc; - }, {} as {[key: string]: Array}); + }, {}); return topLevel; }, {}, @@ -574,33 +576,32 @@ async function migrateVersionedSidebar( } await Promise.all( sidebars.map(async (sidebar) => { - const newSidebar = Object.entries(sidebar.entries).reduce( - (acc, val) => { - const key = `version-${sidebar.version}/${val[0]}`; - acc[key] = Object.entries(val[1]).map((value) => ({ - type: 'category', - label: value[0], - items: (value[1] as SidebarEntry[]).map((sidebarItem) => { - if (typeof sidebarItem === 'string') { - return { - type: 'doc', - id: `version-${sidebar.version}/${sidebarItem}`, - }; - } + const newSidebar = Object.entries( + sidebar.entries, + ).reduce((acc, val) => { + const key = `version-${sidebar.version}/${val[0]}`; + acc[key] = Object.entries(val[1]).map((value) => ({ + type: 'category', + label: value[0], + items: (value[1] as SidebarEntry[]).map((sidebarItem) => { + if (typeof sidebarItem === 'string') { return { - type: 'category', - label: sidebarItem.label, - items: sidebarItem.ids.map((id) => ({ - type: 'doc', - id: `version-${sidebar.version}/${id}`, - })), + type: 'doc', + id: `version-${sidebar.version}/${sidebarItem}`, }; - }), - })); - return acc; - }, - {} as SidebarEntries, - ); + } + return { + type: 'category', + label: sidebarItem.label, + items: sidebarItem.ids.map((id) => ({ + type: 'doc', + id: `version-${sidebar.version}/${id}`, + })), + }; + }), + })); + return acc; + }, {}); await fs.outputFile( path.join( newDir, @@ -702,12 +703,12 @@ async function migrateLatestDocs(context: MigrationContext) { async function migratePackageFile(context: MigrationContext): Promise { const {deps, siteDir, newDir} = context; - const packageFile = importFresh(`${siteDir}/package.json`) as { + const packageFile = importFresh<{ scripts?: {[key: string]: string}; dependencies?: {[key: string]: string}; devDependencies?: {[key: string]: string}; [otherKey: string]: unknown; - }; + }>(`${siteDir}/package.json`); packageFile.scripts = { ...packageFile.scripts, start: 'docusaurus start', diff --git a/packages/docusaurus-migrate/src/sanitizeMD.ts b/packages/docusaurus-migrate/src/sanitizeMD.ts index 55bd803aea51..61e3904cb0aa 100644 --- a/packages/docusaurus-migrate/src/sanitizeMD.ts +++ b/packages/docusaurus-migrate/src/sanitizeMD.ts @@ -37,7 +37,7 @@ export default function sanitizeMD(code: string): string { const htmlTree = unified().use(parse).parse(markdownString); visit(htmlTree, 'element', (node: Element) => { - if (!tags[node.tagName as string]) { + if (!tags[node.tagName]) { (node as Element | Text).type = 'text'; (node as Element & Partial>).value = node.tagName + toText(node); diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index ccb4bf5706fc..cd6bf0d1c910 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -8,7 +8,7 @@ declare module '@generated/client-modules' { import type {ClientModule} from '@docusaurus/types'; - const clientModules: readonly (ClientModule & {default: ClientModule})[]; + const clientModules: readonly (ClientModule & {default?: ClientModule})[]; export default clientModules; } diff --git a/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts b/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts index 739c2f6a99b5..2ed5d2f1a1b1 100644 --- a/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts +++ b/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts @@ -17,7 +17,7 @@ import writeRedirectFiles, { // - https://github.com/facebook/docusaurus/issues/3886 // - https://github.com/facebook/docusaurus/issues/3925 describe('createToUrl', () => { - it('creates appropriate redirect urls', async () => { + it('creates appropriate redirect urls', () => { expect(createToUrl('/', '/docs/something/else')).toBe( '/docs/something/else', ); @@ -29,7 +29,7 @@ describe('createToUrl', () => { ); }); - it('creates appropriate redirect urls with baseUrl', async () => { + it('creates appropriate redirect urls with baseUrl', () => { expect(createToUrl('/baseUrl/', '/docs/something/else')).toBe( '/baseUrl/docs/something/else', ); @@ -43,7 +43,7 @@ describe('createToUrl', () => { }); describe('toRedirectFilesMetadata', () => { - it('creates appropriate metadata trailingSlash=undefined', async () => { + it('creates appropriate metadata trailingSlash=undefined', () => { const pluginContext = { outDir: '/tmp/someFixedOutDir', baseUrl: 'https://docusaurus.io', @@ -70,7 +70,7 @@ describe('toRedirectFilesMetadata', () => { ); }); - it('creates appropriate metadata trailingSlash=true', async () => { + it('creates appropriate metadata trailingSlash=true', () => { const pluginContext = { outDir: '/tmp/someFixedOutDir', baseUrl: 'https://docusaurus.io', @@ -97,7 +97,7 @@ describe('toRedirectFilesMetadata', () => { ); }); - it('creates appropriate metadata trailingSlash=false', async () => { + it('creates appropriate metadata trailingSlash=false', () => { const pluginContext = { outDir: '/tmp/someFixedOutDir', baseUrl: 'https://docusaurus.io', @@ -127,7 +127,7 @@ describe('toRedirectFilesMetadata', () => { ); }); - it('creates appropriate metadata for root baseUrl', async () => { + it('creates appropriate metadata for root baseUrl', () => { const pluginContext = { outDir: '/tmp/someFixedOutDir', baseUrl: '/', @@ -142,7 +142,7 @@ describe('toRedirectFilesMetadata', () => { ); }); - it('creates appropriate metadata for empty baseUrl', async () => { + it('creates appropriate metadata for empty baseUrl', () => { const pluginContext = { outDir: '/tmp/someFixedOutDir', baseUrl: '', diff --git a/packages/docusaurus-plugin-client-redirects/src/index.ts b/packages/docusaurus-plugin-client-redirects/src/index.ts index 78d117c7ca28..237f3f099e9e 100644 --- a/packages/docusaurus-plugin-client-redirects/src/index.ts +++ b/packages/docusaurus-plugin-client-redirects/src/index.ts @@ -18,7 +18,7 @@ import type {PluginOptions, Options} from './options'; export default function pluginClientRedirectsPages( context: LoadContext, options: PluginOptions, -): Plugin { +): Plugin { const {trailingSlash} = context.siteConfig; return { 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 48c3395f728b..7b7981985443 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts @@ -89,6 +89,7 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { }, readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), + truncateMarker: //, } as PluginOptions, ); @@ -128,6 +129,7 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { }, readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), + truncateMarker: //, } 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 11b33cd2a183..384b7014c7ea 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -76,7 +76,7 @@ const getPlugin = async ( editUrl: BaseEditUrl, ...pluginOptions, }, - }) as PluginOptions, + }), ); }; diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts index 62442bbf8151..a29ae6e3acb7 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts @@ -74,7 +74,7 @@ function getSampleTranslationFilesTranslated() { } describe('getContentTranslationFiles', () => { - it('returns translation files matching snapshot', async () => { + it('returns translation files matching snapshot', () => { expect(getSampleTranslationFiles()).toMatchSnapshot(); }); }); diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index cf3bbe5c8522..4d8f7b90b3fb 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -44,7 +44,11 @@ const AuthorsMapSchema = Joi.object() }); export function validateAuthorsMap(content: unknown): AuthorsMap { - return Joi.attempt(content, AuthorsMapSchema); + const {error, value} = AuthorsMapSchema.validate(content); + if (error) { + throw error; + } + return value; } export async function getAuthorsMap(params: { diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 370ddeb50aa3..ee6742c7bff5 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -264,7 +264,7 @@ async function processBlogSourceFile( const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text; const description = frontMatter.description ?? excerpt ?? ''; - const slug = frontMatter.slug || parsedBlogFileName.slug; + const slug = frontMatter.slug ?? parsedBlogFileName.slug; const permalink = normalizeUrl([baseUrl, routeBasePath, slug]); @@ -323,7 +323,7 @@ async function processBlogSourceFile( defaultReadingTime, }) : undefined, - truncated: truncateMarker?.test(content) || false, + truncated: truncateMarker.test(content), authors, frontMatter, }, diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index a3dddc2404f5..2b0355a0f3f1 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -176,10 +176,6 @@ export default async function pluginContentBlog( }, async contentLoaded({content: blogContents, actions}) { - if (!blogContents) { - return; - } - const { blogListComponent, blogPostComponent, @@ -500,11 +496,7 @@ export default async function pluginContentBlog( }, injectHtmlTags({content}) { - if (!content.blogPosts.length) { - return {}; - } - - if (!options.feedOptions?.type) { + if (!content.blogPosts.length || !options.feedOptions.type) { return {}; } diff --git a/packages/docusaurus-plugin-content-blog/src/markdownLoader.ts b/packages/docusaurus-plugin-content-blog/src/markdownLoader.ts index a5f3d4929889..add3e16682c2 100644 --- a/packages/docusaurus-plugin-content-blog/src/markdownLoader.ts +++ b/packages/docusaurus-plugin-content-blog/src/markdownLoader.ts @@ -34,5 +34,5 @@ export default function markdownLoader( finalContent = truncate(finalContent, markdownLoaderOptions.truncateMarker); } - return callback?.(null, finalContent); + return callback(null, finalContent); } diff --git a/packages/docusaurus-plugin-content-blog/src/options.ts b/packages/docusaurus-plugin-content-blog/src/options.ts index f6fa74e726bc..ff06c867dc9d 100644 --- a/packages/docusaurus-plugin-content-blog/src/options.ts +++ b/packages/docusaurus-plugin-content-blog/src/options.ts @@ -136,9 +136,6 @@ export function validateOptions({ validate, options, }: OptionValidationContext): PluginOptions { - const validatedOptions = validate( - PluginOptionSchema, - options, - ) as PluginOptions; + const validatedOptions = validate(PluginOptionSchema, options); return validatedOptions; } diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap index a67e0081748c..b952835b06d0 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap @@ -90,13 +90,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc1 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc1 title", + }, "id": "doc1", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc1 title", "slug": "any", "source": "any", "title": "doc1 title", @@ -106,13 +108,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc2 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc2 title", + }, "id": "doc2", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc2 title", "slug": "any", "source": "any", "title": "doc2 title", @@ -122,13 +126,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc3 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc3 title", + }, "id": "doc3", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc3 title", "slug": "any", "source": "any", "title": "doc3 title", @@ -138,13 +144,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc4 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc4 title", + }, "id": "doc4", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc4 title", "slug": "any", "source": "any", "title": "doc4 title", @@ -154,13 +162,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc5 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc5 title", + }, "id": "doc5", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc5 title", "slug": "any", "source": "any", "title": "doc5 title", @@ -232,13 +242,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc1 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc1 title", + }, "id": "doc1", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc1 title", "slug": "any", "source": "any", "title": "doc1 title", @@ -248,13 +260,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc2 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc2 title", + }, "id": "doc2", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc2 title", "slug": "any", "source": "any", "title": "doc2 title", @@ -264,13 +278,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc3 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc3 title", + }, "id": "doc3", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc3 title", "slug": "any", "source": "any", "title": "doc3 title", @@ -280,13 +296,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc4 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc4 title", + }, "id": "doc4", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc4 title", "slug": "any", "source": "any", "title": "doc4 title", @@ -296,13 +314,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc5 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc5 title", + }, "id": "doc5", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc5 title", "slug": "any", "source": "any", "title": "doc5 title", @@ -374,13 +394,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc1 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc1 title", + }, "id": "doc1", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc1 title", "slug": "any", "source": "any", "title": "doc1 title", @@ -390,13 +412,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc2 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc2 title", + }, "id": "doc2", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc2 title", "slug": "any", "source": "any", "title": "doc2 title", @@ -406,13 +430,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc3 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc3 title", + }, "id": "doc3", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc3 title", "slug": "any", "source": "any", "title": "doc3 title", @@ -422,13 +448,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc4 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc4 title", + }, "id": "doc4", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc4 title", "slug": "any", "source": "any", "title": "doc4 title", @@ -438,13 +466,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "description": "doc5 description", "editUrl": "any", + "frontMatter": { + "sidebar_label": "doc5 title", + }, "id": "doc5", "lastUpdatedAt": 0, "lastUpdatedBy": "any", "next": undefined, "permalink": "any", "previous": undefined, - "sidebar_label": "doc5 title", "slug": "any", "source": "any", "title": "doc5 title", diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts index bb1f1c70a0717b59c9490a839032b75983303d2b..55c50ab0cddf930ca37a38e3b431cfad218d6b70 100644 GIT binary patch delta 35 rcmews@hM`%4i=WY(wv;d`&bw`OY>4v(=zi?QzqZzci7Cyma7H;7HSRp delta 43 xcmewq@hxJ*4i+}0ywaQ;rOD^`>?i+bImoS4nwOHAmYJ8D0upoB%*vLl1^}6d5extT 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 3e0f09010925..9a338c5bf9d2 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -119,7 +119,7 @@ function createTestUtils({ async function testSlug(docFileSource: string, expectedPermalink: string) { const docFile = await readDoc(docFileSource); - const metadata = await processDocMetadata({ + const metadata = processDocMetadata({ docFile, versionMetadata, context, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index 0d54d4bc1308..fd25cc85eef9 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -54,9 +54,9 @@ const createFakeActions = (contentDir: string) => { addRoute: (config: RouteConfig) => { routeConfigs.push(config); }, - createData: async (name: string, content: unknown) => { + createData: (name: string, content: unknown) => { dataContainer[name] = content; - return path.join(contentDir, name); + return Promise.resolve(path.join(contentDir, name)); }, setGlobalData: (data: unknown) => { globalDataContainer.pluginName = {pluginId: data}; 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 bcbaccfe1144..a3ddd11f843d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts @@ -31,11 +31,11 @@ const defaultOptions = { }; describe('normalizeDocsPluginOptions', () => { - it('returns default options for undefined user options', async () => { + it('returns default options for undefined user options', () => { expect(testValidate({})).toEqual(defaultOptions); }); - it('accepts correctly defined user options', async () => { + it('accepts correctly defined user options', () => { const userOptions = { path: 'my-docs', // Path to data on filesystem, relative to site dir. routeBasePath: 'my-docs', // URL Route. @@ -83,7 +83,7 @@ describe('normalizeDocsPluginOptions', () => { }); }); - it('accepts correctly defined remark and rehype plugin options', async () => { + it('accepts correctly defined remark and rehype plugin options', () => { const userOptions = { beforeDefaultRemarkPlugins: [], beforeDefaultRehypePlugins: [markdownPluginsFunctionStub], @@ -100,7 +100,7 @@ describe('normalizeDocsPluginOptions', () => { }); }); - it('accepts admonitions false', async () => { + it('accepts admonitions false', () => { const admonitionsFalse = { admonitions: false, }; @@ -110,7 +110,7 @@ describe('normalizeDocsPluginOptions', () => { }); }); - it('rejects admonitions true', async () => { + it('rejects admonitions true', () => { const admonitionsTrue = { admonitions: true, }; diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts index 5d098e355fb7..a79409ba8d84 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts @@ -30,7 +30,9 @@ function createSampleDoc(doc: Pick): DocMetadata { unversionedId: 'any', version: 'any', title: `${doc.id} title`, - sidebar_label: `${doc.id} title`, + frontMatter: { + sidebar_label: `${doc.id} title`, + }, description: `${doc.id} description`, ...doc, }; @@ -136,7 +138,7 @@ function getSampleTranslationFilesTranslated() { } describe('getLoadedContentTranslationFiles', () => { - it('returns translation files', async () => { + it('returns translation files', () => { expect(getSampleTranslationFiles()).toMatchSnapshot(); }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/client/docsClientUtils.ts b/packages/docusaurus-plugin-content-docs/src/client/docsClientUtils.ts index 752a53d91edc..f3229ac46522 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/docsClientUtils.ts +++ b/packages/docusaurus-plugin-content-docs/src/client/docsClientUtils.ts @@ -126,6 +126,6 @@ export function getDocVersionSuggestions( const latestVersion = getLatestVersion(data); const activeDocContext = getActiveDocContext(data, pathname); const latestDocSuggestion: GlobalDoc | undefined = - activeDocContext?.alternateDocVersions[latestVersion.name]; + activeDocContext.alternateDocVersions[latestVersion.name]; return {latestDocSuggestion, latestVersionSuggestion: latestVersion}; } diff --git a/packages/docusaurus-plugin-content-docs/src/client/index.ts b/packages/docusaurus-plugin-content-docs/src/client/index.ts index 298ed4dcd9c9..bfc2bfd78cb0 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/client/index.ts @@ -34,9 +34,11 @@ const StableEmptyObject = {}; // In blog-only mode, docs hooks are still used by the theme. We need a fail- // safe fallback when the docs plugin is not in use export const useAllDocsData = (): {[pluginId: string]: GlobalPluginData} => - (useAllPluginInstancesData('docusaurus-plugin-content-docs') as { - [pluginId: string]: GlobalPluginData; - }) ?? StableEmptyObject; + (useAllPluginInstancesData('docusaurus-plugin-content-docs') as + | { + [pluginId: string]: GlobalPluginData; + } + | undefined) ?? StableEmptyObject; export const useDocsData = (pluginId: string | undefined): GlobalPluginData => usePluginData('docusaurus-plugin-content-docs', pluginId, { diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 982895957382..afbb809fb718 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -143,7 +143,7 @@ export default async function pluginContentDocs( )}".`, ); } - async function processVersionDoc(docFile: DocFile) { + function processVersionDoc(docFile: DocFile) { return processDocMetadata({ docFile, versionMetadata, diff --git a/packages/docusaurus-plugin-content-docs/src/markdown/index.ts b/packages/docusaurus-plugin-content-docs/src/markdown/index.ts index 5de4aae87f4d..9d846ef8d5c5 100644 --- a/packages/docusaurus-plugin-content-docs/src/markdown/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/markdown/index.ts @@ -16,5 +16,5 @@ export default function markdownLoader( const fileString = source; const callback = this.async(); const options = this.getOptions(); - return callback?.(null, linkify(fileString, this.resourcePath, options)); + return callback(null, linkify(fileString, this.resourcePath, options)); } diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index 27b9118a718f..bd1cd5d70732 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -165,7 +165,7 @@ export function validateOptions({ } } - const normalizedOptions = validate(OptionsSchema, options) as PluginOptions; + const normalizedOptions = validate(OptionsSchema, options); if (normalizedOptions.admonitions) { normalizedOptions.remarkPlugins = normalizedOptions.remarkPlugins.concat([ diff --git a/packages/docusaurus-plugin-content-docs/src/props.ts b/packages/docusaurus-plugin-content-docs/src/props.ts index 8505d5de2cd2..7d27cebaa9b4 100644 --- a/packages/docusaurus-plugin-content-docs/src/props.ts +++ b/packages/docusaurus-plugin-content-docs/src/props.ts @@ -51,7 +51,7 @@ Available document ids are: } = docMetadata; return { type: 'link', - label: sidebarLabel || item.label || title, + label: sidebarLabel ?? item.label ?? title, href: permalink, className: item.className, customProps: diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts index 671c12cfe256..9f01f06347b7 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts @@ -463,7 +463,7 @@ describe('DefaultSidebarItemsGenerator', () => { expect(sidebarSlice).toMatchSnapshot(); }); - it('throws for unknown index link', async () => { + it('throws for unknown index link', () => { const generateSidebar = () => DefaultSidebarItemsGenerator({ numberPrefixParser: DefaultNumberPrefixParser, @@ -499,7 +499,7 @@ describe('DefaultSidebarItemsGenerator', () => { }, }); - await expect(generateSidebar).rejects.toThrowErrorMatchingInlineSnapshot(` + expect(() => generateSidebar()).toThrowErrorMatchingInlineSnapshot(` "Can't find any doc with ID foo. Available doc IDs: - intro" diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts index d0a530bbd7f2..7dc7111dbe0a 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts @@ -26,7 +26,7 @@ describe('processSidebars', () => { function createStaticSidebarItemGenerator( sidebarSlice: SidebarItem[], ): SidebarItemsGenerator { - return jest.fn(async () => sidebarSlice); + return jest.fn(() => sidebarSlice); } const StaticGeneratedSidebarSlice: NormalizedSidebar = [ @@ -40,7 +40,7 @@ describe('processSidebars', () => { // @ts-expect-error: good enough for this test const version: VersionMetadata = { versionName: '1.0.0', - versionPath: '/docs/1.0.0', + path: '/docs/1.0.0', }; const params: SidebarProcessorParams = { diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts index 7c2d4428c642..4085c9931dc7 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts @@ -134,11 +134,11 @@ describe('createSidebarsUtils', () => { getFirstLink, } = createSidebarsUtils(sidebars); - it('getFirstDocIdOfFirstSidebar', async () => { + it('getFirstDocIdOfFirstSidebar', () => { expect(getFirstDocIdOfFirstSidebar()).toBe('doc1'); }); - it('getSidebarNameByDocId', async () => { + it('getSidebarNameByDocId', () => { expect(getSidebarNameByDocId('doc1')).toBe('sidebar1'); expect(getSidebarNameByDocId('doc2')).toBe('sidebar1'); expect(getSidebarNameByDocId('doc3')).toBe('sidebar2'); @@ -149,7 +149,7 @@ describe('createSidebarsUtils', () => { expect(getSidebarNameByDocId('unknown_id')).toBeUndefined(); }); - it('getDocNavigation', async () => { + it('getDocNavigation', () => { expect(getDocNavigation('doc1', 'doc1', undefined)).toEqual({ sidebarName: 'sidebar1', previous: undefined, @@ -229,7 +229,7 @@ describe('createSidebarsUtils', () => { }); }); - it('getCategoryGeneratedIndexNavigation', async () => { + it('getCategoryGeneratedIndexNavigation', () => { expect( getCategoryGeneratedIndexNavigation('/s3-subcategory-index-permalink'), ).toMatchObject({ @@ -259,7 +259,7 @@ describe('createSidebarsUtils', () => { }); }); - it('getCategoryGeneratedIndexList', async () => { + it('getCategoryGeneratedIndexList', () => { expect(getCategoryGeneratedIndexList()).toMatchObject([ { type: 'category', @@ -301,7 +301,7 @@ describe('createSidebarsUtils', () => { }); describe('collectSidebarDocItems', () => { - it('can collect docs', async () => { + it('can collect docs', () => { const sidebar: Sidebar = [ { type: 'category', @@ -357,7 +357,7 @@ describe('collectSidebarDocItems', () => { }); describe('collectSidebarCategories', () => { - it('can collect categories', async () => { + it('can collect categories', () => { const sidebar: Sidebar = [ { type: 'category', @@ -415,7 +415,7 @@ describe('collectSidebarCategories', () => { }); describe('collectSidebarLinks', () => { - it('can collect links', async () => { + it('can collect links', () => { const sidebar: Sidebar = [ { type: 'category', @@ -453,7 +453,7 @@ describe('collectSidebarLinks', () => { }); describe('collectSidebarsDocIds', () => { - it('can collect sidebars doc items', async () => { + it('can collect sidebars doc items', () => { const sidebar1: Sidebar = [ { type: 'category', @@ -499,7 +499,7 @@ describe('collectSidebarsDocIds', () => { }); describe('transformSidebarItems', () => { - it('can transform sidebar items', async () => { + it('can transform sidebar items', () => { const sidebar: Sidebar = [ { type: 'category', diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/validation.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/validation.test.ts index d8f5fcab0d9e..8186601285a0 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/validation.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/validation.test.ts @@ -9,7 +9,7 @@ import {validateSidebars, validateCategoryMetadataFile} from '../validation'; import type {SidebarsConfig, CategoryMetadataFile} from '../types'; describe('validateSidebars', () => { - it('throw for bad value', async () => { + it('throw for bad value', () => { expect(() => validateSidebars({sidebar: [{type: 42}]})) .toThrowErrorMatchingInlineSnapshot(` "{ @@ -21,12 +21,12 @@ describe('validateSidebars', () => { `); }); - it('accept empty object', async () => { + it('accept empty object', () => { const sidebars: SidebarsConfig = {}; validateSidebars(sidebars); }); - it('accept valid values', async () => { + it('accept valid values', () => { const sidebars: SidebarsConfig = { sidebar1: [ {type: 'doc', id: 'doc1'}, @@ -207,7 +207,7 @@ describe('validateSidebars', () => { ).toThrowErrorMatchingInlineSnapshot(`"sidebar.forEach is not a function"`); }); - it('sidebars item doc but id is not a string', async () => { + it('sidebars item doc but id is not a string', () => { expect(() => validateSidebars({ docs: [ @@ -267,18 +267,18 @@ describe('validateSidebars', () => { describe('validateCategoryMetadataFile', () => { // TODO add more tests - it('throw for bad value', async () => { + it('throw for bad value', () => { expect(() => validateCategoryMetadataFile(42), ).toThrowErrorMatchingInlineSnapshot(`""value" must be of type object"`); }); - it('accept empty object', async () => { + it('accept empty object', () => { const content: CategoryMetadataFile = {}; expect(validateCategoryMetadataFile(content)).toEqual(content); }); - it('accept valid values', async () => { + it('accept valid values', () => { const content: CategoryMetadataFile = { className: 'className', label: 'Category Label', @@ -295,7 +295,7 @@ describe('validateCategoryMetadataFile', () => { expect(validateCategoryMetadataFile(content)).toEqual(content); }); - it('rejects permalink', async () => { + it('rejects permalink', () => { const content: CategoryMetadataFile = { className: 'className', label: 'Category Label', diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts index 56e0025a81af..7dc6ece7bedc 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts @@ -46,7 +46,7 @@ type Dir = { }; // Comment for this feature: https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449 -export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({ +export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = ({ numberPrefixParser, isCategoryIndex, docs: allDocs, diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts index 307ed9de8675..58c69912d704 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts @@ -84,7 +84,7 @@ function postProcessSidebarItem( }; } // A non-collapsible category can't be collapsed! - if (category.collapsible === false) { + if (!category.collapsible) { category.collapsed = false; } return category; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/types.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/types.ts index 8284f09048ee..8d038f417537 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/types.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/types.ts @@ -251,7 +251,7 @@ export type SidebarItemsGeneratorArgs = { }; export type SidebarItemsGenerator = ( generatorArgs: SidebarItemsGeneratorArgs, -) => Promise; +) => NormalizedSidebar | Promise; export type SidebarItemsGeneratorOption = ( generatorArgs: { @@ -262,7 +262,7 @@ export type SidebarItemsGeneratorOption = ( */ defaultSidebarItemsGenerator: SidebarItemsGenerator; } & SidebarItemsGeneratorArgs, -) => Promise; +) => NormalizedSidebar | Promise; export type SidebarProcessorParams = { sidebarItemsGenerator: SidebarItemsGeneratorOption; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts index a213b2e7dedc..0c743f42d537 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts @@ -257,7 +257,7 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils { ): boolean { return ( item.type === 'category' && - item.link?.type === 'generated-index' && + item.link.type === 'generated-index' && item.link.permalink === categoryGeneratedIndexPermalink ); } diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts index 22ddcfbf77ce..b9b1bfae007e 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts @@ -144,7 +144,7 @@ function validateSidebarItem( // manually Joi.assert(item, sidebarItemSchema); - if ((item as NormalizedSidebarItemCategory).type === 'category') { + if ((item as NormalizedSidebarItem).type === 'category') { (item as NormalizedSidebarItemCategory).items.forEach(validateSidebarItem); } } @@ -170,5 +170,9 @@ const categoryMetadataFileSchema = Joi.object({ export function validateCategoryMetadataFile( unsafeContent: unknown, ): CategoryMetadataFile { - return Joi.attempt(unsafeContent, categoryMetadataFileSchema); + const {error, value} = categoryMetadataFileSchema.validate(unsafeContent); + if (error) { + throw error; + } + return value; } diff --git a/packages/docusaurus-plugin-content-docs/src/slug.ts b/packages/docusaurus-plugin-content-docs/src/slug.ts index 4815e210b01d..130c7a63b1f5 100644 --- a/packages/docusaurus-plugin-content-docs/src/slug.ts +++ b/packages/docusaurus-plugin-content-docs/src/slug.ts @@ -58,7 +58,7 @@ export default function getSlug({ ) { return dirNameSlug; } - const baseSlug = frontMatterSlug || baseID; + const baseSlug = frontMatterSlug ?? baseID; return resolvePathname(baseSlug, getDirNameSlug()); } diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts index 4a3448460a24..773643ba8441 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts @@ -604,7 +604,7 @@ describe('readVersionsMetadata', () => { context: defaultContext, }), ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Versions should be strings. Found type "number" for version "1.1"."`, + `"Versions should be strings. Found type "number" for version 1.1."`, ); jsonMock.mockImplementationOnce(() => [' ']); diff --git a/packages/docusaurus-plugin-content-docs/src/versions/validation.ts b/packages/docusaurus-plugin-content-docs/src/versions/validation.ts index 422d58f713d3..c2f1505275a0 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions/validation.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions/validation.ts @@ -11,7 +11,9 @@ import type {VersionsOptions} from '@docusaurus/plugin-content-docs'; export function validateVersionName(name: unknown): asserts name is string { if (typeof name !== 'string') { throw new Error( - `Versions should be strings. Found type "${typeof name}" for version "${name}".`, + `Versions should be strings. Found type "${typeof name}" for version ${JSON.stringify( + name, + )}.`, ); } if (!name.trim()) { diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts index f3b94d2df5f4..31706d3a4cd4 100644 --- a/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts @@ -16,7 +16,7 @@ describe('docusaurus-plugin-content-pages', () => { it('loads simple pages', async () => { const siteDir = path.join(__dirname, '__fixtures__', 'website'); const context = await loadContext({siteDir}); - const plugin = await pluginContentPages( + const plugin = pluginContentPages( context, validateOptions({ validate: normalizePluginOptions, @@ -33,7 +33,7 @@ describe('docusaurus-plugin-content-pages', () => { it('loads simple pages with french translations', async () => { const siteDir = path.join(__dirname, '__fixtures__', 'website'); const context = await loadContext({siteDir}); - const plugin = await pluginContentPages( + const plugin = pluginContentPages( { ...context, i18n: { diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 66bcb0d15712..a9051e4545e6 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -39,10 +39,10 @@ export function getContentPathList(contentPaths: PagesContentPaths): string[] { const isMarkdownSource = (source: string) => source.endsWith('.md') || source.endsWith('.mdx'); -export default async function pluginContentPages( +export default function pluginContentPages( context: LoadContext, options: PluginOptions, -): Promise> { +): Plugin { if (options.admonitions) { options.remarkPlugins = options.remarkPlugins.concat([ [admonitions, options.admonitions], diff --git a/packages/docusaurus-plugin-content-pages/src/markdownLoader.ts b/packages/docusaurus-plugin-content-pages/src/markdownLoader.ts index e8ca79a21681..e5c91b7bf797 100644 --- a/packages/docusaurus-plugin-content-pages/src/markdownLoader.ts +++ b/packages/docusaurus-plugin-content-pages/src/markdownLoader.ts @@ -18,5 +18,5 @@ export default function markdownLoader( // TODO provide additional md processing here? like interlinking pages? // fileString = linkify(fileString) - return callback?.(null, fileString); + return callback(null, fileString); } diff --git a/packages/docusaurus-plugin-content-pages/src/options.ts b/packages/docusaurus-plugin-content-pages/src/options.ts index 475ed8311060..2c1f38201c30 100644 --- a/packages/docusaurus-plugin-content-pages/src/options.ts +++ b/packages/docusaurus-plugin-content-pages/src/options.ts @@ -28,7 +28,7 @@ export const DEFAULT_OPTIONS: PluginOptions = { admonitions: {}, }; -const PluginOptionSchema = Joi.object({ +const PluginOptionSchema = Joi.object({ path: Joi.string().default(DEFAULT_OPTIONS.path), routeBasePath: Joi.string().default(DEFAULT_OPTIONS.routeBasePath), include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include), diff --git a/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx b/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx index 64d3954842c5..c366475762f8 100644 --- a/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx +++ b/packages/docusaurus-plugin-debug/src/theme/DebugSiteMetadata/index.tsx @@ -20,7 +20,7 @@ export default function DebugMetadata(): JSX.Element {
Site Version:{' '} - {siteMetadata.siteVersion || 'No version specified'} + {siteMetadata.siteVersion ?? 'No version specified'}

Plugins and themes

    diff --git a/packages/docusaurus-plugin-google-gtag/src/index.ts b/packages/docusaurus-plugin-google-gtag/src/index.ts index 7724c9676683..2e278094e105 100644 --- a/packages/docusaurus-plugin-google-gtag/src/index.ts +++ b/packages/docusaurus-plugin-google-gtag/src/index.ts @@ -25,7 +25,7 @@ export default function pluginGoogleGtag( return { name: 'docusaurus-plugin-google-gtag', - async contentLoaded({actions}) { + contentLoaded({actions}) { actions.setGlobalData(options); }, diff --git a/packages/docusaurus-plugin-ideal-image/src/index.ts b/packages/docusaurus-plugin-ideal-image/src/index.ts index d650e33b1006..4b8862171859 100644 --- a/packages/docusaurus-plugin-ideal-image/src/index.ts +++ b/packages/docusaurus-plugin-ideal-image/src/index.ts @@ -80,7 +80,7 @@ export function validateOptions({ validate, options, }: OptionValidationContext): PluginOptions { - const pluginOptionsSchema = Joi.object({ + const pluginOptionsSchema = Joi.object({ disableInDev: Joi.boolean().default(true), }).unknown(); return validate(pluginOptionsSchema, options); diff --git a/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx b/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx index ff8ea85f6f2b..fbf2d3278a9b 100644 --- a/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx +++ b/packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx @@ -22,9 +22,9 @@ function bytesToSize(bytes: number) { } const scale = Math.floor(Math.log(bytes) / Math.log(1024)); if (scale === 0) { - return `${bytes} ${sizes[scale]}`; + return `${bytes} ${sizes[scale]!}`; } - return `${(bytes / 1024 ** scale).toFixed(1)} ${sizes[scale]}`; + return `${(bytes / 1024 ** scale).toFixed(1)} ${sizes[scale]!}`; } // Adopted from https://github.com/endiliey/react-ideal-image/blob/master/src/components/IdealImage/index.js#L43-L75 @@ -100,8 +100,8 @@ export default function IdealImage(props: Props): JSX.Element { {...props} alt={alt} className={className} - height={img.src.height || 100} - width={img.src.width || 100} + height={img.src.height ?? 100} + width={img.src.width ?? 100} placeholder={{lqip: img.preSrc}} src={img.src.src} srcSet={img.src.images.map((image) => ({ diff --git a/packages/docusaurus-plugin-pwa/src/index.ts b/packages/docusaurus-plugin-pwa/src/index.ts index 7ec58b25f439..448e7d2f9917 100644 --- a/packages/docusaurus-plugin-pwa/src/index.ts +++ b/packages/docusaurus-plugin-pwa/src/index.ts @@ -89,7 +89,7 @@ export default function pluginPWA( new webpack.EnvironmentPlugin({ PWA_DEBUG: debug, PWA_SERVICE_WORKER_URL: path.posix.resolve( - `${config.output?.publicPath || '/'}`, + `${(config.output?.publicPath as string) || '/'}`, 'sw.js', ), PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES: @@ -102,7 +102,7 @@ export default function pluginPWA( injectHtmlTags() { const headTags: HtmlTags = []; - if (isProd && pwaHead) { + if (isProd) { pwaHead.forEach(({tagName, ...attributes}) => { (['href', 'content'] as const).forEach((attribute) => { const attributeValue = attributes[attribute]; @@ -160,7 +160,7 @@ export default function pluginPWA( plugins: [ new webpack.EnvironmentPlugin({ // Fallback value required with Webpack 5 - PWA_SW_CUSTOM: swCustom || '', + PWA_SW_CUSTOM: swCustom ?? '', }), new LogPlugin({ name: 'Service Worker', @@ -189,7 +189,7 @@ export default function pluginPWA( '**/*.{png,jpg,jpeg,gif,svg,ico}', '**/*.{woff,woff2,eot,ttf,otf}', // @ts-expect-error: internal API? - ...(injectManifest.globPatterns ?? []), + ...((injectManifest.globPatterns as string[] | undefined) ?? []), ], // Those attributes are not overrideable swDest, diff --git a/packages/docusaurus-plugin-pwa/src/options.ts b/packages/docusaurus-plugin-pwa/src/options.ts index e96405756ad1..8517028f9f20 100644 --- a/packages/docusaurus-plugin-pwa/src/options.ts +++ b/packages/docusaurus-plugin-pwa/src/options.ts @@ -23,7 +23,7 @@ const DEFAULT_OPTIONS = { reloadPopup: '@theme/PwaReloadPopup', }; -const Schema = Joi.object({ +const optionsSchema = Joi.object({ debug: Joi.bool().default(DEFAULT_OPTIONS.debug), offlineModeActivationStrategies: Joi.array() .items( @@ -58,5 +58,5 @@ export function validateOptions({ validate, options, }: OptionValidationContext): PluginOptions { - return validate(Schema, options); + return validate(optionsSchema, options); } diff --git a/packages/docusaurus-plugin-pwa/src/registerSw.ts b/packages/docusaurus-plugin-pwa/src/registerSw.ts index 2bb7a92eb06b..d48e7b29b2f7 100644 --- a/packages/docusaurus-plugin-pwa/src/registerSw.ts +++ b/packages/docusaurus-plugin-pwa/src/registerSw.ts @@ -9,7 +9,7 @@ import {createStorageSlot} from '@docusaurus/theme-common'; // First: read the env variables (provided by Webpack) /* eslint-disable prefer-destructuring */ -const PWA_SERVICE_WORKER_URL = process.env.PWA_SERVICE_WORKER_URL; +const PWA_SERVICE_WORKER_URL = process.env.PWA_SERVICE_WORKER_URL!; const PWA_RELOAD_POPUP = process.env.PWA_RELOAD_POPUP; const PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES = process.env .PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES as unknown as (keyof typeof OfflineModeActivationStrategiesImplementations)[]; @@ -34,7 +34,7 @@ async function clearRegistrations() { } await Promise.all( registrations.map(async (registration) => { - const result = await registration?.unregister(); + const result = await registration.unregister(); if (debug) { console.log( `[Docusaurus-PWA][registerSw]: unregister() service worker registration`, @@ -69,7 +69,7 @@ async function isAppInstalledEventFired() { declare global { interface Navigator { getInstalledRelatedApps: () => Promise<{platform: string}[]>; - connection: {effectiveType: string; saveData: boolean}; + connection?: {effectiveType: string; saveData: boolean}; } } diff --git a/packages/docusaurus-plugin-sitemap/src/options.ts b/packages/docusaurus-plugin-sitemap/src/options.ts index 5a8302424e83..365f60156eaf 100644 --- a/packages/docusaurus-plugin-sitemap/src/options.ts +++ b/packages/docusaurus-plugin-sitemap/src/options.ts @@ -29,7 +29,8 @@ export const DEFAULT_OPTIONS: PluginOptions = { ignorePatterns: [], }; -const PluginOptionSchema = Joi.object({ +const PluginOptionSchema = Joi.object({ + // @ts-expect-error: forbidden cacheTime: Joi.forbidden().messages({ 'any.unknown': 'Option `cacheTime` in sitemap config is deprecated. Please remove it.', diff --git a/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts b/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts index 28b4c7e89150..39236a1537b4 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts +++ b/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts @@ -62,8 +62,8 @@ const nodeForImport: Literal = { const plugin: Plugin<[PluginOptions?]> = (options = {}) => { const {sync = false} = options; return (root) => { - let transformed = false; - let alreadyImported = false; + let transformed = false as boolean; + let alreadyImported = false as boolean; visit(root, (node: Node) => { if (isImport(node) && node.value.includes('@theme/Tabs')) { alreadyImported = true; diff --git a/packages/docusaurus-theme-classic/src/index.ts b/packages/docusaurus-theme-classic/src/index.ts index a0cb4629cb58..c87fef7f4b7e 100644 --- a/packages/docusaurus-theme-classic/src/index.ts +++ b/packages/docusaurus-theme-classic/src/index.ts @@ -177,7 +177,7 @@ export default function themeClassic( const plugin: PostCssPlugin = { postcssPlugin: 'RtlCssPlugin', prepare: (result) => { - const file = result.root?.source?.input?.file; + const file = result.root.source?.input.file; // Skip Infima as we are using the its RTL version. if (file === resolvedInfimaFile) { return {}; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index ef8c33023fd2..4aa679bd4946 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -21,12 +21,14 @@ // in their tsconfig. declare module '@docusaurus/theme-classic' { - import type {LoadContext, Plugin} from '@docusaurus/types'; + import type {LoadContext, Plugin, PluginModule} from '@docusaurus/types'; export type Options = { customCss?: string | string[]; }; + export const getSwizzleConfig: PluginModule['getSwizzleConfig']; + export default function themeClassic( context: LoadContext, options: Options, diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx index 5a9384f7b638..9947164ddbef 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx @@ -52,7 +52,7 @@ export default function CodeBlockString({ magicComments, }); const showLineNumbers = - showLineNumbersProp || containsLineNumbers(metastring); + showLineNumbersProp ?? containsLineNumbers(metastring); return ( ) : ( -
  • +
  • ); diff --git a/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx b/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx index b6210a2b3660..39c6ce63fdf1 100644 --- a/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx +++ b/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx @@ -27,7 +27,7 @@ export function useCollapsible({ initialState, }: { /** The initial state. Will be non-collapsed by default. */ - initialState: boolean | (() => boolean); + initialState?: boolean | (() => boolean); }): { collapsed: boolean; setCollapsed: Dispatch>; diff --git a/packages/docusaurus-theme-common/src/hooks/useSkipToContent.ts b/packages/docusaurus-theme-common/src/hooks/useSkipToContent.ts index 54e6a42f3a85..bdcac465d487 100644 --- a/packages/docusaurus-theme-common/src/hooks/useSkipToContent.ts +++ b/packages/docusaurus-theme-common/src/hooks/useSkipToContent.ts @@ -40,7 +40,7 @@ export function useSkipToContent(): { e.preventDefault(); const targetElement: HTMLElement | null = - document.querySelector('main:first-of-type') || + document.querySelector('main:first-of-type') ?? document.querySelector(`.${ThemeClassNames.wrapper.main}`); if (targetElement) { diff --git a/packages/docusaurus-theme-common/src/hooks/useTOCHighlight.ts b/packages/docusaurus-theme-common/src/hooks/useTOCHighlight.ts index fca0174fe644..924ede9e09c3 100644 --- a/packages/docusaurus-theme-common/src/hooks/useTOCHighlight.ts +++ b/packages/docusaurus-theme-common/src/hooks/useTOCHighlight.ts @@ -38,15 +38,12 @@ function getAnchors({ }: { minHeadingLevel: number; maxHeadingLevel: number; -}) { +}): HTMLElement[] { const selectors = []; for (let i = minHeadingLevel; i <= maxHeadingLevel; i += 1) { selectors.push(`h${i}.anchor`); } - - return Array.from( - document.querySelectorAll(selectors.join()), - ) as HTMLElement[]; + return Array.from(document.querySelectorAll(selectors.join())); } function getActiveAnchor( diff --git a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts index 97c9056eb297..a0d3163df88e 100644 --- a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts @@ -171,7 +171,7 @@ export function parseLines( const metastringRangeClassName = magicComments[0]!.className; const lines = rangeParser(linesRange) .filter((n) => n > 0) - .map((n) => [n - 1, [metastringRangeClassName]]); + .map((n) => [n - 1, [metastringRangeClassName]] as [number, string[]]); return {lineClassNames: Object.fromEntries(lines), code}; } if (language === undefined) { @@ -189,7 +189,7 @@ export function parseLines( const lineToClassName: {[comment: string]: string} = Object.fromEntries( magicComments .filter((d) => d.line) - .map(({className, line}) => [line, className]), + .map(({className, line}) => [line!, className] as [string, string]), ); const blockStartToClassName: {[comment: string]: string} = Object.fromEntries( magicComments diff --git a/packages/docusaurus-theme-common/src/utils/reactUtils.tsx b/packages/docusaurus-theme-common/src/utils/reactUtils.tsx index 09cb1b7b52e7..4a7410e3fb6d 100644 --- a/packages/docusaurus-theme-common/src/utils/reactUtils.tsx +++ b/packages/docusaurus-theme-common/src/utils/reactUtils.tsx @@ -70,7 +70,7 @@ export class ReactContextError extends Error { this.name = 'ReactContextError'; this.message = `Hook ${ this.stack?.split('\n')[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups! - .name + .name ?? '' } is called outside the <${providerName}>. ${additionalInfo || ''}`; } } diff --git a/packages/docusaurus-theme-common/src/utils/routesUtils.ts b/packages/docusaurus-theme-common/src/utils/routesUtils.ts index 4faa24b675a0..b662ab4bf23d 100644 --- a/packages/docusaurus-theme-common/src/utils/routesUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/routesUtils.ts @@ -18,7 +18,7 @@ export function isSamePath( path2: string | undefined, ): boolean { const normalize = (pathname: string | undefined) => - (!pathname || pathname?.endsWith('/') + (!pathname || pathname.endsWith('/') ? pathname : `${pathname}/` )?.toLowerCase(); diff --git a/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx b/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx index 32095c3feac3..514222d18ac0 100644 --- a/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx +++ b/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx @@ -112,11 +112,7 @@ export function useScrollPosition( return; } const currentPosition = getScrollPosition()!; - - if (dynamicEffect) { - dynamicEffect(currentPosition, lastPositionRef.current); - } - + dynamicEffect(currentPosition, lastPositionRef.current); lastPositionRef.current = currentPosition; }; diff --git a/packages/docusaurus-theme-common/src/utils/searchUtils.ts b/packages/docusaurus-theme-common/src/utils/searchUtils.ts index 7f6fe91e48f0..082f0fb7085c 100644 --- a/packages/docusaurus-theme-common/src/utils/searchUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/searchUtils.ts @@ -39,7 +39,7 @@ export function useContextualSearchFilters(): {locale: string; tags: string[]} { // plugin instances. function getDocPluginTags(pluginId: string) { const activeVersion = - activePluginAndVersion?.activePlugin?.pluginId === pluginId + activePluginAndVersion?.activePlugin.pluginId === pluginId ? activePluginAndVersion.activeVersion : undefined; diff --git a/packages/docusaurus-theme-common/src/utils/tocUtils.ts b/packages/docusaurus-theme-common/src/utils/tocUtils.ts index 8f12d780719d..64be4cb51191 100644 --- a/packages/docusaurus-theme-common/src/utils/tocUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/tocUtils.ts @@ -27,7 +27,7 @@ function treeifyTOC(flatTOC: readonly TOCItem[]): TOCTreeNode[] { // level . We will modify these indices as we iterate through all headings. // e.g. if an ### H3 was last seen at index 2, then prevIndexForLevel[3] === 2 // indices 0 and 1 will remain unused. - const prevIndexForLevel = Array(7).fill(-1); + const prevIndexForLevel = Array(7).fill(-1); headings.forEach((curr, currIndex) => { // Take the last seen index for each ancestor level. the highest index will diff --git a/packages/docusaurus-theme-common/src/utils/usePluralForm.ts b/packages/docusaurus-theme-common/src/utils/usePluralForm.ts index cc5ce45317bf..726d406db2d7 100644 --- a/packages/docusaurus-theme-common/src/utils/usePluralForm.ts +++ b/packages/docusaurus-theme-common/src/utils/usePluralForm.ts @@ -95,7 +95,11 @@ function selectPluralMessage( } if (parts.length > localePluralForms.pluralForms.length) { console.error( - `For locale=${localePluralForms.locale}, a maximum of ${localePluralForms.pluralForms.length} plural forms are expected (${localePluralForms.pluralForms}), but the message contains ${parts.length}: ${pluralMessages}`, + `For locale=${localePluralForms.locale}, a maximum of ${ + localePluralForms.pluralForms.length + } plural forms are expected (${localePluralForms.pluralForms.join( + ',', + )}), but the message contains ${parts.length}: ${pluralMessages}`, ); } const pluralForm = localePluralForms.select(count); diff --git a/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts index 4b9fb583be03..d642214987de 100644 --- a/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-live-codeblock/src/validateThemeConfig.ts @@ -15,7 +15,7 @@ export const DEFAULT_CONFIG = { playgroundPosition: 'bottom', }; -export const Schema = Joi.object({ +export const Schema = Joi.object({ liveCodeBlock: Joi.object({ playgroundPosition: Joi.string() .equal('top', 'bottom') diff --git a/packages/docusaurus-theme-search-algolia/src/index.ts b/packages/docusaurus-theme-search-algolia/src/index.ts index dbd2a58db30c..af54aafba33f 100644 --- a/packages/docusaurus-theme-search-algolia/src/index.ts +++ b/packages/docusaurus-theme-search-algolia/src/index.ts @@ -60,7 +60,7 @@ export default function themeSearchAlgolia(context: LoadContext): Plugin { }); }, - async contentLoaded({actions: {addRoute}}) { + contentLoaded({actions: {addRoute}}) { if (searchPagePath) { addRoute({ path: normalizeUrl([baseUrl, searchPagePath]), diff --git a/packages/docusaurus-theme-search-algolia/src/validateThemeConfig.ts b/packages/docusaurus-theme-search-algolia/src/validateThemeConfig.ts index 68bd60d163a1..a2a2ccd7869e 100644 --- a/packages/docusaurus-theme-search-algolia/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-search-algolia/src/validateThemeConfig.ts @@ -20,7 +20,7 @@ export const DEFAULT_CONFIG = { searchPagePath: 'search', }; -export const Schema = Joi.object({ +export const Schema = Joi.object({ algolia: Joi.object({ // Docusaurus attributes contextualSearch: Joi.boolean().default(DEFAULT_CONFIG.contextualSearch), diff --git a/packages/docusaurus-theme-translations/src/index.ts b/packages/docusaurus-theme-translations/src/index.ts index f6b7e7303e19..8b9afb841d90 100644 --- a/packages/docusaurus-theme-translations/src/index.ts +++ b/packages/docusaurus-theme-translations/src/index.ts @@ -25,9 +25,9 @@ export function codeTranslationLocalesToTry(locale: string): string[] { // unresolved except for simply locales locale, // "zh-CN" / "pt-BR" - `${maximizedLocale.language}-${maximizedLocale.region}`, + `${maximizedLocale.language!}-${maximizedLocale.region!}`, // "zh-Hans" / "pt-Latn" - `${maximizedLocale.language}-${maximizedLocale.script}`, + `${maximizedLocale.language!}-${maximizedLocale.script!}`, // "zh" / "pt" maximizedLocale.language!, ]; diff --git a/packages/docusaurus-utils-validation/src/JoiFrontMatter.ts b/packages/docusaurus-utils-validation/src/JoiFrontMatter.ts index b09f528ec14d..5de48285cc38 100644 --- a/packages/docusaurus-utils-validation/src/JoiFrontMatter.ts +++ b/packages/docusaurus-utils-validation/src/JoiFrontMatter.ts @@ -28,4 +28,4 @@ const JoiFrontMatterString: Joi.Extension = { * @see https://github.com/facebook/docusaurus/issues/4642 * @see https://github.com/sideway/joi/issues/1442#issuecomment-823997884 */ -export const JoiFrontMatter: typeof Joi = Joi.extend(JoiFrontMatterString); +export const JoiFrontMatter = Joi.extend(JoiFrontMatterString) as typeof Joi; diff --git a/packages/docusaurus-utils/src/pathUtils.ts b/packages/docusaurus-utils/src/pathUtils.ts index a9fbb0bd98f7..35b8bd2656e8 100644 --- a/packages/docusaurus-utils/src/pathUtils.ts +++ b/packages/docusaurus-utils/src/pathUtils.ts @@ -56,7 +56,7 @@ export function shortName(str: string): string { * Adopted from https://github.com/sindresorhus/slash/blob/main/index.js */ export function posixPath(str: string): string { - const isExtendedLengthPath = /^\\\\\?\\/.test(str); + const isExtendedLengthPath = str.startsWith('\\\\?\\'); // Forward slashes are only valid Windows paths when they don't contain non- // ascii characters. diff --git a/packages/docusaurus-utils/src/urlUtils.ts b/packages/docusaurus-utils/src/urlUtils.ts index 708d50dbfe57..06694a00bd09 100644 --- a/packages/docusaurus-utils/src/urlUtils.ts +++ b/packages/docusaurus-utils/src/urlUtils.ts @@ -72,11 +72,11 @@ export function normalizeUrl(rawUrls: string[]): string { /^\/+/, // Special case where the first element of rawUrls is empty // ["", "/hello"] => /hello - component[0] === '/' && !hasStartingSlash ? '/' : '', + component.startsWith('/') && !hasStartingSlash ? '/' : '', ); } - hasEndingSlash = component[component.length - 1] === '/'; + hasEndingSlash = component.endsWith('/'); // Removing the ending slashes for each component but the last. For the // last component we will combine multiple slashes to a single one. component = component.replace(/\/+$/, i < urls.length - 1 ? '' : '/'); @@ -95,7 +95,7 @@ export function normalizeUrl(rawUrls: string[]): string { // Replace ? in parameters with &. const parts = str.split('?'); - str = parts.shift() + (parts.length > 0 ? '?' : '') + parts.join('&'); + str = parts.shift()! + (parts.length > 0 ? '?' : '') + parts.join('&'); // Dedupe forward slashes in the entire path, avoiding protocol slashes. str = str.replace(/(?[^:/]\/)\/+/g, '$1'); diff --git a/packages/docusaurus/src/client/docusaurus.ts b/packages/docusaurus/src/client/docusaurus.ts index 80fa879e30cb..987f931ede0a 100644 --- a/packages/docusaurus/src/client/docusaurus.ts +++ b/packages/docusaurus/src/client/docusaurus.ts @@ -19,7 +19,7 @@ declare global { // eslint-disable-next-line camelcase, no-underscore-dangle const __webpack_require__: {gca: (name: string) => string}; interface Navigator { - connection: {effectiveType: string; saveData: boolean}; + connection?: {effectiveType: string; saveData: boolean}; } } diff --git a/packages/docusaurus/src/client/exports/useBaseUrl.ts b/packages/docusaurus/src/client/exports/useBaseUrl.ts index 174ea539c1b7..c5481e57670f 100644 --- a/packages/docusaurus/src/client/exports/useBaseUrl.ts +++ b/packages/docusaurus/src/client/exports/useBaseUrl.ts @@ -10,7 +10,7 @@ import {hasProtocol} from './isInternalUrl'; import type {BaseUrlOptions, BaseUrlUtils} from '@docusaurus/useBaseUrl'; function addBaseUrl( - siteUrl: string | undefined, + siteUrl: string, baseUrl: string, url: string, {forcePrependBaseUrl = false, absolute = false}: BaseUrlOptions = {}, diff --git a/packages/docusaurus/src/commands/serve.ts b/packages/docusaurus/src/commands/serve.ts index da94dc86678d..64845cb5ced4 100644 --- a/packages/docusaurus/src/commands/serve.ts +++ b/packages/docusaurus/src/commands/serve.ts @@ -66,7 +66,7 @@ export async function serve( // Remove baseUrl before calling serveHandler, because /baseUrl/ should // serve /build/index.html, not /build/baseUrl/index.html (does not exist) - req.url = req.url?.replace(baseUrl, '/'); + req.url = req.url.replace(baseUrl, '/'); serveHandler(req, res, { cleanUrls: true, diff --git a/packages/docusaurus/src/commands/swizzle/__tests__/config.test.ts b/packages/docusaurus/src/commands/swizzle/__tests__/config.test.ts index cb924a626ffc..8042d3d51dae 100644 --- a/packages/docusaurus/src/commands/swizzle/__tests__/config.test.ts +++ b/packages/docusaurus/src/commands/swizzle/__tests__/config.test.ts @@ -9,14 +9,14 @@ import {normalizeSwizzleConfig} from '../config'; import type {SwizzleConfig} from '@docusaurus/types'; describe('normalizeSwizzleConfig', () => { - it(`validate no components config`, async () => { + it(`validate no components config`, () => { const config: SwizzleConfig = { components: {}, }; expect(normalizeSwizzleConfig(config)).toEqual(config); }); - it(`validate complete config`, async () => { + it(`validate complete config`, () => { const config: SwizzleConfig = { components: { SomeComponent: { @@ -38,7 +38,7 @@ describe('normalizeSwizzleConfig', () => { expect(normalizeSwizzleConfig(config)).toEqual(config); }); - it(`normalize partial config`, async () => { + it(`normalize partial config`, () => { const config: SwizzleConfig = { components: { SomeComponent: { @@ -59,7 +59,7 @@ describe('normalizeSwizzleConfig', () => { expect(normalizeSwizzleConfig(config)).toMatchSnapshot(); }); - it(`reject missing components`, async () => { + it(`reject missing components`, () => { // @ts-expect-error: incomplete actions map const config: SwizzleConfig = {}; @@ -70,7 +70,7 @@ describe('normalizeSwizzleConfig', () => { ); }); - it(`reject invalid action name`, async () => { + it(`reject invalid action name`, () => { const config: SwizzleConfig = { components: { MyComponent: { @@ -91,7 +91,7 @@ describe('normalizeSwizzleConfig', () => { ); }); - it(`reject invalid action status`, async () => { + it(`reject invalid action status`, () => { const config: SwizzleConfig = { components: { MyComponent: { diff --git a/packages/docusaurus/src/commands/swizzle/actions.ts b/packages/docusaurus/src/commands/swizzle/actions.ts index e295f8c2bd2d..44aba75cca13 100644 --- a/packages/docusaurus/src/commands/swizzle/actions.ts +++ b/packages/docusaurus/src/commands/swizzle/actions.ts @@ -109,7 +109,7 @@ export async function wrap({ const isDirectory = await isDir(path.join(themePath, themeComponentName)); // Top/Parent/ComponentName => ComponentName - const componentName = _.last(themeComponentName.split('/')); + const componentName = _.last(themeComponentName.split('/'))!; const wrapperComponentName = `${componentName}Wrapper`; const wrapperFileName = `${themeComponentName}${isDirectory ? '/index' : ''}${ diff --git a/packages/docusaurus/src/commands/swizzle/config.ts b/packages/docusaurus/src/commands/swizzle/config.ts index 83f0bbe75101..b72f30cc60c9 100644 --- a/packages/docusaurus/src/commands/swizzle/config.ts +++ b/packages/docusaurus/src/commands/swizzle/config.ts @@ -16,9 +16,8 @@ function getModuleSwizzleConfig( swizzlePlugin: SwizzlePlugin, ): SwizzleConfig | undefined { const getSwizzleConfig = - swizzlePlugin.plugin.plugin?.getSwizzleConfig ?? - swizzlePlugin.plugin.pluginModule?.module.getSwizzleConfig ?? - swizzlePlugin.plugin.pluginModule?.module?.getSwizzleConfig; + swizzlePlugin.plugin.plugin.getSwizzleConfig ?? + swizzlePlugin.plugin.pluginModule?.module.getSwizzleConfig; if (getSwizzleConfig) { return getSwizzleConfig(); @@ -26,9 +25,8 @@ function getModuleSwizzleConfig( // TODO deprecate getSwizzleComponentList later const getSwizzleComponentList = - swizzlePlugin.plugin.plugin?.getSwizzleComponentList ?? - swizzlePlugin.plugin.pluginModule?.module.getSwizzleComponentList ?? - swizzlePlugin.plugin.pluginModule?.module?.getSwizzleComponentList; + swizzlePlugin.plugin.plugin.getSwizzleComponentList ?? + swizzlePlugin.plugin.pluginModule?.module.getSwizzleComponentList; if (getSwizzleComponentList) { const safeComponents = getSwizzleComponentList() ?? []; diff --git a/packages/docusaurus/src/commands/swizzle/themes.ts b/packages/docusaurus/src/commands/swizzle/themes.ts index c31b0f28dd8b..84961dd9716c 100644 --- a/packages/docusaurus/src/commands/swizzle/themes.ts +++ b/packages/docusaurus/src/commands/swizzle/themes.ts @@ -15,7 +15,7 @@ import {findStringIgnoringCase, type SwizzlePlugin} from './common'; export function pluginToThemeName(plugin: SwizzlePlugin): string | undefined { if (plugin.instance.getThemePath) { return ( - (plugin.instance.version as {name: string}).name ?? plugin.instance.name + (plugin.instance.version as {name?: string}).name ?? plugin.instance.name ); } return undefined; @@ -76,9 +76,7 @@ function handleInvalidThemeName({ // TODO recover from short theme-names here: "classic" => "@docusaurus/theme-classic" // No recovery value is possible: print error - const suggestion = themeNames.find( - (name) => leven(name, themeNameParam!) < 4, - ); + const suggestion = themeNames.find((name) => leven(name, themeNameParam) < 4); logger.error`Theme name=${themeNameParam} not found. ${ suggestion ? logger.interpolate`Did you mean name=${suggestion}?` @@ -87,13 +85,13 @@ function handleInvalidThemeName({ return process.exit(1); } -async function validateThemeName({ +function validateThemeName({ themeNameParam, themeNames, }: { themeNameParam: string; themeNames: string[]; -}): Promise { +}): string { const isValidName = themeNames.includes(themeNameParam); if (!isValidName) { return handleInvalidThemeName({ diff --git a/packages/docusaurus/src/commands/writeHeadingIds.ts b/packages/docusaurus/src/commands/writeHeadingIds.ts index fe15c0b1f3ef..73bc699c25b3 100644 --- a/packages/docusaurus/src/commands/writeHeadingIds.ts +++ b/packages/docusaurus/src/commands/writeHeadingIds.ts @@ -37,12 +37,12 @@ async function transformMarkdownFile( async function getPathsToWatch(siteDir: string): Promise { const context = await loadContext({siteDir}); const plugins = await initPlugins(context); - return plugins.flatMap((plugin) => plugin?.getPathsToWatch?.() ?? []); + return plugins.flatMap((plugin) => plugin.getPathsToWatch?.() ?? []); } export async function writeHeadingIds( siteDir: string, - files: string[], + files: string[] | undefined, options: WriteHeadingIDOptions, ): Promise { const markdownFiles = await safeGlobby( diff --git a/packages/docusaurus/src/deps.d.ts b/packages/docusaurus/src/deps.d.ts index 06f478ca6330..57de485ea0ce 100644 --- a/packages/docusaurus/src/deps.d.ts +++ b/packages/docusaurus/src/deps.d.ts @@ -20,13 +20,13 @@ declare module 'react-loadable-ssr-addon-v5-slorber' { export type Manifest = { entrypoints: string[]; origins: {[key: string]: number[]}; - assets: Array<{[key: string]: Asset[]}>; + assets: {[key: string]: Asset[]}[]; }; export function getBundles( manifest: Manifest, modulesToBeLoaded: string[], - ): {js: Asset[]; css: Asset[]}; + ): {js?: Asset[]; css?: Asset[]}; export default class ReactLoadableSSRAddon implements WebpackPluginInstance { constructor(props: {filename: string}); diff --git a/packages/docusaurus/src/server/plugins/configs.ts b/packages/docusaurus/src/server/plugins/configs.ts index b7b7bbf6ccd4..eb2898e5d312 100644 --- a/packages/docusaurus/src/server/plugins/configs.ts +++ b/packages/docusaurus/src/server/plugins/configs.ts @@ -63,7 +63,7 @@ async function normalizePluginConfig( const pluginPath = pluginRequire.resolve(pluginModuleImport); const pluginModule = importFresh(pluginPath); return { - plugin: pluginModule?.default ?? pluginModule, + plugin: pluginModule.default ?? pluginModule, options: {}, pluginModule: { path: pluginModuleImport, @@ -90,7 +90,7 @@ async function normalizePluginConfig( const pluginPath = pluginRequire.resolve(pluginModuleImport); const pluginModule = importFresh(pluginPath); return { - plugin: pluginModule?.default ?? pluginModule, + plugin: pluginModule.default ?? pluginModule, options: pluginConfig[1], pluginModule: { path: pluginModuleImport, diff --git a/packages/docusaurus/src/server/plugins/index.ts b/packages/docusaurus/src/server/plugins/index.ts index 812ea7b2e80e..5a8dbb98d095 100644 --- a/packages/docusaurus/src/server/plugins/index.ts +++ b/packages/docusaurus/src/server/plugins/index.ts @@ -52,7 +52,7 @@ export async function loadPlugins(context: LoadContext): Promise<{ plugins.map(async (plugin) => { const content = await plugin.loadContent?.(); const rawTranslationFiles = - (await plugin?.getTranslationFiles?.({content})) ?? []; + (await plugin.getTranslationFiles?.({content})) ?? []; const translationFiles = await Promise.all( rawTranslationFiles.map((translationFile) => localizePluginTranslationFile({ diff --git a/packages/docusaurus/src/server/plugins/init.ts b/packages/docusaurus/src/server/plugins/init.ts index 771a407cccb5..c19f82d15b80 100644 --- a/packages/docusaurus/src/server/plugins/init.ts +++ b/packages/docusaurus/src/server/plugins/init.ts @@ -29,8 +29,8 @@ function getOptionValidationFunction( if (normalizedPluginConfig.pluginModule) { // Support both CommonJS and ES modules return ( - normalizedPluginConfig.pluginModule.module?.default?.validateOptions ?? - normalizedPluginConfig.pluginModule.module?.validateOptions + normalizedPluginConfig.pluginModule.module.default?.validateOptions ?? + normalizedPluginConfig.pluginModule.module.validateOptions ); } return normalizedPluginConfig.plugin.validateOptions; @@ -66,7 +66,7 @@ export async function initPlugins( ): Promise { if (normalizedPluginConfig.pluginModule?.path) { const pluginPath = pluginRequire.resolve( - normalizedPluginConfig.pluginModule?.path, + normalizedPluginConfig.pluginModule.path, ); return getPluginVersion(pluginPath, context.siteDir); } diff --git a/packages/docusaurus/src/server/plugins/moduleShorthand.ts b/packages/docusaurus/src/server/plugins/moduleShorthand.ts index df0ab5570d43..5a106e88fe30 100644 --- a/packages/docusaurus/src/server/plugins/moduleShorthand.ts +++ b/packages/docusaurus/src/server/plugins/moduleShorthand.ts @@ -14,7 +14,10 @@ export function getNamePatterns( if (!moduleName.includes('/')) { return [`${moduleName}/docusaurus-${moduleType}`]; } - const [scope, packageName] = moduleName.split(/\/(?.*)/); + const [scope, packageName] = moduleName.split(/\/(?.*)/) as [ + string, + string, + ]; return [ `${scope}/${packageName}`, `${scope}/docusaurus-${moduleType}-${packageName}`, diff --git a/packages/docusaurus/src/server/plugins/routeConfig.ts b/packages/docusaurus/src/server/plugins/routeConfig.ts index e9b7c589408f..3731eb993d74 100644 --- a/packages/docusaurus/src/server/plugins/routeConfig.ts +++ b/packages/docusaurus/src/server/plugins/routeConfig.ts @@ -50,8 +50,8 @@ export function sortConfig( } // Higher priority get placed first. if (a.priority || b.priority) { - const priorityA = a.priority || 0; - const priorityB = b.priority || 0; + const priorityA = a.priority ?? 0; + const priorityB = b.priority ?? 0; const score = priorityB - priorityA; if (score !== 0) { diff --git a/packages/docusaurus/src/server/plugins/synthetic.ts b/packages/docusaurus/src/server/plugins/synthetic.ts index 67e297ffe5f5..5d4fe38b4d01 100644 --- a/packages/docusaurus/src/server/plugins/synthetic.ts +++ b/packages/docusaurus/src/server/plugins/synthetic.ts @@ -89,7 +89,7 @@ export function createMDXFallbackPlugin({ // processed by content plugins mdx loaders. This works, but a bit // hacky... Not sure there's a way to handle that differently in webpack function getMDXFallbackExcludedPaths(): string[] { - const rules: RuleSetRule[] = config?.module?.rules as RuleSetRule[]; + const rules: RuleSetRule[] = config.module?.rules as RuleSetRule[]; return rules.flatMap((rule) => { const isMDXRule = rule.test instanceof RegExp && rule.test.test('x.mdx'); diff --git a/packages/docusaurus/src/server/routes.ts b/packages/docusaurus/src/server/routes.ts index ab97b1a7b9d7..b13c8cd9b11a 100644 --- a/packages/docusaurus/src/server/routes.ts +++ b/packages/docusaurus/src/server/routes.ts @@ -152,7 +152,7 @@ const isModule = (value: unknown): value is Module => typeof value === 'string' || (typeof value === 'object' && // eslint-disable-next-line no-underscore-dangle - !!(value as {[key: string]: unknown})?.__import); + !!(value as {[key: string]: unknown} | null)?.__import); /** * Takes a {@link Module} (which is nothing more than a path plus some metadata diff --git a/packages/docusaurus/src/server/translations/translationsExtractor.ts b/packages/docusaurus/src/server/translations/translationsExtractor.ts index 6113b23ba933..83be6bcd7503 100644 --- a/packages/docusaurus/src/server/translations/translationsExtractor.ts +++ b/packages/docusaurus/src/server/translations/translationsExtractor.ts @@ -160,7 +160,7 @@ export async function extractSourceCodeFileTranslations( filename: sourceCodeFilePath, }) as Node; - const translations = await extractSourceCodeAstTranslations( + const translations = extractSourceCodeAstTranslations( ast, sourceCodeFilePath, ); @@ -243,9 +243,7 @@ Full code: ${generate(node).code}`; .find( (attr) => attr.isJSXAttribute() && - (attr as NodePath) - .get('name') - .isJSXIdentifier({name: propName}), + attr.get('name').isJSXIdentifier({name: propName}), ); if (attributePath) { diff --git a/packages/docusaurus/src/webpack/base.ts b/packages/docusaurus/src/webpack/base.ts index 4e00fecefaf1..0b66a8d539be 100644 --- a/packages/docusaurus/src/webpack/base.ts +++ b/packages/docusaurus/src/webpack/base.ts @@ -38,7 +38,7 @@ export function excludeJS(modulePath: string): boolean { } // Don't transpile node_modules except any docusaurus npm package return ( - /node_modules/.test(modulePath) && + modulePath.includes('node_modules') && !/docusaurus(?:(?!node_modules).)*\.jsx?$/.test(modulePath) && !LibrariesToTranspileRegex.test(modulePath) ); diff --git a/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts b/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts index 5a8f4770102a..a87d2dcfda05 100644 --- a/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts +++ b/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts @@ -116,7 +116,7 @@ export default class CleanWebpackPlugin { } apply(compiler: Compiler): void { - if (!compiler.options.output || !compiler.options.output.path) { + if (!compiler.options.output.path) { console.warn( 'clean-webpack-plugin: options.output.path not defined. Plugin disabled...', ); @@ -185,7 +185,7 @@ export default class CleanWebpackPlugin { * (relies on del's cwd: outputPath option) */ const staleFiles = this.currentAssets.filter( - (previousAsset) => assets.includes(previousAsset) === false, + (previousAsset) => !assets.includes(previousAsset), ); /** @@ -198,7 +198,7 @@ export default class CleanWebpackPlugin { /** * Remove unused webpack assets */ - if (this.cleanStaleWebpackAssets === true && staleFiles.length !== 0) { + if (this.cleanStaleWebpackAssets && staleFiles.length !== 0) { removePatterns.push(...staleFiles); } @@ -234,10 +234,9 @@ export default class CleanWebpackPlugin { }); } } catch (err) { - const needsForce = - /Cannot delete files\/folders outside the current working directory\./.test( - (err as Error).message, - ); + const needsForce = (err as Error).message.includes( + 'Cannot delete files/folders outside the current working directory.', + ); if (needsForce) { const message = diff --git a/packages/docusaurus/src/webpack/utils.ts b/packages/docusaurus/src/webpack/utils.ts index 79362887679e..8a7d0aef6120 100644 --- a/packages/docusaurus/src/webpack/utils.ts +++ b/packages/docusaurus/src/webpack/utils.ts @@ -185,13 +185,11 @@ export function applyConfigureWebpack( if (typeof configureWebpack === 'function') { const {mergeStrategy, ...res} = configureWebpack(config, isServer, utils, content) ?? {}; - if (res && typeof res === 'object') { - const customizeRules = mergeStrategy ?? {}; - return mergeWithCustomize({ - customizeArray: customizeArray(customizeRules), - customizeObject: customizeObject(customizeRules), - })(config, res); - } + const customizeRules = mergeStrategy ?? {}; + return mergeWithCustomize({ + customizeArray: customizeArray(customizeRules), + customizeObject: customizeObject(customizeRules), + })(config, res); } return config; } @@ -243,7 +241,7 @@ export function compile(config: Configuration[]): Promise { const compiler = webpack(config); compiler.run((err, stats) => { if (err) { - logger.error(err.stack || err); + logger.error(err.stack ?? err); if (err.details) { logger.error(err.details); } diff --git a/packages/lqip-loader/src/index.ts b/packages/lqip-loader/src/index.ts index 6bb0eb526240..5dd78269439c 100644 --- a/packages/lqip-loader/src/index.ts +++ b/packages/lqip-loader/src/index.ts @@ -17,9 +17,7 @@ export default async function lqipLoader( this: LoaderContext, contentBuffer: Buffer, ): Promise { - if (this.cacheable) { - this.cacheable(); - } + this.cacheable(); const callback = this.async(); const imgPath = this.resourcePath; let content = contentBuffer.toString('utf8'); diff --git a/packages/stylelint-copyright/src/index.ts b/packages/stylelint-copyright/src/index.ts index a620d184d0a0..0b591561ea0e 100644 --- a/packages/stylelint-copyright/src/index.ts +++ b/packages/stylelint-copyright/src/index.ts @@ -27,7 +27,8 @@ const plugin = stylelint.createPlugin( }, { actual: secondaryOption, - possible: (v) => typeof (v as SecondaryOption)?.header === 'string', + possible: (v) => + typeof (v as SecondaryOption | undefined)?.header === 'string', }, ); @@ -42,7 +43,7 @@ const plugin = stylelint.createPlugin( } } if (context.fix) { - root.first?.before(`/*${secondaryOption.header}\n */`); + root.first?.before(`/*${secondaryOption.header!}\n */`); return; } diff --git a/website/_dogfooding/docs-tests-sidebars.js b/website/_dogfooding/docs-tests-sidebars.js index 6b8b8f9c4365..e7ebb55ce1a5 100644 --- a/website/_dogfooding/docs-tests-sidebars.js +++ b/website/_dogfooding/docs-tests-sidebars.js @@ -5,7 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +/** + * @typedef {import('@docusaurus/plugin-content-docs').SidebarsConfig} SidebarsConfig + * @typedef {import('@docusaurus/plugin-content-docs/lib/sidebars/types').SidebarItemConfig} SidebarItemConfig + */ + +/** @type {SidebarsConfig} */ const sidebars = { sidebar: [ { @@ -119,6 +124,11 @@ function generateHugeSidebarItems() { const linksCount = 8; const categoriesCount = 8; + /** + * @param {number} maxLevel + * @param {number} currentLevel + * @returns {SidebarItemConfig[]} + */ function generateRecursive(maxLevel, currentLevel = 0) { if (currentLevel === maxLevel) { return [ @@ -130,17 +140,19 @@ function generateHugeSidebarItems() { ]; } - const linkItems = [...Array(linksCount).keys()].map((index) => ({ + const linkItems = Array.from(Array(linksCount).keys()).map((index) => ({ type: 'link', href: '/', label: `Link ${index} (level ${currentLevel + 1})`, })); - const categoryItems = [...Array(categoriesCount).keys()].map((index) => ({ - type: 'category', - label: `Category ${index} (level ${currentLevel + 1})`, - items: generateRecursive(maxLevel, currentLevel + 1), - })); + const categoryItems = Array.from(Array(categoriesCount).keys()).map( + (index) => ({ + type: 'category', + label: `Category ${index} (level ${currentLevel + 1})`, + items: generateRecursive(maxLevel, currentLevel + 1), + }), + ); return [...linkItems, ...categoryItems]; } diff --git a/website/_dogfooding/testSwizzleThemeClassic.mjs b/website/_dogfooding/testSwizzleThemeClassic.mjs index ab75a7d1dafb..6f635bea5718 100644 --- a/website/_dogfooding/testSwizzleThemeClassic.mjs +++ b/website/_dogfooding/testSwizzleThemeClassic.mjs @@ -10,15 +10,16 @@ import fs from 'fs-extra'; import {fileURLToPath} from 'url'; import logger from '@docusaurus/logger'; -import ClassicTheme from '@docusaurus/theme-classic'; +import classicTheme from '@docusaurus/theme-classic'; // Unsafe imports import {readComponentNames} from '@docusaurus/core/lib/commands/swizzle/components.js'; import {normalizeSwizzleConfig} from '@docusaurus/core/lib/commands/swizzle/config.js'; import {wrap, eject} from '@docusaurus/core/lib/commands/swizzle/actions.js'; -const swizzleConfig = normalizeSwizzleConfig(ClassicTheme.getSwizzleConfig()); +const swizzleConfig = normalizeSwizzleConfig(classicTheme.getSwizzleConfig()); +/** @type {"eject" | "wrap"} */ const action = process.env.SWIZZLE_ACTION ?? 'eject'; const typescript = process.env.SWIZZLE_TYPESCRIPT === 'true'; @@ -81,14 +82,12 @@ if (action === 'wrap') { }); } +/** + * @param {string} componentName + */ function getActionStatus(componentName) { const actionStatus = swizzleConfig.components[componentName]?.actions[action] ?? 'unsafe'; - if (!actionStatus) { - throw new Error( - `Unexpected: missing action ${action} for ${componentName}`, - ); - } return actionStatus; } diff --git a/website/delayCrowdin.mjs b/website/delayCrowdin.mjs index d212e0e7c9a0..2fbb232c2f47 100644 --- a/website/delayCrowdin.mjs +++ b/website/delayCrowdin.mjs @@ -13,6 +13,9 @@ And then both try to dl the translations at the same time, and then we have a Used in conjunction with waitForCrowdin.js (which is not enough) */ +/** + * @param {number} ms + */ async function delay(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 4fe18ec4dfb3..6885a87f8667 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -49,7 +49,7 @@ const isDeployPreview = // Used to debug production build issues faster const isBuildFast = !!process.env.BUILD_FAST; -const baseUrl = process.env.BASE_URL || '/'; +const baseUrl = process.env.BASE_URL ?? '/'; // Special deployment for staging locales until they get enough translations // https://app.netlify.com/sites/docusaurus-i18n-staging diff --git a/website/src/components/APITable/index.tsx b/website/src/components/APITable/index.tsx index fb2e69366fde..b6a73d2862cf 100644 --- a/website/src/components/APITable/index.tsx +++ b/website/src/components/APITable/index.tsx @@ -68,8 +68,8 @@ const APITableRowComp = React.forwardRef(APITableRow); */ export default function APITable({children, name}: Props): JSX.Element { const [thead, tbody] = React.Children.toArray(children.props.children) as [ - ReactElement, - ReactElement, + ReactElement<{children: ReactElement[]}>, + ReactElement<{children: ReactElement[]}>, ]; const highlightedRow = useRef(null); useEffect(() => { diff --git a/website/src/components/ColorGenerator/index.tsx b/website/src/components/ColorGenerator/index.tsx index 87e68c528682..7fbcdfa03b60 100644 --- a/website/src/components/ColorGenerator/index.tsx +++ b/website/src/components/ColorGenerator/index.tsx @@ -59,7 +59,9 @@ export default function ColorGenerator(): JSX.Element { // Switch modes -> update state by stored values useEffect(() => { - const storedValues: ColorState = JSON.parse(storage.get() ?? '{}'); + const storedValues = JSON.parse( + storage.get() ?? '{}', + ) as Partial; setInputColor(storedValues.baseColor ?? DEFAULT_PRIMARY_COLOR); setBaseColor(storedValues.baseColor ?? DEFAULT_PRIMARY_COLOR); setBackground(storedValues.background ?? DEFAULT_BACKGROUND_COLOR); diff --git a/website/src/components/TeamProfileCards/index.tsx b/website/src/components/TeamProfileCards/index.tsx index 92b6858df745..d1b3d506291b 100644 --- a/website/src/components/TeamProfileCards/index.tsx +++ b/website/src/components/TeamProfileCards/index.tsx @@ -12,7 +12,7 @@ import Link from '@docusaurus/Link'; function WebsiteLink({to, children}: {to: string; children?: ReactNode}) { return ( - {children || ( + {children ?? ( website )} @@ -23,7 +23,7 @@ type ProfileProps = { className?: string; name: string; children: ReactNode; - githubUrl?: string; + githubUrl: string; twitterUrl?: string; }; diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 6937b6da4ed2..00903c3c7b60 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -99,7 +99,7 @@ function MigrationAnnouncement() { } function TweetsSection() { - const tweetColumns: Array> = [[], [], []]; + const tweetColumns: TweetItem[][] = [[], [], []]; Tweets.filter((tweet) => tweet.showOnHomepage).forEach((tweet, i) => tweetColumns[i % 3]!.push(tweet), ); diff --git a/website/src/pages/showcase/_components/ShowcaseFilterToggle/index.tsx b/website/src/pages/showcase/_components/ShowcaseFilterToggle/index.tsx index acb4516d111f..aaada5d7618f 100644 --- a/website/src/pages/showcase/_components/ShowcaseFilterToggle/index.tsx +++ b/website/src/pages/showcase/_components/ShowcaseFilterToggle/index.tsx @@ -35,7 +35,7 @@ export default function ShowcaseFilterToggle(): JSX.Element { const searchParams = new URLSearchParams(location.search); searchParams.delete(OperatorQueryKey); if (!operator) { - searchParams.append(OperatorQueryKey, operator ? 'OR' : 'AND'); + searchParams.append(OperatorQueryKey, 'AND'); } history.push({ ...location, diff --git a/website/src/pages/showcase/_components/ShowcaseTooltip/index.tsx b/website/src/pages/showcase/_components/ShowcaseTooltip/index.tsx index bcbf5b4709b8..7087fa0e5d2d 100644 --- a/website/src/pages/showcase/_components/ShowcaseTooltip/index.tsx +++ b/website/src/pages/showcase/_components/ShowcaseTooltip/index.tsx @@ -14,7 +14,6 @@ interface Props { anchorEl?: HTMLElement | string; id: string; text: string; - delay?: number; children: React.ReactElement; } @@ -23,7 +22,6 @@ export default function Tooltip({ id, anchorEl, text, - delay, }: Props): JSX.Element { const [open, setOpen] = useState(false); const [referenceElement, setReferenceElement] = useState( @@ -84,7 +82,7 @@ export default function Tooltip({ timeout.current = window.setTimeout(() => { setOpen(true); - }, delay || 400); + }, 400); }; const handleClose = () => { @@ -113,7 +111,7 @@ export default function Tooltip({ }); } }; - }, [referenceElement, text, delay]); + }, [referenceElement, text]); return ( <> diff --git a/website/src/pages/versions.tsx b/website/src/pages/versions.tsx index 9db0ec5d10ee..4a65419b8837 100644 --- a/website/src/pages/versions.tsx +++ b/website/src/pages/versions.tsx @@ -58,38 +58,35 @@ export default function Version(): JSX.Element { - {latestVersion && ( -
    - - - Current version (Stable) - - -

    - - Here you can find the documentation for current released - version. - -

    - - - - - - - - -
    {latestVersion.label} - - - - - - - -
    -
    - )} +
    + + + Current version (Stable) + + +

    + + Here you can find the documentation for current released version. + +

    + + + + + + + + +
    {latestVersion.label} + + + + + + + +
    +
    {currentVersion !== latestVersion && (
    diff --git a/website/src/theme/ColorModeToggle.tsx b/website/src/theme/ColorModeToggle.tsx index 44f81a00ff66..85e886bc75b8 100644 --- a/website/src/theme/ColorModeToggle.tsx +++ b/website/src/theme/ColorModeToggle.tsx @@ -32,7 +32,9 @@ export default function ColorModeToggle(props: Props): JSX.Element { props.onChange(colorMode); const isDarkMode = colorMode === 'dark'; const storage = isDarkMode ? darkStorage : lightStorage; - const colorState: ColorState = JSON.parse(storage.get() ?? 'null') ?? { + const colorState = (JSON.parse( + storage.get() ?? 'null', + ) as ColorState | null) ?? { baseColor: isDarkMode ? DARK_PRIMARY_COLOR : LIGHT_PRIMARY_COLOR, background: isDarkMode ? DARK_BACKGROUND_COLOR diff --git a/website/testCSSOrder.mjs b/website/testCSSOrder.mjs index 9594c9ab3286..62422e3d4ea8 100644 --- a/website/testCSSOrder.mjs +++ b/website/testCSSOrder.mjs @@ -84,9 +84,14 @@ if (missingCSSMarkers.length > 0) { } // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_sortby-and-_orderby -const sortBy = (key) => (a, b) => - // eslint-disable-next-line no-nested-ternary - a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0; +const sortBy = + (/** @type {string} */ key) => + ( + /** @type {Record} */ a, + /** @type {Record} */ b, + ) => + // eslint-disable-next-line no-nested-ternary + a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0; const sortedCSSMarkers = [...cssMarkersWithPositions] .sort(sortBy('position')) diff --git a/website/waitForCrowdin.mjs b/website/waitForCrowdin.mjs index d8e2823b5008..7a02bf0a4ed6 100644 --- a/website/waitForCrowdin.mjs +++ b/website/waitForCrowdin.mjs @@ -28,6 +28,9 @@ const token = process.env.CROWDIN_PERSONAL_TOKEN; // Set on Netlify const translations = new Translations({token}); +/** + * @param {number} ms + */ async function delay(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); From 624735bd92a82724e4fc18239d42e160726af506 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Tue, 24 May 2022 19:19:24 +0800 Subject: [PATCH 04/43] refactor: fix more type-aware linting errors (#7479) --- .eslintrc.js | 4 +- admin/scripts/generateExamples.js | 7 +- packages/create-docusaurus/bin/index.js | 4 +- packages/create-docusaurus/src/index.ts | 2 +- packages/docusaurus-migrate/bin/index.mjs | 6 +- .../src/index.d.ts | 13 ++- .../src/__tests__/feed.test.ts | 4 +- .../docusaurus-plugin-content-docs/src/cli.ts | 10 +- .../src/versions/files.ts | 2 +- .../docusaurus-theme-classic/src/index.ts | 5 +- .../src/theme-classic.d.ts | 3 +- .../src/theme/MDXComponents/Details.tsx | 8 +- .../src/theme/MDXComponents/Head.tsx | 8 +- .../src/theme/MDXComponents/Pre.tsx | 4 +- .../src/theme/Navbar/Content/index.tsx | 3 +- .../MobileSidebar/PrimaryMenu/index.tsx | 3 +- .../DocsVersionDropdownNavbarItem.tsx | 4 +- .../theme/NavbarItem/DropdownNavbarItem.tsx | 3 +- .../src/theme/NavbarItem/index.tsx | 27 ++--- .../src/theme/Tabs/index.tsx | 6 +- .../src/components/Details/index.tsx | 2 +- .../src/hooks/useTOCHighlight.ts | 2 +- .../src/utils/codeBlockUtils.ts | 6 +- .../src/utils/useThemeConfig.ts | 6 +- .../src/theme/Playground/index.tsx | 2 +- .../src/theme/SearchBar/index.tsx | 2 +- .../locales/__tests__/locales.test.ts | 6 +- .../src/index.ts | 2 +- .../src/__tests__/pathUtils.test.ts | 30 +++-- packages/docusaurus/bin/beforeCli.mjs | 4 +- .../src/client/ClientLifecyclesDispatcher.tsx | 2 +- .../src/client/__tests__/flat.test.ts | 2 +- packages/docusaurus/src/client/docusaurus.ts | 2 +- .../docusaurus/src/client/exports/Link.tsx | 5 +- .../exports/__tests__/useGlobalData.test.tsx | 13 --- .../src/client/exports/isInternalUrl.ts | 2 +- .../src/client/exports/useGlobalData.ts | 3 - packages/docusaurus/src/client/flat.ts | 2 +- packages/docusaurus/src/client/prefetch.ts | 4 +- .../docusaurus/src/client/serverEntry.tsx | 4 +- .../configValidation.test.ts.snap | 16 +-- .../docusaurus/src/server/configValidation.ts | 8 +- packages/docusaurus/src/server/htmlTags.ts | 2 +- .../__tests__/__snapshots__/init.test.ts.snap | 4 +- .../src/server/plugins/__tests__/init.test.ts | 2 +- .../translations/translationsExtractor.ts | 6 +- packages/docusaurus/src/webpack/utils.ts | 2 +- packages/lqip-loader/src/index.ts | 7 +- .../src/__tests__/index.test.ts | 110 +++++++++--------- tsconfig.json | 1 + website/src/pages/versions.tsx | 2 +- 51 files changed, 195 insertions(+), 192 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 4dc985f0d9f9..051366201728 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -83,7 +83,7 @@ module.exports = { 'no-restricted-exports': OFF, 'no-restricted-properties': [ ERROR, - ...[ + .../** @type {[string, string][]} */ ([ // TODO: TS doesn't make Boolean a narrowing function yet, // so filter(Boolean) is problematic type-wise // ['compact', 'Array#filter(Boolean)'], @@ -114,7 +114,7 @@ module.exports = { ['take', 'Array#slice(0, n)'], ['takeRight', 'Array#slice(-n)'], ['tail', 'Array#slice(1)'], - ].map(([property, alternative]) => ({ + ]).map(([property, alternative]) => ({ object: '_', property, message: `Use ${alternative} instead.`, diff --git a/admin/scripts/generateExamples.js b/admin/scripts/generateExamples.js index de99e750490b..59020d821d09 100644 --- a/admin/scripts/generateExamples.js +++ b/admin/scripts/generateExamples.js @@ -44,9 +44,10 @@ async function generateTemplateExample(template) { `npm init docusaurus@latest examples/${template} ${command}`, ); - const templatePackageJson = await fs.readJSON( - `examples/${template}/package.json`, - ); + const templatePackageJson = + await /** @type {Promise} */ ( + fs.readJSON(`examples/${template}/package.json`) + ); // Attach the dev script which would be used in code sandbox by default templatePackageJson.scripts.dev = 'docusaurus start'; diff --git a/packages/create-docusaurus/bin/index.js b/packages/create-docusaurus/bin/index.js index 328495345270..35e135ebc65c 100755 --- a/packages/create-docusaurus/bin/index.js +++ b/packages/create-docusaurus/bin/index.js @@ -14,7 +14,9 @@ import logger from '@docusaurus/logger'; import semver from 'semver'; import {program} from 'commander'; -const packageJson = createRequire(import.meta.url)('../package.json'); +const packageJson = /** @type {import("../package.json")} */ ( + createRequire(import.meta.url)('../package.json') +); const requiredVersion = packageJson.engines.node; if (!semver.satisfies(process.version, requiredVersion)) { diff --git a/packages/create-docusaurus/src/index.ts b/packages/create-docusaurus/src/index.ts index 6523b9291766..27d53f50fd59 100755 --- a/packages/create-docusaurus/src/index.ts +++ b/packages/create-docusaurus/src/index.ts @@ -78,7 +78,7 @@ async function askForPackageManagerChoice(): Promise { logger.info`Falling back to name=${defaultPackageManager}`; }, }, - )) as {packageManager: PackageManager} + )) as {packageManager?: PackageManager} ).packageManager ?? defaultPackageManager ); } diff --git a/packages/docusaurus-migrate/bin/index.mjs b/packages/docusaurus-migrate/bin/index.mjs index 769c5e9e3c08..0ace2050c1ca 100755 --- a/packages/docusaurus-migrate/bin/index.mjs +++ b/packages/docusaurus-migrate/bin/index.mjs @@ -15,7 +15,9 @@ import semver from 'semver'; import cli from 'commander'; const moduleRequire = createRequire(import.meta.url); -const requiredVersion = moduleRequire('../package.json').engines.node; +const requiredVersion = /** @type {import("../package.json")} */ ( + moduleRequire('../package.json') +).engines.node; if (!semver.satisfies(process.version, requiredVersion)) { logger.error('Minimum Node.js version not met :('); @@ -25,7 +27,7 @@ if (!semver.satisfies(process.version, requiredVersion)) { // See https://github.com/facebook/docusaurus/pull/6860 const {migrateDocusaurusProject, migrateMDToMDX} = - moduleRequire('../lib/index.js'); + /** @type {import("../lib/index.js")} */ (moduleRequire('../lib/index.js')); cli .command('migrate [siteDir] [newDir]') diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index cd6bf0d1c910..3a900c907d77 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -323,16 +323,27 @@ declare module '@docusaurus/renderRoutes' { declare module '@docusaurus/useGlobalData' { import type {GlobalData, UseDataOptions} from '@docusaurus/types'; + export function useAllPluginInstancesData( + pluginName: string, + options: {failfast: true}, + ): GlobalData[string]; + export function useAllPluginInstancesData( pluginName: string, options?: UseDataOptions, ): GlobalData[string] | undefined; + export function usePluginData( + pluginName: string, + pluginId: string | undefined, + options: {failfast: true}, + ): NonNullable; + export function usePluginData( pluginName: string, pluginId?: string, options?: UseDataOptions, - ): GlobalData[string][string] | undefined; + ): GlobalData[string][string]; export default function useGlobalData(): GlobalData; } 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 7b7981985443..2e5d96872dfe 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts @@ -133,7 +133,9 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => { } as PluginOptions, ); - expect(fsMock.mock.calls.map((call) => call[1])).toMatchSnapshot(); + expect( + fsMock.mock.calls.map((call) => call[1] as string), + ).toMatchSnapshot(); fsMock.mockClear(); }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/cli.ts b/packages/docusaurus-plugin-content-docs/src/cli.ts index 7156d4c6e49a..65e4984affa0 100644 --- a/packages/docusaurus-plugin-content-docs/src/cli.ts +++ b/packages/docusaurus-plugin-content-docs/src/cli.ts @@ -14,6 +14,7 @@ import { getVersionDocsDirPath, getVersionSidebarsPath, getDocsDirPathLocalized, + readVersionsFile, } from './versions/files'; import {validateVersionName} from './versions/validation'; import {loadSidebarsFileUnsafe} from './sidebars'; @@ -69,12 +70,7 @@ export async function cliDocsVersionCommand( throw err; } - // Load existing versions. - let versions: string[] = []; - const versionsJSONFile = getVersionsFilePath(siteDir, pluginId); - if (await fs.pathExists(versionsJSONFile)) { - versions = await fs.readJSON(versionsJSONFile); - } + const versions = (await readVersionsFile(siteDir, pluginId)) ?? []; // Check if version already exists. if (versions.includes(version)) { @@ -137,7 +133,7 @@ export async function cliDocsVersionCommand( // Update versions.json file. versions.unshift(version); await fs.outputFile( - versionsJSONFile, + getVersionsFilePath(siteDir, pluginId), `${JSON.stringify(versions, null, 2)}\n`, ); diff --git a/packages/docusaurus-plugin-content-docs/src/versions/files.ts b/packages/docusaurus-plugin-content-docs/src/versions/files.ts index f9ef69c82944..04c97efaebaa 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions/files.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions/files.ts @@ -89,7 +89,7 @@ export function getVersionsFilePath(siteDir: string, pluginId: string): string { * @throws Throws if validation fails, i.e. `versions.json` doesn't contain an * array of valid version names. */ -async function readVersionsFile( +export async function readVersionsFile( siteDir: string, pluginId: string, ): Promise { diff --git a/packages/docusaurus-theme-classic/src/index.ts b/packages/docusaurus-theme-classic/src/index.ts index c87fef7f4b7e..b52f14d98b57 100644 --- a/packages/docusaurus-theme-classic/src/index.ts +++ b/packages/docusaurus-theme-classic/src/index.ts @@ -19,8 +19,9 @@ import type webpack from 'webpack'; const requireFromDocusaurusCore = createRequire( require.resolve('@docusaurus/core/package.json'), ); -const ContextReplacementPlugin: typeof webpack.ContextReplacementPlugin = - requireFromDocusaurusCore('webpack/lib/ContextReplacementPlugin'); +const ContextReplacementPlugin = requireFromDocusaurusCore( + 'webpack/lib/ContextReplacementPlugin', +) as typeof webpack.ContextReplacementPlugin; // Need to be inlined to prevent dark mode FOUC // Make sure the key is the same as the one in `/theme/hooks/useTheme.js` diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 4aa679bd4946..bc9b9c9bbaf3 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -816,7 +816,6 @@ declare module '@theme/NavbarItem/NavbarNavLink' { declare module '@theme/NavbarItem/DropdownNavbarItem' { import type {Props as NavbarNavLinkProps} from '@theme/NavbarItem/NavbarNavLink'; - import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem'; export type DesktopOrMobileNavBarItemProps = NavbarNavLinkProps & { @@ -976,7 +975,7 @@ declare module '@theme/NavbarItem' { } & SearchNavbarItemProps) ); - export type Types = Props['type']; + export type NavbarItemType = Props['type']; export default function NavbarItem(props: Props): JSX.Element; } diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx index 8ae874a7a23e..c99fdc2a6adb 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Details.tsx @@ -10,11 +10,13 @@ import Details from '@theme/Details'; import type {Props} from '@theme/MDXComponents/Details'; export default function MDXDetails(props: Props): JSX.Element { - const items = React.Children.toArray(props.children) as ReactElement[]; + const items = React.Children.toArray(props.children); // Split summary item from the rest to pass it as a separate prop to the // Details theme component - const summary: ReactElement> | undefined = - items.find((item) => item?.props?.mdxType === 'summary'); + const summary = items.find( + (item): item is ReactElement> => + React.isValidElement(item) && item.props?.mdxType === 'summary', + ); const children = <>{items.filter((item) => item !== summary)}; return ( diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx index c21608e69e36..bf8867f409ba 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Head.tsx @@ -11,8 +11,10 @@ import type {Props} from '@theme/MDXComponents/Head'; // MDX elements are wrapped through the MDX pragma. In some cases (notably usage // with Head/Helmet) we need to unwrap those elements. -function unwrapMDXElement(element: ReactElement) { - if (element?.props?.mdxType && element?.props?.originalType) { +function unwrapMDXElement( + element: ReactElement<{mdxType?: string; originalType?: string} | undefined>, +) { + if (element.props?.mdxType && element.props.originalType) { const {mdxType, originalType, ...newProps} = element.props; return React.createElement(element.props.originalType, newProps); } @@ -21,7 +23,7 @@ function unwrapMDXElement(element: ReactElement) { export default function MDXHead(props: Props): JSX.Element { const unwrappedChildren = React.Children.map(props.children, (child) => - unwrapMDXElement(child as ReactElement), + React.isValidElement(child) ? unwrapMDXElement(child) : child, ); return ( )}>{unwrappedChildren} diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx index bfaf413fd04b..75e64c997171 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Pre.tsx @@ -14,8 +14,8 @@ export default function MDXPre(props: Props): JSX.Element { ); diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx b/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx index 89503a675dcb..cf087e6cefd5 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx @@ -11,13 +11,12 @@ import { useNavbarMobileSidebar, useThemeConfig, } from '@docusaurus/theme-common'; -import NavbarItem from '@theme/NavbarItem'; +import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem'; import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle'; import SearchBar from '@theme/SearchBar'; import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle'; import NavbarLogo from '@theme/Navbar/Logo'; import NavbarSearch from '@theme/Navbar/Search'; -import type {Props as NavbarItemConfig} from '@theme/NavbarItem'; import styles from './styles.module.css'; diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx b/packages/docusaurus-theme-classic/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx index d8fa6524a6f0..3fec36ad617d 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx @@ -7,8 +7,7 @@ import React from 'react'; import {useNavbarMobileSidebar, useThemeConfig} from '@docusaurus/theme-common'; -import NavbarItem from '@theme/NavbarItem'; -import type {Props as NavbarItemConfig} from '@theme/NavbarItem'; +import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem'; function useNavbarItems() { // TODO temporary casting until ThemeConfig type is improved diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx index b351eeeef1a8..47903ce0aa35 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx @@ -38,13 +38,13 @@ export default function DocsVersionDropdownNavbarItem({ // We try to link to the same doc, in another version // When not possible, fallback to the "main doc" of the version const versionDoc = - activeDocContext?.alternateDocVersions[version.name] ?? + activeDocContext.alternateDocVersions[version.name] ?? getVersionMainDoc(version); return { isNavLink: true, label: version.label, to: versionDoc.path, - isActive: () => version === activeDocContext?.activeVersion, + isActive: () => version === activeDocContext.activeVersion, onClick: () => savePreferredVersionName(version.name), }; }); diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx index ca5e03d92f12..45c61dac60e7 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx @@ -15,12 +15,11 @@ import { useLocalPathname, } from '@docusaurus/theme-common'; import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink'; -import NavbarItem from '@theme/NavbarItem'; +import NavbarItem, {type LinkLikeNavbarItemProps} from '@theme/NavbarItem'; import type { DesktopOrMobileNavBarItemProps, Props, } from '@theme/NavbarItem/DropdownNavbarItem'; -import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem'; const dropdownLinkActiveClass = 'dropdown__link--active'; diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx index ca3253143a16..0096e2bdb1e3 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx @@ -7,31 +7,22 @@ import React from 'react'; import ComponentTypes from '@theme/NavbarItem/ComponentTypes'; -import {type Props as DropdownNavbarItemProps} from '@theme/NavbarItem/DropdownNavbarItem'; -import type {Types, Props} from '@theme/NavbarItem'; +import type {NavbarItemType, Props} from '@theme/NavbarItem'; -const getNavbarItemComponent = (type: NonNullable) => { - const component = ComponentTypes[type]; - if (!component) { - throw new Error(`No NavbarItem component found for type "${type}".`); - } - return component; -}; - -function getComponentType(type: Types, isDropdown: boolean) { +function normalizeComponentType(type: NavbarItemType, props: object) { // Backward compatibility: navbar item with no type set // but containing dropdown items should use the type "dropdown" if (!type || type === 'default') { - return isDropdown ? 'dropdown' : 'default'; + return 'items' in props ? 'dropdown' : 'default'; } - return type as NonNullable; + return type; } export default function NavbarItem({type, ...props}: Props): JSX.Element { - const componentType = getComponentType( - type, - (props as DropdownNavbarItemProps).items !== undefined, - ); - const NavbarItemComponent = getNavbarItemComponent(componentType); + const componentType = normalizeComponentType(type, props); + const NavbarItemComponent = ComponentTypes[componentType]; + if (!NavbarItemComponent) { + throw new Error(`No NavbarItem component found for type "${type}".`); + } return ; } diff --git a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx index e81a01d3fc5b..8d055ce06e6f 100644 --- a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx @@ -75,7 +75,7 @@ function TabsComponent(props: Props): JSX.Element { ? defaultValueProp : defaultValueProp ?? children.find((child) => child.props.default)?.props.value ?? - children[0]?.props.value; + children[0]!.props.value; if (defaultValue !== null && !values.some((a) => a.value === defaultValue)) { throw new Error( `Docusaurus error: The has a defaultValue "${defaultValue}" but none of its children has the corresponding value. Available values are: ${values @@ -126,12 +126,12 @@ function TabsComponent(props: Props): JSX.Element { switch (event.key) { case 'ArrowRight': { const nextTab = tabRefs.indexOf(event.currentTarget) + 1; - focusElement = tabRefs[nextTab] || tabRefs[0]!; + focusElement = tabRefs[nextTab] ?? tabRefs[0]!; break; } case 'ArrowLeft': { const prevTab = tabRefs.indexOf(event.currentTarget) - 1; - focusElement = tabRefs[prevTab] || tabRefs[tabRefs.length - 1]!; + focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1]!; break; } default: diff --git a/packages/docusaurus-theme-common/src/components/Details/index.tsx b/packages/docusaurus-theme-common/src/components/Details/index.tsx index 41c34097aa86..19952166bc59 100644 --- a/packages/docusaurus-theme-common/src/components/Details/index.tsx +++ b/packages/docusaurus-theme-common/src/components/Details/index.tsx @@ -92,7 +92,7 @@ export function Details({ } }}> {/* eslint-disable-next-line @docusaurus/no-untranslated-text */} - {summary || Details} + {summary ?? Details} item !== undefined)!; + const directive = match + .slice(1) + .find((item: string | undefined) => item !== undefined)!; if (lineToClassName[directive]) { blocks[lineToClassName[directive]!]!.range += `${lineNumber},`; } else if (blockStartToClassName[directive]) { diff --git a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts index 111468e5ea88..b160bf307c84 100644 --- a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts +++ b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts @@ -85,10 +85,10 @@ export type FooterBase = { }; export type MultiColumnFooter = FooterBase & { - links: Array<{ + links: { title: string | null; items: FooterLinkItem[]; - }>; + }[]; }; export type SimpleFooter = FooterBase & { @@ -123,7 +123,7 @@ export type ThemeConfig = { prism: PrismConfig; footer?: Footer; image?: string; - metadata: Array<{[key: string]: string}>; + metadata: {[key: string]: string}[]; tableOfContents: TableOfContents; }; diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx index 64a6cc354517..ef5c0f0f4ff9 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx +++ b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx @@ -98,7 +98,7 @@ export default function Playground({ {/* @ts-expect-error: type incompatibility with refs */} `${code};`)} + transformCode={transformCode ?? ((code) => `${code};`)} theme={prismTheme} {...props}> {playgroundPosition === 'top' ? ( diff --git a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx index 217555ad316d..bd36e353aa6a 100644 --- a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx +++ b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx @@ -75,7 +75,7 @@ type FacetFilters = Required< function mergeFacetFilters(f1: FacetFilters, f2: FacetFilters): FacetFilters { const normalize = ( f: FacetFilters, - ): readonly string[] | ReadonlyArray => + ): readonly string[] | readonly (string | readonly string[])[] => typeof f === 'string' ? [f] : f; return [...normalize(f1), ...normalize(f2)] as FacetFilters; } diff --git a/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts b/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts index 3b7a611cbcd6..446a1ea9d090 100644 --- a/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts +++ b/packages/docusaurus-theme-translations/locales/__tests__/locales.test.ts @@ -22,8 +22,10 @@ describe('theme translations', () => { .then((files) => Promise.all( files.map( - (baseMessagesFile): Promise<{[key: string]: string}> => - fs.readJSON(path.join(baseMessagesDirPath, baseMessagesFile)), + (baseMessagesFile) => + fs.readJSON( + path.join(baseMessagesDirPath, baseMessagesFile), + ) as Promise<{[key: string]: string}>, ), ), ) diff --git a/packages/docusaurus-theme-translations/src/index.ts b/packages/docusaurus-theme-translations/src/index.ts index 8b9afb841d90..4c2538044409 100644 --- a/packages/docusaurus-theme-translations/src/index.ts +++ b/packages/docusaurus-theme-translations/src/index.ts @@ -51,7 +51,7 @@ export async function readDefaultCodeTranslationMessages({ const filePath = path.resolve(dirPath, localeToTry, `${name}.json`); if (await fs.pathExists(filePath)) { - return fs.readJSON(filePath); + return fs.readJSON(filePath) as Promise; } } diff --git a/packages/docusaurus-utils/src/__tests__/pathUtils.test.ts b/packages/docusaurus-utils/src/__tests__/pathUtils.test.ts index eb6cc8d13f07..6059d2946d08 100644 --- a/packages/docusaurus-utils/src/__tests__/pathUtils.test.ts +++ b/packages/docusaurus-utils/src/__tests__/pathUtils.test.ts @@ -37,21 +37,24 @@ describe('isNameTooLong', () => { }; const oldProcessPlatform = process.platform; Object.defineProperty(process, 'platform', {value: 'darwin'}); - Object.keys(asserts).forEach((file) => { + (Object.keys(asserts) as (keyof typeof asserts)[]).forEach((file) => { + const expected = asserts[file]; expect(isNameTooLong(file)).toBe( - typeof asserts[file] === 'boolean' ? asserts[file] : asserts[file].apfs, + typeof expected === 'boolean' ? expected : expected.apfs, ); }); Object.defineProperty(process, 'platform', {value: 'win32'}); - Object.keys(asserts).forEach((file) => { + (Object.keys(asserts) as (keyof typeof asserts)[]).forEach((file) => { + const expected = asserts[file]; expect(isNameTooLong(file)).toBe( - typeof asserts[file] === 'boolean' ? asserts[file] : asserts[file].apfs, + typeof expected === 'boolean' ? expected : expected.apfs, ); }); Object.defineProperty(process, 'platform', {value: 'android'}); - Object.keys(asserts).forEach((file) => { + (Object.keys(asserts) as (keyof typeof asserts)[]).forEach((file) => { + const expected = asserts[file]; expect(isNameTooLong(file)).toBe( - typeof asserts[file] === 'boolean' ? asserts[file] : asserts[file].xfs, + typeof expected === 'boolean' ? expected : expected.xfs, ); }); Object.defineProperty(process, 'platform', {value: oldProcessPlatform}); @@ -79,21 +82,24 @@ describe('shortName', () => { }; const oldProcessPlatform = process.platform; Object.defineProperty(process, 'platform', {value: 'darwin'}); - Object.keys(asserts).forEach((file) => { + (Object.keys(asserts) as (keyof typeof asserts)[]).forEach((file) => { + const expected = asserts[file]; expect(shortName(file)).toBe( - typeof asserts[file] === 'string' ? asserts[file] : asserts[file].apfs, + typeof expected === 'string' ? expected : expected.apfs, ); }); Object.defineProperty(process, 'platform', {value: 'win32'}); - Object.keys(asserts).forEach((file) => { + (Object.keys(asserts) as (keyof typeof asserts)[]).forEach((file) => { + const expected = asserts[file]; expect(shortName(file)).toBe( - typeof asserts[file] === 'string' ? asserts[file] : asserts[file].apfs, + typeof expected === 'string' ? expected : expected.apfs, ); }); Object.defineProperty(process, 'platform', {value: 'android'}); - Object.keys(asserts).forEach((file) => { + (Object.keys(asserts) as (keyof typeof asserts)[]).forEach((file) => { + const expected = asserts[file]; expect(shortName(file)).toBe( - typeof asserts[file] === 'string' ? asserts[file] : asserts[file].xfs, + typeof expected === 'string' ? expected : expected.xfs, ); }); Object.defineProperty(process, 'platform', {value: oldProcessPlatform}); diff --git a/packages/docusaurus/bin/beforeCli.mjs b/packages/docusaurus/bin/beforeCli.mjs index fa4cecdbc77c..238939f2a0b8 100644 --- a/packages/docusaurus/bin/beforeCli.mjs +++ b/packages/docusaurus/bin/beforeCli.mjs @@ -16,7 +16,9 @@ import updateNotifier from 'update-notifier'; import boxen from 'boxen'; import {DOCUSAURUS_VERSION} from '@docusaurus/utils'; -const packageJson = createRequire(import.meta.url)('../package.json'); +const packageJson = /** @type {import("../package.json")} */ ( + createRequire(import.meta.url)('../package.json') +); /** @type {Record} */ let sitePkg; try { diff --git a/packages/docusaurus/src/client/ClientLifecyclesDispatcher.tsx b/packages/docusaurus/src/client/ClientLifecyclesDispatcher.tsx index caf75a1647bf..e9cb7f8d5f5a 100644 --- a/packages/docusaurus/src/client/ClientLifecyclesDispatcher.tsx +++ b/packages/docusaurus/src/client/ClientLifecyclesDispatcher.tsx @@ -15,7 +15,7 @@ export function dispatchLifecycleAction( ...args: Parameters> ): () => void { const callbacks = clientModules.map((clientModule) => { - const lifecycleFunction = (clientModule?.default?.[lifecycleAction] ?? + const lifecycleFunction = (clientModule.default?.[lifecycleAction] ?? clientModule[lifecycleAction]) as | (( ...a: Parameters> diff --git a/packages/docusaurus/src/client/__tests__/flat.test.ts b/packages/docusaurus/src/client/__tests__/flat.test.ts index f931108938bb..54c252393dd1 100644 --- a/packages/docusaurus/src/client/__tests__/flat.test.ts +++ b/packages/docusaurus/src/client/__tests__/flat.test.ts @@ -41,7 +41,7 @@ describe('flat', () => { null: null, undefined, }; - Object.keys(primitives).forEach((key) => { + (Object.keys(primitives) as (keyof typeof primitives)[]).forEach((key) => { const value = primitives[key]; expect( flat({ diff --git a/packages/docusaurus/src/client/docusaurus.ts b/packages/docusaurus/src/client/docusaurus.ts index 987f931ede0a..da1236cacede 100644 --- a/packages/docusaurus/src/client/docusaurus.ts +++ b/packages/docusaurus/src/client/docusaurus.ts @@ -70,7 +70,7 @@ const docusaurus = { // In some cases, webpack might decide to optimize further, leading to // the chunk assets being merged to another chunk. In this case, we can // safely filter it out and don't need to load it. - if (chunkAsset && !/undefined/.test(chunkAsset)) { + if (chunkAsset && !chunkAsset.includes('undefined')) { return prefetchHelper(chunkAsset); } return Promise.resolve(); diff --git a/packages/docusaurus/src/client/exports/Link.tsx b/packages/docusaurus/src/client/exports/Link.tsx index 78a3f91a6b7b..614c608c3faf 100644 --- a/packages/docusaurus/src/client/exports/Link.tsx +++ b/packages/docusaurus/src/client/exports/Link.tsx @@ -47,10 +47,7 @@ function Link( const linksCollector = useLinksCollector(); const innerRef = useRef(null); - useImperativeHandle( - forwardedRef, - () => innerRef.current as HTMLAnchorElement, - ); + useImperativeHandle(forwardedRef, () => innerRef.current!); // IMPORTANT: using to or href should not change anything // For example, MDX links will ALWAYS give us the href props diff --git a/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx b/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx index b688427aa9a5..1f52a15b4070 100644 --- a/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx +++ b/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx @@ -26,19 +26,6 @@ describe('useGlobalData', () => { }).result.current, ).toEqual({foo: 'bar'}); }); - - it('throws when global data not found', () => { - // Can it actually happen? - expect( - () => - renderHook(() => useGlobalData(), { - wrapper: ({children}) => ( - // eslint-disable-next-line react/jsx-no-constructed-context-values - {children} - ), - }).result.current, - ).toThrowErrorMatchingInlineSnapshot(`"Docusaurus global data not found."`); - }); }); describe('useAllPluginInstancesData', () => { diff --git a/packages/docusaurus/src/client/exports/isInternalUrl.ts b/packages/docusaurus/src/client/exports/isInternalUrl.ts index f3158e6e9859..489aff74bc0d 100644 --- a/packages/docusaurus/src/client/exports/isInternalUrl.ts +++ b/packages/docusaurus/src/client/exports/isInternalUrl.ts @@ -6,7 +6,7 @@ */ export function hasProtocol(url: string): boolean { - return /^(?:\w*:|\/\/)/.test(url) === true; + return /^(?:\w*:|\/\/)/.test(url); } export default function isInternalUrl(url?: string): boolean { diff --git a/packages/docusaurus/src/client/exports/useGlobalData.ts b/packages/docusaurus/src/client/exports/useGlobalData.ts index 004d99e38a16..7036878568bd 100644 --- a/packages/docusaurus/src/client/exports/useGlobalData.ts +++ b/packages/docusaurus/src/client/exports/useGlobalData.ts @@ -11,9 +11,6 @@ import type {GlobalData, UseDataOptions} from '@docusaurus/types'; export default function useGlobalData(): GlobalData { const {globalData} = useDocusaurusContext(); - if (!globalData) { - throw new Error('Docusaurus global data not found.'); - } return globalData; } diff --git a/packages/docusaurus/src/client/flat.ts b/packages/docusaurus/src/client/flat.ts index 8413842b8b76..3ef06a2d38e6 100644 --- a/packages/docusaurus/src/client/flat.ts +++ b/packages/docusaurus/src/client/flat.ts @@ -10,7 +10,7 @@ import type {ChunkNames} from '@docusaurus/types'; type Chunk = ChunkNames[string]; type Tree = Exclude; -const isTree = (x: Chunk): x is Tree => +const isTree = (x: unknown): x is Tree => typeof x === 'object' && !!x && Object.keys(x).length > 0; /** diff --git a/packages/docusaurus/src/client/prefetch.ts b/packages/docusaurus/src/client/prefetch.ts index a7a58008a753..4b84c7e884a0 100644 --- a/packages/docusaurus/src/client/prefetch.ts +++ b/packages/docusaurus/src/client/prefetch.ts @@ -8,8 +8,8 @@ function supports(feature: string) { try { const fakeLink = document.createElement('link'); - return fakeLink.relList?.supports?.(feature); - } catch (err) { + return fakeLink.relList.supports(feature); + } catch { return false; } } diff --git a/packages/docusaurus/src/client/serverEntry.tsx b/packages/docusaurus/src/client/serverEntry.tsx index 9918e4220adb..528a0a96e3a8 100644 --- a/packages/docusaurus/src/client/serverEntry.tsx +++ b/packages/docusaurus/src/client/serverEntry.tsx @@ -115,9 +115,9 @@ async function doRender(locals: Locals & {path: string}) { // Using readJSON seems to fail for users of some plugins, possibly because of // the eval sandbox having a different `Buffer` instance (native one instead // of polyfilled one) - const manifest: Manifest = await fs + const manifest = (await fs .readFile(manifestPath, 'utf-8') - .then(JSON.parse); + .then(JSON.parse)) as Manifest; // Get all required assets for this particular page based on client // manifest information. diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap index b8a9733d0214..5aceb9625550 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/configValidation.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`normalizeConfig should throw error if plugins is not a string and it's not an array #1 for the input of: [123] 1`] = ` -" => Bad Docusaurus plugin value as path [plugins,0]. +" => Bad Docusaurus plugin value plugins[0]. Example valid plugin config: { plugins: [ @@ -17,7 +17,7 @@ Example valid plugin config: `; exports[`normalizeConfig should throw error if plugins is not an array of [string, object][] #1 for the input of: [[Array]] 1`] = ` -" => Bad Docusaurus plugin value as path [plugins,0]. +" => Bad Docusaurus plugin value plugins[0]. Example valid plugin config: { plugins: [ @@ -33,7 +33,7 @@ Example valid plugin config: `; exports[`normalizeConfig should throw error if plugins is not an array of [string, object][] #2 for the input of: [[Array]] 1`] = ` -" => Bad Docusaurus plugin value as path [plugins,0]. +" => Bad Docusaurus plugin value plugins[0]. Example valid plugin config: { plugins: [ @@ -49,7 +49,7 @@ Example valid plugin config: `; exports[`normalizeConfig should throw error if plugins is not an array of [string, object][] #3 for the input of: [[Array]] 1`] = ` -" => Bad Docusaurus plugin value as path [plugins,0]. +" => Bad Docusaurus plugin value plugins[0]. Example valid plugin config: { plugins: [ @@ -70,7 +70,7 @@ exports[`normalizeConfig should throw error if plugins is not array for the inpu `; exports[`normalizeConfig should throw error if themes is not a string and it's not an array #1 for the input of: [123] 1`] = ` -" => Bad Docusaurus theme value as path [themes,0]. +" => Bad Docusaurus theme value themes[0]. Example valid theme config: { themes: [ @@ -86,7 +86,7 @@ Example valid theme config: `; exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #1 for the input of: [[Array]] 1`] = ` -" => Bad Docusaurus theme value as path [themes,0]. +" => Bad Docusaurus theme value themes[0]. Example valid theme config: { themes: [ @@ -102,7 +102,7 @@ Example valid theme config: `; exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #2 for the input of: [[Array]] 1`] = ` -" => Bad Docusaurus theme value as path [themes,0]. +" => Bad Docusaurus theme value themes[0]. Example valid theme config: { themes: [ @@ -118,7 +118,7 @@ Example valid theme config: `; exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #3 for the input of: [[Array]] 1`] = ` -" => Bad Docusaurus theme value as path [themes,0]. +" => Bad Docusaurus theme value themes[0]. Example valid theme config: { themes: [ diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index 2820e4b44dc3..f5ef6a3cc9a4 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -100,7 +100,9 @@ function createPluginSchema(theme: boolean) { error.message = ` => Bad Docusaurus ${ theme ? 'theme' : 'plugin' - } value as path [${error.path}]. + } value ${error.path.reduce((acc, cur) => + typeof cur === 'string' ? `${acc}.${cur}` : `${acc}[${cur}]`, + )}. ${validConfigExample} `; }); @@ -247,7 +249,9 @@ export function validateConfig(config: unknown): DocusaurusConfig { if (error) { const unknownFields = error.details.reduce((formattedError, err) => { if (err.type === 'object.unknown') { - return `${formattedError}"${err.path}",`; + return `${formattedError}"${err.path.reduce((acc, cur) => + typeof cur === 'string' ? `${acc}.${cur}` : `${acc}[${cur}]`, + )}",`; } return formattedError; }, ''); diff --git a/packages/docusaurus/src/server/htmlTags.ts b/packages/docusaurus/src/server/htmlTags.ts index 81cce416352a..e61f94680404 100644 --- a/packages/docusaurus/src/server/htmlTags.ts +++ b/packages/docusaurus/src/server/htmlTags.ts @@ -83,5 +83,5 @@ export function loadHtmlTags( .trim(), ), ), - ); + ) as Pick; } diff --git a/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/init.test.ts.snap b/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/init.test.ts.snap index b900cdd18224..048fb326e44f 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/init.test.ts.snap +++ b/packages/docusaurus/src/server/plugins/__tests__/__snapshots__/init.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`initPlugins throws user-friendly error message for plugins with bad values 1`] = ` -" => Bad Docusaurus plugin value as path [plugins,0]. +" => Bad Docusaurus plugin value plugins[0]. Example valid plugin config: { plugins: [ @@ -13,7 +13,7 @@ Example valid plugin config: ], }; - => Bad Docusaurus plugin value as path [plugins,1]. + => Bad Docusaurus plugin value plugins[1]. Example valid plugin config: { plugins: [ diff --git a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts index adcd9147dcb6..30fe4cb603a9 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts @@ -21,7 +21,7 @@ describe('initPlugins', () => { it('parses plugins correctly and loads them in correct order', async () => { const {context, plugins} = await loadSite(); - expect(context.siteConfig.plugins?.length).toBe(4); + expect(context.siteConfig.plugins).toHaveLength(4); expect(plugins).toHaveLength(8); expect(plugins[0].name).toBe('preset-plugin1'); diff --git a/packages/docusaurus/src/server/translations/translationsExtractor.ts b/packages/docusaurus/src/server/translations/translationsExtractor.ts index 83be6bcd7503..dc3b44a3aef4 100644 --- a/packages/docusaurus/src/server/translations/translationsExtractor.ts +++ b/packages/docusaurus/src/server/translations/translationsExtractor.ts @@ -184,7 +184,7 @@ function extractSourceCodeAstTranslations( sourceCodeFilePath: string, ): SourceCodeFileTranslations { function sourceWarningPart(node: Node) { - return `File: ${sourceCodeFilePath} at line ${node.loc?.start.line} + return `File: ${sourceCodeFilePath} at line ${node.loc?.start.line ?? '?'} Full code: ${generate(node).code}`; } @@ -313,7 +313,9 @@ ${sourceWarningPart(path.node)}`); if (isJSXText || isJSXExpressionContainer) { message = isJSXText ? singleChildren.node.value.trim().replace(/\s+/g, ' ') - : (singleChildren.get('expression') as NodePath).evaluate().value; + : String( + (singleChildren.get('expression') as NodePath).evaluate().value, + ); translations[id ?? message] = { message, diff --git a/packages/docusaurus/src/webpack/utils.ts b/packages/docusaurus/src/webpack/utils.ts index 8a7d0aef6120..1d045731b64f 100644 --- a/packages/docusaurus/src/webpack/utils.ts +++ b/packages/docusaurus/src/webpack/utils.ts @@ -198,7 +198,7 @@ export function applyConfigurePostCss( configurePostCss: NonNullable, config: Configuration, ): Configuration { - type LocalPostCSSLoader = unknown & { + type LocalPostCSSLoader = object & { options: {postcssOptions: PostCssOptions}; }; diff --git a/packages/lqip-loader/src/index.ts b/packages/lqip-loader/src/index.ts index 5dd78269439c..66d828fffb80 100644 --- a/packages/lqip-loader/src/index.ts +++ b/packages/lqip-loader/src/index.ts @@ -6,7 +6,7 @@ */ import * as lqip from './lqip'; -import type {LoaderContext} from 'webpack'; +import type {LoaderContext, LoaderModule} from 'webpack'; type Options = { base64: boolean; @@ -36,8 +36,9 @@ export default async function lqipLoader( } else { if (!contentIsFileExport) { // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires - const fileLoader = require('file-loader') as typeof import('file-loader'); - content = fileLoader.call(this, contentBuffer); + const fileLoader = require('file-loader') as LoaderModule['default']; + // @ts-expect-error: type is a bit unwieldy... + content = fileLoader!.call(this, contentBuffer) as string; } source = content.match( /^(?:export default|module.exports =) (?.*);/, diff --git a/packages/stylelint-copyright/src/__tests__/index.test.ts b/packages/stylelint-copyright/src/__tests__/index.test.ts index 4d0f865e153d..aa4b5de12e27 100644 --- a/packages/stylelint-copyright/src/__tests__/index.test.ts +++ b/packages/stylelint-copyright/src/__tests__/index.test.ts @@ -43,68 +43,64 @@ function getOutputCss(output: stylelint.LinterResult) { function testStylelintRule(config: stylelint.Config, tests: TestSuite) { describe(`${tests.ruleName}`, () => { const checkTestCaseContent = (testCase: TestCase) => - testCase.description || testCase.code; - - if (tests.accept?.length) { - describe('accept cases', () => { - tests.accept.forEach((testCase) => { - it(`${checkTestCaseContent(testCase)}`, async () => { - const options: stylelint.LinterOptions = { - code: testCase.code, - config, - }; - - const output = await stylelint.lint(options); - expect(output.results[0]!.warnings).toEqual([]); - if (!tests.fix) { - return; - } - const fixedOutput = await stylelint.lint({...options, fix: true}); - const fixedCode = getOutputCss(fixedOutput); - expect(fixedCode).toBe(testCase.code); - }); + testCase.description ?? testCase.code; + + describe('accept cases', () => { + tests.accept.forEach((testCase) => { + it(`${checkTestCaseContent(testCase)}`, async () => { + const options: stylelint.LinterOptions = { + code: testCase.code, + config, + }; + + const output = await stylelint.lint(options); + expect(output.results[0]!.warnings).toEqual([]); + if (!tests.fix) { + return; + } + const fixedOutput = await stylelint.lint({...options, fix: true}); + const fixedCode = getOutputCss(fixedOutput); + expect(fixedCode).toBe(testCase.code); }); }); - } + }); - if (tests.reject?.length) { - describe('reject cases', () => { - tests.reject.forEach((testCase) => { - it(`${checkTestCaseContent(testCase)}`, async () => { - const options = { - code: testCase.code, - config, - }; - - const output = await stylelint.lint(options); - const {warnings} = output.results[0]!; - const warning = warnings[0]!; - expect(warnings.length).toBeGreaterThanOrEqual(1); - expect(testCase).toHaveMessage(); - if (testCase.message != null) { - expect(warning.text).toBe(testCase.message); - } - if (testCase.line != null) { - expect(warning.line).toBe(testCase.line); - } - if (testCase.column != null) { - expect(warning.column).toBe(testCase.column); - } - if (!tests.fix) { - return; - } - if (!testCase.fixed) { - throw new Error( - 'If using { fix: true } in test tests, all reject cases must have { fixed: .. }', - ); - } - const fixedOutput = await stylelint.lint({...options, fix: true}); - const fixedCode = getOutputCss(fixedOutput); - expect(fixedCode).toBe(testCase.fixed); - }); + describe('reject cases', () => { + tests.reject.forEach((testCase) => { + it(`${checkTestCaseContent(testCase)}`, async () => { + const options = { + code: testCase.code, + config, + }; + + const output = await stylelint.lint(options); + const {warnings} = output.results[0]!; + const warning = warnings[0]!; + expect(warnings.length).toBeGreaterThanOrEqual(1); + expect(testCase).toHaveMessage(); + if (testCase.message != null) { + expect(warning.text).toBe(testCase.message); + } + if (testCase.line != null) { + expect(warning.line).toBe(testCase.line); + } + if (testCase.column != null) { + expect(warning.column).toBe(testCase.column); + } + if (!tests.fix) { + return; + } + if (!testCase.fixed) { + throw new Error( + 'If using { fix: true } in test tests, all reject cases must have { fixed: .. }', + ); + } + const fixedOutput = await stylelint.lint({...options, fix: true}); + const fixedCode = getOutputCss(fixedOutput); + expect(fixedCode).toBe(testCase.fixed); }); }); - } + }); expect.extend({ toHaveMessage(testCase: TestCase) { diff --git a/tsconfig.json b/tsconfig.json index 34195b64e138..5a379450a1b0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -51,6 +51,7 @@ "allowJs": true, "skipLibCheck": true // @types/webpack and webpack/types.d.ts are not the same thing }, + "include": ["./**/*", "./**/.eslintrc.js"], "exclude": [ "node_modules", "coverage/**", diff --git a/website/src/pages/versions.tsx b/website/src/pages/versions.tsx index 4a65419b8837..12d042e92eda 100644 --- a/website/src/pages/versions.tsx +++ b/website/src/pages/versions.tsx @@ -45,7 +45,7 @@ export default function Version(): JSX.Element { const pastVersions = versions.filter( (version) => version !== latestVersion && version.name !== 'current', ); - const repoUrl = `https://github.com/${organizationName}/${projectName}`; + const repoUrl = `https://github.com/${organizationName!}/${projectName!}`; return ( Date: Wed, 25 May 2022 11:46:10 +0800 Subject: [PATCH 05/43] test: fix some type errors in test files (#7486) --- jest/deps.d.ts | 17 ++++ .../remark/headings/__tests__/index.test.ts | 2 +- .../transformLinks/__tests__/index.test.ts | 10 +- .../src/__tests__/options.test.ts | 2 +- .../src/__tests__/writeRedirectFiles.test.ts | 6 +- .../src/options.ts | 2 +- .../__snapshots__/translations.test.ts.snap | 6 ++ .../src/__tests__/blogUtils.test.ts | 4 + .../src/__tests__/feed.test.ts | 3 + .../src/__tests__/frontMatter.test.ts | 4 +- .../src/__tests__/index.test.ts | 25 +++-- .../src/__tests__/options.test.ts | 8 +- .../src/__tests__/translations.test.ts | 3 + .../src/options.ts | 2 +- .../remark/__tests__/footnoteIDFixer.test.ts | 2 +- .../src/__tests__/cli.test.ts | Bin 11378 -> 11753 bytes .../src/__tests__/frontMatter.test.ts | 4 +- .../src/__tests__/globalData.test.ts | 10 +- .../src/__tests__/index.test.ts | 92 ++++++++++++------ .../src/__tests__/options.test.ts | 27 +++-- .../src/__tests__/props.test.ts | 16 +-- .../src/plugin-content-docs.d.ts | 19 +++- .../src/sidebars/__tests__/utils.test.ts | 15 +-- .../src/versions/__tests__/index.test.ts | 8 +- .../src/__tests__/createSitemap.test.ts | 5 +- .../src/__tests__/options.test.ts | 4 +- .../src/__tests__/translations.test.ts | 4 +- .../src/__tests__/validateThemeConfig.test.ts | 2 +- .../src/theme-classic.d.ts | 6 +- .../src/theme/Tabs/index.tsx | 2 +- .../src/utils/__tests__/docsUtils.test.tsx | 34 ++++--- .../utils/__tests__/usePluralForm.test.tsx | 8 +- .../src/__tests__/index.test.ts | 1 + .../src/__tests__/jsUtils.test.ts | 10 +- .../src/__tests__/webpackUtils.test.ts | 2 +- .../src/client/__tests__/flat.test.ts | 2 +- .../__tests__/normalizeLocation.test.ts | 19 ++-- .../exports/__tests__/Interpolate.test.tsx | 6 +- .../exports/__tests__/useBaseUrl.test.tsx | 8 +- .../server/plugins/__tests__/index.test.ts | 4 +- .../src/server/plugins/__tests__/init.test.ts | 16 +-- .../plugins/__tests__/pluginIds.test.ts | 7 +- .../server/plugins/__tests__/presets.test.ts | 6 +- .../__tests__/translations.test.ts | 14 ++- .../__tests__/translationsExtractor.test.ts | 4 +- .../src/webpack/__tests__/base.test.ts | 4 +- .../src/webpack/__tests__/server.test.ts | 12 ++- .../src/webpack/__tests__/utils.test.ts | 19 ++-- .../__tests__/no-untranslated-text.test.ts | 9 +- .../string-literal-i18n-messages.test.ts | 8 +- 50 files changed, 320 insertions(+), 183 deletions(-) create mode 100644 jest/deps.d.ts diff --git a/jest/deps.d.ts b/jest/deps.d.ts new file mode 100644 index 000000000000..a0694f5b8128 --- /dev/null +++ b/jest/deps.d.ts @@ -0,0 +1,17 @@ +/** + * 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. + */ + +// modules only used in tests + +declare module 'to-vfile'; + +declare module 'remark-mdx'; + +declare module '@testing-utils/git' { + const createTempRepo: typeof import('./utils/git').createTempRepo; + export {createTempRepo}; +} diff --git a/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts index 2d5ba57c2b78..47a31c836fc8 100644 --- a/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts @@ -21,7 +21,7 @@ function process(doc: string, plugins: Plugin[] = []) { return removePosition(processor.runSync(processor.parse(doc)), true); } -function heading(label: string, id: string) { +function heading(label: string | null, id: string) { return u( 'heading', {depth: 2, data: {id, hProperties: {id}}}, diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts index e4511f827484..181ddd4f7315 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts @@ -13,15 +13,15 @@ import plugin from '..'; import transformImage, {type PluginOptions} from '../../transformImage'; const processFixture = async (name: string, options?: PluginOptions) => { - const filePath = path.join(__dirname, `__fixtures__/${name}.md`); + const siteDir = path.join(__dirname, `__fixtures__`); const staticDirs = [ - path.join(__dirname, '__fixtures__/static'), - path.join(__dirname, '__fixtures__/static2'), + path.join(siteDir, 'static'), + path.join(siteDir, 'static2'), ]; - const file = await vfile.read(filePath); + const file = await vfile.read(path.join(siteDir, `${name}.md`)); const result = await remark() .use(mdx) - .use(transformImage, {...options, filePath, staticDirs}) + .use(transformImage, {...options, siteDir, staticDirs}) .use(plugin, { ...options, staticDirs, diff --git a/packages/docusaurus-plugin-client-redirects/src/__tests__/options.test.ts b/packages/docusaurus-plugin-client-redirects/src/__tests__/options.test.ts index 1d526c351b4d..6ef2c84d4985 100644 --- a/packages/docusaurus-plugin-client-redirects/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-client-redirects/src/__tests__/options.test.ts @@ -9,7 +9,7 @@ import {normalizePluginOptions} from '@docusaurus/utils-validation'; import {validateOptions, DEFAULT_OPTIONS} from '../options'; import type {Options} from '../options'; -function testValidate(options: Options) { +function testValidate(options?: Options) { return validateOptions({validate: normalizePluginOptions, options}); } diff --git a/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts b/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts index 2ed5d2f1a1b1..32b992c08650 100644 --- a/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts +++ b/packages/docusaurus-plugin-client-redirects/src/__tests__/writeRedirectFiles.test.ts @@ -176,11 +176,11 @@ describe('writeRedirectFiles', () => { await writeRedirectFiles(filesMetadata); await expect( - fs.readFile(filesMetadata[0].fileAbsolutePath, 'utf8'), + fs.readFile(filesMetadata[0]!.fileAbsolutePath, 'utf8'), ).resolves.toBe('content 1'); await expect( - fs.readFile(filesMetadata[1].fileAbsolutePath, 'utf8'), + fs.readFile(filesMetadata[1]!.fileAbsolutePath, 'utf8'), ).resolves.toBe('content 2'); }); @@ -195,7 +195,7 @@ describe('writeRedirectFiles', () => { ]; await fs.outputFile( - filesMetadata[0].fileAbsolutePath, + filesMetadata[0]!.fileAbsolutePath, 'file already exists!', ); diff --git a/packages/docusaurus-plugin-client-redirects/src/options.ts b/packages/docusaurus-plugin-client-redirects/src/options.ts index 72f3da3010bd..389e90b958aa 100644 --- a/packages/docusaurus-plugin-client-redirects/src/options.ts +++ b/packages/docusaurus-plugin-client-redirects/src/options.ts @@ -66,6 +66,6 @@ const UserOptionsSchema = Joi.object({ export function validateOptions({ validate, options: userOptions, -}: OptionValidationContext): PluginOptions { +}: OptionValidationContext): PluginOptions { return validate(UserOptionsSchema, userOptions); } diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap index beb31a882566..729181bd219d 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap @@ -44,11 +44,14 @@ exports[`translateContent falls back when translation is incomplete 1`] = ` ], "blogPosts": [ { + "content": "", "id": "hello", "metadata": { + "authors": [], "date": 2021-07-19T00:00:00.000Z, "description": "/blog/2021/06/19/hello", "formattedDate": "June 19, 2021", + "frontMatter": {}, "permalink": "/blog/2021/06/19/hello", "source": "/blog/2021/06/19/hello", "tags": [], @@ -85,11 +88,14 @@ exports[`translateContent returns translated loaded 1`] = ` ], "blogPosts": [ { + "content": "", "id": "hello", "metadata": { + "authors": [], "date": 2021-07-19T00:00:00.000Z, "description": "/blog/2021/06/19/hello", "formattedDate": "June 19, 2021", + "frontMatter": {}, "permalink": "/blog/2021/06/19/hello", "source": "/blog/2021/06/19/hello", "tags": [], diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts index 1d9cafef920f..2adc44ca9831 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts @@ -211,7 +211,11 @@ describe('linkify', () => { title: 'date-matter', }, truncated: false, + frontMatter: {}, + authors: [], + formattedDate: '', }, + content: '', }, ]; 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 2e5d96872dfe..d7747d16300c 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts @@ -21,6 +21,9 @@ const DefaultI18N: I18n = { defaultLocale: 'en', localeConfigs: { en: { + label: 'English', + direction: 'ltr', + htmlLang: 'en', calendar: 'gregory', }, }, diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts index 36cc680df0e0..7d769afe3f69 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts @@ -56,7 +56,9 @@ function testField(params: { ); } catch (err) { // eslint-disable-next-line jest/no-conditional-expect - expect(err.message).toMatch(new RegExp(escapeStringRegexp(message))); + expect((err as Error).message).toMatch( + new RegExp(escapeStringRegexp(message)), + ); } }); }); 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 384b7014c7ea..0c49808e9c33 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -41,7 +41,14 @@ function getI18n(locale: string): I18n { currentLocale: locale, locales: [locale], defaultLocale: locale, - localeConfigs: {[locale]: {calendar: 'gregory'}}, + localeConfigs: { + [locale]: { + calendar: 'gregory', + label: locale, + htmlLang: locale, + direction: 'ltr', + }, + }, }; } @@ -297,28 +304,28 @@ describe('blog plugin', () => { const siteDir = path.join(__dirname, '__fixtures__', 'website'); const blogPostsFrench = await getBlogPosts(siteDir, {}, getI18n('fr')); expect(blogPostsFrench).toHaveLength(8); - expect(blogPostsFrench[0].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[0]!.metadata.formattedDate).toMatchInlineSnapshot( `"6 mars 2021"`, ); - expect(blogPostsFrench[1].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[1]!.metadata.formattedDate).toMatchInlineSnapshot( `"5 mars 2021"`, ); - expect(blogPostsFrench[2].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[2]!.metadata.formattedDate).toMatchInlineSnapshot( `"16 août 2020"`, ); - expect(blogPostsFrench[3].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[3]!.metadata.formattedDate).toMatchInlineSnapshot( `"15 août 2020"`, ); - expect(blogPostsFrench[4].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[4]!.metadata.formattedDate).toMatchInlineSnapshot( `"27 février 2020"`, ); - expect(blogPostsFrench[5].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[5]!.metadata.formattedDate).toMatchInlineSnapshot( `"2 janvier 2019"`, ); - expect(blogPostsFrench[6].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[6]!.metadata.formattedDate).toMatchInlineSnapshot( `"1 janvier 2019"`, ); - expect(blogPostsFrench[7].metadata.formattedDate).toMatchInlineSnapshot( + expect(blogPostsFrench[7]!.metadata.formattedDate).toMatchInlineSnapshot( `"14 décembre 2018"`, ); }); 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 dd2e562bdabc..61f0da6c99c0 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts @@ -9,7 +9,7 @@ import {normalizePluginOptions} from '@docusaurus/utils-validation'; import {validateOptions, DEFAULT_OPTIONS} from '../options'; import type {Options} from '@docusaurus/plugin-content-blog'; -function testValidate(options: Options) { +function testValidate(options?: Options) { return validateOptions({validate: normalizePluginOptions, options}); } @@ -44,13 +44,14 @@ describe('validateOptions', () => { }); it('accepts valid user options', () => { - const userOptions = { + const userOptions: Options = { ...defaultOptions, routeBasePath: 'myBlog', beforeDefaultRemarkPlugins: [], beforeDefaultRehypePlugins: [markdownPluginsFunctionStub], remarkPlugins: [[markdownPluginsFunctionStub, {option1: '42'}]], rehypePlugins: [ + // @ts-expect-error: it seems to work in practice markdownPluginsObjectStub, [markdownPluginsFunctionStub, {option1: '42'}], ], @@ -73,6 +74,7 @@ describe('validateOptions', () => { expect(() => testValidate({ feedOptions: { + // @ts-expect-error: test type: 'none', }, }), @@ -138,6 +140,7 @@ describe('validateOptions', () => { it('rejects "abcdef" sidebar count', () => { const userOptions = {blogSidebarCount: 'abcdef'}; + // @ts-expect-error: test expect(() => testValidate(userOptions)).toThrowErrorMatchingInlineSnapshot( `""blogSidebarCount" must be one of [ALL, number]"`, ); @@ -153,6 +156,7 @@ describe('validateOptions', () => { it('rejects 42 sidebar title', () => { const userOptions = {blogSidebarTitle: 42}; + // @ts-expect-error: test expect(() => testValidate(userOptions)).toThrowErrorMatchingInlineSnapshot( `""blogSidebarTitle" must be a string"`, ); diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts index a29ae6e3acb7..5056da948215 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts @@ -33,7 +33,10 @@ const sampleBlogPosts: BlogPost[] = [ tags: [], title: 'Hello', truncated: true, + authors: [], + frontMatter: {}, }, + content: '', }, ]; diff --git a/packages/docusaurus-plugin-content-blog/src/options.ts b/packages/docusaurus-plugin-content-blog/src/options.ts index ff06c867dc9d..0375aba578e3 100644 --- a/packages/docusaurus-plugin-content-blog/src/options.ts +++ b/packages/docusaurus-plugin-content-blog/src/options.ts @@ -135,7 +135,7 @@ const PluginOptionSchema = Joi.object({ export function validateOptions({ validate, options, -}: OptionValidationContext): PluginOptions { +}: OptionValidationContext): PluginOptions { const validatedOptions = validate(PluginOptionSchema, options); return validatedOptions; } diff --git a/packages/docusaurus-plugin-content-blog/src/remark/__tests__/footnoteIDFixer.test.ts b/packages/docusaurus-plugin-content-blog/src/remark/__tests__/footnoteIDFixer.test.ts index 2890766350c9..1c757047444b 100644 --- a/packages/docusaurus-plugin-content-blog/src/remark/__tests__/footnoteIDFixer.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/remark/__tests__/footnoteIDFixer.test.ts @@ -13,7 +13,7 @@ import footnoteIDFixer from '../footnoteIDFixer'; const processFixture = async (name: string) => { const filepath = path.join(__dirname, `__fixtures__/${name}.md`); - const result = await mdx(await fs.readFile(filepath), { + const result = await mdx(await fs.readFile(filepath, 'utf8'), { filepath, remarkPlugins: [footnoteIDFixer], }); diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts index 55c50ab0cddf930ca37a38e3b431cfad218d6b70..194ce3c4e46e20344c3dc2a7f279d59ada8235f0 100644 GIT binary patch delta 650 zcmewq@iKaY4wFG4b%_z1H9+SDPtM?J z#3>id`vr?l!INk4?Zzs;f`1!U@r?rSu!!4EULee|`H5gXHdotjULYLE$f!8^qlh|? zyd`rGNY0j(;!?CyD9y{x%P-HHoTwT)Sy*oN6v-{1tppJdBu}MnQJCL0^;}VVvMzu4LM~e^YbZ8 zzQl3_&VIx?7e&@=GbcMMBT(9Yatz0@&4!%bAPz{M+2(s(ml#nLn@_gpZ9s@@=I7Ib ztDZcYe>Y6$ { it('generates the right docs, sidebars, and metadata', () => { @@ -25,7 +26,7 @@ describe('toGlobalDataVersion', () => { sidebar: 'tutorial', frontMatter: {}, }, - ]; + ] as DocMetadata[]; const sidebars: Sidebars = { tutorial: [ { @@ -46,6 +47,8 @@ describe('toGlobalDataVersion', () => { id: 'doc', }, ], + collapsed: false, + collapsible: true, }, ], links: [ @@ -75,6 +78,8 @@ describe('toGlobalDataVersion', () => { id: 'doc', }, ], + collapsed: false, + collapsible: true, }, ], }; @@ -85,7 +90,6 @@ describe('toGlobalDataVersion', () => { label: 'Label', isLast: true, path: '/current', - mainDocId: 'main', docs, drafts: [ { @@ -93,7 +97,7 @@ describe('toGlobalDataVersion', () => { permalink: '/current/draft', sidebar: undefined, }, - ], + ] as DocMetadata[], sidebars, categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({ docs, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index fd25cc85eef9..2f83e3f0b576 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -26,13 +26,28 @@ import * as cliDocs from '../cli'; import {validateOptions} from '../options'; import type {RouteConfig} from '@docusaurus/types'; -import type {LoadedVersion} from '@docusaurus/plugin-content-docs'; -import type {SidebarItem, SidebarItemsGeneratorOption} from '../sidebars/types'; - -function findDocById(version: LoadedVersion, unversionedId: string) { +import type { + LoadedVersion, + PropSidebarItemLink, +} from '@docusaurus/plugin-content-docs'; +import type { + SidebarItemsGeneratorOption, + NormalizedSidebar, +} from '../sidebars/types'; + +function findDocById( + version: LoadedVersion | undefined, + unversionedId: string, +) { + if (!version) { + throw new Error('Version not found'); + } return version.docs.find((item) => item.unversionedId === unversionedId); } -function getDocById(version: LoadedVersion, unversionedId: string) { +function getDocById(version: LoadedVersion | undefined, unversionedId: string) { + if (!version) { + throw new Error('Version not found'); + } const doc = findDocById(version, unversionedId); if (!doc) { throw new Error( @@ -83,7 +98,10 @@ Entries created: getGlobalData: () => globalDataContainer, getRouteConfigs: () => routeConfigs, - checkVersionMetadataPropCreated: (version: LoadedVersion) => { + checkVersionMetadataPropCreated: (version: LoadedVersion | undefined) => { + if (!version) { + throw new Error('Version not found'); + } const versionMetadataProp = getCreatedDataByPrefix( `version-${_.kebabCase(version.versionName)}-metadata-prop`, ); @@ -164,7 +182,7 @@ describe('sidebar', () => { const result = await plugin.loadContent!(); expect(result.loadedVersions).toHaveLength(1); - expect(result.loadedVersions[0].sidebars).toMatchSnapshot(); + expect(result.loadedVersions[0]!.sidebars).toMatchSnapshot(); }); it('site with disabled sidebar', async () => { @@ -182,7 +200,7 @@ describe('sidebar', () => { const result = await plugin.loadContent!(); expect(result.loadedVersions).toHaveLength(1); - expect(result.loadedVersions[0].sidebars).toEqual(DisabledSidebars); + expect(result.loadedVersions[0]!.sidebars).toEqual(DisabledSidebars); }); }); @@ -309,7 +327,7 @@ describe('simple website', () => { expect(getDocById(currentVersion, 'foo/bar')).toMatchSnapshot(); - expect(currentVersion.sidebars).toMatchSnapshot(); + expect(currentVersion!.sidebars).toMatchSnapshot(); const {actions, utils} = createFakeActions(pluginContentDir); @@ -427,10 +445,12 @@ describe('versioned website', () => { expect(getDocById(version101, 'hello')).toMatchSnapshot(); expect(getDocById(version100, 'foo/baz')).toMatchSnapshot(); - expect(currentVersion.sidebars).toMatchSnapshot('current version sidebars'); - expect(version101.sidebars).toMatchSnapshot('101 version sidebars'); - expect(version100.sidebars).toMatchSnapshot('100 version sidebars'); - expect(versionWithSlugs.sidebars).toMatchSnapshot( + expect(currentVersion!.sidebars).toMatchSnapshot( + 'current version sidebars', + ); + expect(version101!.sidebars).toMatchSnapshot('101 version sidebars'); + expect(version100!.sidebars).toMatchSnapshot('100 version sidebars'); + expect(versionWithSlugs!.sidebars).toMatchSnapshot( 'withSlugs version sidebars', ); @@ -534,8 +554,10 @@ describe('versioned website (community)', () => { expect(getDocById(currentVersion, 'team')).toMatchSnapshot(); expect(getDocById(version100, 'team')).toMatchSnapshot(); - expect(currentVersion.sidebars).toMatchSnapshot('current version sidebars'); - expect(version100.sidebars).toMatchSnapshot('100 version sidebars'); + expect(currentVersion!.sidebars).toMatchSnapshot( + 'current version sidebars', + ); + expect(version100!.sidebars).toMatchSnapshot('100 version sidebars'); const {actions, utils} = createFakeActions(pluginContentDir); await plugin.contentLoaded!({ @@ -544,8 +566,8 @@ describe('versioned website (community)', () => { allContent: {}, }); - utils.checkVersionMetadataPropCreated(currentVersion); - utils.checkVersionMetadataPropCreated(version100); + utils.checkVersionMetadataPropCreated(currentVersion!); + utils.checkVersionMetadataPropCreated(version100!); utils.expectSnapshot(); }); @@ -574,18 +596,22 @@ describe('site with doc label', () => { it('label in sidebar.json is used', async () => { const {content} = await loadSite(); - const loadedVersion = content.loadedVersions[0]; + const loadedVersion = content.loadedVersions[0]!; const sidebarProps = toSidebarsProp(loadedVersion); - expect(sidebarProps.docs[0].label).toBe('Hello One'); + expect((sidebarProps.docs![0] as PropSidebarItemLink).label).toBe( + 'Hello One', + ); }); it('sidebar_label in doc has higher precedence over label in sidebar.json', async () => { const {content} = await loadSite(); - const loadedVersion = content.loadedVersions[0]; + const loadedVersion = content.loadedVersions[0]!; const sidebarProps = toSidebarsProp(loadedVersion); - expect(sidebarProps.docs[1].label).toBe('Hello 2 From Doc'); + expect((sidebarProps.docs![1] as PropSidebarItemLink).label).toBe( + 'Hello 2 From Doc', + ); }); }); @@ -614,14 +640,14 @@ describe('site with full autogenerated sidebar', () => { it('sidebar is fully autogenerated', async () => { const {content} = await loadSite(); - const version = content.loadedVersions[0]; + const version = content.loadedVersions[0]!; expect(version.sidebars).toMatchSnapshot(); }); it('docs in fully generated sidebar have correct metadata', async () => { const {content} = await loadSite(); - const version = content.loadedVersions[0]; + const version = content.loadedVersions[0]!; expect(getDocById(version, 'getting-started')).toMatchSnapshot(); expect(getDocById(version, 'installation')).toMatchSnapshot(); @@ -675,14 +701,14 @@ describe('site with partial autogenerated sidebars', () => { it('sidebar is partially autogenerated', async () => { const {content} = await loadSite(); - const version = content.loadedVersions[0]; + const version = content.loadedVersions[0]!; expect(version.sidebars).toMatchSnapshot(); }); it('docs in partially generated sidebar have correct metadata', async () => { const {content} = await loadSite(); - const version = content.loadedVersions[0]; + const version = content.loadedVersions[0]!; // Only looking at the docs of the autogen sidebar, others metadata should // not be affected @@ -731,7 +757,7 @@ describe('site with partial autogenerated sidebars 2 (fix #4638)', () => { it('sidebar is partially autogenerated', async () => { const {content} = await loadSite(); - const version = content.loadedVersions[0]; + const version = content.loadedVersions[0]!; expect(version.sidebars).toMatchSnapshot(); }); @@ -763,8 +789,10 @@ describe('site with custom sidebar items generator', () => { const customSidebarItemsGeneratorMock = jest.fn(async () => []); const {siteDir} = await loadSite(customSidebarItemsGeneratorMock); - const generatorArg: Parameters[0] = - customSidebarItemsGeneratorMock.mock.calls[0][0]; + const generatorArg = ( + customSidebarItemsGeneratorMock.mock + .calls[0] as unknown as Parameters + )[0]; // Make test pass even if docs are in different order and paths are // absolutes @@ -797,12 +825,12 @@ describe('site with custom sidebar items generator', () => { const {content} = await loadSite(customSidebarItemsGenerator); const version = content.loadedVersions[0]; - expect(version.sidebars).toMatchSnapshot(); + expect(version!.sidebars).toMatchSnapshot(); }); it('sidebarItemsGenerator can wrap/enhance/sort/reverse the default sidebar generator', async () => { - function reverseSidebarItems(items: SidebarItem[]): SidebarItem[] { - const result: SidebarItem[] = items.map((item) => { + function reverseSidebarItems(items: NormalizedSidebar): NormalizedSidebar { + const result: NormalizedSidebar = items.map((item) => { if (item.type === 'category') { return {...item, items: reverseSidebarItems(item.items)}; } @@ -821,7 +849,7 @@ describe('site with custom sidebar items generator', () => { }; const {content} = await loadSite(reversedSidebarItemsGenerator); - const version = content.loadedVersions[0]; + const version = content.loadedVersions[0]!; expect(version.sidebars).toMatchSnapshot(); }); 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 a3ddd11f843d..ea4ebf043114 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts @@ -36,7 +36,7 @@ describe('normalizeDocsPluginOptions', () => { }); it('accepts correctly defined user options', () => { - const userOptions = { + const userOptions: Options = { path: 'my-docs', // Path to data on filesystem, relative to site dir. routeBasePath: 'my-docs', // URL Route. tagsBasePath: 'tags', // URL Tags Route. @@ -51,6 +51,7 @@ describe('normalizeDocsPluginOptions', () => { docTagsListComponent: '@theme/DocTagsListPage', docCategoryGeneratedIndexComponent: '@theme/DocCategoryGeneratedIndexPage', + // @ts-expect-error: it seems to work in practice? remarkPlugins: [markdownPluginsObjectStub], rehypePlugins: [markdownPluginsFunctionStub], beforeDefaultRehypePlugins: [], @@ -79,16 +80,17 @@ describe('normalizeDocsPluginOptions', () => { expect(testValidate(userOptions)).toEqual({ ...defaultOptions, ...userOptions, - remarkPlugins: [...userOptions.remarkPlugins, expect.any(Array)], + remarkPlugins: [...userOptions.remarkPlugins!, expect.any(Array)], }); }); it('accepts correctly defined remark and rehype plugin options', () => { - const userOptions = { + const userOptions: Options = { beforeDefaultRemarkPlugins: [], beforeDefaultRehypePlugins: [markdownPluginsFunctionStub], remarkPlugins: [[markdownPluginsFunctionStub, {option1: '42'}]], rehypePlugins: [ + // @ts-expect-error: it seems to work in practice markdownPluginsObjectStub, [markdownPluginsFunctionStub, {option1: '42'}], ], @@ -96,12 +98,12 @@ describe('normalizeDocsPluginOptions', () => { expect(testValidate(userOptions)).toEqual({ ...defaultOptions, ...userOptions, - remarkPlugins: [...userOptions.remarkPlugins, expect.any(Array)], + remarkPlugins: [...userOptions.remarkPlugins!, expect.any(Array)], }); }); it('accepts admonitions false', () => { - const admonitionsFalse = { + const admonitionsFalse: Options = { admonitions: false, }; expect(testValidate(admonitionsFalse)).toEqual({ @@ -111,7 +113,7 @@ describe('normalizeDocsPluginOptions', () => { }); it('rejects admonitions true', () => { - const admonitionsTrue = { + const admonitionsTrue: Options = { admonitions: true, }; expect(() => @@ -124,7 +126,10 @@ describe('normalizeDocsPluginOptions', () => { it('accepts numberPrefixParser function', () => { function customNumberPrefixParser() {} expect( - testValidate({numberPrefixParser: customNumberPrefixParser}), + testValidate({ + numberPrefixParser: + customNumberPrefixParser as unknown as Options['numberPrefixParser'], + }), ).toEqual({ ...defaultOptions, numberPrefixParser: customNumberPrefixParser, @@ -148,6 +153,7 @@ describe('normalizeDocsPluginOptions', () => { it('rejects invalid remark plugin options', () => { expect(() => testValidate({ + // @ts-expect-error: test remarkPlugins: [[{option1: '42'}, markdownPluginsFunctionStub]], }), ).toThrowErrorMatchingInlineSnapshot(` @@ -161,6 +167,7 @@ describe('normalizeDocsPluginOptions', () => { expect(() => testValidate({ rehypePlugins: [ + // @ts-expect-error: test [ markdownPluginsFunctionStub, {option1: '42'}, @@ -176,6 +183,7 @@ describe('normalizeDocsPluginOptions', () => { }); it('rejects bad path inputs', () => { + // @ts-expect-error: test expect(() => testValidate({path: 2})).toThrowErrorMatchingInlineSnapshot( `""path" must be a string"`, ); @@ -183,12 +191,14 @@ describe('normalizeDocsPluginOptions', () => { it('rejects bad include inputs', () => { expect(() => + // @ts-expect-error: test testValidate({include: '**/*.{md,mdx}'}), ).toThrowErrorMatchingInlineSnapshot(`""include" must be an array"`); }); it('rejects bad showLastUpdateTime inputs', () => { expect(() => + // @ts-expect-error: test testValidate({showLastUpdateTime: 'true'}), ).toThrowErrorMatchingInlineSnapshot( `""showLastUpdateTime" must be a boolean"`, @@ -197,12 +207,14 @@ describe('normalizeDocsPluginOptions', () => { it('rejects bad remarkPlugins input', () => { expect(() => + // @ts-expect-error: test testValidate({remarkPlugins: 'remark-math'}), ).toThrowErrorMatchingInlineSnapshot(`""remarkPlugins" must be an array"`); }); it('rejects bad lastVersion', () => { expect(() => + // @ts-expect-error: test testValidate({lastVersion: false}), ).toThrowErrorMatchingInlineSnapshot(`""lastVersion" must be a string"`); }); @@ -212,6 +224,7 @@ describe('normalizeDocsPluginOptions', () => { testValidate({ versions: { current: { + // @ts-expect-error: test hey: 3, }, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/props.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/props.test.ts index 9db11b7cdddb..7103e3908d59 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/props.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/props.test.ts @@ -21,30 +21,30 @@ describe('toTagDocListProp', () => { docIds: ['id1', 'id3'], }; - const doc1: Doc = { + const doc1 = { id: 'id1', title: 'ZZZ 1', description: 'Description 1', permalink: '/doc1', - }; - const doc2: Doc = { + } as Doc; + const doc2 = { id: 'id2', title: 'XXX 2', description: 'Description 2', permalink: '/doc2', - }; - const doc3: Doc = { + } as Doc; + const doc3 = { id: 'id3', title: 'AAA 3', description: 'Description 3', permalink: '/doc3', - }; - const doc4: Doc = { + } as Doc; + const doc4 = { id: 'id4', title: 'UUU 4', description: 'Description 4', permalink: '/doc4', - }; + } as Doc; const result = toTagDocListProp({ allTagsPath, 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 1d7784c63fc7..1d7be06b74dc 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' { Tag, } from '@docusaurus/utils'; import type {Plugin, LoadContext} from '@docusaurus/types'; - import type {Required} from 'utility-types'; + import type {Overwrite, Required} from 'utility-types'; export type Assets = { image?: string; @@ -206,7 +206,22 @@ declare module '@docusaurus/plugin-content-docs' { */ tagsBasePath: string; }; - export type Options = Partial; + export type Options = Partial< + Overwrite< + PluginOptions, + { + /** + * Custom parsing logic to extract number prefixes from file names. Use + * `false` to disable this behavior and leave the docs untouched, and + * `true` to use the default parser. + * + * @param filename One segment of the path, without any slashes. + * @see https://docusaurus.io/docs/sidebar#using-number-prefixes + */ + numberPrefixParser: PluginOptions['numberPrefixParser'] | boolean; + } + > + >; export type SidebarsConfig = import('./sidebars/types').SidebarsConfig; export type VersionMetadata = ContentPaths & { diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts index 4085c9931dc7..60c30b96a889 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/utils.test.ts @@ -100,10 +100,13 @@ describe('createSidebarsUtils', () => { const sidebar4: Sidebar = [ { type: 'category', + collapsed: false, + collapsible: true, + label: 'Related', items: [ - {type: 'link', href: 'https://facebook.com'}, - {type: 'link', href: 'https://reactjs.org'}, - {type: 'link', href: 'https://docusaurus.io'}, + {type: 'link', href: 'https://facebook.com', label: 'Facebook'}, + {type: 'link', href: 'https://reactjs.org', label: 'React'}, + {type: 'link', href: 'https://docusaurus.io', label: 'Docusaurus'}, ], }, { @@ -696,10 +699,10 @@ describe('toNavigationLink', () => { it('with doc items', () => { expect(toNavigationLink({type: 'doc', id: 'doc1'}, docsById)).toEqual( - toDocNavigationLink(docsById.doc1), + toDocNavigationLink(docsById.doc1!), ); expect(toNavigationLink({type: 'doc', id: 'doc2'}, docsById)).toEqual( - toDocNavigationLink(docsById.doc2), + toDocNavigationLink(docsById.doc2!), ); expect(() => toNavigationLink({type: 'doc', id: 'doc3'}, docsById), @@ -724,7 +727,7 @@ describe('toNavigationLink', () => { }, docsById, ), - ).toEqual(toDocNavigationLink(docsById.doc1)); + ).toEqual(toDocNavigationLink(docsById.doc1!)); expect(() => toNavigationLink( { diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts index 773643ba8441..15bb3d06d720 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/index.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils'; import {readVersionsMetadata} from '../index'; import {DEFAULT_OPTIONS} from '../../options'; -import type {I18n} from '@docusaurus/types'; +import type {I18n, LoadContext} from '@docusaurus/types'; import type { PluginOptions, VersionMetadata, @@ -37,7 +37,7 @@ describe('readVersionsMetadata', () => { siteDir: simpleSiteDir, baseUrl: '/', i18n: DefaultI18N, - }; + } as LoadContext; const vCurrent: VersionMetadata = { contentPath: path.join(simpleSiteDir, 'docs'), @@ -198,7 +198,7 @@ describe('readVersionsMetadata', () => { siteDir: versionedSiteDir, baseUrl: '/', i18n: DefaultI18N, - }; + } as LoadContext; const vCurrent: VersionMetadata = { contentPath: path.join(versionedSiteDir, 'docs'), @@ -636,7 +636,7 @@ describe('readVersionsMetadata', () => { siteDir: versionedSiteDir, baseUrl: '/', i18n: DefaultI18N, - }; + } as LoadContext; const vCurrent: VersionMetadata = { contentPath: path.join(versionedSiteDir, 'community'), diff --git a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts index 26fd096caf41..bc34ee51d87f 100644 --- a/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts +++ b/packages/docusaurus-plugin-sitemap/src/__tests__/createSitemap.test.ts @@ -8,6 +8,7 @@ import React from 'react'; import {EnumChangefreq} from 'sitemap'; import createSitemap from '../createSitemap'; +import type {PluginOptions} from '../options'; import type {DocusaurusConfig} from '@docusaurus/types'; describe('createSitemap', () => { @@ -31,7 +32,8 @@ describe('createSitemap', () => { it('empty site', () => expect(async () => { - await createSitemap({} as DocusaurusConfig, [], {}, {}); + // @ts-expect-error: test + await createSitemap({}, [], {}, {} as PluginOptions); }).rejects.toThrow( 'URL in docusaurus.config.js cannot be empty/undefined.', )); @@ -148,6 +150,7 @@ describe('createSitemap', () => { { '/noindex': { meta: { + // @ts-expect-error: bad lib def toComponent: () => [ React.createElement('meta', {name: 'robots', content: 'noindex'}), ], diff --git a/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts b/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts index 8d57746125b9..e48bc9302e49 100644 --- a/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts @@ -23,7 +23,7 @@ describe('validateOptions', () => { }); it('accepts correctly defined user options', () => { - const userOptions = { + const userOptions: Options = { changefreq: 'yearly', priority: 0.9, ignorePatterns: ['/search/**'], @@ -52,9 +52,11 @@ describe('validateOptions', () => { it('rejects bad ignorePatterns inputs', () => { expect(() => + // @ts-expect-error: test testValidate({ignorePatterns: '/search'}), ).toThrowErrorMatchingInlineSnapshot(`""ignorePatterns" must be an array"`); expect(() => + // @ts-expect-error: test testValidate({ignorePatterns: [/^\/search/]}), ).toThrowErrorMatchingInlineSnapshot( `""ignorePatterns[0]" must be a string"`, diff --git a/packages/docusaurus-theme-classic/src/__tests__/translations.test.ts b/packages/docusaurus-theme-classic/src/__tests__/translations.test.ts index 48a2c70f3ff7..ba4d3464ea35 100644 --- a/packages/docusaurus-theme-classic/src/__tests__/translations.test.ts +++ b/packages/docusaurus-theme-classic/src/__tests__/translations.test.ts @@ -9,7 +9,7 @@ import {updateTranslationFileMessages} from '@docusaurus/utils'; import {getTranslationFiles, translateThemeConfig} from '../translations'; import type {ThemeConfig} from '@docusaurus/theme-common'; -const ThemeConfigSample: ThemeConfig = { +const ThemeConfigSample = { colorMode: {}, announcementBar: {}, prism: {}, @@ -47,7 +47,7 @@ const ThemeConfigSample: ThemeConfig = { }, ], }, -}; +} as unknown as ThemeConfig; const ThemeConfigSampleSimpleFooter: ThemeConfig = { ...ThemeConfigSample, diff --git a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts index e7c9d7dcb1b0..dd4eaae6df49 100644 --- a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts @@ -674,7 +674,7 @@ describe('themeConfig', () => { }); it('max config', () => { - const colorMode = { + const colorMode: ThemeConfig['colorMode'] = { defaultMode: 'dark', disableSwitch: false, respectPrefersColorScheme: true, diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index bc9b9c9bbaf3..76861545731f 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1032,10 +1032,10 @@ declare module '@theme/Tabs' { readonly lazy?: boolean; readonly block?: boolean; readonly children: readonly ReactElement[]; - readonly defaultValue?: string | null; + readonly defaultValue?: string | number | null; readonly values?: readonly { - value: string; - label?: string; + value: string | number; + label?: string | number; attributes?: {[key: string]: unknown}; }[]; readonly groupId?: string; diff --git a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx index 8d055ce06e6f..098879881f9e 100644 --- a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx @@ -115,7 +115,7 @@ function TabsComponent(props: Props): JSX.Element { setSelectedValue(newTabValue); if (groupId != null) { - setTabGroupChoices(groupId, newTabValue); + setTabGroupChoices(groupId, String(newTabValue)); } } }; diff --git a/packages/docusaurus-theme-common/src/utils/__tests__/docsUtils.test.tsx b/packages/docusaurus-theme-common/src/utils/__tests__/docsUtils.test.tsx index b8ac8fb9eedd..8f4c48011299 100644 --- a/packages/docusaurus-theme-common/src/utils/__tests__/docsUtils.test.tsx +++ b/packages/docusaurus-theme-common/src/utils/__tests__/docsUtils.test.tsx @@ -26,6 +26,7 @@ import type { PropSidebarItemLink, PropVersionMetadata, } from '@docusaurus/plugin-content-docs'; +import type {DocusaurusContext} from '@docusaurus/types'; // Make tests more readable with some useful category item defaults function testCategory( @@ -294,19 +295,22 @@ describe('isActiveSidebarItem', () => { describe('useSidebarBreadcrumbs', () => { const createUseSidebarBreadcrumbsMock = - (sidebar: PropSidebar, breadcrumbsOption?: boolean) => (location: string) => + (sidebar: PropSidebar | undefined, breadcrumbsOption?: boolean) => + (location: string) => renderHook(() => useSidebarBreadcrumbs(), { wrapper: ({children}) => ( + } as unknown as DocusaurusContext + }> {children} @@ -421,7 +425,9 @@ describe('useSidebarBreadcrumbs', () => { }); it('returns null when there is no sidebar', () => { - expect(createUseSidebarBreadcrumbsMock(null, false)('/foo')).toBeNull(); + expect( + createUseSidebarBreadcrumbsMock(undefined, false)('/foo'), + ).toBeNull(); }); }); @@ -436,9 +442,12 @@ describe('useCurrentSidebarCategory', () => { ), }).result.current; it('works', () => { - const category = { + const category: PropSidebarItemCategory = { type: 'category', + label: 'Category', href: '/cat', + collapsible: true, + collapsed: false, items: [ {type: 'link', href: '/cat/foo', label: 'Foo'}, {type: 'link', href: '/cat/bar', label: 'Bar'}, @@ -453,8 +462,11 @@ describe('useCurrentSidebarCategory', () => { }); it('throws for non-category index page', () => { - const category = { + const category: PropSidebarItemCategory = { type: 'category', + label: 'Category', + collapsible: true, + collapsed: false, items: [ {type: 'link', href: '/cat/foo', label: 'Foo'}, {type: 'link', href: '/cat/bar', label: 'Bar'}, diff --git a/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx b/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx index f7618dbb258c..f789734119f7 100644 --- a/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx +++ b/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx @@ -24,7 +24,7 @@ describe('usePluralForm', () => { i18n: { currentLocale: 'en', }, - }); + } as DocusaurusContext); expect(mockUsePluralForm().selectMessage(1, 'one|many')).toBe('one'); expect(mockUsePluralForm().selectMessage(10, 'one|many')).toBe('many'); }); @@ -34,7 +34,7 @@ describe('usePluralForm', () => { i18n: { currentLocale: 'zh-Hans', }, - }); + } as DocusaurusContext); const consoleMock = jest .spyOn(console, 'error') .mockImplementation(() => {}); @@ -50,7 +50,7 @@ describe('usePluralForm', () => { i18n: { currentLocale: 'en', }, - }); + } as DocusaurusContext); expect(mockUsePluralForm().selectMessage(10, 'many')).toBe('many'); }); @@ -59,7 +59,7 @@ describe('usePluralForm', () => { i18n: { currentLocale: 'zh-Hans', }, - }); + } as DocusaurusContext); const consoleMock = jest .spyOn(console, 'error') .mockImplementation(() => {}); diff --git a/packages/docusaurus-theme-translations/src/__tests__/index.test.ts b/packages/docusaurus-theme-translations/src/__tests__/index.test.ts index af47cd2f1754..571c35474ce6 100644 --- a/packages/docusaurus-theme-translations/src/__tests__/index.test.ts +++ b/packages/docusaurus-theme-translations/src/__tests__/index.test.ts @@ -78,6 +78,7 @@ describe('readDefaultCodeTranslationMessages', () => { it('for empty locale', async () => { await expect( readDefaultCodeTranslationMessages({ + name: 'default', locale: '', dirPath, }), diff --git a/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts b/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts index ca7218ab02ad..5831ad69626b 100644 --- a/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts +++ b/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts @@ -58,7 +58,7 @@ describe('mapAsyncSequential', () => { const timeBefore = Date.now(); await expect( mapAsyncSequential(items, async (item) => { - const itemTimeout = itemToTimeout[item]; + const itemTimeout = itemToTimeout[item]!; itemMapStartsAt[item] = Date.now(); await sleep(itemTimeout); itemMapEndsAt[item] = Date.now(); @@ -72,12 +72,10 @@ describe('mapAsyncSequential', () => { const totalTimeouts = _.sum(Object.values(itemToTimeout)); expect(timeTotal).toBeGreaterThanOrEqual(totalTimeouts - 100); - expect(itemMapStartsAt['1']).toBeGreaterThanOrEqual(0); - expect(itemMapStartsAt['2']).toBeGreaterThanOrEqual( - itemMapEndsAt['1'] - 100, - ); + expect(itemMapStartsAt[1]).toBeGreaterThanOrEqual(0); + expect(itemMapStartsAt[2]).toBeGreaterThanOrEqual(itemMapEndsAt[1]! - 100); expect(itemMapStartsAt['3']).toBeGreaterThanOrEqual( - itemMapEndsAt['2'] - 100, + itemMapEndsAt[2]! - 100, ); }); }); diff --git a/packages/docusaurus-utils/src/__tests__/webpackUtils.test.ts b/packages/docusaurus-utils/src/__tests__/webpackUtils.test.ts index f4ce3578bf1b..3d2c70f68924 100644 --- a/packages/docusaurus-utils/src/__tests__/webpackUtils.test.ts +++ b/packages/docusaurus-utils/src/__tests__/webpackUtils.test.ts @@ -10,7 +10,7 @@ import {getFileLoaderUtils} from '../webpackUtils'; describe('getFileLoaderUtils()', () => { it('plugin svgo/removeViewBox and removeTitle should be disabled', () => { const {oneOf} = getFileLoaderUtils().rules.svg(); - expect(oneOf[0].use).toContainEqual( + expect(oneOf![0]!.use).toContainEqual( expect.objectContaining({ loader: require.resolve('@svgr/webpack'), options: expect.objectContaining({ diff --git a/packages/docusaurus/src/client/__tests__/flat.test.ts b/packages/docusaurus/src/client/__tests__/flat.test.ts index 54c252393dd1..358a0c547d16 100644 --- a/packages/docusaurus/src/client/__tests__/flat.test.ts +++ b/packages/docusaurus/src/client/__tests__/flat.test.ts @@ -46,7 +46,7 @@ describe('flat', () => { expect( flat({ foo: { - bar: value, + bar: value as string, }, }), ).toEqual({ diff --git a/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts b/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts index fad94198575c..fcc23ba63cd3 100644 --- a/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts +++ b/packages/docusaurus/src/client/__tests__/normalizeLocation.test.ts @@ -7,13 +7,14 @@ import {jest} from '@jest/globals'; import normalizeLocation from '../normalizeLocation'; +import type {Location} from 'history'; describe('normalizeLocation', () => { it('rewrites locations with index.html', () => { expect( normalizeLocation({ pathname: '/index.html', - }), + } as Location), ).toEqual({ pathname: '/', }); @@ -23,7 +24,7 @@ describe('normalizeLocation', () => { pathname: '/docs/introduction/index.html', search: '?search=foo', hash: '#features', - }), + } as Location), ).toEqual({ pathname: '/docs/introduction', search: '?search=foo', @@ -35,7 +36,7 @@ describe('normalizeLocation', () => { pathname: '/index.html', search: '', hash: '#features', - }), + } as Location), ).toEqual({ pathname: '/', search: '', @@ -47,7 +48,7 @@ describe('normalizeLocation', () => { expect( normalizeLocation({ pathname: '/docs/installation.html', - }), + } as Location), ).toEqual({ pathname: '/docs/installation', }); @@ -56,7 +57,7 @@ describe('normalizeLocation', () => { pathname: '/docs/introduction/foo.html', search: '', hash: '#bar', - }), + } as Location), ).toEqual({ pathname: '/docs/introduction/foo', search: '', @@ -65,7 +66,7 @@ describe('normalizeLocation', () => { }); it('does not strip extension if the route location has one', () => { - expect(normalizeLocation({pathname: '/page.html'})).toEqual({ + expect(normalizeLocation({pathname: '/page.html'} as Location)).toEqual({ pathname: '/page.html', }); }); @@ -78,7 +79,7 @@ describe('normalizeLocation', () => { pathname: '/docs/introduction', search: '', hash: '#features', - }), + } as Location), ).toEqual({ pathname: '/docs/introduction', search: '', @@ -91,7 +92,7 @@ describe('normalizeLocation', () => { pathname: '/docs/introduction', search: '', hash: '#features', - }), + } as Location), ).toEqual({ pathname: '/docs/introduction', search: '', @@ -102,7 +103,7 @@ describe('normalizeLocation', () => { expect( normalizeLocation({ pathname: '/', - }), + } as Location), ).toEqual({ pathname: '/', }); diff --git a/packages/docusaurus/src/client/exports/__tests__/Interpolate.test.tsx b/packages/docusaurus/src/client/exports/__tests__/Interpolate.test.tsx index 57f944d58b8f..d21b296f1253 100644 --- a/packages/docusaurus/src/client/exports/__tests__/Interpolate.test.tsx +++ b/packages/docusaurus/src/client/exports/__tests__/Interpolate.test.tsx @@ -31,7 +31,7 @@ describe('interpolate', () => { object: {hello: 'world'}, array: ['Hello'], }; - // Do we need to improve the JS type -> String conversion logic here? + // @ts-expect-error: test expect(interpolate(text, values)).toMatchInlineSnapshot( `"42 Hello [object Object] Hello"`, ); @@ -52,6 +52,7 @@ describe('interpolate', () => { // Should we emit warnings in such case? const text = 'Hello {name} how are you {unprovidedValue}?'; const values = {name: 'Sébastien', extraValue: 'today'}; + // @ts-expect-error: test expect(interpolate(text, values)).toMatchInlineSnapshot( `"Hello Sébastien how are you {unprovidedValue}?"`, ); @@ -61,6 +62,7 @@ describe('interpolate', () => { // Should we emit warnings in such case? const text = 'Hello {name} how are you {day}?'; expect(interpolate(text)).toEqual(text); + // @ts-expect-error: test expect(interpolate(text, {})).toEqual(text); }); @@ -84,6 +86,7 @@ describe('interpolate', () => { extraUselessValue1:
    test
    , extraUselessValue2: 'hi', }; + // @ts-expect-error: test expect(interpolate(text, values)).toMatchSnapshot(); }); }); @@ -133,6 +136,7 @@ describe('', () => { `"The Docusaurus component only accept simple string values. Received: React element"`, ); expect(() => + // @ts-expect-error: test renderer.create({null}), ).toThrowErrorMatchingInlineSnapshot( `"The Docusaurus component only accept simple string values. Received: object"`, diff --git a/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx b/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx index 5478f7c358f9..1c6724da3069 100644 --- a/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx +++ b/packages/docusaurus/src/client/exports/__tests__/useBaseUrl.test.tsx @@ -28,7 +28,7 @@ describe('useBaseUrl', () => { baseUrl: '/', url: 'https://docusaurus.io', }, - }); + } as DocusaurusContext); expect(mockUseBaseUrl('hello')).toBe('/hello'); expect(mockUseBaseUrl('/hello')).toBe('/hello'); @@ -56,7 +56,7 @@ describe('useBaseUrl', () => { baseUrl: '/docusaurus/', url: 'https://docusaurus.io', }, - }); + } as DocusaurusContext); expect(mockUseBaseUrl('')).toBe(''); expect(mockUseBaseUrl('hello')).toBe('/docusaurus/hello'); @@ -97,7 +97,7 @@ describe('useBaseUrlUtils().withBaseUrl()', () => { baseUrl: '/', url: 'https://docusaurus.io', }, - }); + } as DocusaurusContext); expect(withBaseUrl('hello')).toBe('/hello'); expect(withBaseUrl('/hello')).toBe('/hello'); @@ -125,7 +125,7 @@ describe('useBaseUrlUtils().withBaseUrl()', () => { baseUrl: '/docusaurus/', url: 'https://docusaurus.io', }, - }); + } as DocusaurusContext); expect(withBaseUrl('hello')).toBe('/docusaurus/hello'); expect(withBaseUrl('/hello')).toBe('/docusaurus/hello'); diff --git a/packages/docusaurus/src/server/plugins/__tests__/index.test.ts b/packages/docusaurus/src/server/plugins/__tests__/index.test.ts index 7e3ae0f428e2..148e20fa46a6 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/index.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/index.test.ts @@ -7,6 +7,7 @@ import path from 'path'; import {loadPlugins} from '..'; +import type {Props} from '@docusaurus/types'; describe('loadPlugins', () => { it('loads plugins', async () => { @@ -16,7 +17,6 @@ describe('loadPlugins', () => { siteDir, generatedFilesDir: path.join(siteDir, '.docusaurus'), outDir: path.join(siteDir, 'build'), - // @ts-expect-error: good enough siteConfig: { baseUrl: '/', trailingSlash: true, @@ -51,7 +51,7 @@ describe('loadPlugins', () => { ], }, siteConfigPath: path.join(siteDir, 'docusaurus.config.js'), - }), + } as unknown as Props), ).resolves.toMatchSnapshot(); }); }); diff --git a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts index 30fe4cb603a9..249b5af2bf54 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts @@ -24,14 +24,14 @@ describe('initPlugins', () => { expect(context.siteConfig.plugins).toHaveLength(4); expect(plugins).toHaveLength(8); - expect(plugins[0].name).toBe('preset-plugin1'); - expect(plugins[1].name).toBe('preset-plugin2'); - expect(plugins[2].name).toBe('preset-theme1'); - expect(plugins[3].name).toBe('preset-theme2'); - expect(plugins[4].name).toBe('first-plugin'); - expect(plugins[5].name).toBe('second-plugin'); - expect(plugins[6].name).toBe('third-plugin'); - expect(plugins[7].name).toBe('fourth-plugin'); + expect(plugins[0]!.name).toBe('preset-plugin1'); + expect(plugins[1]!.name).toBe('preset-plugin2'); + expect(plugins[2]!.name).toBe('preset-theme1'); + expect(plugins[3]!.name).toBe('preset-theme2'); + expect(plugins[4]!.name).toBe('first-plugin'); + expect(plugins[5]!.name).toBe('second-plugin'); + expect(plugins[6]!.name).toBe('third-plugin'); + expect(plugins[7]!.name).toBe('fourth-plugin'); expect(context.siteConfig.themeConfig).toEqual({a: 1}); }); diff --git a/packages/docusaurus/src/server/plugins/__tests__/pluginIds.test.ts b/packages/docusaurus/src/server/plugins/__tests__/pluginIds.test.ts index a6315f59a813..e01417689a12 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/pluginIds.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/pluginIds.test.ts @@ -8,12 +8,11 @@ import {ensureUniquePluginInstanceIds} from '../pluginIds'; import type {InitializedPlugin} from '@docusaurus/types'; -function createTestPlugin(name: string, id?: string): InitializedPlugin { - // @ts-expect-error: good enough for tests +function createTestPlugin(name: string, id?: string) { return { name, - options: {id}, - }; + options: {id: id ?? 'default'}, + } as InitializedPlugin; } describe('ensureUniquePluginInstanceIds', () => { diff --git a/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts b/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts index 10d50a29506a..c91709df62df 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts @@ -62,7 +62,7 @@ describe('loadPresets', () => { [path.join(__dirname, '__fixtures__/presets/preset-plugins.js')], ], }, - } as Partial; + } as unknown as LoadContext; const presets = await loadPresets(context); expect(presets).toMatchSnapshot(); }); @@ -78,7 +78,7 @@ describe('loadPresets', () => { ], ], }, - } as Partial; + } as unknown as LoadContext; const presets = await loadPresets(context); expect(presets).toMatchSnapshot(); }); @@ -98,7 +98,7 @@ describe('loadPresets', () => { ], ], }, - } as Partial; + } as unknown as LoadContext; const presets = await loadPresets(context); expect(presets).toMatchSnapshot(); }); diff --git a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts index f34318cd4707..7ced1c70b5c2 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts @@ -20,6 +20,7 @@ import { } from '../translations'; import type { InitializedPlugin, + LoadedPlugin, TranslationFile, TranslationFileContent, } from '@docusaurus/types'; @@ -399,7 +400,7 @@ describe('writePluginTranslations', () => { options: { id: 'my-plugin-id', }, - }, + } as LoadedPlugin, options: {}, }), @@ -426,11 +427,10 @@ describe('localizePluginTranslationFile', () => { siteDir, locale: 'fr', translationFile, - // @ts-expect-error: enough for this test plugin: { name: 'my-plugin-name', options: {}, - }, + } as LoadedPlugin, }); expect(localizedTranslationFile).toEqual(translationFile); @@ -466,11 +466,10 @@ describe('localizePluginTranslationFile', () => { siteDir, locale: 'fr', translationFile, - // @ts-expect-error: enough for this test plugin: { name: 'my-plugin-name', options: {}, - }, + } as LoadedPlugin, }); expect(localizedTranslationFile).toEqual({ @@ -521,25 +520,30 @@ describe('readCodeTranslationFileContent', () => { it('fails for invalid translation file content', async () => { await expect(() => + // @ts-expect-error: test testReadTranslation('HEY'), ).rejects.toThrowErrorMatchingInlineSnapshot( `""value" must be of type object"`, ); await expect(() => + // @ts-expect-error: test testReadTranslation(42), ).rejects.toThrowErrorMatchingInlineSnapshot( `""value" must be of type object"`, ); await expect(() => + // @ts-expect-error: test testReadTranslation({key: {description: 'no message'}}), ).rejects.toThrowErrorMatchingInlineSnapshot(`""key.message" is required"`); await expect(() => + // @ts-expect-error: test testReadTranslation({key: {message: 42}}), ).rejects.toThrowErrorMatchingInlineSnapshot( `""key.message" must be a string"`, ); await expect(() => testReadTranslation({ + // @ts-expect-error: test key: {message: 'Message', description: 42}, }), ).rejects.toThrowErrorMatchingInlineSnapshot( diff --git a/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts b/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts index e06bc5f57d1f..ac74f839ea2e 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts @@ -15,7 +15,7 @@ import { extractSiteSourceCodeTranslations, } from '../translationsExtractor'; import {getBabelOptions} from '../../../webpack/utils'; -import type {InitializedPlugin} from '@docusaurus/types'; +import type {InitializedPlugin, LoadedPlugin} from '@docusaurus/types'; const TestBabelOptions = getBabelOptions({ isServer: true, @@ -693,7 +693,7 @@ export default function MyComponent(props: Props) { plugin1, plugin2, {name: 'dummy', options: {}, version: {type: 'synthetic'}} as const, - ]; + ] as LoadedPlugin[]; const translations = await extractSiteSourceCodeTranslations( siteDir, plugins, diff --git a/packages/docusaurus/src/webpack/__tests__/base.test.ts b/packages/docusaurus/src/webpack/__tests__/base.test.ts index 3e39adfda435..469d6a5540a5 100644 --- a/packages/docusaurus/src/webpack/__tests__/base.test.ts +++ b/packages/docusaurus/src/webpack/__tests__/base.test.ts @@ -63,7 +63,7 @@ describe('babel transpilation exclude logic', () => { }); describe('base webpack config', () => { - const props: Props = { + const props = { outDir: '', siteDir: path.resolve(__dirname, '__fixtures__', 'base_test_site'), siteConfig: {staticDirectories: ['static']}, @@ -98,7 +98,7 @@ describe('base webpack config', () => { }, }, ], - }; + } as Props; afterEach(() => { jest.restoreAllMocks(); diff --git a/packages/docusaurus/src/webpack/__tests__/server.test.ts b/packages/docusaurus/src/webpack/__tests__/server.test.ts index b722f46f7dd0..f3207fdc2fe2 100644 --- a/packages/docusaurus/src/webpack/__tests__/server.test.ts +++ b/packages/docusaurus/src/webpack/__tests__/server.test.ts @@ -15,7 +15,11 @@ describe('webpack production config', () => { it('simple', async () => { jest.spyOn(console, 'log').mockImplementation(() => {}); const props = await loadSetup('simple'); - const config = await createServerConfig({props}); + const config = await createServerConfig({ + props, + onHeadTagsCollected: () => {}, + onLinksCollected: () => {}, + }); const errors = webpack.validate(config); expect(errors).toBeUndefined(); }); @@ -23,7 +27,11 @@ describe('webpack production config', () => { it('custom', async () => { jest.spyOn(console, 'log').mockImplementation(() => {}); const props = await loadSetup('custom'); - const config = await createServerConfig({props}); + const config = await createServerConfig({ + props, + onHeadTagsCollected: () => {}, + onLinksCollected: () => {}, + }); const errors = webpack.validate(config); expect(errors).toBeUndefined(); }); diff --git a/packages/docusaurus/src/webpack/__tests__/utils.test.ts b/packages/docusaurus/src/webpack/__tests__/utils.test.ts index 411ed9180469..f5366ded41c1 100644 --- a/packages/docusaurus/src/webpack/__tests__/utils.test.ts +++ b/packages/docusaurus/src/webpack/__tests__/utils.test.ts @@ -60,6 +60,7 @@ describe('extending generated webpack config', () => { }, }; + // @ts-expect-error: Testing an edge-case that we did not write types for const configureWebpack: Plugin['configureWebpack'] = ( generatedConfig, isServer, @@ -125,14 +126,16 @@ describe('extending generated webpack config', () => { }, }; - const createConfigureWebpack: (mergeStrategy?: { - [key: string]: 'prepend' | 'append'; - }) => Plugin['configureWebpack'] = (mergeStrategy) => () => ({ - module: { - rules: [{use: 'zzz'}], - }, - mergeStrategy, - }); + const createConfigureWebpack = + (mergeStrategy?: { + [key: string]: 'prepend' | 'append'; + }): Plugin['configureWebpack'] => + () => ({ + module: { + rules: [{use: 'zzz'}], + }, + mergeStrategy, + }); const defaultStrategyMergeConfig = applyConfigureWebpack( createConfigureWebpack(), diff --git a/packages/eslint-plugin/src/rules/__tests__/no-untranslated-text.test.ts b/packages/eslint-plugin/src/rules/__tests__/no-untranslated-text.test.ts index 869605a48c68..dc287f602c3a 100644 --- a/packages/eslint-plugin/src/rules/__tests__/no-untranslated-text.test.ts +++ b/packages/eslint-plugin/src/rules/__tests__/no-untranslated-text.test.ts @@ -8,12 +8,7 @@ import rule from '../no-untranslated-text'; import {getCommonValidTests, RuleTester} from './testUtils'; -const errorsJSX = [ - {messageId: 'translateChildren', type: 'JSXElement'}, -] as const; -const errorsJSXFragment = [ - {messageId: 'translateChildren', type: 'JSXFragment'}, -]; +const errorsJSX = [{messageId: 'translateChildren'}] as const; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -110,7 +105,7 @@ ruleTester.run('no-untranslated-text', rule, { }, { code: '<>text', - errors: errorsJSXFragment, + errors: errorsJSX, }, { code: '· — ×', diff --git a/packages/eslint-plugin/src/rules/__tests__/string-literal-i18n-messages.test.ts b/packages/eslint-plugin/src/rules/__tests__/string-literal-i18n-messages.test.ts index d836979acd22..066017931d7a 100644 --- a/packages/eslint-plugin/src/rules/__tests__/string-literal-i18n-messages.test.ts +++ b/packages/eslint-plugin/src/rules/__tests__/string-literal-i18n-messages.test.ts @@ -8,12 +8,8 @@ import rule from '../string-literal-i18n-messages'; import {getCommonValidTests, RuleTester} from './testUtils'; -const errorsJSX = [ - {messageId: 'translateChildren', type: 'JSXElement'}, -] as const; -const errorsFunc = [ - {messageId: 'translateArg', type: 'CallExpression'}, -] as const; +const errorsJSX = [{messageId: 'translateChildren'}] as const; +const errorsFunc = [{messageId: 'translateArg'}] as const; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', From d50fe3b670a55688e5593a44f753bc5b6e75eb80 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Wed, 25 May 2022 14:01:10 +0800 Subject: [PATCH 06/43] test: fix ALL type errors in tests (#7487) --- .../src/__tests__/index.test.ts | 13 ++- .../src/__tests__/options.test.ts | 11 +- .../__snapshots__/translations.test.ts.snap | 66 ++++++++++- .../src/__tests__/index.test.ts | 37 ++++--- .../src/__tests__/options.test.ts | 8 +- .../src/__tests__/translations.test.ts | 10 +- .../client/__tests__/docsClientUtils.test.ts | 47 ++++++-- .../src/markdown/__tests__/linkify.test.ts | 8 +- .../src/sidebars/__tests__/generator.test.ts | 103 +++++++++++++----- .../src/sidebars/__tests__/index.test.ts | 17 +-- .../sidebars/__tests__/normalization.test.ts | 5 + .../sidebars/__tests__/postProcessor.test.ts | 17 +-- .../src/sidebars/__tests__/processor.test.ts | 8 +- .../src/sidebars/postProcessor.ts | 2 +- .../src/__tests__/options.test.ts | 18 ++- .../src/__tests__/validateThemeConfig.test.ts | 4 +- .../src/theme-classic.d.ts | 6 +- .../src/theme/Tabs/__tests__/index.test.tsx | 3 + .../src/utils/__tests__/generalUtils.test.tsx | 2 +- .../__tests__/useAlternatePageUtils.test.tsx | 8 +- .../utils/__tests__/useLocalPathname.test.tsx | 4 +- .../utils/__tests__/usePluralForm.test.tsx | 5 +- .../exports/__tests__/useGlobalData.test.tsx | 46 ++++++-- .../swizzle/__tests__/actions.test.ts | 2 +- .../commands/swizzle/__tests__/index.test.ts | 6 +- .../server/__tests__/clientModules.test.ts | 12 +- .../server/__tests__/configValidation.test.ts | 25 +++-- .../src/server/__tests__/htmlTags.test.ts | 23 ++-- .../src/server/__tests__/i18n.test.ts | 2 +- .../src/server/__tests__/siteMetadata.test.ts | 5 +- .../src/server/__tests__/utils.test.ts | 4 +- .../server/plugins/__tests__/index.test.ts | 37 ++++--- .../server/plugins/__tests__/presets.test.ts | 3 +- .../__tests__/translations.test.ts | 11 +- .../__tests__/translationsExtractor.test.ts | 2 +- .../src/webpack/__tests__/utils.test.ts | 8 +- .../webpack/aliases/__tests__/index.test.ts | 3 +- 37 files changed, 407 insertions(+), 184 deletions(-) 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 0c49808e9c33..47d4b98fd4e0 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -11,9 +11,15 @@ import {normalizePluginOptions} from '@docusaurus/utils-validation'; import {posixPath, getFileCommitDate} from '@docusaurus/utils'; import pluginContentBlog from '../index'; import {validateOptions} from '../options'; -import type {DocusaurusConfig, LoadContext, I18n} from '@docusaurus/types'; +import type { + DocusaurusConfig, + LoadContext, + I18n, + Validate, +} from '@docusaurus/types'; import type { BlogPost, + Options, PluginOptions, EditUrlFunction, } from '@docusaurus/plugin-content-blog'; @@ -77,7 +83,10 @@ const getPlugin = async ( i18n, } as LoadContext, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate< + Options | undefined, + PluginOptions + >, options: { path: PluginPath, editUrl: BaseEditUrl, 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 61f0da6c99c0..92eae01ae547 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/options.test.ts @@ -7,10 +7,17 @@ import {normalizePluginOptions} from '@docusaurus/utils-validation'; import {validateOptions, DEFAULT_OPTIONS} from '../options'; -import type {Options} from '@docusaurus/plugin-content-blog'; +import type {Options, PluginOptions} from '@docusaurus/plugin-content-blog'; +import type {Validate} from '@docusaurus/types'; function testValidate(options?: Options) { - return validateOptions({validate: normalizePluginOptions, options}); + return validateOptions({ + validate: normalizePluginOptions as Validate< + Options | undefined, + PluginOptions + >, + options, + }); } // The type of remark/rehype plugins can be either function, object or array diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap index b952835b06d0..4098aeb59399 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap @@ -84,11 +84,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` { "loadedVersions": [ { + "badge": true, + "banner": null, + "className": "", "contentPath": "any", "contentPathLocalized": "any", "docs": [ { "description": "doc1 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc1 title", @@ -101,12 +105,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc1 title", "unversionedId": "any", "version": "any", }, { "description": "doc2 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc2 title", @@ -119,12 +126,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc2 title", "unversionedId": "any", "version": "any", }, { "description": "doc3 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc3 title", @@ -137,12 +147,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc3 title", "unversionedId": "any", "version": "any", }, { "description": "doc4 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc4 title", @@ -155,12 +168,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc4 title", "unversionedId": "any", "version": "any", }, { "description": "doc5 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc5 title", @@ -173,14 +189,16 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc5 title", "unversionedId": "any", "version": "any", }, ], + "drafts": [], "isLast": true, "label": "current label (translated)", - "mainDocId": "", "path": "/docs/", "routePriority": undefined, "sidebarFilePath": "any", @@ -188,6 +206,7 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "docs": [ { "collapsed": false, + "collapsible": true, "items": [ { "id": "doc1", @@ -233,14 +252,19 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` }, ], }, + "tagsPath": "/tags/", "versionName": "current", }, { + "badge": true, + "banner": null, + "className": "", "contentPath": "any", "contentPathLocalized": "any", "docs": [ { "description": "doc1 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc1 title", @@ -253,12 +277,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc1 title", "unversionedId": "any", "version": "any", }, { "description": "doc2 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc2 title", @@ -271,12 +298,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc2 title", "unversionedId": "any", "version": "any", }, { "description": "doc3 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc3 title", @@ -289,12 +319,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc3 title", "unversionedId": "any", "version": "any", }, { "description": "doc4 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc4 title", @@ -307,12 +340,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc4 title", "unversionedId": "any", "version": "any", }, { "description": "doc5 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc5 title", @@ -325,14 +361,16 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc5 title", "unversionedId": "any", "version": "any", }, ], + "drafts": [], "isLast": true, "label": "2.0.0 label (translated)", - "mainDocId": "", "path": "/docs/", "routePriority": undefined, "sidebarFilePath": "any", @@ -340,6 +378,7 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "docs": [ { "collapsed": false, + "collapsible": true, "items": [ { "id": "doc1", @@ -385,14 +424,19 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` }, ], }, + "tagsPath": "/tags/", "versionName": "2.0.0", }, { + "badge": true, + "banner": null, + "className": "", "contentPath": "any", "contentPathLocalized": "any", "docs": [ { "description": "doc1 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc1 title", @@ -405,12 +449,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc1 title", "unversionedId": "any", "version": "any", }, { "description": "doc2 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc2 title", @@ -423,12 +470,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc2 title", "unversionedId": "any", "version": "any", }, { "description": "doc3 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc3 title", @@ -441,12 +491,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc3 title", "unversionedId": "any", "version": "any", }, { "description": "doc4 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc4 title", @@ -459,12 +512,15 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc4 title", "unversionedId": "any", "version": "any", }, { "description": "doc5 description", + "draft": false, "editUrl": "any", "frontMatter": { "sidebar_label": "doc5 title", @@ -477,14 +533,16 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "previous": undefined, "slug": "any", "source": "any", + "sourceDirName": "", + "tags": [], "title": "doc5 title", "unversionedId": "any", "version": "any", }, ], + "drafts": [], "isLast": true, "label": "1.0.0 label (translated)", - "mainDocId": "", "path": "/docs/", "routePriority": undefined, "sidebarFilePath": "any", @@ -492,6 +550,7 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` "docs": [ { "collapsed": false, + "collapsible": true, "items": [ { "id": "doc1", @@ -537,6 +596,7 @@ exports[`translateLoadedContent returns translated loaded content 1`] = ` }, ], }, + "tagsPath": "/tags/", "versionName": "1.0.0", }, ], diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index 2f83e3f0b576..746288ca95e9 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -25,9 +25,11 @@ import {DisabledSidebars} from '../sidebars'; import * as cliDocs from '../cli'; import {validateOptions} from '../options'; -import type {RouteConfig} from '@docusaurus/types'; +import type {RouteConfig, Validate, Plugin} from '@docusaurus/types'; import type { LoadedVersion, + Options, + PluginOptions, PropSidebarItemLink, } from '@docusaurus/plugin-content-docs'; import type { @@ -133,7 +135,7 @@ describe('sidebar', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { sidebarPath, }, @@ -150,7 +152,7 @@ describe('sidebar', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { sidebarPath: 'wrong-path-sidebar.json', }, @@ -173,7 +175,7 @@ describe('sidebar', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { sidebarPath: undefined, }, @@ -191,7 +193,7 @@ describe('sidebar', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { sidebarPath: false, }, @@ -212,7 +214,10 @@ describe('empty/no docs website', () => { await fs.ensureDir(path.join(siteDir, 'docs')); const plugin = await pluginContentDocs( context, - validateOptions({validate: normalizePluginOptions, options: {}}), + validateOptions({ + validate: normalizePluginOptions as Validate, + options: {}, + }), ); await expect( plugin.loadContent!(), @@ -227,7 +232,7 @@ describe('empty/no docs website', () => { pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { path: 'path/does/not/exist', }, @@ -245,7 +250,7 @@ describe('simple website', () => { const context = await loadContext({siteDir}); const sidebarPath = path.join(siteDir, 'sidebars.json'); const options = validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { path: 'docs', sidebarPath, @@ -299,7 +304,7 @@ describe('simple website', () => { const content = await plugin.loadContent?.(); const config = applyConfigureWebpack( - plugin.configureWebpack, + plugin.configureWebpack as NonNullable, { entry: './src/index.js', output: { @@ -352,7 +357,7 @@ describe('versioned website', () => { const sidebarPath = path.join(siteDir, 'sidebars.json'); const routeBasePath = 'docs'; const options = validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { routeBasePath, sidebarPath, @@ -478,7 +483,7 @@ describe('versioned website (community)', () => { const routeBasePath = 'community'; const pluginId = 'community'; const options = validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { id: 'community', path: 'community', @@ -581,7 +586,7 @@ describe('site with doc label', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { path: 'docs', sidebarPath, @@ -626,7 +631,7 @@ describe('site with full autogenerated sidebar', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { path: 'docs', }, @@ -681,7 +686,7 @@ describe('site with partial autogenerated sidebars', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { path: 'docs', sidebarPath: path.join( @@ -737,7 +742,7 @@ describe('site with partial autogenerated sidebars 2 (fix #4638)', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { path: 'docs', sidebarPath: path.join( @@ -774,7 +779,7 @@ describe('site with custom sidebar items generator', () => { const plugin = await pluginContentDocs( context, validateOptions({ - validate: normalizePluginOptions, + validate: normalizePluginOptions as Validate, options: { path: 'docs', sidebarItemsGenerator, 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 ea4ebf043114..534eb3712000 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts @@ -13,14 +13,18 @@ import { DefaultNumberPrefixParser, DisabledNumberPrefixParser, } from '../numberPrefix'; -import type {Options} from '@docusaurus/plugin-content-docs'; +import type {Options, PluginOptions} from '@docusaurus/plugin-content-docs'; +import type {Validate} from '@docusaurus/types'; // The type of remark/rehype plugins can be function/object const markdownPluginsFunctionStub = () => {}; const markdownPluginsObjectStub = {}; function testValidate(options: Options) { - return validateOptions({validate: normalizePluginOptions, options}); + return validateOptions({ + validate: normalizePluginOptions as Validate, + options, + }); } const defaultOptions = { diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts index a79409ba8d84..fb099e8eb63d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts @@ -19,6 +19,9 @@ import type { function createSampleDoc(doc: Pick): DocMetadata { return { + sourceDirName: '', + draft: false, + tags: [], editUrl: 'any', lastUpdatedAt: 0, lastUpdatedBy: 'any', @@ -44,12 +47,16 @@ function createSampleVersion( return { label: `${version.versionName} label`, path: '/docs/', - mainDocId: '', routePriority: undefined, sidebarFilePath: 'any', isLast: true, contentPath: 'any', contentPathLocalized: 'any', + tagsPath: '/tags/', + banner: null, + badge: true, + className: '', + drafts: [], docs: [ createSampleDoc({id: 'doc1'}), createSampleDoc({id: 'doc2'}), @@ -63,6 +70,7 @@ function createSampleVersion( type: 'category', label: 'Getting started', collapsed: false, + collapsible: true, link: { type: 'generated-index', slug: '/category/getting-started-index-slug', diff --git a/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsClientUtils.test.ts b/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsClientUtils.test.ts index 093aaad1db93..16fc4e7a9c80 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsClientUtils.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsClientUtils.test.ts @@ -17,6 +17,7 @@ import type { GlobalPluginData, GlobalVersion, ActivePlugin, + GlobalDoc, } from '@docusaurus/plugin-content-docs/client'; describe('docsClientUtils', () => { @@ -25,10 +26,12 @@ describe('docsClientUtils', () => { pluginIosId: { path: '/ios', versions: [], + breadcrumbs: true, }, pluginAndroidId: { path: '/android', versions: [], + breadcrumbs: true, }, }; @@ -48,7 +51,7 @@ describe('docsClientUtils', () => { const activePluginIos: ActivePlugin = { pluginId: 'pluginIosId', - pluginData: data.pluginIosId, + pluginData: data.pluginIosId!, }; expect(getActivePlugin(data, '/ios')).toEqual(activePluginIos); expect(getActivePlugin(data, '/ios/')).toEqual(activePluginIos); @@ -56,38 +59,42 @@ describe('docsClientUtils', () => { const activePluginAndroid: ActivePlugin = { pluginId: 'pluginAndroidId', - pluginData: data.pluginAndroidId, + pluginData: data.pluginAndroidId!, }; expect(getActivePlugin(data, '/android')).toEqual(activePluginAndroid); expect(getActivePlugin(data, '/android/')).toEqual(activePluginAndroid); expect(getActivePlugin(data, '/android/ijk')).toEqual(activePluginAndroid); // https://github.com/facebook/docusaurus/issues/6434 - const onePluginAtRoot = { + const onePluginAtRoot: {[key: string]: GlobalPluginData} = { pluginIosId: { path: '/', versions: [], + breadcrumbs: true, }, pluginAndroidId: { path: '/android', versions: [], + breadcrumbs: true, }, }; - expect(getActivePlugin(onePluginAtRoot, '/android/foo').pluginId).toBe( + expect(getActivePlugin(onePluginAtRoot, '/android/foo')!.pluginId).toBe( 'pluginAndroidId', ); - const onePluginAtRootReversed = { + const onePluginAtRootReversed: {[key: string]: GlobalPluginData} = { pluginAndroidId: { path: '/android', versions: [], + breadcrumbs: true, }, pluginIosId: { path: '/', versions: [], + breadcrumbs: true, }, }; expect( - getActivePlugin(onePluginAtRootReversed, '/android/foo').pluginId, + getActivePlugin(onePluginAtRootReversed, '/android/foo')!.pluginId, ).toBe('pluginAndroidId'); }); @@ -100,6 +107,7 @@ describe('docsClientUtils', () => { isLast: false, docs: [], mainDocId: '???', + draftIds: [], }, { name: 'version2', @@ -108,6 +116,7 @@ describe('docsClientUtils', () => { isLast: true, docs: [], mainDocId: '???', + draftIds: [], }, { name: 'version3', @@ -116,6 +125,7 @@ describe('docsClientUtils', () => { isLast: false, docs: [], mainDocId: '???', + draftIds: [], }, ]; @@ -123,6 +133,7 @@ describe('docsClientUtils', () => { getLatestVersion({ path: '???', versions, + breadcrumbs: true, }), ).toEqual(versions[1]); }); @@ -138,6 +149,7 @@ describe('docsClientUtils', () => { path: '/docs/next', docs: [], mainDocId: '???', + draftIds: [], }, { name: 'version2', @@ -146,6 +158,7 @@ describe('docsClientUtils', () => { path: '/docs', docs: [], mainDocId: '???', + draftIds: [], }, { name: 'version1', @@ -154,8 +167,10 @@ describe('docsClientUtils', () => { path: '/docs/version1', docs: [], mainDocId: '???', + draftIds: [], }, ], + breadcrumbs: true, }; expect(getActiveVersion(data, '/someUnknownPath')).toBeUndefined(); @@ -191,7 +206,8 @@ describe('docsClientUtils', () => { id: 'doc2', path: '/docs/next/doc2', }, - ], + ] as GlobalDoc[], + draftIds: [], }; const version2: GlobalVersion = { @@ -209,7 +225,8 @@ describe('docsClientUtils', () => { id: 'doc2', path: '/docs/doc2', }, - ], + ] as GlobalDoc[], + draftIds: [], }; const version1: GlobalVersion = { @@ -223,7 +240,8 @@ describe('docsClientUtils', () => { id: 'doc1', path: '/docs/version1/', }, - ], + ] as GlobalDoc[], + draftIds: [], }; // Shuffle, because order shouldn't matter @@ -236,6 +254,7 @@ describe('docsClientUtils', () => { const data: GlobalPluginData = { path: 'docs', versions, + breadcrumbs: true, }; expect(getActiveDocContext(data, '/doesNotExist')).toEqual({ @@ -320,7 +339,8 @@ describe('docsClientUtils', () => { id: 'doc2', path: '/docs/next/doc2', }, - ], + ] as GlobalDoc[], + draftIds: [], }; const version2: GlobalVersion = { @@ -338,7 +358,8 @@ describe('docsClientUtils', () => { id: 'doc2', path: '/docs/doc2', }, - ], + ] as GlobalDoc[], + draftIds: [], }; const version1: GlobalVersion = { @@ -352,7 +373,8 @@ describe('docsClientUtils', () => { id: 'doc1', path: '/docs/version1/', }, - ], + ] as GlobalDoc[], + draftIds: [], }; // Shuffle, because order shouldn't matter @@ -365,6 +387,7 @@ describe('docsClientUtils', () => { const data: GlobalPluginData = { path: 'docs', versions, + breadcrumbs: true, }; expect(getDocVersionSuggestions(data, '/doesNotExist')).toEqual({ diff --git a/packages/docusaurus-plugin-content-docs/src/markdown/__tests__/linkify.test.ts b/packages/docusaurus-plugin-content-docs/src/markdown/__tests__/linkify.test.ts index 864d5a39c274..6d3f11a2c427 100644 --- a/packages/docusaurus-plugin-content-docs/src/markdown/__tests__/linkify.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/markdown/__tests__/linkify.test.ts @@ -28,8 +28,12 @@ function createFakeVersion({ }): VersionMetadata { return { versionName, - versionLabel: 'Any', - versionPath: 'any', + label: 'Any', + path: 'any', + badge: true, + banner: null, + tagsPath: '/tags/', + className: '', contentPath, contentPathLocalized, sidebarFilePath: 'any', diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts index 9f01f06347b7..43e40938df0e 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts @@ -27,10 +27,6 @@ describe('DefaultSidebarItemsGenerator', () => { contentPath: 'docs', }, docs: [], - options: { - sidebarCollapsed: true, - sidebarCollapsible: true, - }, categoriesMetadata: {}, ...params, }); @@ -69,6 +65,8 @@ describe('DefaultSidebarItemsGenerator', () => { frontMatter: { sidebar_label: 'doc1 sidebar label', }, + title: '', + unversionedId: 'doc1', }, { id: 'doc2', @@ -76,6 +74,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: 3, frontMatter: {}, + title: '', + unversionedId: 'doc2', }, { id: 'doc3', @@ -83,6 +83,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: 1, frontMatter: {}, + title: '', + unversionedId: 'doc3', }, { id: 'doc4', @@ -90,6 +92,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: 1.5, frontMatter: {}, + title: '', + unversionedId: 'doc4', }, { id: 'doc5', @@ -97,12 +101,12 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: undefined, frontMatter: {}, + title: '', + unversionedId: 'doc5', }, ], - options: { - sidebarCollapsed: true, - sidebarCollapsible: true, - }, + isCategoryIndex: () => false, + categoriesMetadata: {}, }); expect(sidebarSlice).toMatchSnapshot(); @@ -144,6 +148,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: 0, frontMatter: {}, + title: '', + unversionedId: 'intro', }, { id: 'tutorials-index', @@ -151,6 +157,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '01-Tutorials', sidebarPosition: 2, frontMatter: {}, + title: 'Tutorials', + unversionedId: 'tutorials-index', }, { id: 'tutorial2', @@ -158,6 +166,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '01-Tutorials', sidebarPosition: 2, frontMatter: {}, + title: '', + unversionedId: 'tutorial2', }, { id: 'tutorial1', @@ -165,12 +175,16 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '01-Tutorials', sidebarPosition: 1, frontMatter: {}, + title: '', + unversionedId: 'tutorial1', }, { id: 'guides-index', source: '@site/docs/02-Guides/02-Guides.md', // TODO should we allow to just use "Guides.md" to have an index? sourceDirName: '02-Guides', frontMatter: {}, + title: 'Guides', + unversionedId: 'guides-index', }, { id: 'guide2', @@ -178,6 +192,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '02-Guides', sidebarPosition: 2, frontMatter: {}, + title: '', + unversionedId: 'guide2', }, { id: 'guide1', @@ -187,6 +203,8 @@ describe('DefaultSidebarItemsGenerator', () => { frontMatter: { sidebar_class_name: 'foo', }, + title: '', + unversionedId: 'guide1', }, { id: 'nested-guide', @@ -194,6 +212,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '02-Guides/01-SubGuides', sidebarPosition: undefined, frontMatter: {}, + title: '', + unversionedId: 'nested-guide', }, { id: 'end', @@ -201,12 +221,10 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: 3, frontMatter: {}, + title: '', + unversionedId: 'end', }, ], - options: { - sidebarCollapsed: true, - sidebarCollapsible: true, - }, }); expect(sidebarSlice).toMatchSnapshot(); @@ -249,6 +267,7 @@ describe('DefaultSidebarItemsGenerator', () => { title: 'Subsubsubfolder category label', sidebarPosition: undefined, frontMatter: {}, + unversionedId: 'doc1', }, { id: 'doc2', @@ -256,6 +275,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: 'subfolder', sidebarPosition: undefined, frontMatter: {}, + title: '', + unversionedId: 'doc2', }, { id: 'doc3', @@ -263,6 +284,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: undefined, frontMatter: {}, + title: '', + unversionedId: 'doc2', }, { id: 'doc4', @@ -270,6 +293,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: 'subfolder/subsubfolder', sidebarPosition: undefined, frontMatter: {}, + title: '', + unversionedId: 'doc4', }, { id: 'doc5', @@ -277,6 +302,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: 'subfolder/subsubfolder/subsubsubfolder', sidebarPosition: undefined, frontMatter: {}, + title: '', + unversionedId: 'doc5', }, { id: 'doc6', @@ -284,6 +311,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: 'subfolder/subsubfolder/subsubsubfolder2', sidebarPosition: undefined, frontMatter: {}, + title: '', + unversionedId: 'doc6', }, { id: 'doc7', @@ -291,6 +320,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: 'subfolder/subsubfolder/subsubsubfolder3', sidebarPosition: 2, frontMatter: {}, + title: '', + unversionedId: 'doc7', }, { id: 'doc8', @@ -298,12 +329,10 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: 'subfolder/subsubfolder/subsubsubfolder3', sidebarPosition: 1, frontMatter: {}, + title: '', + unversionedId: 'doc8', }, ], - options: { - sidebarCollapsed: true, - sidebarCollapsible: true, - }, }); expect(sidebarSlice).toMatchSnapshot(); @@ -339,42 +368,51 @@ describe('DefaultSidebarItemsGenerator', () => { source: '@site/docs/Category/index.md', sourceDirName: 'Category', frontMatter: {}, + title: '', + unversionedId: 'parent/doc1', }, { id: 'parent/doc2', source: '@site/docs/Category/doc2.md', sourceDirName: 'Category', frontMatter: {}, + title: '', + unversionedId: 'parent/doc2', }, { id: 'parent/doc3', source: '@site/docs/Category/doc3.md', sourceDirName: 'Category', frontMatter: {}, + title: '', + unversionedId: 'parent/doc3', }, { id: 'parent/doc4', source: '@site/docs/Category2/doc1.md', sourceDirName: 'Category2', frontMatter: {}, + title: '', + unversionedId: 'parent/doc4', }, { id: 'parent/doc5', source: '@site/docs/Category2/index.md', sourceDirName: 'Category2', frontMatter: {}, + title: '', + unversionedId: 'parent/doc5', }, { id: 'parent/doc6', source: '@site/docs/Category2/doc3.md', sourceDirName: 'Category2', frontMatter: {}, + title: '', + unversionedId: 'parent/doc6', }, ], - options: { - sidebarCollapsed: true, - sidebarCollapsible: true, - }, + isCategoryIndex: () => false, }); expect(sidebarSlice).toMatchSnapshot(); @@ -387,7 +425,7 @@ describe('DefaultSidebarItemsGenerator', () => { return ( fileName.replace( `${DefaultNumberPrefixParser( - directories[0], + directories[0]!, ).filename.toLowerCase()}-`, '', ) === 'index' @@ -409,6 +447,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '.', sidebarPosition: 0, frontMatter: {}, + title: '', + unversionedId: 'intro', }, { id: 'tutorials-index', @@ -416,6 +456,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '01-Tutorials', sidebarPosition: 2, frontMatter: {}, + title: 'Tutorials', + unversionedId: 'tutorials-index', }, { id: 'tutorial2', @@ -423,6 +465,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '01-Tutorials', sidebarPosition: 2, frontMatter: {}, + title: '', + unversionedId: 'tutorial2', }, { id: 'tutorial1', @@ -430,12 +474,16 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '01-Tutorials', sidebarPosition: 1, frontMatter: {}, + title: '', + unversionedId: 'tutorial1', }, { id: 'not-guides-index', source: '@site/docs/02-Guides/README.md', sourceDirName: '02-Guides', frontMatter: {}, + title: 'Guides', + unversionedId: 'not-guides-index', }, { id: 'guide2', @@ -443,6 +491,8 @@ describe('DefaultSidebarItemsGenerator', () => { sourceDirName: '02-Guides', sidebarPosition: 2, frontMatter: {}, + title: 'guide2', + unversionedId: 'guide2', }, { id: 'guide1', @@ -452,12 +502,10 @@ describe('DefaultSidebarItemsGenerator', () => { frontMatter: { sidebar_class_name: 'foo', }, + title: '', + unversionedId: 'guide1', }, ], - options: { - sidebarCollapsed: true, - sidebarCollapsible: true, - }, }); expect(sidebarSlice).toMatchSnapshot(); @@ -491,12 +539,9 @@ describe('DefaultSidebarItemsGenerator', () => { source: '@site/docs/category/intro.md', sourceDirName: 'category', frontMatter: {}, + title: '', }, ], - options: { - sidebarCollapsed: true, - sidebarCollapsible: true, - }, }); expect(() => generateSidebar()).toThrowErrorMatchingInlineSnapshot(` diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts index 5a1eed4f1d1b..5981cfefadd6 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts @@ -11,7 +11,10 @@ import {createSlugger} from '@docusaurus/utils'; import {loadSidebars, DisabledSidebars} from '../index'; import {DefaultSidebarItemsGenerator} from '../generator'; import type {SidebarProcessorParams} from '../types'; -import type {DocMetadata} from '@docusaurus/plugin-content-docs'; +import type { + DocMetadata, + VersionMetadata, +} from '@docusaurus/plugin-content-docs'; describe('loadSidebars', () => { const fixtureDir = path.join(__dirname, '__fixtures__', 'sidebars'); @@ -25,14 +28,14 @@ describe('loadSidebars', () => { id: 'bar', frontMatter: {}, }, - ], + ] as DocMetadata[], drafts: [], version: { path: 'version', contentPath: path.join(fixtureDir, 'docs'), contentPathLocalized: path.join(fixtureDir, 'docs'), - }, - categoryLabelSlugger: null, + } as VersionMetadata, + categoryLabelSlugger: {slug: (v) => v}, sidebarOptions: {sidebarCollapsed: true, sidebarCollapsible: true}, }; it('sidebars with known sidebar item type', async () => { @@ -137,7 +140,7 @@ describe('loadSidebars', () => { sourceDirName: 'tutorials/tutorial-basics', frontMatter: {}, }, - ], + ] as DocMetadata[], }); expect(result).toMatchSnapshot(); }); @@ -146,7 +149,7 @@ describe('loadSidebars', () => { const sidebarPath = path.join(fixtureDir, 'sidebars-drafts.json'); const result = await loadSidebars(sidebarPath, { ...params, - drafts: [{id: 'draft1'}, {id: 'draft2'}, {id: 'draft3'}], + drafts: [{id: 'draft1'}, {id: 'draft2'}, {id: 'draft3'}] as DocMetadata[], categoryLabelSlugger: createSlugger(), }); expect(result).toMatchSnapshot(); @@ -169,7 +172,7 @@ describe('loadSidebars', () => { version: { contentPath: path.join(fixtureDir, 'invalid-docs'), contentPathLocalized: path.join(fixtureDir, 'invalid-docs'), - }, + } as VersionMetadata, }), ).rejects.toThrowErrorMatchingInlineSnapshot(`""foo" is not allowed"`); expect(consoleWarnMock).toBeCalledWith( diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/normalization.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/normalization.test.ts index f9413e73f68e..f7f9ad2ee2e8 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/normalization.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/normalization.test.ts @@ -41,7 +41,9 @@ describe('normalization', () => { expect(() => normalizeSidebars({ sidebar: { + // @ts-expect-error: test Category: {type: 'autogenerated', dirName: 'foo'}, + // @ts-expect-error: test Category2: {type: 'autogenerated', dirName: 'bar'}, }, }), @@ -55,6 +57,7 @@ describe('normalization', () => { 'foo', { Category: { + // @ts-expect-error: test type: 'category', items: ['bar', 'baz'], }, @@ -70,6 +73,7 @@ describe('normalization', () => { sidebar: [ 'foo', { + // @ts-expect-error: test Category: 'bar', }, ], @@ -80,6 +84,7 @@ describe('normalization', () => { expect(() => normalizeSidebars({ + // @ts-expect-error: test sidebar: 'item', }), ).toThrowErrorMatchingInlineSnapshot( diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/postProcessor.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/postProcessor.test.ts index 16196c7c3de8..ac897e12ce97 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/postProcessor.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/postProcessor.test.ts @@ -5,7 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -import {postProcessSidebars} from '../postProcessor'; +import { + postProcessSidebars, + type SidebarPostProcessorParams, +} from '../postProcessor'; describe('postProcess', () => { it('transforms category without subitems', () => { @@ -36,7 +39,7 @@ describe('postProcess', () => { sidebarOptions: {sidebarCollapsed: true, sidebarCollapsible: true}, version: {path: 'version'}, drafts: [], - }, + } as unknown as SidebarPostProcessorParams, ); expect(processedSidebar).toMatchSnapshot(); @@ -56,7 +59,7 @@ describe('postProcess', () => { sidebarOptions: {sidebarCollapsed: true, sidebarCollapsible: true}, version: {path: 'version'}, drafts: [], - }, + } as unknown as SidebarPostProcessorParams, ); }).toThrowErrorMatchingInlineSnapshot( `"Sidebar category Bad category has neither any subitem nor a link. This makes this item not able to link to anything."`, @@ -82,7 +85,7 @@ describe('postProcess', () => { sidebarOptions: {sidebarCollapsed: true, sidebarCollapsible: true}, version: {path: 'version'}, drafts: [], - }, + } as unknown as SidebarPostProcessorParams, ), ).toMatchSnapshot(); @@ -103,7 +106,7 @@ describe('postProcess', () => { sidebarOptions: {sidebarCollapsed: false, sidebarCollapsible: false}, version: {path: 'version'}, drafts: [], - }, + } as unknown as SidebarPostProcessorParams, ), ).toMatchSnapshot(); @@ -123,7 +126,7 @@ describe('postProcess', () => { sidebarOptions: {sidebarCollapsed: true, sidebarCollapsible: false}, version: {path: 'version'}, drafts: [], - }, + } as unknown as SidebarPostProcessorParams, ), ).toMatchSnapshot(); }); @@ -153,7 +156,7 @@ describe('postProcess', () => { sidebarOptions: {sidebarCollapsed: true, sidebarCollapsible: true}, version: {path: 'version'}, drafts: [{id: 'foo', unversionedId: 'foo'}], - }, + } as unknown as SidebarPostProcessorParams, ), ).toMatchSnapshot(); }); diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts index 7dc7111dbe0a..bb5eefda526f 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/processor.test.ts @@ -12,7 +12,7 @@ import {DefaultSidebarItemsGenerator} from '../generator'; import {DefaultNumberPrefixParser} from '../../numberPrefix'; import {isCategoryIndex} from '../../docs'; import type { - SidebarItem, + Sidebar, SidebarItemsGenerator, NormalizedSidebar, NormalizedSidebars, @@ -24,12 +24,12 @@ import type {VersionMetadata} from '@docusaurus/plugin-content-docs'; describe('processSidebars', () => { function createStaticSidebarItemGenerator( - sidebarSlice: SidebarItem[], + sidebarSlice: NormalizedSidebar, ): SidebarItemsGenerator { return jest.fn(() => sidebarSlice); } - const StaticGeneratedSidebarSlice: NormalizedSidebar = [ + const StaticGeneratedSidebarSlice: Sidebar = [ {type: 'doc', id: 'doc-generated-id-1'}, {type: 'doc', id: 'doc-generated-id-2'}, ]; @@ -215,7 +215,7 @@ describe('processSidebars', () => { }, ]; - const unprocessedSidebars = { + const unprocessedSidebars: NormalizedSidebars = { someSidebar: [{type: 'autogenerated', dirName: 'dir2'}], }; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts index 58c69912d704..d8399e502279 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/postProcessor.ts @@ -18,7 +18,7 @@ import type { SidebarItemCategoryLink, } from './types'; -type SidebarPostProcessorParams = SidebarProcessorParams & { +export type SidebarPostProcessorParams = SidebarProcessorParams & { draftIds: Set; }; diff --git a/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts b/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts index e48bc9302e49..7754ced825af 100644 --- a/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-sitemap/src/__tests__/options.test.ts @@ -6,10 +6,20 @@ */ import {normalizePluginOptions} from '@docusaurus/utils-validation'; -import {validateOptions, DEFAULT_OPTIONS, type Options} from '../options'; +import { + validateOptions, + DEFAULT_OPTIONS, + type Options, + type PluginOptions, +} from '../options'; +import type {EnumChangefreq} from 'sitemap'; +import type {Validate} from '@docusaurus/types'; function testValidate(options: Options) { - return validateOptions({validate: normalizePluginOptions, options}); + return validateOptions({ + validate: normalizePluginOptions as Validate, + options, + }); } const defaultOptions = { @@ -24,7 +34,7 @@ describe('validateOptions', () => { it('accepts correctly defined user options', () => { const userOptions: Options = { - changefreq: 'yearly', + changefreq: 'yearly' as EnumChangefreq, priority: 0.9, ignorePatterns: ['/search/**'], }; @@ -44,7 +54,7 @@ describe('validateOptions', () => { it('rejects bad changefreq inputs', () => { expect(() => - testValidate({changefreq: 'annually'}), + testValidate({changefreq: 'annually' as EnumChangefreq}), ).toThrowErrorMatchingInlineSnapshot( `""changefreq" must be one of [daily, monthly, always, hourly, weekly, yearly, never]"`, ); diff --git a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts index dd4eaae6df49..da76d5edd34e 100644 --- a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts @@ -501,7 +501,7 @@ describe('themeConfig', () => { links: [ { title: null, // Default value is important to distinguish simple footer from multi-column footer - items: partialConfig.footer.links[0].items, + items: partialConfig.footer.links[0]!.items, }, ], }, @@ -657,7 +657,7 @@ describe('themeConfig', () => { }); describe('color mode config', () => { - const withDefaultValues = (colorMode: ThemeConfig['colorMode']) => + const withDefaultValues = (colorMode?: ThemeConfig['colorMode']) => _.merge({}, DEFAULT_CONFIG.colorMode, colorMode); it('switch config', () => { diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 76861545731f..bc9b9c9bbaf3 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1032,10 +1032,10 @@ declare module '@theme/Tabs' { readonly lazy?: boolean; readonly block?: boolean; readonly children: readonly ReactElement[]; - readonly defaultValue?: string | number | null; + readonly defaultValue?: string | null; readonly values?: readonly { - value: string | number; - label?: string | number; + value: string; + label?: string; attributes?: {[key: string]: unknown}; }[]; readonly groupId?: string; diff --git a/packages/docusaurus-theme-classic/src/theme/Tabs/__tests__/index.test.tsx b/packages/docusaurus-theme-classic/src/theme/Tabs/__tests__/index.test.tsx index f5d4f2d7f58f..79329bf518aa 100644 --- a/packages/docusaurus-theme-classic/src/theme/Tabs/__tests__/index.test.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Tabs/__tests__/index.test.tsx @@ -117,9 +117,12 @@ describe('Tabs', () => { ({label: t, value: idx}))} + // @ts-expect-error: for an edge-case that we didn't write types for defaultValue={0}> {tabs.map((t, idx) => ( + // @ts-expect-error: for an edge-case that we didn't write types for {t} diff --git a/packages/docusaurus-theme-common/src/utils/__tests__/generalUtils.test.tsx b/packages/docusaurus-theme-common/src/utils/__tests__/generalUtils.test.tsx index 6a2680fde148..02c2ad551993 100644 --- a/packages/docusaurus-theme-common/src/utils/__tests__/generalUtils.test.tsx +++ b/packages/docusaurus-theme-common/src/utils/__tests__/generalUtils.test.tsx @@ -25,7 +25,7 @@ describe('useTitleFormatter', () => { title: 'my site', titleDelimiter: '·', }, - }); + } as DocusaurusContext); expect(mockUseTitleFormatter('a page')).toBe('a page · my site'); expect(mockUseTitleFormatter(undefined)).toBe('my site'); expect(mockUseTitleFormatter(' ')).toBe('my site'); diff --git a/packages/docusaurus-theme-common/src/utils/__tests__/useAlternatePageUtils.test.tsx b/packages/docusaurus-theme-common/src/utils/__tests__/useAlternatePageUtils.test.tsx index e10b938baa4b..fb964b015fec 100644 --- a/packages/docusaurus-theme-common/src/utils/__tests__/useAlternatePageUtils.test.tsx +++ b/packages/docusaurus-theme-common/src/utils/__tests__/useAlternatePageUtils.test.tsx @@ -26,7 +26,7 @@ describe('useAlternatePageUtils', () => { const mockUseAlternatePageUtils = createUseAlternatePageUtilsMock({ siteConfig: {baseUrl: '/', url: 'https://example.com'}, i18n: {defaultLocale: 'en', currentLocale: 'en'}, - }); + } as DocusaurusContext); expect( mockUseAlternatePageUtils('/').createUrl({ locale: 'zh-Hans', @@ -51,7 +51,7 @@ describe('useAlternatePageUtils', () => { const mockUseAlternatePageUtils = createUseAlternatePageUtilsMock({ siteConfig: {baseUrl: '/zh-Hans/', url: 'https://example.com'}, i18n: {defaultLocale: 'en', currentLocale: 'zh-Hans'}, - }); + } as DocusaurusContext); expect( mockUseAlternatePageUtils('/zh-Hans/').createUrl({ locale: 'en', @@ -76,7 +76,7 @@ describe('useAlternatePageUtils', () => { const mockUseAlternatePageUtils = createUseAlternatePageUtilsMock({ siteConfig: {baseUrl: '/base/', url: 'https://example.com'}, i18n: {defaultLocale: 'en', currentLocale: 'en'}, - }); + } as DocusaurusContext); expect( mockUseAlternatePageUtils('/base/').createUrl({ locale: 'zh-Hans', @@ -101,7 +101,7 @@ describe('useAlternatePageUtils', () => { const mockUseAlternatePageUtils = createUseAlternatePageUtilsMock({ siteConfig: {baseUrl: '/base/zh-Hans/', url: 'https://example.com'}, i18n: {defaultLocale: 'en', currentLocale: 'zh-Hans'}, - }); + } as DocusaurusContext); expect( mockUseAlternatePageUtils('/base/zh-Hans/').createUrl({ locale: 'en', diff --git a/packages/docusaurus-theme-common/src/utils/__tests__/useLocalPathname.test.tsx b/packages/docusaurus-theme-common/src/utils/__tests__/useLocalPathname.test.tsx index f2f6e189393a..d0b78511d00d 100644 --- a/packages/docusaurus-theme-common/src/utils/__tests__/useLocalPathname.test.tsx +++ b/packages/docusaurus-theme-common/src/utils/__tests__/useLocalPathname.test.tsx @@ -25,14 +25,14 @@ describe('useLocalPathname', () => { it('works for baseUrl: /', () => { const mockUseLocalPathname = createUseLocalPathnameMock({ siteConfig: {baseUrl: '/'}, - }); + } as DocusaurusContext); expect(mockUseLocalPathname('/foo')).toBe('/foo'); }); it('works for non-root baseUrl', () => { const mockUseLocalPathname = createUseLocalPathnameMock({ siteConfig: {baseUrl: '/base/'}, - }); + } as DocusaurusContext); expect(mockUseLocalPathname('/base/foo')).toBe('/foo'); }); }); diff --git a/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx b/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx index f789734119f7..81a251bb3c5e 100644 --- a/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx +++ b/packages/docusaurus-theme-common/src/utils/__tests__/usePluralForm.test.tsx @@ -40,7 +40,7 @@ describe('usePluralForm', () => { .mockImplementation(() => {}); expect(mockUsePluralForm().selectMessage(1, 'one|many')).toBe('one'); expect(mockUsePluralForm().selectMessage(10, 'one|many')).toBe('one'); - expect(consoleMock.mock.calls[0][0]).toMatchInlineSnapshot( + expect(consoleMock.mock.calls[0]![0]).toMatchInlineSnapshot( `"For locale=zh-Hans, a maximum of 1 plural forms are expected (other), but the message contains 2: one|many"`, ); }); @@ -65,10 +65,11 @@ describe('usePluralForm', () => { .mockImplementation(() => {}); const pluralMock = jest .spyOn(Intl, 'PluralRules') + // @ts-expect-error: for testing when it doesn't exist .mockImplementation(() => undefined); expect(mockUsePluralForm().selectMessage(1, 'one|many')).toBe('one'); expect(mockUsePluralForm().selectMessage(10, 'one|many')).toBe('many'); - expect(consoleMock.mock.calls[0][0]).toMatchInlineSnapshot(` + expect(consoleMock.mock.calls[0]![0]).toMatchInlineSnapshot(` "Failed to use Intl.PluralRules for locale "zh-Hans". Docusaurus will fallback to the default (English) implementation. Error: pluralRules.resolvedOptions is not a function diff --git a/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx b/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx index 1f52a15b4070..e3f1c52abc31 100644 --- a/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx +++ b/packages/docusaurus/src/client/exports/__tests__/useGlobalData.test.tsx @@ -12,14 +12,16 @@ import useGlobalData, { usePluginData, } from '../useGlobalData'; import {Context} from '../../docusaurusContext'; +import type {DocusaurusContext} from '@docusaurus/types'; describe('useGlobalData', () => { it('returns global data from context', () => { expect( renderHook(() => useGlobalData(), { wrapper: ({children}) => ( - // eslint-disable-next-line react/jsx-no-constructed-context-values - + {children} ), @@ -34,8 +36,12 @@ describe('useAllPluginInstancesData', () => { renderHook(() => useAllPluginInstancesData('foo'), { wrapper: ({children}) => ( + value={ + // eslint-disable-next-line react/jsx-no-constructed-context-values + { + globalData: {foo: {default: 'default', bar: 'bar'}}, + } as unknown as DocusaurusContext + }> {children} ), @@ -49,8 +55,12 @@ describe('useAllPluginInstancesData', () => { renderHook(() => useAllPluginInstancesData('bar', {failfast: true}), { wrapper: ({children}) => ( + value={ + // eslint-disable-next-line react/jsx-no-constructed-context-values + { + globalData: {foo: {default: 'default', bar: 'bar'}}, + } as unknown as DocusaurusContext + }> {children} ), @@ -67,8 +77,12 @@ describe('usePluginData', () => { renderHook(() => usePluginData('foo', 'bar'), { wrapper: ({children}) => ( + value={ + // eslint-disable-next-line react/jsx-no-constructed-context-values + { + globalData: {foo: {default: 'default', bar: 'bar'}}, + } as unknown as DocusaurusContext + }> {children} ), @@ -81,8 +95,12 @@ describe('usePluginData', () => { renderHook(() => usePluginData('foo'), { wrapper: ({children}) => ( + value={ + // eslint-disable-next-line react/jsx-no-constructed-context-values + { + globalData: {foo: {default: 'default', bar: 'bar'}}, + } as unknown as DocusaurusContext + }> {children} ), @@ -96,8 +114,12 @@ describe('usePluginData', () => { renderHook(() => usePluginData('foo', 'baz', {failfast: true}), { wrapper: ({children}) => ( + value={ + // eslint-disable-next-line react/jsx-no-constructed-context-values + { + globalData: {foo: {default: 'default', bar: 'bar'}}, + } as unknown as DocusaurusContext + }> {children} ), diff --git a/packages/docusaurus/src/commands/swizzle/__tests__/actions.test.ts b/packages/docusaurus/src/commands/swizzle/__tests__/actions.test.ts index d73280553085..2bbfca6407ab 100644 --- a/packages/docusaurus/src/commands/swizzle/__tests__/actions.test.ts +++ b/packages/docusaurus/src/commands/swizzle/__tests__/actions.test.ts @@ -126,7 +126,7 @@ describe('wrap', () => { siteDir, siteThemePath, createdFiles: stableCreatedFiles(siteThemePath, result.createdFiles), - firstFileContent: () => fs.readFile(result.createdFiles[0], 'utf8'), + firstFileContent: () => fs.readFile(result.createdFiles[0]!, 'utf8'), tree: tree(siteThemePath), }; } diff --git a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts index c2317cb41c22..74e94678f3c2 100644 --- a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts +++ b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts @@ -55,13 +55,13 @@ class MockExitError extends Error { } function createExitMock() { - let mock: jest.SpyInstance; + let mock: jest.SpyInstance<(code?: number) => never>; // eslint-disable-next-line jest/require-top-level-describe beforeEach(async () => { mock = jest.spyOn(process, 'exit').mockImplementation((code) => { - throw new MockExitError(code); - }); + throw new MockExitError(code!); + }) as jest.SpyInstance<(code?: number) => never>; }); // eslint-disable-next-line jest/require-top-level-describe afterEach(async () => { diff --git a/packages/docusaurus/src/server/__tests__/clientModules.test.ts b/packages/docusaurus/src/server/__tests__/clientModules.test.ts index c27ba51c1900..5e22efd63057 100644 --- a/packages/docusaurus/src/server/__tests__/clientModules.test.ts +++ b/packages/docusaurus/src/server/__tests__/clientModules.test.ts @@ -8,20 +8,20 @@ import {loadClientModules} from '../clientModules'; import type {LoadedPlugin} from '@docusaurus/types'; -const pluginEmpty: LoadedPlugin = { +const pluginEmpty = { name: 'plugin-empty', path: __dirname, -}; +} as LoadedPlugin; -const pluginFooBar: LoadedPlugin = { +const pluginFooBar = { name: 'plugin-foo-bar', path: __dirname, getClientModules() { return ['foo', 'bar']; }, -}; +} as LoadedPlugin; -const pluginHelloWorld: LoadedPlugin = { +const pluginHelloWorld = { plugin: 'plugin-hello-world', path: __dirname, getClientModules() { @@ -31,7 +31,7 @@ const pluginHelloWorld: LoadedPlugin = { 'world', ]; }, -}; +} as unknown as LoadedPlugin; describe('loadClientModules', () => { it('loads an empty plugin', () => { diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index 70eaa3900e3c..bd42f1f96569 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -10,15 +10,16 @@ import { DEFAULT_CONFIG, validateConfig, } from '../configValidation'; -import type {DocusaurusConfig} from '@docusaurus/types'; +import type {Config} from '@docusaurus/types'; -const baseConfig: DocusaurusConfig = { +const baseConfig = { baseUrl: '/', title: 'my site', url: 'https://mysite.com', -}; +} as Config; -const normalizeConfig = (config) => validateConfig({...baseConfig, ...config}); +const normalizeConfig = (config: Partial) => + validateConfig({...baseConfig, ...config}); describe('normalizeConfig', () => { it('normalizes empty config', () => { @@ -79,6 +80,7 @@ describe('normalizeConfig', () => { it('throws error for unknown field', () => { expect(() => { normalizeConfig({ + // @ts-expect-error: test invalid: true, }); }).toThrowErrorMatchingSnapshot(); @@ -113,6 +115,7 @@ describe('normalizeConfig', () => { ])(`%s for the input of: %p`, (_message, plugins) => { expect(() => { normalizeConfig({ + // @ts-expect-error: test plugins, }); }).toThrowErrorMatchingSnapshot(); @@ -139,6 +142,7 @@ describe('normalizeConfig', () => { ])(`%s for the input of: %p`, (_message, themes) => { expect(() => { normalizeConfig({ + // @ts-expect-error: test themes, }); }).toThrowErrorMatchingSnapshot(); @@ -174,12 +178,12 @@ describe('normalizeConfig', () => { 'should accept [function, object] for plugin', [[() => {}, {it: 'should work'}]], ], - ['should accept false/null for plugin', [false, null, 'classic']], + ['should accept false/null for plugin', [false as const, null, 'classic']], ])(`%s for the input of: %p`, (_message, plugins) => { expect(() => { normalizeConfig({ plugins, - }); + } as Config); }).not.toThrowError(); }); @@ -218,13 +222,14 @@ describe('normalizeConfig', () => { expect(() => { normalizeConfig({ themes, - }); + } as Config); }).not.toThrowError(); }); it('throws error if themes is not array', () => { expect(() => { normalizeConfig({ + // @ts-expect-error: test themes: {}, }); }).toThrowErrorMatchingInlineSnapshot(` @@ -236,6 +241,7 @@ describe('normalizeConfig', () => { it('throws error if presets is not array', () => { expect(() => { normalizeConfig({ + // @ts-expect-error: test presets: {}, }); }).toThrowErrorMatchingInlineSnapshot(` @@ -247,6 +253,7 @@ describe('normalizeConfig', () => { it('throws error if presets looks invalid', () => { expect(() => { normalizeConfig({ + // @ts-expect-error: test presets: [() => {}], }); }).toThrowErrorMatchingInlineSnapshot(` @@ -314,10 +321,10 @@ describe('config warnings', () => { const warning = getWarning({ ...baseConfig, url: 'https://mysite.com/someSubpath', - }); + })!; expect(warning).toBeDefined(); expect(warning.details).toHaveLength(1); - expect(warning.details[0].message).toMatchInlineSnapshot( + expect(warning.details[0]!.message).toMatchInlineSnapshot( `"Docusaurus config validation warning. Field "url": the url is not supposed to contain a sub-path like '/someSubpath', please use the baseUrl field for sub-paths"`, ); }); diff --git a/packages/docusaurus/src/server/__tests__/htmlTags.test.ts b/packages/docusaurus/src/server/__tests__/htmlTags.test.ts index d701d23f1b57..ba2f82fdc39a 100644 --- a/packages/docusaurus/src/server/__tests__/htmlTags.test.ts +++ b/packages/docusaurus/src/server/__tests__/htmlTags.test.ts @@ -8,11 +8,11 @@ import {loadHtmlTags} from '../htmlTags'; import type {LoadedPlugin} from '@docusaurus/types'; -const pluginEmpty: LoadedPlugin = { +const pluginEmpty = { name: 'plugin-empty', -}; +} as LoadedPlugin; -const pluginPreBodyTags: LoadedPlugin = { +const pluginPreBodyTags = { name: 'plugin-preBodyTags', injectHtmlTags() { return { @@ -26,9 +26,9 @@ const pluginPreBodyTags: LoadedPlugin = { }, }; }, -}; +} as unknown as LoadedPlugin; -const pluginHeadTags: LoadedPlugin = { +const pluginHeadTags = { name: 'plugin-headTags-only', injectHtmlTags() { return { @@ -59,9 +59,9 @@ const pluginHeadTags: LoadedPlugin = { ], }; }, -}; +} as unknown as LoadedPlugin; -const pluginPostBodyTags: LoadedPlugin = { +const pluginPostBodyTags = { name: 'plugin-postBody-tags', injectHtmlTags() { return { @@ -74,14 +74,14 @@ const pluginPostBodyTags: LoadedPlugin = { ], }; }, -}; +} as unknown as LoadedPlugin; -const pluginMaybeInjectHeadTags: LoadedPlugin = { +const pluginMaybeInjectHeadTags = { name: 'plugin-postBody-tags', injectHtmlTags() { return undefined; }, -}; +} as unknown as LoadedPlugin; describe('loadHtmlTags', () => { it('works for an empty plugin', () => { @@ -170,6 +170,7 @@ describe('loadHtmlTags', () => { it('throws for invalid tag', () => { expect(() => loadHtmlTags([ + // @ts-expect-error: test { injectHtmlTags() { return { @@ -192,6 +193,7 @@ describe('loadHtmlTags', () => { expect(() => loadHtmlTags([ { + // @ts-expect-error: test injectHtmlTags() { return { headTags: { @@ -210,6 +212,7 @@ describe('loadHtmlTags', () => { expect(() => loadHtmlTags([ { + // @ts-expect-error: test injectHtmlTags() { return { headTags: 2, diff --git a/packages/docusaurus/src/server/__tests__/i18n.test.ts b/packages/docusaurus/src/server/__tests__/i18n.test.ts index 5142d0972fbb..84e1e83ada2d 100644 --- a/packages/docusaurus/src/server/__tests__/i18n.test.ts +++ b/packages/docusaurus/src/server/__tests__/i18n.test.ts @@ -180,7 +180,7 @@ describe('loadI18n', () => { }, 'it', ); - expect(consoleSpy.mock.calls[0][0]).toMatch( + expect(consoleSpy.mock.calls[0]![0]).toMatch( /The locale .*it.* was not found in your site configuration/, ); }); diff --git a/packages/docusaurus/src/server/__tests__/siteMetadata.test.ts b/packages/docusaurus/src/server/__tests__/siteMetadata.test.ts index 30a40bb7521d..3985173a03b8 100644 --- a/packages/docusaurus/src/server/__tests__/siteMetadata.test.ts +++ b/packages/docusaurus/src/server/__tests__/siteMetadata.test.ts @@ -8,6 +8,7 @@ import {jest} from '@jest/globals'; import path from 'path'; import {getPluginVersion, loadSiteMetadata} from '../siteMetadata'; +import type {LoadedPlugin} from '@docusaurus/types'; describe('getPluginVersion', () => { it('detects external packages plugins versions', async () => { @@ -51,11 +52,11 @@ describe('loadSiteMetadata', () => { name: '@docusaurus/plugin-content-docs', }, }, - ], + ] as LoadedPlugin[], siteDir: path.join(__dirname, '__fixtures__/siteMetadata'), }), ).resolves.toMatchSnapshot(); - expect(consoleMock.mock.calls[0][0]).toMatchInlineSnapshot(` + expect(consoleMock.mock.calls[0]![0]).toMatchInlineSnapshot(` "[ERROR] Invalid docusaurus-plugin-content-docs version 1.0.0. All official @docusaurus/* packages should have the exact same version as @docusaurus/core (). Maybe you want to check, or regenerate your yarn.lock or package-lock.json file?" diff --git a/packages/docusaurus/src/server/__tests__/utils.test.ts b/packages/docusaurus/src/server/__tests__/utils.test.ts index 646657350522..a93adea41f69 100644 --- a/packages/docusaurus/src/server/__tests__/utils.test.ts +++ b/packages/docusaurus/src/server/__tests__/utils.test.ts @@ -25,8 +25,8 @@ describe('getAllFinalRoutes', () => { }, ]; expect(getAllFinalRoutes(routes)).toEqual([ - routes[0].routes[0], - routes[0].routes[1], + routes[0]!.routes![0], + routes[0]!.routes![1], routes[1], ]); }); diff --git a/packages/docusaurus/src/server/plugins/__tests__/index.test.ts b/packages/docusaurus/src/server/plugins/__tests__/index.test.ts index 148e20fa46a6..2d85798e3633 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/index.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/index.test.ts @@ -7,7 +7,7 @@ import path from 'path'; import {loadPlugins} from '..'; -import type {Props} from '@docusaurus/types'; +import type {Plugin, Props} from '@docusaurus/types'; describe('loadPlugins', () => { it('loads plugins', async () => { @@ -23,23 +23,24 @@ describe('loadPlugins', () => { themeConfig: {}, presets: [], plugins: [ - () => ({ - name: 'test1', - prop: 'a', - async loadContent() { - // Testing that plugin lifecycle is bound to the plugin instance - return this.prop; - }, - async contentLoaded({content, actions}) { - actions.addRoute({ - path: 'foo', - component: 'Comp', - modules: {content: 'path'}, - context: {content: 'path'}, - }); - actions.setGlobalData({content, prop: this.prop}); - }, - }), + () => + ({ + name: 'test1', + prop: 'a', + async loadContent() { + // Testing that plugin lifecycle is bound to the plugin instance + return this.prop; + }, + async contentLoaded({content, actions}) { + actions.addRoute({ + path: 'foo', + component: 'Comp', + modules: {content: 'path'}, + context: {content: 'path'}, + }); + actions.setGlobalData({content, prop: this.prop}); + }, + } as Plugin & ThisType<{prop: 'a'}>), ], themes: [ () => ({ diff --git a/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts b/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts index c91709df62df..6cff740b08b0 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/presets.test.ts @@ -6,7 +6,6 @@ */ import path from 'path'; - import {loadPresets} from '../presets'; import type {LoadContext} from '@docusaurus/types'; @@ -17,7 +16,7 @@ describe('loadPresets', () => { siteConfig: { presets: [], }, - } as LoadContext; + } as unknown as LoadContext; const presets = await loadPresets(context); expect(presets).toMatchInlineSnapshot(` { diff --git a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts index 7ced1c70b5c2..70da33ffd3eb 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts @@ -292,13 +292,12 @@ describe('writePluginTranslations', () => { key3: {message: 'key3 message'}, }, }, - // @ts-expect-error: enough for this test plugin: { name: 'my-plugin-name', options: { - id: undefined, + id: 'default', }, - }, + } as LoadedPlugin, }); await expect(fs.readJSON(filePath)).resolves.toEqual({ @@ -698,7 +697,7 @@ describe('applyDefaultCodeTranslations', () => { }, }); expect(consoleWarnMock).toHaveBeenCalledTimes(1); - expect(consoleWarnMock.mock.calls[0][0]).toMatch(/unknownId/); + expect(consoleWarnMock.mock.calls[0]![0]).toMatch(/unknownId/); }); it('works for realistic scenario', () => { @@ -740,7 +739,7 @@ describe('applyDefaultCodeTranslations', () => { }, }); expect(consoleWarnMock).toHaveBeenCalledTimes(1); - expect(consoleWarnMock.mock.calls[0][0]).toMatch(/idUnknown1/); - expect(consoleWarnMock.mock.calls[0][0]).toMatch(/idUnknown2/); + expect(consoleWarnMock.mock.calls[0]![0]).toMatch(/idUnknown1/); + expect(consoleWarnMock.mock.calls[0]![0]).toMatch(/idUnknown2/); }); }); diff --git a/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts b/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts index ac74f839ea2e..f1fa317671ba 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts @@ -721,7 +721,7 @@ export default function MyComponent(props: Props) { message: 'plugin2 message 2', }, }); - expect(consoleWarnMock.mock.calls[0][0]).toMatch( + expect(consoleWarnMock.mock.calls[0]![0]).toMatch( /.*\[WARNING\].* Translation extraction warnings for file .*src.theme.file4\.jsx.*\n.*- translate\(\) first arg should be a statically evaluable object\./, ); }); diff --git a/packages/docusaurus/src/webpack/__tests__/utils.test.ts b/packages/docusaurus/src/webpack/__tests__/utils.test.ts index f5366ded41c1..d8c84cacc3a3 100644 --- a/packages/docusaurus/src/webpack/__tests__/utils.test.ts +++ b/packages/docusaurus/src/webpack/__tests__/utils.test.ts @@ -61,7 +61,7 @@ describe('extending generated webpack config', () => { }; // @ts-expect-error: Testing an edge-case that we did not write types for - const configureWebpack: Plugin['configureWebpack'] = ( + const configureWebpack: NonNullable = ( generatedConfig, isServer, ) => { @@ -129,7 +129,7 @@ describe('extending generated webpack config', () => { const createConfigureWebpack = (mergeStrategy?: { [key: string]: 'prepend' | 'append'; - }): Plugin['configureWebpack'] => + }): NonNullable => () => ({ module: { rules: [{use: 'zzz'}], @@ -272,7 +272,7 @@ describe('extending PostCSS', () => { expect(postCssLoader1.loader).toBe('postcss-loader-1'); const pluginNames1 = postCssLoader1.options.postcssOptions.plugins.map( - (p: unknown) => p[0], + (p: unknown[]) => p[0], ); expect(pluginNames1).toHaveLength(4); expect(pluginNames1).toEqual([ @@ -287,7 +287,7 @@ describe('extending PostCSS', () => { expect(postCssLoader2.loader).toBe('postcss-loader-2'); const pluginNames2 = postCssLoader2.options.postcssOptions.plugins.map( - (p: unknown) => p[0], + (p: unknown[]) => p[0], ); expect(pluginNames2).toHaveLength(4); expect(pluginNames2).toEqual([ diff --git a/packages/docusaurus/src/webpack/aliases/__tests__/index.test.ts b/packages/docusaurus/src/webpack/aliases/__tests__/index.test.ts index b2154a41f5db..ae831259198f 100644 --- a/packages/docusaurus/src/webpack/aliases/__tests__/index.test.ts +++ b/packages/docusaurus/src/webpack/aliases/__tests__/index.test.ts @@ -13,6 +13,7 @@ import { sortAliases, createAliasesForTheme, } from '../index'; +import type {LoadedPlugin} from '@docusaurus/types'; describe('sortAliases', () => { // https://github.com/facebook/docusaurus/issues/6878 @@ -197,7 +198,7 @@ describe('loadThemeAliases', () => { plugins: [ {getThemePath: () => theme1Path}, {getThemePath: () => theme2Path}, - ], + ] as LoadedPlugin[], }); // Testing entries, because order matters! From cd21a31005eefb4e04124d3cd1f53334e1f76254 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Wed, 25 May 2022 15:38:44 +0800 Subject: [PATCH 07/43] test: strengthen internal types (#7488) --- jest/deps.d.ts | 13 +++++++-- .../__tests__/index.test.ts | 12 ++++----- packages/docusaurus-migrate/src/index.ts | 2 +- packages/docusaurus-migrate/src/types.ts | 27 +++++++++---------- .../src/__tests__/index.test.ts | 11 ++++---- .../src/utils/reactUtils.tsx | 2 +- .../src/theme/SearchBar/index.tsx | 4 ++- .../src/__tests__/validationUtils.test.ts | 7 +++-- .../src/client/PendingNavigation.tsx | 6 ++--- packages/docusaurus/src/commands/deploy.ts | 20 +++++++------- .../commands/swizzle/__tests__/index.test.ts | 2 +- .../server/plugins/__tests__/index.test.ts | 2 +- .../docs/api/plugins/plugin-content-docs.md | 4 +-- website/docs/api/plugins/plugin-pwa.md | 6 ++--- .../markdown-features-toc.mdx | 4 +-- 15 files changed, 67 insertions(+), 55 deletions(-) diff --git a/jest/deps.d.ts b/jest/deps.d.ts index a0694f5b8128..16ad1b75fdbd 100644 --- a/jest/deps.d.ts +++ b/jest/deps.d.ts @@ -7,9 +7,18 @@ // modules only used in tests -declare module 'to-vfile'; +declare module 'to-vfile' { + import type {VFile} from 'vfile'; -declare module 'remark-mdx'; + export function read(path: string, encoding?: string): Promise; +} + +declare module 'remark-mdx' { + import type {Plugin} from 'unified'; + + const mdx: Plugin; + export = mdx; +} declare module '@testing-utils/git' { const createTempRepo: typeof import('./utils/git').createTempRepo; diff --git a/packages/docusaurus-cssnano-preset/src/remove-overridden-custom-properties/__tests__/index.test.ts b/packages/docusaurus-cssnano-preset/src/remove-overridden-custom-properties/__tests__/index.test.ts index 8e50db5a74bd..9ce352bd90c5 100644 --- a/packages/docusaurus-cssnano-preset/src/remove-overridden-custom-properties/__tests__/index.test.ts +++ b/packages/docusaurus-cssnano-preset/src/remove-overridden-custom-properties/__tests__/index.test.ts @@ -10,8 +10,8 @@ import vfile from 'to-vfile'; import postcss from 'postcss'; import postCssRemoveOverriddenCustomProperties from '../index'; -const processFixture = (name: string) => { - const input = vfile.readSync( +const processFixture = async (name: string) => { + const input = await vfile.read( path.join(__dirname, '__fixtures__', `${name}.css`), 'utf8', ); @@ -23,11 +23,11 @@ const processFixture = (name: string) => { }; describe('remove-overridden-custom-properties', () => { - it('overridden custom properties should be removed', () => { - expect(processFixture('normal')).toMatchSnapshot(); + it('overridden custom properties should be removed', async () => { + await expect(processFixture('normal')).resolves.toMatchSnapshot(); }); - it('overridden custom properties with `!important` rule should not be removed', () => { - expect(processFixture('important_rule')).toMatchSnapshot(); + it('overridden custom properties with `!important` rule should not be removed', async () => { + await expect(processFixture('important_rule')).resolves.toMatchSnapshot(); }); }); diff --git a/packages/docusaurus-migrate/src/index.ts b/packages/docusaurus-migrate/src/index.ts index 165c7c2fd32f..f5bf38134bc0 100644 --- a/packages/docusaurus-migrate/src/index.ts +++ b/packages/docusaurus-migrate/src/index.ts @@ -552,7 +552,7 @@ async function migrateVersionedSidebar( (topLevel: SidebarEntries, value) => { const key = value[0].replace(versionRegex, ''); topLevel[key] = Object.entries(value[1]).reduce<{ - [key: string]: Array; + [key: string]: (string | {[key: string]: unknown})[]; }>((acc, val) => { acc[val[0].replace(versionRegex, '')] = ( val[1] as SidebarEntry[] diff --git a/packages/docusaurus-migrate/src/types.ts b/packages/docusaurus-migrate/src/types.ts index 022139f3489d..39b5fc2d53ae 100644 --- a/packages/docusaurus-migrate/src/types.ts +++ b/packages/docusaurus-migrate/src/types.ts @@ -34,7 +34,7 @@ export type SidebarEntry = export type SidebarEntries = { [key: string]: | {[key: string]: unknown} - | Array<{[key: string]: unknown} | string>; + | ({[key: string]: unknown} | string)[]; }; export type VersionTwoConfig = { @@ -49,7 +49,7 @@ export type VersionTwoConfig = { githubHost?: string; onBrokenLinks: string; onBrokenMarkdownLinks: string; - plugins: Array<[string, {[key: string]: unknown}]>; + plugins: [string, {[key: string]: unknown}][]; themes?: []; presets: [[string, ClassicPresetEntries]]; themeConfig: { @@ -58,17 +58,14 @@ export type VersionTwoConfig = { logo?: { src?: string; }; - items: Array<{[key: string]: unknown} | null>; + items: ({[key: string]: unknown} | null)[]; }; image?: string; footer: { - links: Array<{ + links: { title: string; - items: Array<{ - label: string; - to: string; - }>; - }>; + items: {label: string; to: string}[]; + }[]; copyright?: string; logo: { src?: string; @@ -104,26 +101,26 @@ export type VersionOneConfig = { organizationName?: string; projectName?: string; noIndex?: boolean; - headerLinks?: Array<{doc: string; href: string; label: string; page: string}>; + headerLinks?: {doc: string; href: string; label: string; page: string}[]; headerIcon?: string; favicon?: string; colors?: {primaryColor: string}; copyright?: string; editUrl?: string; customDocsPath?: string; - users?: Array<{[key: string]: unknown}>; + users?: {[key: string]: unknown}[]; disableHeaderTitle?: string; disableTitleTagline?: string; - separateCss?: Array<{[key: string]: unknown}>; + separateCss?: {[key: string]: unknown}[]; footerIcon?: string; translationRecruitingLink?: string; algolia?: {[key: string]: unknown}; gaTrackingId?: string; gaGtag?: boolean; highlight?: {[key: string]: unknown}; - markdownPlugins?: Array<() => void>; - scripts?: Array<{src: string; [key: string]: unknown} | string>; - stylesheets?: Array<{href: string; [key: string]: unknown} | string>; + markdownPlugins?: (() => void)[]; + scripts?: ({src: string; [key: string]: unknown} | string)[]; + stylesheets?: ({href: string; [key: string]: unknown} | string)[]; facebookAppId?: string; facebookComments?: true; facebookPixelId?: string; diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index 746288ca95e9..11e54417d884 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -31,6 +31,7 @@ import type { Options, PluginOptions, PropSidebarItemLink, + PropSidebars, } from '@docusaurus/plugin-content-docs'; import type { SidebarItemsGeneratorOption, @@ -82,7 +83,7 @@ const createFakeActions = (contentDir: string) => { // Query by prefix, because files have a hash at the end so it's not // convenient to query by full filename - const getCreatedDataByPrefix = (prefix: string) => { + function getCreatedDataByPrefix(prefix: string) { const entry = Object.entries(dataContainer).find(([key]) => key.startsWith(prefix), ); @@ -92,8 +93,8 @@ Entries created: - ${Object.keys(dataContainer).join('\n- ')} `); } - return JSON.parse(entry[1] as string); - }; + return JSON.parse(entry[1] as string) as PropSidebars; + } // Extra fns useful for tests! const utils = { @@ -571,8 +572,8 @@ describe('versioned website (community)', () => { allContent: {}, }); - utils.checkVersionMetadataPropCreated(currentVersion!); - utils.checkVersionMetadataPropCreated(version100!); + utils.checkVersionMetadataPropCreated(currentVersion); + utils.checkVersionMetadataPropCreated(version100); utils.expectSnapshot(); }); diff --git a/packages/docusaurus-theme-common/src/utils/reactUtils.tsx b/packages/docusaurus-theme-common/src/utils/reactUtils.tsx index 4a7410e3fb6d..4e0982807121 100644 --- a/packages/docusaurus-theme-common/src/utils/reactUtils.tsx +++ b/packages/docusaurus-theme-common/src/utils/reactUtils.tsx @@ -71,6 +71,6 @@ export class ReactContextError extends Error { this.message = `Hook ${ this.stack?.split('\n')[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups! .name ?? '' - } is called outside the <${providerName}>. ${additionalInfo || ''}`; + } is called outside the <${providerName}>. ${additionalInfo ?? ''}`; } } diff --git a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx index bd36e353aa6a..beef496dffcd 100644 --- a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx +++ b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx @@ -120,7 +120,9 @@ function DocSearch({ } return Promise.all([ - import('@docsearch/react/modal'), + import('@docsearch/react/modal') as Promise< + typeof import('@docsearch/react') + >, import('@docsearch/react/style'), import('./styles.css'), ]).then(([{DocSearchModal: Modal}]) => { diff --git a/packages/docusaurus-utils-validation/src/__tests__/validationUtils.test.ts b/packages/docusaurus-utils-validation/src/__tests__/validationUtils.test.ts index 771ff94c855c..0bb0fd99a9f3 100644 --- a/packages/docusaurus-utils-validation/src/__tests__/validationUtils.test.ts +++ b/packages/docusaurus-utils-validation/src/__tests__/validationUtils.test.ts @@ -42,7 +42,7 @@ describe('normalizePluginOptions', () => { it('throws for invalid options', () => { const options = {foo: 1}; expect(() => - normalizePluginOptions(Joi.object({foo: Joi.string()}), options), + normalizePluginOptions(Joi.object({foo: Joi.string()}), options), ).toThrowErrorMatchingInlineSnapshot(`""foo" must be a string"`); }); @@ -90,7 +90,10 @@ describe('normalizeThemeConfig', () => { it('throws for invalid options', () => { const themeConfig = {foo: 1, bar: 1}; expect(() => - normalizeThemeConfig(Joi.object({foo: Joi.string()}), themeConfig), + normalizeThemeConfig( + Joi.object({foo: Joi.string()}), + themeConfig, + ), ).toThrowErrorMatchingInlineSnapshot(`""foo" must be a string"`); }); diff --git a/packages/docusaurus/src/client/PendingNavigation.tsx b/packages/docusaurus/src/client/PendingNavigation.tsx index 24e1e38faa2d..e1e38f40f817 100644 --- a/packages/docusaurus/src/client/PendingNavigation.tsx +++ b/packages/docusaurus/src/client/PendingNavigation.tsx @@ -35,7 +35,7 @@ class PendingNavigation extends React.Component { ? dispatchLifecycleAction('onRouteUpdate', { previousLocation: null, location: this.props.location, - })! + }) : () => {}; this.state = { nextRouteHasLoaded: true, @@ -60,14 +60,14 @@ class PendingNavigation extends React.Component { this.routeUpdateCleanupCb = dispatchLifecycleAction('onRouteUpdate', { previousLocation: this.previousLocation, location: nextLocation, - })!; + }); // Load data while the old screen remains. Force preload instead of using // `window.docusaurus`, because we want to avoid loading screen even when // user is on saveData preload(nextLocation.pathname) .then(() => { - this.routeUpdateCleanupCb?.(); + this.routeUpdateCleanupCb(); this.setState({nextRouteHasLoaded: true}); }) .catch((e: unknown) => console.warn(e)); diff --git a/packages/docusaurus/src/commands/deploy.ts b/packages/docusaurus/src/commands/deploy.ts index e35783ddb745..9b5f233f5bf4 100644 --- a/packages/docusaurus/src/commands/deploy.ts +++ b/packages/docusaurus/src/commands/deploy.ts @@ -69,7 +69,7 @@ This behavior can have SEO impacts and create relative link issues. // The source branch; defaults to the currently checked out branch const sourceBranch = - process.env.CURRENT_BRANCH || + process.env.CURRENT_BRANCH ?? shell.exec('git rev-parse --abbrev-ref HEAD', {silent: true}).stdout.trim(); const gitUser = process.env.GIT_USER; @@ -90,8 +90,8 @@ This behavior can have SEO impacts and create relative link issues. } const organizationName = - process.env.ORGANIZATION_NAME || - process.env.CIRCLE_PROJECT_USERNAME || + process.env.ORGANIZATION_NAME ?? + process.env.CIRCLE_PROJECT_USERNAME ?? siteConfig.organizationName; if (!organizationName) { throw new Error( @@ -101,8 +101,8 @@ This behavior can have SEO impacts and create relative link issues. logger.info`organizationName: name=${organizationName}`; const projectName = - process.env.PROJECT_NAME || - process.env.CIRCLE_PROJECT_REPONAME || + process.env.PROJECT_NAME ?? + process.env.CIRCLE_PROJECT_REPONAME ?? siteConfig.projectName; if (!projectName) { throw new Error( @@ -113,7 +113,7 @@ This behavior can have SEO impacts and create relative link issues. // We never deploy on pull request. const isPullRequest = - process.env.CI_PULL_REQUEST || process.env.CIRCLE_PULL_REQUEST; + process.env.CI_PULL_REQUEST ?? process.env.CIRCLE_PULL_REQUEST; if (isPullRequest) { shell.echo('Skipping deploy on a pull request.'); shell.exit(0); @@ -136,12 +136,12 @@ You can also set the deploymentBranch property in docusaurus.config.js .`); } const deploymentBranch = - process.env.DEPLOYMENT_BRANCH || siteConfig.deploymentBranch || 'gh-pages'; + process.env.DEPLOYMENT_BRANCH ?? siteConfig.deploymentBranch ?? 'gh-pages'; logger.info`deploymentBranch: name=${deploymentBranch}`; const githubHost = - process.env.GITHUB_HOST || siteConfig.githubHost || 'github.com'; - const githubPort = process.env.GITHUB_PORT || siteConfig.githubPort; + process.env.GITHUB_HOST ?? siteConfig.githubHost ?? 'github.com'; + const githubPort = process.env.GITHUB_PORT ?? siteConfig.githubPort; let deploymentRepoURL: string; if (useSSH) { @@ -214,7 +214,7 @@ You can also set the deploymentBranch property in docusaurus.config.js .`); shellExecLog('git add --all'); const commitMessage = - process.env.CUSTOM_COMMIT_MESSAGE || + process.env.CUSTOM_COMMIT_MESSAGE ?? `Deploy website - based on ${currentCommit}`; const commitResults = shellExecLog(`git commit -m "${commitMessage}"`); if ( diff --git a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts index 74e94678f3c2..462c44c1a09e 100644 --- a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts +++ b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts @@ -65,7 +65,7 @@ function createExitMock() { }); // eslint-disable-next-line jest/require-top-level-describe afterEach(async () => { - mock?.mockRestore(); + mock.mockRestore(); }); return { diff --git a/packages/docusaurus/src/server/plugins/__tests__/index.test.ts b/packages/docusaurus/src/server/plugins/__tests__/index.test.ts index 2d85798e3633..0ace57b22cd9 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/index.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/index.test.ts @@ -28,7 +28,7 @@ describe('loadPlugins', () => { name: 'test1', prop: 'a', async loadContent() { - // Testing that plugin lifecycle is bound to the plugin instance + // Testing that plugin lifecycle is bound to the instance return this.prop; }, async contentLoaded({content, actions}) { diff --git a/website/docs/api/plugins/plugin-content-docs.md b/website/docs/api/plugins/plugin-content-docs.md index e5971ee2fa59..331c7cb0a9f9 100644 --- a/website/docs/api/plugins/plugin-content-docs.md +++ b/website/docs/api/plugins/plugin-content-docs.md @@ -96,14 +96,14 @@ type SidebarGenerator = (generatorArgs: { /** Useful metadata for the version this sidebar belongs to. */ version: {contentPath: string; versionName: string}; /** All the docs of that version (unfiltered). */ - docs: Array<{ + docs: { id: string; title: string; frontMatter: DocFrontMatter & Record; source: string; sourceDirName: string; sidebarPosition?: number | undefined; - }>; + }[]; /** Number prefix parser configured for this plugin. */ numberPrefixParser: PrefixParser; /** The default category index matcher which you can override. */ diff --git a/website/docs/api/plugins/plugin-pwa.md b/website/docs/api/plugins/plugin-pwa.md index 1a7ab67bbe01..7dc019fe97fb 100644 --- a/website/docs/api/plugins/plugin-pwa.md +++ b/website/docs/api/plugins/plugin-pwa.md @@ -112,8 +112,8 @@ Turn debug mode on: ### `offlineModeActivationStrategies` {#offlinemodeactivationstrategies} -- Type: `Array<'appInstalled' | 'mobile' | 'saveData'| 'queryString' | 'always'>` -- Default: `['appInstalled','queryString','standalone']` +- Type: `('appInstalled' | 'mobile' | 'saveData'| 'queryString' | 'always')[]` +- Default: `['appInstalled', 'queryString', 'standalone']` Strategies used to turn the offline mode on: @@ -194,7 +194,7 @@ The default theme includes an implementation for the reload popup and uses [Infi ### `pwaHead` {#pwahead} -- Type: `Array<{ tagName: string } & Record>` +- Type: `({ tagName: string; [attributeName: string]: string })[]` - Default: `[]` Array of objects containing `tagName` and key-value pairs for attributes to inject into the `` tag. Technically you can inject any head tag through this, but it's ideally used for tags to make your site PWA compliant. Here's a list of tag to make your app fully compliant: diff --git a/website/docs/guides/markdown-features/markdown-features-toc.mdx b/website/docs/guides/markdown-features/markdown-features-toc.mdx index 18e2d5d17614..1cc1ed43d27c 100644 --- a/website/docs/guides/markdown-features/markdown-features-toc.mdx +++ b/website/docs/guides/markdown-features/markdown-features-toc.mdx @@ -83,11 +83,11 @@ import TOCInline from '@theme/TOCInline'; The `toc` global is just a list of heading items: ```ts -declare const toc: Array<{ +declare const toc: { value: string; id: string; level: number; -}>; +}[]; ``` Note that the `toc` global is a flat array, so you can easily cut out unwanted nodes or insert extra nodes, and create a new TOC tree. From 5fcb742aa1a378833e83607f8ca7249db8fce261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Peer=20St=C3=B6cklmair?= Date: Wed, 25 May 2022 12:41:05 +0200 Subject: [PATCH 08/43] feat(theme-classic): allow className as option for type: "search" (#7357) * feat(theme-classic): allow className as option for type: "search" * fixup! feat(theme-classic): allow className as option for type: "search" * refactor Co-authored-by: Jan Peer Stoecklmair Co-authored-by: Joshua Chen --- .../src/__tests__/validateThemeConfig.test.ts | 6 ++++++ packages/docusaurus-theme-classic/src/theme-classic.d.ts | 2 ++ .../src/theme/Navbar/Content/index.tsx | 4 ++-- .../src/theme/Navbar/Search/index.tsx | 8 ++++++-- .../src/theme/NavbarItem/SearchNavbarItem.tsx | 7 +++++-- .../docusaurus-theme-classic/src/validateThemeConfig.ts | 1 + website/docs/api/themes/theme-configuration.md | 1 + 7 files changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts index da76d5edd34e..850eeb044255 100644 --- a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts @@ -243,6 +243,12 @@ describe('themeConfig', () => { position: 'left', label: 'Current version', }, + // Search with className + { + type: 'search', + position: 'right', + className: 'search-bar-wrapper', + }, ], }, }; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index bc9b9c9bbaf3..82ebfdf45d1b 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -777,6 +777,7 @@ declare module '@theme/Navbar/Search' { export interface Props { readonly children: ReactNode; + readonly className?: string; } export default function NavbarSearch(props: Props): JSX.Element; @@ -834,6 +835,7 @@ declare module '@theme/NavbarItem/DropdownNavbarItem' { declare module '@theme/NavbarItem/SearchNavbarItem' { export interface Props { readonly mobile?: boolean; + readonly className?: string; } export default function SearchNavbarItem(props: Props): JSX.Element; diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx b/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx index cf087e6cefd5..c81437a3fa8b 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/Content/index.tsx @@ -56,7 +56,7 @@ export default function NavbarContent(): JSX.Element { const items = useNavbarItems(); const [leftItems, rightItems] = splitNavbarItems(items); - const autoAddSearchBar = !items.some((item) => item.type === 'search'); + const searchBarItem = items.find((item) => item.type === 'search'); return ( - {autoAddSearchBar && ( + {!searchBarItem && ( diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/Search/index.tsx b/packages/docusaurus-theme-classic/src/theme/Navbar/Search/index.tsx index 8d3fe1b19d2f..236d237aa082 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/Search/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/Search/index.tsx @@ -6,10 +6,14 @@ */ import React from 'react'; +import clsx from 'clsx'; import type {Props} from '@theme/Navbar/Search'; import styles from './styles.module.css'; -export default function NavbarSearch({children}: Props): JSX.Element { - return
    {children}
    ; +export default function NavbarSearch({ + children, + className, +}: Props): JSX.Element { + return
    {children}
    ; } diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/SearchNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/SearchNavbarItem.tsx index 9e95436025b2..f401f8f17621 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/SearchNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/SearchNavbarItem.tsx @@ -10,13 +10,16 @@ import SearchBar from '@theme/SearchBar'; import NavbarSearch from '@theme/Navbar/Search'; import type {Props} from '@theme/NavbarItem/SearchNavbarItem'; -export default function SearchNavbarItem({mobile}: Props): JSX.Element | null { +export default function SearchNavbarItem({ + mobile, + className, +}: Props): JSX.Element | null { if (mobile) { return null; } return ( - + ); diff --git a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts index d5bdb78e53e7..d64b671f0270 100644 --- a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts @@ -200,6 +200,7 @@ const LocaleDropdownNavbarItemSchema = NavbarItemBaseSchema.append({ const SearchItemSchema = Joi.object({ type: Joi.string().equal('search').required(), + className: Joi.string(), }); const NavbarItemSchema = Joi.object({ diff --git a/website/docs/api/themes/theme-configuration.md b/website/docs/api/themes/theme-configuration.md index 02e3c66db8f5..d1291bbc3cbc 100644 --- a/website/docs/api/themes/theme-configuration.md +++ b/website/docs/api/themes/theme-configuration.md @@ -602,6 +602,7 @@ However, with this special navbar item type, you can change the default location | --- | --- | --- | --- | | `type` | `'search'` | **Required** | Sets the type of this item to a search bar. | | `position` | 'left' \| 'right' | `'left'` | The side of the navbar this item should appear on. | +| `className` | `string` | / | Custom CSS class for this navbar item. | From f609acab4f4ea2bf001432e216c3ddb3f362abdf Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Thu, 26 May 2022 01:01:29 +0800 Subject: [PATCH 09/43] fix(theme-classic): consistently apply the right active class name for all navbar items (#7430) --- .../src/getSwizzleConfig.ts | 7 ------- .../src/theme-classic.d.ts | 14 ++------------ .../src/theme/NavbarItem/DefaultNavbarItem.tsx | 5 +++-- .../src/theme/NavbarItem/DocNavbarItem.tsx | 16 ++++------------ .../theme/NavbarItem/DocSidebarNavbarItem.tsx | 9 +-------- .../NavbarItem/DocsVersionDropdownNavbarItem.tsx | 1 - .../src/theme/NavbarItem/DropdownNavbarItem.tsx | 12 ++++++------ .../LocaleDropdownNavbarItem/index.tsx | 12 ++++++++++-- .../src/theme/NavbarItem/NavbarNavLink.tsx | 8 +------- .../src/theme/NavbarItem/utils.ts | 13 ------------- 10 files changed, 27 insertions(+), 70 deletions(-) delete mode 100644 packages/docusaurus-theme-classic/src/theme/NavbarItem/utils.ts diff --git a/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts b/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts index 0c34618bdc32..a0549256e98f 100644 --- a/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts +++ b/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts @@ -214,13 +214,6 @@ export default function getSwizzleConfig(): SwizzleConfig { description: 'The Navbar item components mapping. Can be ejected to add custom navbar item types. See https://github.com/facebook/docusaurus/issues/7227.', }, - // TODO should probably not even appear here - 'NavbarItem/utils': { - actions: { - eject: 'forbidden', - wrap: 'forbidden', - }, - }, NotFound: { actions: { eject: 'safe', diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 82ebfdf45d1b..1986158d8e22 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -809,7 +809,8 @@ declare module '@theme/NavbarItem/NavbarNavLink' { readonly exact?: boolean; readonly label?: ReactNode; readonly html?: string; - readonly prependBaseUrlToHref?: string; + readonly prependBaseUrlToHref?: boolean; + readonly isDropdownLink?: boolean; } export default function NavbarNavLink(props: Props): JSX.Element; @@ -982,17 +983,6 @@ declare module '@theme/NavbarItem' { export default function NavbarItem(props: Props): JSX.Element; } -declare module '@theme/NavbarItem/utils' { - /** - * On desktop and mobile, we would apply different class names for dropdown - * items. - * @see https://github.com/facebook/docusaurus/pull/5431 - */ - export function getInfimaActiveClassName( - mobile?: boolean, - ): `${'menu' | 'navbar'}__link--active`; -} - declare module '@theme/PaginatorNavLink' { import type {ReactNode} from 'react'; import type {PropNavigationLink} from '@docusaurus/plugin-content-docs'; diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx index 7036b2b6c12e..948d6507d7bc 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx @@ -8,7 +8,6 @@ import React from 'react'; import clsx from 'clsx'; import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink'; -import {getInfimaActiveClassName} from '@theme/NavbarItem/utils'; import type { DesktopOrMobileNavBarItemProps, Props, @@ -25,6 +24,7 @@ function DefaultNavbarItemDesktop({ isDropdownItem ? 'dropdown__link' : 'navbar__item navbar__link', className, )} + isDropdownLink={isDropdownItem} {...props} /> ); @@ -58,7 +58,8 @@ export default function DefaultNavbarItem({ ); diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocNavbarItem.tsx index 797ef1ec2d50..76df1591ba90 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocNavbarItem.tsx @@ -6,11 +6,9 @@ */ import React from 'react'; -import clsx from 'clsx'; import {useActiveDocContext} from '@docusaurus/plugin-content-docs/client'; import {useLayoutDoc} from '@docusaurus/theme-common'; import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; -import {getInfimaActiveClassName} from '@theme/NavbarItem/utils'; import type {Props} from '@theme/NavbarItem/DocNavbarItem'; export default function DocNavbarItem({ @@ -27,20 +25,14 @@ export default function DocNavbarItem({ return null; } - const activeDocInfimaClassName = getInfimaActiveClassName(props.mobile); - return ( + activeDoc?.path === doc.path || + (!!activeDoc?.sidebar && activeDoc.sidebar === doc.sidebar) + } label={staticLabel ?? doc.id} to={doc.path} /> diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx index 874605bcf1a1..08771f8aa6c7 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx @@ -6,11 +6,9 @@ */ import React from 'react'; -import clsx from 'clsx'; import {useActiveDocContext} from '@docusaurus/plugin-content-docs/client'; import {useLayoutDocsSidebar} from '@docusaurus/theme-common'; import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; -import {getInfimaActiveClassName} from '@theme/NavbarItem/utils'; import type {Props} from '@theme/NavbarItem/DocSidebarNavbarItem'; export default function DocSidebarNavbarItem({ @@ -26,16 +24,11 @@ export default function DocSidebarNavbarItem({ `DocSidebarNavbarItem: Sidebar with ID "${sidebarId}" doesn't have anything to be linked to.`, ); } - const activeDocInfimaClassName = getInfimaActiveClassName(props.mobile); - return ( activeDoc?.sidebar === sidebarId} label={label ?? sidebarLink.label} to={sidebarLink.path} /> diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx index 47903ce0aa35..8893306f7abd 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx @@ -41,7 +41,6 @@ export default function DocsVersionDropdownNavbarItem({ activeDocContext.alternateDocVersions[version.name] ?? getVersionMainDoc(version); return { - isNavLink: true, label: version.label, to: versionDoc.path, isActive: () => version === activeDocContext.activeVersion, diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx index 45c61dac60e7..3678d9d0bb03 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DropdownNavbarItem.tsx @@ -21,8 +21,6 @@ import type { Props, } from '@theme/NavbarItem/DropdownNavbarItem'; -const dropdownLinkActiveClass = 'dropdown__link--active'; - function isItemActive( item: LinkLikeNavbarItemProps, localPathname: string, @@ -50,6 +48,7 @@ function DropdownNavbarItemDesktop({ items, position, className, + onClick, ...props }: DesktopOrMobileNavBarItemProps) { const dropdownRef = useRef(null); @@ -113,12 +112,12 @@ function DropdownNavbarItemDesktop({ ? nextNavbarItem : // Next item is another dropdown; focus on the inner // anchor element instead so there's outline - nextNavbarItem.querySelector('a'); - (targetItem as HTMLElement).focus(); + nextNavbarItem.querySelector('a')!; + targetItem.focus(); } } }} - activeClassName={dropdownLinkActiveClass} + activeClassName="dropdown__link--active" {...childItemProps} key={i} /> @@ -132,6 +131,7 @@ function DropdownNavbarItemMobile({ items, className, position, // Need to destructure position from props so that it doesn't get passed on. + onClick, ...props }: DesktopOrMobileNavBarItemProps) { const localPathname = useLocalPathname(); @@ -171,7 +171,7 @@ function DropdownNavbarItemMobile({ activeBaseRegex diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/utils.ts b/packages/docusaurus-theme-classic/src/theme/NavbarItem/utils.ts deleted file mode 100644 index a98db455f25e..000000000000 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/utils.ts +++ /dev/null @@ -1,13 +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. - */ - -/* eslint-disable import/no-named-export */ - -export const getInfimaActiveClassName = ( - mobile?: boolean, -): `${'menu' | 'navbar'}__link--active` => - mobile ? 'menu__link--active' : 'navbar__link--active'; From 89ddc6d258d1ad8ddb48bf9760abeda38b12a931 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Thu, 26 May 2022 01:02:32 -0400 Subject: [PATCH 10/43] misc: avoid using fs.realpathSync in website (#7496) * dogfood fix * remove other mentions Co-authored-by: Joshua Chen --- website/_dogfooding/README.md | 1 - website/_dogfooding/docs-tests-symlink | 1 - website/_dogfooding/dogfooding.config.js | 8 ++------ 3 files changed, 2 insertions(+), 8 deletions(-) delete mode 120000 website/_dogfooding/docs-tests-symlink diff --git a/website/_dogfooding/README.md b/website/_dogfooding/README.md index 0b6ba0b479f0..8acadfac2e9b 100644 --- a/website/_dogfooding/README.md +++ b/website/_dogfooding/README.md @@ -11,7 +11,6 @@ Eventually, we could move these tests later so another test site? Note there is Fancy things we can test for here: - Plugin Multi-instance -- Symlinks support - Webpack configs - \_ prefix convention - Huge sidebars impact diff --git a/website/_dogfooding/docs-tests-symlink b/website/_dogfooding/docs-tests-symlink deleted file mode 120000 index 4a3222e9fd36..000000000000 --- a/website/_dogfooding/docs-tests-symlink +++ /dev/null @@ -1 +0,0 @@ -_docs tests \ No newline at end of file diff --git a/website/_dogfooding/dogfooding.config.js b/website/_dogfooding/dogfooding.config.js index 95c1d5161843..b6239f787b42 100644 --- a/website/_dogfooding/dogfooding.config.js +++ b/website/_dogfooding/dogfooding.config.js @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -const fs = require('fs'); - /** @type {import('@docusaurus/types').PluginConfig[]} */ const dogfoodingThemeInstances = [ /** @type {import('@docusaurus/types').PluginModule} */ @@ -29,10 +27,8 @@ const dogfoodingPluginInstances = [ routeBasePath: '/tests/docs', sidebarPath: '_dogfooding/docs-tests-sidebars.js', - // Using a symlinked folder as source, test for use-case https://github.com/facebook/docusaurus/issues/3272 - // The target folder uses a _ prefix to test against an edge case regarding MDX partials: https://github.com/facebook/docusaurus/discussions/5181#discussioncomment-1018079 - // eslint-disable-next-line no-restricted-properties - path: fs.realpathSync('_dogfooding/docs-tests-symlink'), + // 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', showLastUpdateTime: true, sidebarItemsGenerator(args) { return args.defaultSidebarItemsGenerator({ From f94701569b35f8ee59a02580c60ff7c34acbb7b0 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Thu, 26 May 2022 03:06:22 -0400 Subject: [PATCH 11/43] fix: avoid printing period after localhost URL (#7499) * fix: output of URL * fix: adding formatting to start.ts --- packages/docusaurus/src/commands/serve.ts | 4 ++-- packages/docusaurus/src/commands/start.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/docusaurus/src/commands/serve.ts b/packages/docusaurus/src/commands/serve.ts index 64845cb5ced4..7777d448f734 100644 --- a/packages/docusaurus/src/commands/serve.ts +++ b/packages/docusaurus/src/commands/serve.ts @@ -76,8 +76,8 @@ export async function serve( }); }); - logger.success`Serving path=${buildDir} directory at url=${ + logger.success`Serving path=${buildDir} directory at: url=${ servingUrl + baseUrl - }.`; + }`; server.listen(port); } diff --git a/packages/docusaurus/src/commands/start.ts b/packages/docusaurus/src/commands/start.ts index a0cae8416493..f49874839d68 100644 --- a/packages/docusaurus/src/commands/start.ts +++ b/packages/docusaurus/src/commands/start.ts @@ -67,7 +67,7 @@ export async function start( const urls = prepareUrls(protocol, host, port); const openUrl = normalizeUrl([urls.localUrlForBrowser, baseUrl]); - logger.success`Docusaurus website is running at url=${openUrl}.`; + logger.success`Docusaurus website is running at: url=${openUrl}`; // Reload files processing. const reload = _.debounce(() => { @@ -75,7 +75,7 @@ export async function start( .then(({baseUrl: newBaseUrl}) => { const newOpenUrl = normalizeUrl([urls.localUrlForBrowser, newBaseUrl]); if (newOpenUrl !== openUrl) { - logger.success`Docusaurus website is running at url=${newOpenUrl}.`; + logger.success`Docusaurus website is running at: url=${newOpenUrl}`; } }) .catch((err: Error) => { From 4f97c7b52c5621af201a62912848b73ddcdf4b7a Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Thu, 26 May 2022 03:06:36 -0400 Subject: [PATCH 12/43] docs: link every reference of types in API table to the type definition (#7497) * dogfood fix * feat: links for plugin types * better syntax * little refactor * use code title * complete the rest Co-authored-by: Joshua Chen --- .../api/plugins/plugin-client-redirects.md | 12 ++++- .../docs/api/plugins/plugin-content-blog.md | 24 +++++++--- .../docs/api/plugins/plugin-content-docs.md | 48 +++++++++++++------ 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/website/docs/api/plugins/plugin-client-redirects.md b/website/docs/api/plugins/plugin-client-redirects.md index 3b881f58810a..991ea778ad91 100644 --- a/website/docs/api/plugins/plugin-client-redirects.md +++ b/website/docs/api/plugins/plugin-client-redirects.md @@ -41,17 +41,25 @@ Accepted fields: | --- | --- | --- | --- | | `fromExtensions` | `string[]` | `[]` | The extensions to be removed from the route after redirecting. | | `toExtensions` | `string[]` | `[]` | The extensions to be appended to the route after redirecting. | -| `redirects` | `RedirectRule[]` | `[]` | The list of redirect rules. | -| `createRedirects` | `CreateRedirectsFn` | `undefined` | A callback to create a redirect rule. | +| `redirects` | RedirectRule[] | `[]` | The list of redirect rules. | +| `createRedirects` | CreateRedirectsFn | `undefined` | A callback to create a redirect rule. | +### Types {#types} + +#### `RedirectRule` {#RedirectRule} + ```ts type RedirectRule = { to: string; from: string | string[]; }; +``` +#### `CreateRedirectsFn` {#CreateRedirectsFn} + +```ts type CreateRedirectsFn = (path: string) => string[] | string | null | undefined; ``` diff --git a/website/docs/api/plugins/plugin-content-blog.md b/website/docs/api/plugins/plugin-content-blog.md index 27db9055ecc6..8cdc51d7c668 100644 --- a/website/docs/api/plugins/plugin-content-blog.md +++ b/website/docs/api/plugins/plugin-content-blog.md @@ -38,7 +38,7 @@ Accepted fields: | Name | Type | Default | Description | | --- | --- | --- | --- | | `path` | `string` | `'blog'` | Path to the blog content directory on the file system, relative to site dir. | -| `editUrl` | string \| EditUrlFunction | `undefined` | 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 \| EditUrlFn | `undefined` | 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. | | `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | | `blogTitle` | `string` | `'Blog'` | Blog page title for better SEO. | | `blogDescription` | `string` | `'Blog'` | Blog page meta description for better SEO. | @@ -61,10 +61,10 @@ Accepted fields: | `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | | `truncateMarker` | `RegExp` | `//` | Truncate marker marking where the summary ends. | | `showReadingTime` | `boolean` | `true` | Show estimated reading time for the blog post. | -| `readingTime` | `ReadingTimeFunctionOption` | The default reading time | A callback to customize the reading time number displayed. | +| `readingTime` | `ReadingTimeFn` | The default reading time | A callback to customize the reading time number displayed. | | `authorsMapPath` | `string` | `'authors.yml'` | Path to the authors map file, relative to the blog content directory. | | `feedOptions` | _See below_ | `{type: ['rss', 'atom']}` | Blog feed. | -| `feedOptions.type` | FeedType \| FeedType[] \| 'all' \| null | **Required** | Type of feed to be generated. Use `null` to disable generation. | +| `feedOptions.type` | FeedType \| FeedType[] \| 'all' \| null | **Required** | Type of feed to be generated. Use `null` to disable generation. | | `feedOptions.title` | `string` | `siteConfig.title` | Title of the feed. | | `feedOptions.description` | `string` | \`${siteConfig.title} Blog\` | Description of the feed. | | `feedOptions.copyright` | `string` | `undefined` | Copyright message. | @@ -73,6 +73,10 @@ Accepted fields: +### Types {#types} + +#### `EditUrlFn` {#EditUrlFn} + ```ts type EditUrlFunction = (params: { blogDirPath: string; @@ -80,24 +84,32 @@ type EditUrlFunction = (params: { permalink: string; locale: string; }) => string | undefined; +``` + +#### `ReadingTimeFn` {#ReadingTimeFn} +```ts type ReadingTimeOptions = { wordsPerMinute: number; wordBound: (char: string) => boolean; }; -type ReadingTimeFunction = (params: { +type ReadingTimeCalculator = (params: { content: string; frontMatter?: BlogPostFrontMatter & Record; options?: ReadingTimeOptions; }) => number; -type ReadingTimeFunctionOption = (params: { +type ReadingTimeFn = (params: { content: string; frontMatter: BlogPostFrontMatter & Record; - defaultReadingTime: ReadingTimeFunction; + defaultReadingTime: ReadingTimeCalculator; }) => number | undefined; +``` +#### `FeedType` {#FeedType} + +```ts type FeedType = 'rss' | 'atom' | 'json'; ``` diff --git a/website/docs/api/plugins/plugin-content-docs.md b/website/docs/api/plugins/plugin-content-docs.md index 331c7cb0a9f9..a44ce3ca1a5a 100644 --- a/website/docs/api/plugins/plugin-content-docs.md +++ b/website/docs/api/plugins/plugin-content-docs.md @@ -32,7 +32,7 @@ Accepted fields: | Name | Type | Default | Description | | --- | --- | --- | --- | | `path` | `string` | `'docs'` | Path to the docs content directory on the file system, relative to site directory. | -| `editUrl` | string \| EditUrlFunction | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativeDocPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | +| `editUrl` | string \| EditUrlFunction | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativeDocPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | | `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | | `editCurrentVersion` | `boolean` | `false` | The edit URL will always target the current version doc instead of older versions. Ignored when `editUrl` is a function. | | `routeBasePath` | `string` | `'docs'` | URL route for the docs section of your site. **DO NOT** include a trailing slash. Use `/` for shipping docs without base path. | @@ -42,8 +42,8 @@ Accepted fields: | `sidebarPath` | false \| string | `undefined` | Path to sidebar configuration. Use `false` to disable sidebars, or `undefined` to create a fully autogenerated sidebar. | | `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. See also [Collapsible categories](/docs/sidebar#collapsible-categories) | | `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. See also [Expanded categories by default](/docs/sidebar#expanded-categories-by-default) | -| `sidebarItemsGenerator` | `SidebarGenerator` | _Omitted_ | Function used to replace the sidebar items of type `'autogenerated'` with real sidebar items (docs, categories, links...). See also [Customize the sidebar items generator](/docs/sidebar#customize-the-sidebar-items-generator) | -| `numberPrefixParser` | boolean \| PrefixParser | _Omitted_ | Custom parsing logic to extract number prefixes from file names. Use `false` to disable this behavior and leave the docs untouched, and `true` to use the default parser. See also [Using number prefixes](/docs/sidebar#using-number-prefixes) | +| `sidebarItemsGenerator` | SidebarGenerator | _Omitted_ | Function used to replace the sidebar items of type `'autogenerated'` with real sidebar items (docs, categories, links...). See also [Customize the sidebar items generator](/docs/sidebar#customize-the-sidebar-items-generator) | +| `numberPrefixParser` | boolean \| PrefixParser | _Omitted_ | Custom parsing logic to extract number prefixes from file names. Use `false` to disable this behavior and leave the docs untouched, and `true` to use the default parser. See also [Using number prefixes](/docs/sidebar#using-number-prefixes) | | `docLayoutComponent` | `string` | `'@theme/DocPage'` | Root layout component of each doc page. Provides the version data context, and is not unmounted when switching docs. | | `docItemComponent` | `string` | `'@theme/DocItem'` | Main doc container, with TOC, pagination, etc. | | `docTagsListComponent` | `string` | `'@theme/DocTagsListPage'` | Root component of the tags list page | @@ -60,10 +60,14 @@ Accepted fields: | `includeCurrentVersion` | `boolean` | `true` | Include the current version of your docs. | | `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` | `{}` | Independent customization of each version's properties. | +| `versions` | VersionsConfig | `{}` | Independent customization of each version's properties. | +### Types {#types} + +#### `EditUrlFunction` {#EditUrlFunction} + ```ts type EditUrlFunction = (params: { version: string; @@ -72,24 +76,20 @@ type EditUrlFunction = (params: { permalink: string; locale: string; }) => string | undefined; +``` +#### `PrefixParser` {#PrefixParser} + +```ts type PrefixParser = (filename: string) => { filename: string; numberPrefix?: number; }; +``` -type CategoryIndexMatcher = (param: { - /** The file name, without extension */ - fileName: string; - /** - * The list of directories, from lowest level to highest. - * If there's no dir name, directories is ['.'] - */ - directories: string[]; - /** The extension, with a leading dot */ - extension: string; -}) => boolean; +#### `SidebarGenerator` {#SidebarGenerator} +```ts type SidebarGenerator = (generatorArgs: { /** The sidebar item with type "autogenerated" to be transformed. */ item: {type: 'autogenerated'; dirName: string}; @@ -118,8 +118,26 @@ type SidebarGenerator = (generatorArgs: { * Docusaurus. */ defaultSidebarItemsGenerator: SidebarGenerator; + // Returns an array of sidebar items — same as what you can declare in + // sidebars.js, except for shorthands. See https://docusaurus.io/docs/sidebar/items }) => Promise; +type CategoryIndexMatcher = (param: { + /** The file name, without extension */ + fileName: string; + /** + * The list of directories, from lowest level to highest. + * If there's no dir name, directories is ['.'] + */ + directories: string[]; + /** The extension, with a leading dot */ + extension: string; +}) => boolean; +``` + +#### `VersionsConfig` {#VersionsConfig} + +```ts type VersionsConfig = { [versionName: string]: { /** From 47a2cca17df1c83638b421da6b77c3b9faa4dbef Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Thu, 26 May 2022 17:44:18 +0800 Subject: [PATCH 13/43] chore: require Node 16.14 (#7501) --- .github/workflows/tests-e2e.yml | 2 +- .github/workflows/tests-windows.yml | 2 +- .github/workflows/tests.yml | 2 +- .nvmrc | 2 +- packages/create-docusaurus/package.json | 2 +- packages/docusaurus-cssnano-preset/package.json | 3 +++ packages/docusaurus-logger/package.json | 2 +- packages/docusaurus-mdx-loader/package.json | 2 +- packages/docusaurus-migrate/package.json | 2 +- packages/docusaurus-plugin-client-redirects/package.json | 2 +- packages/docusaurus-plugin-content-blog/package.json | 2 +- packages/docusaurus-plugin-content-docs/package.json | 2 +- packages/docusaurus-plugin-content-pages/package.json | 2 +- packages/docusaurus-plugin-debug/package.json | 2 +- packages/docusaurus-plugin-google-analytics/package.json | 2 +- packages/docusaurus-plugin-google-gtag/package.json | 2 +- packages/docusaurus-plugin-ideal-image/package.json | 2 +- packages/docusaurus-plugin-pwa/package.json | 3 +++ packages/docusaurus-plugin-sitemap/package.json | 2 +- packages/docusaurus-preset-classic/package.json | 2 +- packages/docusaurus-remark-plugin-npm2yarn/package.json | 2 +- packages/docusaurus-theme-classic/package.json | 2 +- packages/docusaurus-theme-common/package.json | 2 +- packages/docusaurus-theme-live-codeblock/package.json | 2 +- packages/docusaurus-theme-search-algolia/package.json | 2 +- packages/docusaurus-theme-translations/package.json | 2 +- packages/docusaurus-utils-common/package.json | 2 +- packages/docusaurus-utils-validation/package.json | 2 +- packages/docusaurus-utils/package.json | 2 +- packages/docusaurus/package.json | 2 +- packages/eslint-plugin/package.json | 2 +- packages/lqip-loader/package.json | 2 +- website/docs/installation.md | 2 +- 33 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.github/workflows/tests-e2e.yml b/.github/workflows/tests-e2e.yml index f10f08f65786..92b9f5319f84 100644 --- a/.github/workflows/tests-e2e.yml +++ b/.github/workflows/tests-e2e.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: ['14', '16', '18'] + node: ['16.14', '16', '18'] steps: - name: Checkout uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3 diff --git a/.github/workflows/tests-windows.yml b/.github/workflows/tests-windows.yml index 186833e7d080..d4dbaef8da9f 100644 --- a/.github/workflows/tests-windows.yml +++ b/.github/workflows/tests-windows.yml @@ -22,7 +22,7 @@ jobs: runs-on: windows-latest strategy: matrix: - node: ['14', '16', '18'] + node: ['16.14', '16', '18'] steps: - name: Support longpaths run: git config --system core.longpaths true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a078a2bf3639..502a4812fd64 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: ['14', '16', '18'] + node: ['16.14', '16', '18'] steps: - name: Checkout uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3 diff --git a/.nvmrc b/.nvmrc index 832d38506443..3c032078a4a2 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.14.0 +18 diff --git a/packages/create-docusaurus/package.json b/packages/create-docusaurus/package.json index d7a60dba1c13..46ae2253e1b4 100755 --- a/packages/create-docusaurus/package.json +++ b/packages/create-docusaurus/package.json @@ -36,6 +36,6 @@ "@types/supports-color": "^8.1.1" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-cssnano-preset/package.json b/packages/docusaurus-cssnano-preset/package.json index 6469eba2405a..aec575bf1c3b 100644 --- a/packages/docusaurus-cssnano-preset/package.json +++ b/packages/docusaurus-cssnano-preset/package.json @@ -24,5 +24,8 @@ }, "devDependencies": { "to-vfile": "^6.1.0" + }, + "engines": { + "node": ">=16.14" } } diff --git a/packages/docusaurus-logger/package.json b/packages/docusaurus-logger/package.json index 6c91e0d029ec..2c6dcab1b1c8 100644 --- a/packages/docusaurus-logger/package.json +++ b/packages/docusaurus-logger/package.json @@ -24,7 +24,7 @@ "tslib": "^2.4.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" }, "devDependencies": { "@types/supports-color": "^8.1.1" diff --git a/packages/docusaurus-mdx-loader/package.json b/packages/docusaurus-mdx-loader/package.json index b071b9732ba3..36e190295f02 100644 --- a/packages/docusaurus-mdx-loader/package.json +++ b/packages/docusaurus-mdx-loader/package.json @@ -52,6 +52,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-migrate/package.json b/packages/docusaurus-migrate/package.json index 9d43bdcf7a73..2102cac885c8 100644 --- a/packages/docusaurus-migrate/package.json +++ b/packages/docusaurus-migrate/package.json @@ -4,7 +4,7 @@ "description": "A CLI tool to migrate from older versions of Docusaurus.", "license": "MIT", "engines": { - "node": ">=14" + "node": ">=16.14" }, "scripts": { "build": "tsc --build", diff --git a/packages/docusaurus-plugin-client-redirects/package.json b/packages/docusaurus-plugin-client-redirects/package.json index 426d13b139d2..b0a378708339 100644 --- a/packages/docusaurus-plugin-client-redirects/package.json +++ b/packages/docusaurus-plugin-client-redirects/package.json @@ -36,6 +36,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-content-blog/package.json b/packages/docusaurus-plugin-content-blog/package.json index 5d0dbade229e..85ce797f5e6e 100644 --- a/packages/docusaurus-plugin-content-blog/package.json +++ b/packages/docusaurus-plugin-content-blog/package.json @@ -44,6 +44,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-content-docs/package.json b/packages/docusaurus-plugin-content-docs/package.json index bf59cd020096..0a49a06e77ec 100644 --- a/packages/docusaurus-plugin-content-docs/package.json +++ b/packages/docusaurus-plugin-content-docs/package.json @@ -56,6 +56,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-content-pages/package.json b/packages/docusaurus-plugin-content-pages/package.json index 4e8e2eb7edf5..4ec059c3cfef 100644 --- a/packages/docusaurus-plugin-content-pages/package.json +++ b/packages/docusaurus-plugin-content-pages/package.json @@ -35,6 +35,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-debug/package.json b/packages/docusaurus-plugin-debug/package.json index 3382fcab737a..98f9c72f08cf 100644 --- a/packages/docusaurus-plugin-debug/package.json +++ b/packages/docusaurus-plugin-debug/package.json @@ -34,6 +34,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-google-analytics/package.json b/packages/docusaurus-plugin-google-analytics/package.json index f62db432005c..d97f66f979a6 100644 --- a/packages/docusaurus-plugin-google-analytics/package.json +++ b/packages/docusaurus-plugin-google-analytics/package.json @@ -30,6 +30,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-google-gtag/package.json b/packages/docusaurus-plugin-google-gtag/package.json index c353d7a1a28c..146b913d71da 100644 --- a/packages/docusaurus-plugin-google-gtag/package.json +++ b/packages/docusaurus-plugin-google-gtag/package.json @@ -30,6 +30,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-ideal-image/package.json b/packages/docusaurus-plugin-ideal-image/package.json index 5bda29fd0203..582127cb4bc9 100644 --- a/packages/docusaurus-plugin-ideal-image/package.json +++ b/packages/docusaurus-plugin-ideal-image/package.json @@ -47,6 +47,6 @@ } }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-pwa/package.json b/packages/docusaurus-plugin-pwa/package.json index f47075267b29..429ae3f1b186 100644 --- a/packages/docusaurus-plugin-pwa/package.json +++ b/packages/docusaurus-plugin-pwa/package.json @@ -45,5 +45,8 @@ "peerDependencies": { "react": "^16.8.4 || ^17.0.0", "react-dom": "^16.8.4 || ^17.0.0" + }, + "engines": { + "node": ">=16.14" } } diff --git a/packages/docusaurus-plugin-sitemap/package.json b/packages/docusaurus-plugin-sitemap/package.json index deabe52f3741..f6fd11b8921b 100644 --- a/packages/docusaurus-plugin-sitemap/package.json +++ b/packages/docusaurus-plugin-sitemap/package.json @@ -35,6 +35,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-preset-classic/package.json b/packages/docusaurus-preset-classic/package.json index 310a920bf4db..40a209675956 100644 --- a/packages/docusaurus-preset-classic/package.json +++ b/packages/docusaurus-preset-classic/package.json @@ -35,6 +35,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-remark-plugin-npm2yarn/package.json b/packages/docusaurus-remark-plugin-npm2yarn/package.json index a47e1de9c9e0..0c9c44fdc3a2 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/package.json +++ b/packages/docusaurus-remark-plugin-npm2yarn/package.json @@ -28,6 +28,6 @@ "to-vfile": "^6.1.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index 577babee2892..9439db4a2c40 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -58,6 +58,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-theme-common/package.json b/packages/docusaurus-theme-common/package.json index ff097aa08e95..9e0208c32eb4 100644 --- a/packages/docusaurus-theme-common/package.json +++ b/packages/docusaurus-theme-common/package.json @@ -49,6 +49,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-theme-live-codeblock/package.json b/packages/docusaurus-theme-live-codeblock/package.json index f107b6b8b302..4454d741c479 100644 --- a/packages/docusaurus-theme-live-codeblock/package.json +++ b/packages/docusaurus-theme-live-codeblock/package.json @@ -42,6 +42,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-theme-search-algolia/package.json b/packages/docusaurus-theme-search-algolia/package.json index 6ec7ab36203a..518e0836e599 100644 --- a/packages/docusaurus-theme-search-algolia/package.json +++ b/packages/docusaurus-theme-search-algolia/package.json @@ -52,6 +52,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-theme-translations/package.json b/packages/docusaurus-theme-translations/package.json index a296a446f3eb..5b10cbf18e24 100644 --- a/packages/docusaurus-theme-translations/package.json +++ b/packages/docusaurus-theme-translations/package.json @@ -28,6 +28,6 @@ "lodash": "^4.17.21" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-utils-common/package.json b/packages/docusaurus-utils-common/package.json index 31f9a3fcd0c8..9bdb0b8d122c 100644 --- a/packages/docusaurus-utils-common/package.json +++ b/packages/docusaurus-utils-common/package.json @@ -25,6 +25,6 @@ "@docusaurus/types": "2.0.0-beta.20" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-utils-validation/package.json b/packages/docusaurus-utils-validation/package.json index a112ef5797c4..9059249d9b04 100644 --- a/packages/docusaurus-utils-validation/package.json +++ b/packages/docusaurus-utils-validation/package.json @@ -25,6 +25,6 @@ "tslib": "^2.4.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-utils/package.json b/packages/docusaurus-utils/package.json index 36dd648ff13d..4a460a57d648 100644 --- a/packages/docusaurus-utils/package.json +++ b/packages/docusaurus-utils/package.json @@ -35,7 +35,7 @@ "webpack": "^5.72.1" }, "engines": { - "node": ">=14" + "node": ">=16.14" }, "devDependencies": { "@docusaurus/types": "2.0.0-beta.20", diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json index 9c2ead275092..664fd9977dbd 100644 --- a/packages/docusaurus/package.json +++ b/packages/docusaurus/package.json @@ -126,6 +126,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 8bd7a9494539..8dca637d064b 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -31,6 +31,6 @@ "eslint": ">=6" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/lqip-loader/package.json b/packages/lqip-loader/package.json index 5e96bac253fe..1311e978db16 100644 --- a/packages/lqip-loader/package.json +++ b/packages/lqip-loader/package.json @@ -24,7 +24,7 @@ "tslib": "^2.4.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" }, "devDependencies": { "@types/file-loader": "^5.0.1", diff --git a/website/docs/installation.md b/website/docs/installation.md index 90c16645303a..92576624eec1 100644 --- a/website/docs/installation.md +++ b/website/docs/installation.md @@ -20,7 +20,7 @@ Use **[docusaurus.new](https://docusaurus.new)** to test Docusaurus immediately ## Requirements {#requirements} -- [Node.js](https://nodejs.org/en/download/) version 14.13 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) for managing multiple Node versions on a single machine installed. +- [Node.js](https://nodejs.org/en/download/) version 16.14 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) for managing multiple Node versions on a single machine installed. - When installing Node.js, you are recommended to check all checkboxes related to dependencies. ## Scaffold project website {#scaffold-project-website} From 309a7e8bd4bd46d8b6aa99a39b091df6ee3fd071 Mon Sep 17 00:00:00 2001 From: Massoud Maboudi Date: Thu, 26 May 2022 18:38:14 +0800 Subject: [PATCH 14/43] docs: add Massoud Maboudi's portfolio to showcase (#7412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: add Massoud Maboudi's portfolio to showcase * optimize image * Update website/src/data/users.tsx Co-authored-by: Joshua Chen Co-authored-by: Sébastien Lorber --- website/src/data/showcase/iammassoud.png | Bin 0 -> 18166 bytes website/src/data/users.tsx | 8 ++++++++ 2 files changed, 8 insertions(+) create mode 100644 website/src/data/showcase/iammassoud.png diff --git a/website/src/data/showcase/iammassoud.png b/website/src/data/showcase/iammassoud.png new file mode 100644 index 0000000000000000000000000000000000000000..e31b3126ed60886aa9fe76a0ae13e6f11084f31a GIT binary patch literal 18166 zcma&MWl$VUur9p2I0^3V7Tg^ccZc9Xf;+)|ahKo{ED+q?-Q9z;xCeLp-gBzHd;i|~ zGc#RJbw4#dQ`6luk*dlvD9D7!0000*PF7MK002P%03a9<=06D$mN4Ic9jv98k{AF` z8~^Fm1n$2%&_!KF98fhyd<+1<08|w^q&udc545B|fv5zw<7pB&!&#yUGcdw6_2JlcPJdb+*6+uqrEeSMvo znB+4q@tx$*VO8cBWsBy+bbgN>l;c;$Xv=H zmseDhP*ocl85I@V;>OC z%*LGfgR;Pn;(1W#p#pz<2Rf8Q9$`!MSW7rFyZAFXrMj}=cUh&aoddt5Y+rxBZ$Oxb zhmVAT#V=2amvQqmd+XXz@|dV(Ejw2$ZJMu&w5iG2r8V_s5b}@5tvWg!sS35Qqf*OX^t(~{-CP$@YZ>v8wjLnO*ziR8~IT_NvU(UX5W-nWO z7gW~ph=^0x`*vMH<7GA{b~%m7HHB0j3-KZX6h&(mOg~=izN`A!+37m8`1t zR7nMqlQp$>ZcAi+J8Hk}kTn+-Yc|l+GgaL`xx9&x4R8_u6VCZCW`9@5XYLhvpBVFg zHgwTva=ct~2hqIGW=ZtpFGz~iM^~h9d8ZY-akG5VSK;7 z_R}?dg>L=J#-AyYpBwA_Hx)MHZ2#QedNTLR_ZwAmkkaeyOr16OAPYOx-}wFHg$pYqiz1a8sJ(OC@Hn#pp9E7 zDOU}en36G`toW3XA)Cds zGzRzI8hmhOP2GwYm36`08p6jn-fpLxw{;h4C*qV&blEj0hy;oXOxk5(r3>CdG-XnA zqQ`ehl5+uxeSH?|B41FClKzE2PgL}9eLIt^Zp$cJmU;R54+0rxPjBNeUKXD5+_PD8 zF6r7blLpA>%qV27YfNuS8uLDs1&ptLmO?xro>Uk&NXWy36tk@NCrJ|D2e_L{U8E7n zjkWTT5W+il@UfgA=+!^%G7BPcY4e==H(Ql?*6rl+o3tHBw+O#+7RQQ9DmKZ2;EOQn zjzNQJbxKT!|C!r2f3s6y#18v?=&MgO!RVRtJ4uo0X zdaY&u_V^pbXlts5%aAoiZCKZ-sBsxax$!uS{5>z*_{XG2BFX$Pb0}ncT^=q zRNypY;C*5LkE;Qe_{;#DkP=`CIX>wBO8;L*kCS=LDL=183T5dn7wzC1+_bJ&207+5 zm&zJ>QtBOY^DD~}6}Zg{CqUmAEH}uF7m=5HzgHHxc*QEnSRw=jV}eMvLa9!gm=tVcKf ze`Nc6sNy|e@M?nVdl%dzjl{Lf_xD&BX^aIeqgP9|@k$Bygta@cKwldnorgv}JpU=2 zg$W8SO3Cf*qxDW@#1HB%#$%gT3?jGsPacI7L4mIcZ{G^H?w7_29YcnNrGdj9V}vf9 zTvqb~wVMu&#KEed{0@-Fnp$bsvytQ1o|Gq(#mjqKSlHYHHpTvN-IM|CkLOUN<(}81 zbicMwK(W#TZX#+srDBoKH;VTvJCgy_K##-vYR&q14+?VC4g}xki(L7;n`%b=t+F3y zzm&!P<0#4mZQq93BISAi?xUsEbJC83h=`4S>0I^k(pFo0m4AZXUp`GvuBzBmnLYQ; z4tLo6-$b@2?9l7ouXN|y6%GXY6J~tZ{cso%YjpiAx_EgLp93cjMtl?l!UVj0xBejI zHAY3m#=5-UZ|hFGy`Uow1CAjbbsA_tKx4(<#lVO?0y2KWYrC%@xtT}m#TF+B7-$OGw0Pez{p)6rcJsQ% zf5#n&jt(MaCeQjXjH~~9v;OYr77YgHB}0C^I$xyT+9K-=@GsgF(f135)V0^4lBu{}if&2+cmK4*xOwdp}-xUu&U&#Cs_B zZph~OKk9hl4p}~^(9!AXjDrTreg>^^G>^MK;lPGK{=jk7zhC5(Uv@#$yxu$M{=?83 z-@mSHr(hhoyqkFO3w9TAI81w`@otTmUObJA zd%^F;1bqvEptIoxD2^Xf0*Oe=zj}OHir|p|t11IOO$A_AC$zn|Haq?N!3+z#kF6Rf zdO!W~V=2Oc{C~N=KPtrCrNblYc&%eUM6ko2s4g*PgIccinAK)zw{w z`+*w0sJ8$3D4Lufew2C;IJFnw&(C%JtEyX=l(HUwLa(X$5d0Tx16v=XiA+q1L ziick5Of>shw~|4r3xaww>RZ~$B?z1KY#?GgmXU2FExBcudplLsI9hU)oix6>{?p0~ z{7!sm;QusDXvok?L}C>0T|5;E3ExG#|KK^YVcrVR_;_xSs5#~WE&XB!p1X=`Fp=y2 z-j&?Vw=VT5h;#LodzMPu@dEuDEP18*t1=^nfTdc0Xe=mvDQ9GKNU1QFgJ>N$)|yXq zJg=XVkkm^={a{(?D*gNy6Sa1u-%1ddJiBDevj&MYs3W z{rMZ-RyXOa*?)INl{1{3@E?fnuQqNXW>DI_7#5vJSsw^qm`brnRb{42R)SQ(B<(fR zY7!}Zv%n;k5N+^x9i%97dGp`^Gj{6qAr&NSj>XsGRQab+`Z+Kb?qW(BwQMxp1bWaH=Wzv`cal^k6*$4g&fN5 zzhM(YlGftd#O?g!B?XJkm6x7VO&+|V#f-(qQ$$Nx`l8^0Bpxz1^$X(8igG7cO1(jp z1V=ptj0LZHm&7*+mM9PgW%?+YC9%kJk|ov0pUZ_WNHWLP|C9g`N^q4@(RxhlVmc+b zxH?SI*F93zq^5aP4!wPUGs)?AbSNt-GGYLFxt*369+0Y45S$tA?lm#c8OLFQ#<2L& z45_c3j*T%cG-FWrk(PH%D7lAAY)5{65^uvR&1Mox;IX6?lRF`(8!Zi`A)H9H@_PXzhX$Axb^OQ}Eou;&(Kz@n_xd=t;cAAK&QH0qYGaE38D6;H1r~ID@^x)? zz`W+1l1^I;C}Gk*vBM6lX!%2k$=~*v0X?DcI0QU&6#TOSQiPGVm~$_yKcQ}Uh>?~N zbd}C^e8UNM=v^1s`05S^3OkNTh_swiN2kPoP`kcEm=BdPxMe+QUH7eIyc%$=j46d$ zLD}PBNC`rSoiVn#9njT}`HjE!Ojb}6#zBbYTvZSiB4Z#_8RQ}I1d>>Hs@8qHRWw09 zvtkmQ-#$5Ov{9s?sLCkhLp(TzndP#t==oee_VXuN>3o5wTkn5DAY|jMkwNhkd8-nG zfjV|nRM3x=_O*1LDM0}AFca`5s9gqy^d}-$H|4kY>;4zNe2V$;CnPO1P3e1vZK?ilwp4G4Qj%-<@^Je1CW)5+mDrxpeCv{KiOm(m`X0h$ znbX0L)dLA~&-!qsJ(#o2SwQ0pS*OAm>C=rAfXIhjJdzU?Ku*r>ee$(7N$W$J2+s zr+kYWNC*&~#5qOqL|$9xD*)OBvVEgvLfOro!zSZeow;ZvQeNN*;6;+5%O9c$4~Duy zv|+6;W%mi-ULd^_Rte@RUkc$}(a79uH(RI;%}xNnQUA&U`e@9E)LA?W<70e~z|{bo z`0{>c@}4pXcIlQgpz&2A%{CQi*Hx?y*@ewBr%Xb-%t2B`SO%fjRg;mgF!db)%CEc| z=>z4LI$(Q7>tMHe>U`u<`Fplq?Sq(bk?MN&)F&BM@!~d-tnt9;{XKH9#tAT0&cnck zAu_FT+M$Rc?y6HiiIwqfUhwC zd!dVokAZ8U<6@M(sj8@Hk%r!zRZdu;>HuN03g@eo$6Z9n#id>3;%18;^GawWH{+Ut z_p*Xdkk;l9VR)@f(^F!>Dqq~grC9ZR>BX9RZLcjAoy1h=1%KoGGvw&vbgLG33}yH6 zXBhJz7{wx72co~fjaZ~17Ip$)%kHaJEg(c}%X*-wxd%T$#g?Quo;5ZdFuBYJwtp3? z{$NIEd5NUKp;)E8Jwapa+mjS^1&vLe#$@x7a8Mg(_O3UDIDA_m^T3ULs*nshm0%tz{AFNa^(G zSXU)zS-VxJ>+6kyc`rWy2%e7j3~b9J@C0M<*|Eg+kEf8zQ0Hhe4Qt}@!ruDC_crfn zfP;KGpqaDhjho9mZ1i#0%2LUC5_y(0S5e9Qd~(2oDRqGw$p4XEwTTINvE`vrgsc&e zD-`@lnCcc9s=^*#UNQ3)um=2MQNV&|B<(zQe1nEgBDAD!{Br6v2Ca7iZidL{D#}y* zpkFLm8H-DL4-O(d)q1>^+R9i^cLdqPfQo8WJR^q^=BL*XtkqB$VD4(zaS6m$jYOK8qc9)Mp`!So`w;VZ-u(i& zA!Kj+^F+-K8*S`a+A!}vHes7M{$~FXpaLAfOsi=6ewX?Wax(1LrMv}q{gUOyd>P^{ z=akA0tm3sfZ#?CDxWoR2i^F(mv`%{Uizv5SpqGsi_@9ybNj}3V%c+jAltS(ng#U?=H!_t#Peg9@vz}(DirX3 z?e?aWj>iSLMO|MHOc!pt^#FUO zXsm>asyqe8-nv3rw)E_(ft(#QW}s|wU|a}5;Eu&KVK_rBT&J_EvA#k>(B_U3vNt0} zRUmpw9sap)XlvI`A8T-#FDb_7#d;MZrL4z7xbUxZdO zKyTl7S%m)2l3L2Bt|my`KZ-OWBggm!9GqI;YIV#?0ARaEeoe<{#@{6k+MI6wQa+0k z?V>y8znC%D56JHK0Pq{gEY?E>A+MF^7qY;0OavBDJ`Dyd0R6U-eS|CL z1c$z| zjH^V`^k)&GVp~BgF-V9B3jq>eGo{X{b$0+qG7w5y5>aBRsFSxmD5*R$sA70M<<7ee zP5pFb?I?o{3309bRd2|e%w3tG#{!UHj*Y!K)D>AQu}U&@Q)I7>*$A& z;2sn3^Dlfge)HBBBTSDUe~m=uZNQoNM-HPZ_}QLyatik63Mj z01IyMCtQg%lFaM=Z*oC4bZj7gk2y<9L-C6gGYnDD(SLiDAxXYb27B<0+FrE$jh0k3DeuWeTF>5c~Ext-&s>o8UZZ-h{4aoujoNh-L@J?^@|_R`>!iQTdQCIdEVd;emH1*Qr2>~9J9Ec(+FAzym zJ)c9eZs~Y5lt4bjcUB)uytM^4giB5qau>tD{XFjxs`hAWEpD>dznE;@1F7X>>w6l7 z>F!O3Q?njO(N7!VkRpZ2gYGHRXxYyL zBfHK_#LxR1T&C{as=gn7S2L}-Bn$ML7Jm38aXtTW`pYNoh^L)5>*Nots&f!=pMEmg zu>Q+F01>`jmN7;Sr62_q2?GR>h#e=wFL=wbhVs^vl}*U9KrX$0ZOmdXK-ezXKvulP z_0wf>NxXZ9v!rQ_Gr1GkH@YZCgM_MqpLt;~;md)u@Agy~Z9$YE&x19=rSHLHSDu!v zXf+zn@ztAW6K#QijeF~d&kl4hyuZl155r%{rtqpY=-xl=8JKN9TZjyzelYOXsdxd zID+0|vG4~}ra;b@l8+&G1%SPM_zQ$)Ir3gtUGll~-Wyw}a)Q}Q&oUR8evp{}ZYO}^&{af#L zKTkbc3H8Sh5i*^&{*P@1;n;5zdt+XqPylLg3v70A9vt@!tRSd9jO8qtU-mk=f7@Y- z`uCHYnFOQignRGY%t-9F?<^4G1+ce-o`*IIgwESr8DF;U2|>r4J0VQKeq@8#bdH5O zGP=C8(Bunt=5>zo4J4d!L_^O-1x9(zb2ic~5CdjKahuAqZ9QLgBOwij9QJMk7lz)) zPdGANCcT>mAQjIl@(qd-K=WKy{lOj;M5N2A`i=?WTa~KA9p@aVLLE5(hJ(Zbw4I*k z@`y0>q$X2@#1o2xa4J71*`X%N${HTYcpvkApOr@{{# zLC2PlzE`$3=oS1wbN3@=9!S(78nl5Yfn>9U=fAqo8x3<}Di!Ik@TQE7f2xWl_Pyn( zF{mEXvgPPY4q_e*mAE8|Iz&Gn78(cgW(WRSy%;k8Sc&LFZEly+&bK%BnawX^C9#<^ zcUc#(HH;VJiohd1g3;rNEzY;}S&yS41gtisu_Y(tq81Xx<4N}>uL$GdTS~K9g}TW| z=TA0TPfl<-Rr;;egl#o_N9NlWd)n#x>eqQdUD^lrEpEbIiKf5|Jdk=$nveU1cIUAo_5|7<=o4Jf5|+=#YM_ zl}M8&D-7)q>sddr>4Sq7LC+lAC0h9!)Q8Ti95gZxiol~j^KPy?5{r0V3{K>L(0s~s zTa=twgX!P~5KpBx?jp6SM3cdNN_H$61H5l>EMj?Lgo%-S8$=TFi)r=;WPtbL%YMU@ zsD2qV2PkMFzBzua?M1sD8TSn7|NcbJ5ja9Ov~vhV`!Z}h21qS4OEV+!cd>t8Rbhc~ z5+4AfBT$mz;eqqzk?-kKWXAtP_&N?sD*A&C&IBtqv2b9~CnGw#n^k=Xm5?JYUUQ5Rx^RO0?#o>pncDGRaLZB{OD;Q&^NW}AeZG{M)2zQ4w{#*m zI|OT$UeA+^(@BuxKpmk!0>vXX-)y(^l-}DHk_PQaH@YxZjM}Rqnq(y`=S0f+l zhxr*&Q)-N}V3I<+oE~F(T_}(wk9->W=L^Ad5xsDkyKu>FemKHxGkh6aqd$v zm^ps*38bqCcuWCnsEh*g3-+=)tkskTr%qcV)8|7|jZr2zb3ehr`1$$KkyS-*UT13n z@wpLr2Da|0SOp-)>Zy6V3_h60!hOeza13c8+h-+6&w>>rV=HH_`2P6)Qx1JOF?2Mp zS(6BlUv*b4iCn+DimWQPSov^;CC8#Iq38>mISW+Dh4{_p^|0n#t=Rdu8=1;KQYvvO zBh3_34`mQW#kuw?3@UQufF%fApPBJ{X!S_02B{=H)*a|78XTu!FPcLAOt4UHSw!s7 zJo=3~8BLO2&XJN#<8ne?b$9O>`lJQlFn#L!=`Vw8go$xvtbO#16|WByuS$MTUJ&K; z=)?Sb^{c|t83EdLw9a^)$p?I-Fb>c7US@}%?p&cnCw3w{zs%yIlM1N-T@z zqoih3r3-Z&AZFf1NkIC~oprRYbSzPz$2^aQ9#&=UXAL9`eeCzol*$RnAfn22F~%?7 zP4aD`oTOBF<&YqqMUi9Jc0@W#Lp65F$OZ!4NQGKiRlsJlgH`C7<;|1e{o0n{tL{gS zI8{6G!IJl*k0;%@&$eM zo*!pK{J&&QL@%Vj9DpKxK)WBHkc)vNqK9>^kZeiG>N0o)A?A?{GC)icpJiZ*+tVv6 zPU?-dqW5iroahT1!Ut-b6;n8V$`RmCig#AM`uRz;oKlSGOIU@$*EfXi`aX zWMfeOM7B0W5g)daNP6aKN^Y1Hh|kX7M_nzz<`_92yEfMyT8*p2UOMOdH-D7&Qit}| z@lhb-{%b&9F}0C9Eg;IgQz$XP|E+tx?m;KezH06(Dr&!#H%45UygcT`nj#PauFxwx zvhkYs>j_2(STYOdO@$W0Pca$%$|kYpgAfEA*1H3ImzGf+Odq}fvdgv=0Fpx?$bh+g zV-}hyF%(xc+t9Gff|fvX+rf(Whl))*0aTs_>C&f&uTZ9%#cv4UrJgkqq>GTq_yj=s z6rmgGO|YDwR__Fz@FVwjW1z&ns(^vAbJM5uG+9s-Js@-fzf%+bCI*OI!FSS|%87Mv zqZo%G0m=qLXwd-*-U)B)<~C00`2ELDn%0Oxxv_w;cl1>k6wgamC7za6*dJdw19t1L z1Schx`B2!;A0f@6)$w|lo>jhX*ZmJhKk>~Rfr=&`W$0onh<$P23=#*BSzV&ki%iWK zK6zwL$ysRHT;vbQ?!ZCJw z98y|Ro5wKvvknCOT$z@@^xKrw0!9}CD_s*sEv~3ETETm$#GnpL(Ht#2`>)!pn;tkH z^1(XzE2Q6v&lR8?Tx4H~i$SB6kI6wSoe+bqA9wJ1bms@4Oq3=}5xFR{>L{i2FXU7i ziuSS8WBfh^$blUxTrflMTFvPJg_%i%e@S5^ z*{v~Vsy zJ11mJq&^Iu%R-q-77d5VgYBZvp3L=SySNFPEm7I6j0Ch!cpm#gEa?c`zfhjjn4%It z_U*R11e^p!h{ZJlqP;gPrsN{w(avF(x7DkM4A*~(PWSlgN2U)x`y@MjtZ;@+@(hr- z*Y_|pYJDT>`Fo0^D1=q~aPfUuK8M|D2D}yf!G+!z6&~FX-pk04ammth)x9 zT$C1SQ{vc%nVfG%1S5QooW5OtBxaZGetv0aZGFeyQ^uj~Z0I$fHP7g6G=M7$>xj;l1>*dLGh?4B#Va%bdjTsOe!fM*fWz$b zCP0hgW`Td2RaZM_&IGbrAWRGDb<)E|+uL&uu^Z57+z(8a?QV8{Jl}YSl-k`DqM+>< zLs_X!JbtLPcUq1ACnyX*r$9`>>n-mz=!)&DO{8X|IQ#l)h;OM7kj(%jj6Y82jS=pX zn;=TYGWhy=Jo{7N=6HDRZ?q!mvWV;O-bIwlPOyGtGq6xv9z&;(GyRn`*YkpvJU`XZm=Yqimi5m2r4!3c-RuQAL|6BNltK3 zI4x$F^_X-3doO>${}o#|P2d7vlB6v{A7R^`GxxXX45rV}Sa(Tf(7aYw>kj4WDUt7tOeQF01?UxdxbwVL79Xh3NGB4aCr4Q0U5I zcvJ}={Ix>wda}1i4j6kRwipkq#+X+!cmmXf0|YlZZJOG6okd?7zf{uyx#oeiRnt>y z?BP^WaTz=R7opZ;r8^%-w7w^l^k`wmLhG&uUQfnO0C8gL20d~?i|lEO6hu9DGGc8_ z06u}$M{lf(OBJKrKUoVlCR$fo3J}D9Byxt0d?4~XxIFXu74cPZ3XS;S6>deX-)%Cu!)FzBCdzjjyR9RB0OKD*MW!M_#bmd?E?K2jt{U+r2T~aazOQ{J9gDmIeDFjz^W%6{LBV`8A)Slq`D$>Z{+)~jdkE|EoHKW?{-iY5 z3SAZt#HQ?|9vE}_-hs(9g_6RA<@`--NNJY6mmGkL%s#sWv7yf{$O39!Q~eZxWICaC z`!kddMBx@_`l|n-to5QQx#=PV$Z9>I58ryD^u%cRYI6T;UUozARJ?qGiS(pHe=KgQ zn<>QSI8BXs3OVY+F%2f$NxqBeto8W}iXq|me_R?*nAe#Z%76Gd*KWc;C<%|QfyCjrWfn; zh~$;R?F@3pOMP=_Eww)-cSPyhZ$n)}BLZKe1-J^s?WH3ApmWG+-ZHozSPCo_mF_0G z^L?HpKE{pCOr0g7&FbP&V2+|)^tO>Up{MBV@+f1ksZKA3r1~k)x)`>F#1A5{#T?7 z!4-+}mo5|A8w%P&c(r=j&o<5RumP9BuF)EX`g(tTg%AHq3pW?BN7?ehxU}6UUGi%7 zwXlBltq|3J=j<0G*wru#4x9*B5nP*Ts^X0M)VEJs9}-EO5H=o)z4LjNoh6w8!vl-5 zisOhyA#GHFB@i);z9BK{040orCXN}YkPkK>!hrqLxW%J6YFza0YFz9&O;dgAD6UQx z=Fk{osNYy~%H8Rd%hckypBgn|oEzNX7S~7}6XP$k={2t@7dC@g#U>}Y9jVEuIr7V= z50SUW`R>j~!yrvNOr-}?!#z4?3zaE^d6jX1KL+(En?LM|j8Nx;8-9`D?Dny`(fgmf zE!!5YkR?F_j;VSiN=gr*fh0ht0utMHH2jxHaQBBGv`{BqhBnfAj09*KvnnTI{Y88+QdVcFb$sh)lV$E?zn zU(Dt{C%)!j5Q$c)Tj%3%pj4z}6hoPTJAeB-(CDWuV)EcTI@~*wyO@YS{q-wC=-v(9 zRv&)vK|E}C@K!k9L{i3q0?kqJ?!I5^>Gx$|{8I*k!xniB2YF!JXx%cg^1$_|Nlfm@ zDH68S%5ezpkxGaH+Q<9f=7tOGx+i>o%yl!=YoBYDV9OXXH|#Qhto+DZ)y1yM&KW-U z;bXO?MEkPuDL^Dw#ngO`^JpCHzb{^&_{|9_p!#SZucOw*8tBxNVom~5&YcOGnIf1% z3R?kd$q^GT`9un7wI891wo27Cp?3OO2m48CDVkfp_ zTdx`xNYR` z@WyLaA@h!5BT#q!9x^0eeu=*NS#rp;t-Hv7C7Pf9&_#qmVk1pL*7I0W+EImoG$v4FfOg?gWL3^1z>`S4X`E?{VX2yiOs1AUbJTu8tRh; zRNXKGG{rldeqwhpeRa*aBwYjh5zKW4epX)|D|ok>B#e)c7qFKlEav zfb^|FcOtF8yRoPt}^Y;gBrdDE6?-`BOUvQ<=gvWY9^``)2RyiqNqTrDFt1cY5) z=5MaKm5t19QS&&a2ENgLY>u)aM57X8`V>G#W9qOf{YT?zvK75GEU@ljupIgkwjN@h zT}}6OnxCJ(L)nUm!rS#X24uxD*+~<0Ug)vQs*3$jyjsMWB7nR%nPRGujR`hA0U+6b z+sXBY^2u@Fc?(RaE~lVKEAFUG{Z>Y`s^V6!)x-%2A_cQ>{QyoabOX;zP&z(UiZ;>lVODhske{J)Cs00xm=#T6klh_qskBPB2^=|cRk8xR4M&tZ#*r+!?nvZu zT-@e0&nQXLG7p^U&V*86C8cUIGb5P8b#Q&|ko>Aa8n-c!8cnU<#uZh+hXC_}WToun zFIpW1hdbQN@#2edyn)SFnxwv`aV2BX^yTc~&p0rLu=Hqoxkz#bMeuk$i@VSjMKU5A zjFlsvP~}4}iNhrFx!?B&`oAMx=C8F&pUM0he9ix=cD$NXYka1XLQ2%GxDyAI^h{)t zM+59X8EfbEB6zgOTgYM;3QNuCmcJtkBNZ_>jtx{?c^)fpmrmq^!>-+5$joN&grxJHIa$egOG|WBPwG6qr;c3=`7pj>0ou!d?WZD{bj6Y;Q|v~)!(~d$H48z z-cihren8)TbNtyr`#e>@Z|VtVa_9qpV@;G06cyOF*!>=##&E&_>wI4Lq+eBMKVp_F zu(1*A3G+69LR|Xi!G;cOK@Ji;Dud=p z^imPg#g-PT$U|jCE0^+uFrJ>Zs|YUN`tpX&e5;xT2NXrypUbtkX>64AVnNIx@P{^kFERp=X_v;xHO=(uh6N=%r%tgj)j zA3u5-Pr4uWkQB&bKvJ20_f2?Xqe7qH@E*JgU>`eD9g!}%kLI@6eV-}j z{E%TO8}rb^KatFa3K5dQXe$=u__;+_)^7k^iSb)%HrB|41;Y{s;u^OS47yg(A;Dqo zA#!NOd}UJpwUp;k(tPk8!7CH}zwqHKin>N|SN{P_Nd#}9?+qT!DEY&c(T^39*9k?6 zc|2%=%5?HYvQt@u0oPWfGU2WC>Qs@C)p_S2W>+G>k<*z6@zc{tYP++<c z_2)GTE`+OnDE<0fj}xpi-1pBKQlh^GLN<@mr}1=-_{MSDm;r^}^)K%g?P3ZMDEY$5D-j%g~V$Fnak(L@33Z?X^kU|atdQC* z5&c!>wdw5dGwz?q|IehVr<^2+Ub@2xXi=YUK%1C}Xd*)_F)KO1TR&={(L@B1+#>4< zb1K#yo%&3cK64zKWvN1%9{SJL`EZRwqlVzuh}n_5Qx`xg{pg2C1}bGk3|4ZwI18%o z_fH%C08_t*ne)NWArzBf3?sO%m6wgx^|>uBgD3*71<+wWngI9)y#(C<)qo??1)4!^ zJskh77f>hf>H~^sym+kM6g=E?t^5H2Ci^s$rkkXuG=lGtIi7AM~$vvNz<>D%YG z!>7V1Eb=`fVwT_8cG$Bhpt0S6D_Okk)&nNb5H6(6 zC!=Un&V)%ZCnl;IGB%if^aETju{X_~eEa%6@=; z#m;3qD`)t7x*}5HPnkX*sE>T$hju@S`e@_LOEwJ?6$Mf(R~Fg9N%s6vAd=Jx^tqF+ zq4CwVW-<=Nl(2~yx0rXIpIJj_flC%IjHXEa6t)b{wIjYvF2{aUSt{8kg6_rEKEy=b z&OQsBH^kfx9?e`AJpAQ9(J()E-0AEw@`~BWInPh*;{Vz`{b6TS;Sg$rPu9i{hqOFe z$u*9I$hX|(9dH$Z9ui>Kv1KzF!{ZGXiwL`~XY>maidqQzi-2+Q@7P~nCx|efl(%Kg zW~+*5^Hhmx^rzG#0 ze1SN*#@mdF5r2y7@i6jEaq6Vd*YcHN1-*?w3xZ7hO zfJ6qPk11-Ql@I8(mGrvC$|or!;x!S$BgFJu8<=6bY*JsU(reL7lQbkU`RABng#fX6 zy#$ywq!Fx96(z4?9QgGP$WZyDYiI~vTCSC#WQ+{+8Uwm#UYo6bg-i}kl+>pM^CR&`T@#aS zI!9X^mPPOUdl)OV+ol@y2_UJ!gw$^j93bcTpH~12caso>%jMqdvSv0@?P!dYQjgX{ z4q3S?b-9ZI5VVeK`|@07IT;ZM+s1jZO`4_bdGcq|p)E&loq`n1`zS}-ybu5)#*~37 zf?%<;Bwnc!7{7kIW2PECv_0Ndz|1isP?A!-GaX;#)Y3hfo7+p}&c(%KLz--XzBcZ< z!4>S)C_c;-YJ|tW>0iA4O$AWc=8zk^#7PD@!#)NF0tFd93&$Wu$nBXuU&UW~S|+6jU;3bXcDI4HEDJKN`x>Re2g#@gyEeD5l zOmGFux@N0V@8Q=FA<}pJzPeVaV?rl%G-h^I`JicNW_Oo&eJ+A3;rXw1eN<)63>$W##%@Simjj z=ZaxZ+wV@B$6dH%h%QrU;Zu&EyHFd0TTx60-|@5!j&2u!PH%X&eo?%5*pD7&q0lwHNhoY+Q_~{O~v^{TQDHf z!$lWZvu@aA{@2$pd?B#LKYH3LWG2S99Ph{beoI<c*J-cwm2{$PoRR5sel8iL9tg@ zY@B3j3g0GnBcU=3ale1wOs*>`TF!#K=Nsm~Kh}D@3(-Ds_vtA>wNtyGAER<5V`LG1Do$fmtJf=1& zO166n~1DHjGt+S+!AHQiS z{b(Ae*WELQ=<(!?amyHU0_PKaoCm6Zu;YJLEYhgrp!ux)(rNJtI|xA`podaEr}80v5?(@P$M-F_37ESTeI65H6n-!f6MuC@qXK5#3AoK(_w&mI_&=xWO6RVzZ2ZsLC{(qHWWFc)JpNNFh+$W{S#% zWejHK#R<9ZUc*DEZ7$aiUI{o3EnVfk<`=&FNZ*EdSTk_w3(ui(5f&Rf9LTk!U!0OynwBl=eWgY6#+rPl{70X zkyc1`Froo$5s_1yall$GX)eRrfnw%wcn@y@p9D7=yiTuSAu=jB>7CH4G#BSq!wC2| zI8Fm`HN`D9iwG#p0UXK=GuuEBLOfy&DsMH_@5Krnzz}3srAkPy`6kf)>fx=6kb}b$ z9{0478WHqNAW~kO3M1g<;5eOx7s541U=ab~)}x4WK2QcNwZs!o0b4{OV%1`hQBGzQ zj(eP%Ixa)8neLmnp2Kr#G=om}v?jzqTQE}dA&h{bREVsZYmUGs0*cL`l1fOYm9yd- zJjU%5000AgNkl4@< znQPO_A_9W!g(Fhaf+R;A1|S01A`)2vC2o)s?n&G+Y1xek!PUKV=Q~(1qp~?c2R4m{ zq>VMp6atQiVnMfwD{iq_LO{a&ld5TKwR}P>#+_0Vs-=8+D+3wfqeNoZvw zp~>TFpM{O|r>3??dpPIkpu#k5^E)NhpC|+*HRi1&WGQ!G+(!cTW@cu8v`YA+0xG5s z9Jp2xx|BEw4M}g*N%>XG%IiC&QB1~q2VWVNA=tW;HH8l#S%VW9Y<>T zI60I;`@4n-=bj>i&}!1F!c;KXe!R~`qCXNcpF!Dz&CuIfYq1)T`c7Xuzc(etOtaGY zaK|shUxfy~lD-HE`_#eD+Sw3%6kqswZt3n2BH<5I0+L=HAULC2u;Lz6$qCJ)@05CjMiAP5k+iu`7Bb_Nsz9L6$FybA`-^&G-;k$nLTQKB)K n@K<;!F-|0K0|-5g207{rutNlFf5V2G00000NkvXXu0mjfpG8mj literal 0 HcmV?d00001 diff --git a/website/src/data/users.tsx b/website/src/data/users.tsx index 88e6dffe9df8..2e78d627d001 100644 --- a/website/src/data/users.tsx +++ b/website/src/data/users.tsx @@ -886,6 +886,14 @@ const Users: User[] = [ source: 'https://github.com/ggicci/httpin/tree/documentation/docs', tags: ['opensource'], }, + { + title: 'I am Massoud', + description: 'The portfolio of Massoud Maboudi, Full Stack Developer', + preview: require('./showcase/iammassoud.png'), + website: 'https://iammassoud.ir/', + source: null, + tags: ['personal', 'rtl'], + }, { title: 'icodex', description: 'Front end engineer personal website', From e955ae472da3264db45980c0cfd6a943651cce17 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Thu, 26 May 2022 18:41:23 +0800 Subject: [PATCH 15/43] fix(theme-classic): allow nested task lists to preserve the indent (#7438) * fix(theme-classic): allow nested task lists to preserve the indent * add Ul back --- .../MDXComponents/{Ul.tsx => Ul/index.tsx} | 6 ++-- .../theme/MDXComponents/Ul/styles.module.css | 14 ++++++++ .../_pages tests/markdownPageTests.md | 32 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) rename packages/docusaurus-theme-classic/src/theme/MDXComponents/{Ul.tsx => Ul/index.tsx} (78%) create mode 100644 packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/styles.module.css diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/index.tsx similarity index 78% rename from packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul.tsx rename to packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/index.tsx index 080ecaac2a1a..d426298f6a8d 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/index.tsx @@ -9,13 +9,15 @@ import React from 'react'; import clsx from 'clsx'; import type {Props} from '@theme/MDXComponents/Ul'; +import styles from './styles.module.css'; + function transformUlClassName(className?: string): string { return clsx( className, // This class is set globally by GitHub/MDX. We keep the global class, and - // add another Infima class to get list without styling + // add another class to get a task list without the default ul styling // See https://github.com/syntax-tree/mdast-util-to-hast/issues/28 - className?.includes('contains-task-list') && 'clean-list', + className?.includes('contains-task-list') && styles.containsTaskList, ); } diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/styles.module.css b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/styles.module.css new file mode 100644 index 000000000000..c1d9c4f95dbd --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/styles.module.css @@ -0,0 +1,14 @@ +/** + * 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. + */ + +.containsTaskList { + list-style: none; +} + +:not(.containsTaskList > li) > .containsTaskList { + padding-left: 0; +} diff --git a/website/_dogfooding/_pages tests/markdownPageTests.md b/website/_dogfooding/_pages tests/markdownPageTests.md index ca7e9fcff7d2..dc8695b11179 100644 --- a/website/_dogfooding/_pages tests/markdownPageTests.md +++ b/website/_dogfooding/_pages tests/markdownPageTests.md @@ -189,3 +189,35 @@ This is a fragment: <>Hello It should work :) + +## Task list + +A list: + +- [ ] Simple +- [x] Tasks +- [ ] Has simple +- [ ] Styles + +Another list: + +- Nested + - [ ] Tasks + - [ ] Should be well-formatted +- [ ] No matter +- [ ] How weird + +Can be arbitrarily nested: + +- Level + - [ ] Task + - [ ] Task + - Another level + - [ ] Task + - [ ] Task + - Deeper + - [ ] Task + - [ ] Task + - [ ] Task + - [ ] Task +- [ ] Task From 9cf2bf11997eb6341af5fc5c7031ade849c42235 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Thu, 26 May 2022 19:05:03 +0800 Subject: [PATCH 16/43] fix(core): always treat error boundary fallback as a callback (#7492) Co-authored-by: sebastienlorber --- .../src/index.d.ts | 23 +++++++++---------- .../src/theme/Layout/index.tsx | 4 +++- packages/docusaurus/src/client/App.tsx | 4 +--- .../src/client/exports/ErrorBoundary.tsx | 22 +++++++++++++----- website/docs/docusaurus-core.md | 8 ++++++- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index 3a900c907d77..c8f2c995f012 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -77,14 +77,9 @@ declare module '@theme-original/*'; declare module '@theme-init/*'; declare module '@theme/Error' { - import type {ComponentProps} from 'react'; - import type ErrorBoundary from '@docusaurus/ErrorBoundary'; + import type {FallbackParams} from '@docusaurus/ErrorBoundary'; - type ErrorProps = ComponentProps< - NonNullable['fallback']> - >; - - export interface Props extends ErrorProps {} + export interface Props extends FallbackParams {} export default function Error(props: Props): JSX.Element; } @@ -125,13 +120,17 @@ declare module '@docusaurus/constants' { } declare module '@docusaurus/ErrorBoundary' { - import type {ReactNode, ComponentType} from 'react'; + import type {ReactNode} from 'react'; + + export type FallbackParams = { + readonly error: Error; + readonly tryAgain: () => void; + }; + + export type FallbackFunction = (params: FallbackParams) => JSX.Element; export interface Props { - readonly fallback?: ComponentType<{ - readonly error: Error; - readonly tryAgain: () => void; - }>; + readonly fallback?: FallbackFunction; readonly children: ReactNode; } export default function ErrorBoundary(props: Props): JSX.Element; diff --git a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx index c5503edcaaa2..7f58712af95c 100644 --- a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx @@ -45,7 +45,9 @@ export default function Layout(props: Props): JSX.Element {
    - {children} + }> + {children} +
    {!noFooter &&