chore: tighten ESLint config (#6931)

* chore: tighten ESLint config

* more refactor

* refactor push

* fix
This commit is contained in:
Joshua Chen 2022-03-17 17:59:41 +08:00 committed by GitHub
parent f70ddf7e69
commit cc0bceab9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 177 additions and 193 deletions

View file

@ -62,6 +62,7 @@ module.exports = {
'no-await-in-loop': OFF, 'no-await-in-loop': OFF,
'no-case-declarations': WARNING, 'no-case-declarations': WARNING,
'no-console': OFF, 'no-console': OFF,
'no-continue': OFF,
'no-control-regex': WARNING, 'no-control-regex': WARNING,
'no-else-return': [WARNING, {allowElseIf: true}], 'no-else-return': [WARNING, {allowElseIf: true}],
'no-empty': [WARNING, {allowEmptyCatch: true}], 'no-empty': [WARNING, {allowEmptyCatch: true}],
@ -275,6 +276,7 @@ module.exports = {
}, },
], ],
'@typescript-eslint/no-inferrable-types': OFF, '@typescript-eslint/no-inferrable-types': OFF,
'@typescript-eslint/no-namespace': [WARNING, {allowDeclarations: true}],
'no-use-before-define': OFF, 'no-use-before-define': OFF,
'@typescript-eslint/no-use-before-define': [ '@typescript-eslint/no-use-before-define': [
ERROR, ERROR,
@ -286,14 +288,11 @@ module.exports = {
'no-shadow': OFF, 'no-shadow': OFF,
'@typescript-eslint/no-shadow': ERROR, '@typescript-eslint/no-shadow': ERROR,
'no-unused-vars': OFF, 'no-unused-vars': OFF,
'@typescript-eslint/no-unused-vars': [ // We don't provide any escape hatches for this rule. Rest siblings and
ERROR, // function placeholder params are always ignored, and any other unused
{ // locals must be justified with a disable comment.
argsIgnorePattern: '^_', '@typescript-eslint/no-unused-vars': [ERROR, {ignoreRestSiblings: true}],
varsIgnorePattern: '^_', '@typescript-eslint/prefer-optional-chain': ERROR,
ignoreRestSiblings: true,
},
],
}, },
overrides: [ overrides: [
{ {
@ -340,7 +339,17 @@ module.exports = {
}, },
}, },
{ {
files: ['*.test.ts', '*.test.tsx'], // Internal files where extraneous deps don't matter much at long as
// they run
files: [
'*.test.ts',
'*.test.tsx',
'admin/**',
'jest/**',
'website/**',
'packages/docusaurus-theme-translations/update.mjs',
'packages/docusaurus-theme-translations/src/utils.ts',
],
rules: { rules: {
'import/no-extraneous-dependencies': OFF, 'import/no-extraneous-dependencies': OFF,
}, },

View file

@ -10,8 +10,19 @@ import fs from 'fs-extra';
type PackageJsonFile = { type PackageJsonFile = {
file: string; file: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any content: {
content: any; name?: string;
private?: boolean;
version?: string;
repository?: {
type?: string;
url?: string;
directory?: string;
};
publishConfig?: {
access?: string;
};
};
}; };
async function getPackagesJsonFiles(): Promise<PackageJsonFile[]> { async function getPackagesJsonFiles(): Promise<PackageJsonFile[]> {

View file

@ -9,6 +9,6 @@ import type {Handler} from '@netlify/functions';
import {createPlaygroundResponse} from '../functionUtils/playgroundUtils'; import {createPlaygroundResponse} from '../functionUtils/playgroundUtils';
export const handler: Handler = async function handler(_event, _context) { export const handler: Handler = async function handler() {
return createPlaygroundResponse('codesandbox'); return createPlaygroundResponse('codesandbox');
}; };

View file

@ -13,7 +13,7 @@ import {
createPlaygroundDocumentationResponse, createPlaygroundDocumentationResponse,
} from '../functionUtils/playgroundUtils'; } from '../functionUtils/playgroundUtils';
export const handler: Handler = async (event, _context) => { export const handler: Handler = async (event) => {
const playgroundName = readPlaygroundName(event); const playgroundName = readPlaygroundName(event);
return playgroundName return playgroundName
? createPlaygroundResponse(playgroundName) ? createPlaygroundResponse(playgroundName)

View file

@ -9,6 +9,6 @@ import type {Handler} from '@netlify/functions';
import {createPlaygroundResponse} from '../functionUtils/playgroundUtils'; import {createPlaygroundResponse} from '../functionUtils/playgroundUtils';
export const handler: Handler = async function handler(_event, _context) { export const handler: Handler = async function handler() {
return createPlaygroundResponse('stackblitz'); return createPlaygroundResponse('stackblitz');
}; };

View file

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
/* eslint-disable import/no-extraneous-dependencies */
import fs from 'fs-extra'; import fs from 'fs-extra';
import shell from 'shelljs'; import shell from 'shelljs';

View file

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
/* eslint-disable import/no-extraneous-dependencies */
import sharp from 'sharp'; import sharp from 'sharp';
import fs from 'fs-extra'; import fs from 'fs-extra';
import path from 'path'; import path from 'path';

View file

@ -4,7 +4,6 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
/* eslint-disable import/no-extraneous-dependencies */
// Forked from https://github.com/tribou/jest-serializer-path/blob/master/lib/index.js // Forked from https://github.com/tribou/jest-serializer-path/blob/master/lib/index.js
// Added some project-specific handlers // Added some project-specific handlers

View file

@ -162,7 +162,7 @@ export default async function mdxLoader(
// MDX partials are MDX files starting with _ or in a folder starting with _ // MDX partials are MDX files starting with _ or in a folder starting with _
// Partial are not expected to have associated metadata files or front matter // Partial are not expected to have associated metadata files or front matter
const isMDXPartial = options.isMDXPartial && options.isMDXPartial(filePath); const isMDXPartial = options.isMDXPartial?.(filePath);
if (isMDXPartial && hasFrontMatter) { if (isMDXPartial && hasFrontMatter) {
const errorMessage = `Docusaurus MDX partial files should not contain FrontMatter. const errorMessage = `Docusaurus MDX partial files should not contain FrontMatter.
Those partial files use the _ prefix as a convention by default, but this is configurable. Those partial files use the _ prefix as a convention by default, but this is configurable.

View file

@ -76,7 +76,7 @@ export default function plugin(options: PluginOptions = {}): Transformer {
return (root) => { return (root) => {
const headings: TOCItem[] = []; const headings: TOCItem[] = [];
visit(root, 'heading', (child: Heading, _index, parent) => { visit(root, 'heading', (child: Heading, index, parent) => {
const value = toString(child); const value = toString(child);
// depth:1 headings are titles and not included in the TOC // depth:1 headings are titles and not included in the TOC
@ -93,7 +93,7 @@ export default function plugin(options: PluginOptions = {}): Transformer {
const {children} = root as Parent<Literal>; const {children} = root as Parent<Literal>;
const targetIndex = getOrCreateExistingTargetIndex(children, name); const targetIndex = getOrCreateExistingTargetIndex(children, name);
if (headings && headings.length) { if (headings.length) {
children[targetIndex]!.value = `export const ${name} = ${stringifyObject( children[targetIndex]!.value = `export const ${name} = ${stringifyObject(
headings, headings,
)};`; )};`;

View file

@ -17,7 +17,7 @@ import type {Code, Parent} from 'mdast';
// See https://github.com/facebook/docusaurus/pull/4278 // See https://github.com/facebook/docusaurus/pull/4278
export default function plugin(this: Processor): Transformer { export default function plugin(this: Processor): Transformer {
return (root) => { return (root) => {
visit(root, 'code', (node: Code, _index, parent) => { visit(root, 'code', (node: Code, index, parent) => {
if (node.lang === 'mdx-code-block') { if (node.lang === 'mdx-code-block') {
const newChildren = (this.parse(node.value) as Parent).children; const newChildren = (this.parse(node.value) as Parent).children;

View file

@ -31,7 +31,7 @@ async function walk(dir: string): Promise<string[]> {
for (const file of list) { for (const file of list) {
const fullPath = `${dir}/${file}`; const fullPath = `${dir}/${file}`;
const stat = await fs.stat(fullPath); const stat = await fs.stat(fullPath);
if (stat && stat.isDirectory()) { if (stat.isDirectory()) {
results.push(...(await walk(fullPath))); results.push(...(await walk(fullPath)));
} else { } else {
results.push(fullPath); results.push(fullPath);

View file

@ -31,9 +31,7 @@ describe('normalizePluginOptions', () => {
}); });
it('overrides all default options with valid user options', () => { it('overrides all default options with valid user options', () => {
const createRedirects: Options['createRedirects'] = ( const createRedirects: Options['createRedirects'] = () => [];
_routePath: string,
) => [];
expect( expect(
testValidate({ testValidate({
fromExtensions: ['exe', 'zip'], fromExtensions: ['exe', 'zip'],

View file

@ -41,7 +41,7 @@ const UserOptionsSchema = Joi.object<PluginOptions>({
redirects: Joi.array() redirects: Joi.array()
.items(RedirectPluginOptionValidation) .items(RedirectPluginOptionValidation)
.default(DEFAULT_OPTIONS.redirects), .default(DEFAULT_OPTIONS.redirects),
createRedirects: Joi.function().arity(1), createRedirects: Joi.function().maxArity(1),
}).default(DEFAULT_OPTIONS); }).default(DEFAULT_OPTIONS);
export function validateOptions({ export function validateOptions({

View file

@ -45,7 +45,7 @@ async function generateBlogFeed({
const {url: siteUrl, baseUrl, title, favicon} = siteConfig; const {url: siteUrl, baseUrl, title, favicon} = siteConfig;
const blogBaseUrl = normalizeUrl([siteUrl, baseUrl, routeBasePath]); const blogBaseUrl = normalizeUrl([siteUrl, baseUrl, routeBasePath]);
const updated = blogPosts[0] && blogPosts[0].metadata.date; const updated = blogPosts[0]?.metadata.date;
const feed = new Feed({ const feed = new Feed({
id: blogBaseUrl, id: blogBaseUrl,

View file

@ -34,5 +34,5 @@ export default function markdownLoader(
finalContent = truncate(finalContent, markdownLoaderOptions.truncateMarker); finalContent = truncate(finalContent, markdownLoaderOptions.truncateMarker);
} }
return callback && callback(null, finalContent); return callback?.(null, finalContent);
} }

View file

@ -745,9 +745,7 @@ describe('site with custom sidebar items generator', () => {
} }
it('sidebarItemsGenerator is called with appropriate data', async () => { it('sidebarItemsGenerator is called with appropriate data', async () => {
const customSidebarItemsGeneratorMock = jest.fn( const customSidebarItemsGeneratorMock = jest.fn(async () => []);
async (_arg: SidebarItemsGeneratorOptionArgs) => [],
);
const {siteDir} = await loadSite(customSidebarItemsGeneratorMock); const {siteDir} = await loadSite(customSidebarItemsGeneratorMock);
const generatorArg: SidebarItemsGeneratorOptionArgs = const generatorArg: SidebarItemsGeneratorOptionArgs =

View file

@ -16,7 +16,5 @@ export default function markdownLoader(
const fileString = source; const fileString = source;
const callback = this.async(); const callback = this.async();
const options = this.getOptions(); const options = this.getOptions();
return ( return callback?.(null, linkify(fileString, this.resourcePath, options));
callback && callback(null, linkify(fileString, this.resourcePath, options))
);
} }

View file

@ -118,8 +118,7 @@ function getSidebarTranslationFileContent(
}, },
]); ]);
if (category.link) { if (category.link?.type === 'generated-index') {
if (category.link.type === 'generated-index') {
if (category.link.title) { if (category.link.title) {
entries.push([ entries.push([
`sidebar.${sidebarName}.category.${category.label}.link.generated-index.title`, `sidebar.${sidebarName}.category.${category.label}.link.generated-index.title`,
@ -139,7 +138,6 @@ function getSidebarTranslationFileContent(
]); ]);
} }
} }
}
return entries; return entries;
}), }),

View file

@ -18,5 +18,5 @@ export default function markdownLoader(
// TODO provide additional md processing here? like interlinking pages? // TODO provide additional md processing here? like interlinking pages?
// fileString = linkify(fileString) // fileString = linkify(fileString)
return callback && callback(null, fileString); return callback?.(null, fileString);
} }

View file

@ -39,9 +39,7 @@ function PluginContent({
<div> <div>
{Object.entries(pluginContent) {Object.entries(pluginContent)
// filter plugin instances with no content // filter plugin instances with no content
.filter( .filter(([, pluginInstanceContent]) => !!pluginInstanceContent)
([_pluginId, pluginInstanceContent]) => !!pluginInstanceContent,
)
.map(([pluginId, pluginInstanceContent]) => ( .map(([pluginId, pluginInstanceContent]) => (
<PluginInstanceContent <PluginInstanceContent
key={pluginId} key={pluginId}
@ -61,7 +59,7 @@ export default function DebugContent({allContent}: Props): JSX.Element {
<div> <div>
{Object.entries(allContent) {Object.entries(allContent)
// filter plugins with no content // filter plugins with no content
.filter(([_pluginName, pluginContent]) => .filter(([, pluginContent]) =>
Object.values(pluginContent).some( Object.values(pluginContent).some(
(instanceContent) => !!instanceContent, (instanceContent) => !!instanceContent,
), ),

View file

@ -79,7 +79,7 @@ function isStandaloneDisplayMode() {
const OfflineModeActivationStrategiesImplementations = { const OfflineModeActivationStrategiesImplementations = {
always: () => true, always: () => true,
mobile: () => window.innerWidth <= MAX_MOBILE_WIDTH, mobile: () => window.innerWidth <= MAX_MOBILE_WIDTH,
saveData: () => !!(navigator.connection && navigator.connection.saveData), saveData: () => !!navigator.connection?.saveData,
appInstalled: async () => { appInstalled: async () => {
const installedEventFired = await isAppInstalledEventFired(); const installedEventFired = await isAppInstalledEventFired();
const installedRelatedApps = await isAppInstalledRelatedApps(); const installedRelatedApps = await isAppInstalledRelatedApps();

View file

@ -137,7 +137,7 @@ function getPossibleURLs(url) {
}); });
} }
const type = event.data && event.data.type; const type = event.data?.type;
if (type === 'SKIP_WAITING') { if (type === 'SKIP_WAITING') {
self.skipWaiting(); self.skipWaiting();

View file

@ -833,11 +833,8 @@ declare module '@theme/IconExternalLink' {
} }
declare module '@theme/TagsListByLetter' { declare module '@theme/TagsListByLetter' {
export type TagsListItem = Readonly<{ import type {TagsListItem} from '@docusaurus/theme-common';
name: string;
permalink: string;
count: number;
}>;
export interface Props { export interface Props {
readonly tags: readonly TagsListItem[]; readonly tags: readonly TagsListItem[];
} }
@ -853,7 +850,7 @@ declare module '@theme/TagsListInline' {
} }
declare module '@theme/Tag' { declare module '@theme/Tag' {
import type {TagsListItem} from '@theme/TagsListByLetter'; import type {TagsListItem} from '@docusaurus/theme-common';
import type {Optional} from 'utility-types'; import type {Optional} from 'utility-types';
export interface Props extends Optional<TagsListItem, 'count'> {} export interface Props extends Optional<TagsListItem, 'count'> {}

View file

@ -234,9 +234,7 @@ function DocSidebarItemHtml({
)} )}
key={index} key={index}
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{__html: value}}
__html: value,
}}
/> />
); );
} }

View file

@ -14,9 +14,7 @@ export default function FooterCopyright({copyright}: Props): JSX.Element {
className="footer__copyright" className="footer__copyright"
// Developer provided the HTML, so assume it's safe. // Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{__html: copyright}}
__html: copyright,
}}
/> />
); );
} }

View file

@ -18,9 +18,7 @@ function ColumnLinkItem({item}: {item: ColumnItemType}) {
className="footer__item" className="footer__item"
// Developer provided the HTML, so assume it's safe. // Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{__html: item.html}}
__html: item.html,
}}
/> />
) : ( ) : (
<li key={item.href || item.to} className="footer__item"> <li key={item.href || item.to} className="footer__item">

View file

@ -19,9 +19,7 @@ function SimpleLinkItem({item}: {item: Props['links'][number]}) {
className="footer__link-item" className="footer__link-item"
// Developer provided the HTML, so assume it's safe. // Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{__html: item.html}}
__html: item.html,
}}
/> />
) : ( ) : (
<LinkItem item={item} /> <LinkItem item={item} />

View file

@ -41,7 +41,7 @@ function DefaultNavbarItemDesktop({
function DefaultNavbarItemMobile({ function DefaultNavbarItemMobile({
className, className,
isDropdownItem: _isDropdownItem, isDropdownItem,
...props ...props
}: DesktopOrMobileNavBarItemProps) { }: DesktopOrMobileNavBarItemProps) {
return ( return (
@ -53,7 +53,7 @@ function DefaultNavbarItemMobile({
export default function DefaultNavbarItem({ export default function DefaultNavbarItem({
mobile = false, mobile = false,
position: _position, // Need to destructure position from props so that it doesn't get passed on. position, // Need to destructure position from props so that it doesn't get passed on.
...props ...props
}: Props): JSX.Element { }: Props): JSX.Element {
const Comp = mobile ? DefaultNavbarItemMobile : DefaultNavbarItemDesktop; const Comp = mobile ? DefaultNavbarItemMobile : DefaultNavbarItemDesktop;

View file

@ -124,7 +124,7 @@ function DropdownNavbarItemDesktop({
function DropdownNavbarItemMobile({ function DropdownNavbarItemMobile({
items, items,
className, className,
position: _position, // Need to destructure position from props so that it doesn't get passed on. position, // Need to destructure position from props so that it doesn't get passed on.
...props ...props
}: DesktopOrMobileNavBarItemProps) { }: DesktopOrMobileNavBarItemProps) {
const localPathname = useLocalPathname(); const localPathname = useLocalPathname();

View file

@ -5,26 +5,25 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
export {useThemeConfig} from './utils/useThemeConfig'; export {
useThemeConfig,
type ThemeConfig,
type UserThemeConfig,
type Navbar,
type NavbarItem,
type NavbarLogo,
type MultiColumnFooter,
type SimpleFooter,
type Footer,
type FooterLogo,
type FooterLinkItem,
type ColorModeConfig,
} from './utils/useThemeConfig';
export { export {
DocSidebarItemsExpandedStateProvider, DocSidebarItemsExpandedStateProvider,
useDocSidebarItemsExpandedState, useDocSidebarItemsExpandedState,
} from './utils/docSidebarItemsExpandedState'; } from './utils/docSidebarItemsExpandedState';
export type {
ThemeConfig,
UserThemeConfig,
Navbar,
NavbarItem,
NavbarLogo,
MultiColumnFooter,
SimpleFooter,
Footer,
FooterLogo,
FooterLinkItem,
ColorModeConfig,
} from './utils/useThemeConfig';
export {createStorageSlot, listStorageKeys} from './utils/storageUtils'; export {createStorageSlot, listStorageKeys} from './utils/storageUtils';
export {useAlternatePageUtils} from './utils/useAlternatePageUtils'; export {useAlternatePageUtils} from './utils/useAlternatePageUtils';
@ -63,14 +62,14 @@ export {useLocationChange} from './utils/useLocationChange';
export {usePrevious} from './utils/usePrevious'; export {usePrevious} from './utils/usePrevious';
export {useCollapsible, Collapsible} from './components/Collapsible'; export {
export type { useCollapsible,
UseCollapsibleConfig, Collapsible,
UseCollapsibleReturns, type UseCollapsibleConfig,
type UseCollapsibleReturns,
} from './components/Collapsible'; } from './components/Collapsible';
export {default as Details} from './components/Details'; export {default as Details, type DetailsProps} from './components/Details';
export type {DetailsProps} from './components/Details';
export { export {
MobileSecondaryMenuProvider, MobileSecondaryMenuProvider,
@ -97,13 +96,19 @@ export {
export {useLocalPathname} from './utils/useLocalPathname'; export {useLocalPathname} from './utils/useLocalPathname';
export {translateTagsPageTitle, listTagsByLetters} from './utils/tagsUtils'; export {
export type {TagLetterEntry} from './utils/tagsUtils'; translateTagsPageTitle,
listTagsByLetters,
type TagLetterEntry,
type TagsListItem,
} from './utils/tagsUtils';
export {useHistoryPopHandler} from './utils/historyUtils'; export {useHistoryPopHandler} from './utils/historyUtils';
export {default as useTOCHighlight} from './utils/useTOCHighlight'; export {
export type {TOCHighlightConfig} from './utils/useTOCHighlight'; default as useTOCHighlight,
type TOCHighlightConfig,
} from './utils/useTOCHighlight';
export { export {
useFilteredAndTreeifiedTOC, useFilteredAndTreeifiedTOC,

View file

@ -199,14 +199,12 @@ function getBreadcrumbs({
function extract(items: PropSidebar) { function extract(items: PropSidebar) {
for (const item of items) { for (const item of items) {
if ( if (
item.type === 'category' && (item.type === 'category' &&
(isSamePath(item.href, pathname) || extract(item.items)) (isSamePath(item.href, pathname) || extract(item.items))) ||
(item.type === 'link' && isSamePath(item.href, pathname))
) { ) {
breadcrumbs.push(item); breadcrumbs.push(item);
return true; return true;
} else if (item.type === 'link' && isSamePath(item.href, pathname)) {
breadcrumbs.push(item);
return true;
} }
} }

View file

@ -10,7 +10,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
export function useTitleFormatter(title?: string | undefined): string { export function useTitleFormatter(title?: string | undefined): string {
const {siteConfig} = useDocusaurusContext(); const {siteConfig} = useDocusaurusContext();
const {title: siteTitle, titleDelimiter} = siteConfig; const {title: siteTitle, titleDelimiter} = siteConfig;
return title && title.trim().length return title?.trim().length
? `${title.trim()} ${titleDelimiter} ${siteTitle}` ? `${title.trim()} ${titleDelimiter} ${siteTitle}`
: siteTitle; : siteTitle;
} }

View file

@ -14,7 +14,11 @@ export const translateTagsPageTitle = (): string =>
description: 'The title of the tag list page', description: 'The title of the tag list page',
}); });
type TagsListItem = Readonly<{name: string; permalink: string; count: number}>; // TODO remove duplicated type :s export type TagsListItem = Readonly<{
name: string;
permalink: string;
count: number;
}>;
export type TagLetterEntry = Readonly<{letter: string; tags: TagsListItem[]}>; export type TagLetterEntry = Readonly<{letter: string; tags: TagsListItem[]}>;

View file

@ -8,10 +8,8 @@
import {useEffect, useRef} from 'react'; import {useEffect, useRef} from 'react';
import {useThemeConfig} from './useThemeConfig'; import {useThemeConfig} from './useThemeConfig';
/* // TODO make the hardcoded theme-classic classnames configurable (or add them
TODO make the hardcoded theme-classic classnames configurable // to ThemeClassNames?)
(or add them to ThemeClassNames?)
*/
// If the anchor has no height and is just a "marker" in the dom; we'll use the // If the anchor has no height and is just a "marker" in the dom; we'll use the
// parent (normally the link text) rect boundaries instead // parent (normally the link text) rect boundaries instead

View file

@ -10,7 +10,6 @@
// update script has ts-check anyways) (b) the test coverage isn't destroyed by // update script has ts-check anyways) (b) the test coverage isn't destroyed by
// the untested update.mjs file (c) we can ergonomically import the util // the untested update.mjs file (c) we can ergonomically import the util
// functions in the Jest test without using `await import` // functions in the Jest test without using `await import`
/* eslint-disable import/no-extraneous-dependencies */
import path from 'path'; import path from 'path';
import fs from 'fs-extra'; import fs from 'fs-extra';

View file

@ -6,7 +6,6 @@
*/ */
// @ts-check // @ts-check
/* eslint-disable import/no-extraneous-dependencies */
import logger from '@docusaurus/logger'; import logger from '@docusaurus/logger';
import path from 'path'; import path from 'path';

View file

@ -49,7 +49,6 @@ export async function getDataFileData<T>(
const unsafeContent = Yaml.load(contentString); const unsafeContent = Yaml.load(contentString);
return validate(unsafeContent); return validate(unsafeContent);
} catch (err) { } catch (err) {
// TODO replace later by error cause, see https://v8.dev/features/error-cause
logger.error`The ${params.fileType} file at path=${filePath} looks invalid.`; logger.error`The ${params.fileType} file at path=${filePath} looks invalid.`;
throw err; throw err;
} }

View file

@ -38,7 +38,6 @@ export function createExcerpt(fileString: string): string | undefined {
let inCode = false; let inCode = false;
let lastCodeFence = ''; let lastCodeFence = '';
/* eslint-disable no-continue */
for (const fileLine of fileLines) { for (const fileLine of fileLines) {
// Skip empty line. // Skip empty line.
if (!fileLine.trim()) { if (!fileLine.trim()) {

View file

@ -50,7 +50,6 @@ export function normalizeUrl(rawUrls: string[]): string {
if (i === urls.length - 1 && hasEndingSlash) { if (i === urls.length - 1 && hasEndingSlash) {
resultArray.push('/'); resultArray.push('/');
} }
// eslint-disable-next-line no-continue
continue; continue;
} }

View file

@ -72,8 +72,7 @@ export default async function beforeCli() {
* @param {import('update-notifier').UpdateInfo} update * @param {import('update-notifier').UpdateInfo} update
*/ */
function ignoreUpdate(update) { function ignoreUpdate(update) {
const isCanaryRelease = const isCanaryRelease = update?.current?.startsWith('0.0.0');
update && update.current && update.current.startsWith('0.0.0');
return isCanaryRelease; return isCanaryRelease;
} }

View file

@ -52,8 +52,7 @@ export default function ComponentCreator(
if (chunkRegistry) { if (chunkRegistry) {
// eslint-disable-next-line prefer-destructuring // eslint-disable-next-line prefer-destructuring
optsLoader[key] = chunkRegistry[0]; optsLoader[key] = chunkRegistry[0];
optsModules.push(chunkRegistry[1]); optsModules.push(chunkRegistry[1], chunkRegistry[2]);
optsWebpack.push(chunkRegistry[2]);
} }
}); });
@ -75,7 +74,7 @@ export default function ComponentCreator(
const nonDefaultKeys = Object.keys(loaded[key]).filter( const nonDefaultKeys = Object.keys(loaded[key]).filter(
(k) => k !== 'default', (k) => k !== 'default',
); );
if (nonDefaultKeys && nonDefaultKeys.length) { if (nonDefaultKeys?.length) {
nonDefaultKeys.forEach((nonDefaultKey) => { nonDefaultKeys.forEach((nonDefaultKey) => {
val[keyPath[keyPath.length - 1]!][nonDefaultKey] = val[keyPath[keyPath.length - 1]!][nonDefaultKey] =
loaded[key][nonDefaultKey]; loaded[key][nonDefaultKey];

View file

@ -26,7 +26,8 @@ function statusTable(): string {
head: ['Status', 'CLI option', 'Description'], head: ['Status', 'CLI option', 'Description'],
}); });
table.push({ table.push(
{
[tableStatusLabel('safe')]: [ [tableStatusLabel('safe')]: [
'', '',
` `
@ -34,9 +35,8 @@ This component is safe to swizzle and was designed for this purpose.
The swizzled component is retro-compatible with minor version upgrades. The swizzled component is retro-compatible with minor version upgrades.
`, `,
], ],
}); },
{
table.push({
[tableStatusLabel('unsafe')]: [ [tableStatusLabel('unsafe')]: [
logger.code('--danger'), logger.code('--danger'),
` `
@ -50,16 +50,16 @@ ${logger.green(
Report it here: https://github.com/facebook/docusaurus/discussions/5468 Report it here: https://github.com/facebook/docusaurus/discussions/5468
`, `,
], ],
}); },
{
table.push({
[tableStatusLabel('forbidden')]: [ [tableStatusLabel('forbidden')]: [
'', '',
` `
This component is not meant to be swizzled. This component is not meant to be swizzled.
`, `,
], ],
}); },
);
return table.toString(); return table.toString();
} }
@ -69,7 +69,8 @@ function actionsTable(): string {
head: ['Actions', 'CLI option', 'Description'], head: ['Actions', 'CLI option', 'Description'],
}); });
table.push({ table.push(
{
[logger.bold('Wrap')]: [ [logger.bold('Wrap')]: [
logger.code('--wrap'), logger.code('--wrap'),
` `
@ -81,9 +82,8 @@ ${logger.green('Tip')}: prefer ${logger.code(
)} whenever possible to reduce the amount of code to maintain. )} whenever possible to reduce the amount of code to maintain.
`, `,
], ],
}); },
{
table.push({
[logger.bold('Eject')]: [ [logger.bold('Eject')]: [
logger.code('--eject'), logger.code('--eject'),
` `
@ -95,7 +95,8 @@ ${logger.green('Tip')}: ${logger.code(
)} can be useful for completely redesigning a component. )} can be useful for completely redesigning a component.
`, `,
], ],
}); },
);
return table.toString(); return table.toString();
} }

View file

@ -168,13 +168,10 @@ describe('normalizeConfig', () => {
['this/should/work', {too: 'yes'}], ['this/should/work', {too: 'yes'}],
], ],
], ],
[ ['should accept function for plugin', [function plugin() {}]],
'should accept function for plugin',
[function plugin(_context, _options) {}],
],
[ [
'should accept [function, object] for plugin', 'should accept [function, object] for plugin',
[[(_context, _options) => {}, {it: 'should work'}]], [[() => {}, {it: 'should work'}]],
], ],
])(`%s for the input of: %p`, (_message, plugins) => { ])(`%s for the input of: %p`, (_message, plugins) => {
expect(() => { expect(() => {
@ -209,13 +206,10 @@ describe('normalizeConfig', () => {
['this/should/work', {too: 'yes'}], ['this/should/work', {too: 'yes'}],
], ],
], ],
[ ['should accept function for theme', [function theme() {}]],
'should accept function for theme',
[function theme(_context, _options) {}],
],
[ [
'should accept [function, object] for theme', 'should accept [function, object] for theme',
[[function theme(_context, _options) {}, {it: 'should work'}]], [[function theme() {}, {it: 'should work'}]],
], ],
])(`%s for the input of: %p`, (_message, themes) => { ])(`%s for the input of: %p`, (_message, themes) => {
expect(() => { expect(() => {

View file

@ -190,8 +190,10 @@ async function filterExistingFileLinks({
// -> /outDir/javadoc/index.html // -> /outDir/javadoc/index.html
const filePathsToTry: string[] = [baseFilePath]; const filePathsToTry: string[] = [baseFilePath];
if (!path.extname(baseFilePath)) { if (!path.extname(baseFilePath)) {
filePathsToTry.push(`${baseFilePath}.html`); filePathsToTry.push(
filePathsToTry.push(path.join(baseFilePath, 'index.html')); `${baseFilePath}.html`,
path.join(baseFilePath, 'index.html'),
);
} }
for (const file of filePathsToTry) { for (const file of filePathsToTry) {

View file

@ -277,7 +277,7 @@ function createMDXFallbackPlugin({
path.resolve(siteDir, dir), path.resolve(siteDir, dir),
), ),
siteDir, siteDir,
isMDXPartial: (_filename: string) => true, // External mdx files are always meant to be imported as partials isMDXPartial: () => true, // External mdx files are always meant to be imported as partials
isMDXPartialFrontMatterWarningDisabled: true, // External mdx files might have front matter, let's just disable the warning isMDXPartialFrontMatterWarningDisabled: true, // External mdx files might have front matter, let's just disable the warning
remarkPlugins: [admonitions], remarkPlugins: [admonitions],
}, },
@ -341,8 +341,10 @@ export default ${JSON.stringify(siteConfig, null, 2)};
`, `,
); );
plugins.push(createBootstrapPlugin({siteDir, siteConfig})); plugins.push(
plugins.push(createMDXFallbackPlugin({siteDir, siteConfig})); createBootstrapPlugin({siteDir, siteConfig}),
createMDXFallbackPlugin({siteDir, siteConfig}),
);
// Load client modules. // Load client modules.
const clientModules = loadClientModules(plugins); const clientModules = loadClientModules(plugins);

View file

@ -308,10 +308,9 @@ ${sourceWarningPart(path.node)}`);
), ),
) )
.pop(); .pop();
const isJSXText = singleChildren && singleChildren.isJSXText(); const isJSXText = singleChildren?.isJSXText();
const isJSXExpressionContainer = const isJSXExpressionContainer =
singleChildren && singleChildren?.isJSXExpressionContainer() &&
singleChildren.isJSXExpressionContainer() &&
(singleChildren.get('expression') as NodePath).evaluate().confident; (singleChildren.get('expression') as NodePath).evaluate().confident;
if (isJSXText || isJSXExpressionContainer) { if (isJSXText || isJSXExpressionContainer) {

View file

@ -23,7 +23,7 @@ function testStylelintRule(config, tests) {
const checkTestCaseContent = (testCase) => const checkTestCaseContent = (testCase) =>
testCase.description || testCase.code || 'no description'; testCase.description || testCase.code || 'no description';
if (tests.accept && tests.accept.length) { if (tests.accept?.length) {
describe('accept cases', () => { describe('accept cases', () => {
tests.accept.forEach((testCase) => { tests.accept.forEach((testCase) => {
it(`${checkTestCaseContent(testCase)}`, async () => { it(`${checkTestCaseContent(testCase)}`, async () => {
@ -46,7 +46,7 @@ function testStylelintRule(config, tests) {
}); });
} }
if (tests.reject && tests.reject.length) { if (tests.reject?.length) {
describe('reject cases', () => { describe('reject cases', () => {
tests.reject.forEach((testCase) => { tests.reject.forEach((testCase) => {
it(`${checkTestCaseContent(testCase)}`, async () => { it(`${checkTestCaseContent(testCase)}`, async () => {

View file

@ -120,7 +120,6 @@ for (const componentName of componentNames) {
logger.warn( logger.warn(
`${componentName} is marked as forbidden for action ${action} => skipping`, `${componentName} is marked as forbidden for action ${action} => skipping`,
); );
// eslint-disable-next-line no-continue
continue; continue;
} }

View file

@ -13,7 +13,6 @@ import path from 'path';
import imageSize from 'image-size'; import imageSize from 'image-size';
declare global { declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace jest { namespace jest {
interface Matchers<R> { interface Matchers<R> {
toHaveGoodDimensions: () => R; toHaveGoodDimensions: () => R;

View file

@ -4,7 +4,6 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
/* eslint-disable import/no-extraneous-dependencies */
const path = require('path'); const path = require('path');
const fs = require('fs-extra'); const fs = require('fs-extra');

View file

@ -7,7 +7,6 @@
import React from 'react'; import React from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
// eslint-disable-next-line import/no-extraneous-dependencies
import {MDXProvider} from '@mdx-js/react'; import {MDXProvider} from '@mdx-js/react';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl'; import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';

View file

@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
// eslint-disable-next-line import/no-extraneous-dependencies
import darkTheme from 'prism-react-renderer/themes/vsDark/index.cjs.js'; import darkTheme from 'prism-react-renderer/themes/vsDark/index.cjs.js';
export default { export default {

View file

@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
// eslint-disable-next-line import/no-extraneous-dependencies
import lightTheme from 'prism-react-renderer/themes/github/index.cjs.js'; import lightTheme from 'prism-react-renderer/themes/github/index.cjs.js';
export default { export default {