mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 17:57:48 +02:00
chore: tighten ESLint config (#6931)
* chore: tighten ESLint config * more refactor * refactor push * fix
This commit is contained in:
parent
f70ddf7e69
commit
cc0bceab9c
54 changed files with 177 additions and 193 deletions
27
.eslintrc.js
27
.eslintrc.js
|
@ -62,6 +62,7 @@ module.exports = {
|
|||
'no-await-in-loop': OFF,
|
||||
'no-case-declarations': WARNING,
|
||||
'no-console': OFF,
|
||||
'no-continue': OFF,
|
||||
'no-control-regex': WARNING,
|
||||
'no-else-return': [WARNING, {allowElseIf: true}],
|
||||
'no-empty': [WARNING, {allowEmptyCatch: true}],
|
||||
|
@ -275,6 +276,7 @@ module.exports = {
|
|||
},
|
||||
],
|
||||
'@typescript-eslint/no-inferrable-types': OFF,
|
||||
'@typescript-eslint/no-namespace': [WARNING, {allowDeclarations: true}],
|
||||
'no-use-before-define': OFF,
|
||||
'@typescript-eslint/no-use-before-define': [
|
||||
ERROR,
|
||||
|
@ -286,14 +288,11 @@ module.exports = {
|
|||
'no-shadow': OFF,
|
||||
'@typescript-eslint/no-shadow': ERROR,
|
||||
'no-unused-vars': OFF,
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
ERROR,
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
ignoreRestSiblings: true,
|
||||
},
|
||||
],
|
||||
// We don't provide any escape hatches for this rule. Rest siblings and
|
||||
// function placeholder params are always ignored, and any other unused
|
||||
// locals must be justified with a disable comment.
|
||||
'@typescript-eslint/no-unused-vars': [ERROR, {ignoreRestSiblings: true}],
|
||||
'@typescript-eslint/prefer-optional-chain': ERROR,
|
||||
},
|
||||
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: {
|
||||
'import/no-extraneous-dependencies': OFF,
|
||||
},
|
||||
|
|
|
@ -10,8 +10,19 @@ import fs from 'fs-extra';
|
|||
|
||||
type PackageJsonFile = {
|
||||
file: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
content: any;
|
||||
content: {
|
||||
name?: string;
|
||||
private?: boolean;
|
||||
version?: string;
|
||||
repository?: {
|
||||
type?: string;
|
||||
url?: string;
|
||||
directory?: string;
|
||||
};
|
||||
publishConfig?: {
|
||||
access?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
async function getPackagesJsonFiles(): Promise<PackageJsonFile[]> {
|
||||
|
|
|
@ -9,6 +9,6 @@ import type {Handler} from '@netlify/functions';
|
|||
|
||||
import {createPlaygroundResponse} from '../functionUtils/playgroundUtils';
|
||||
|
||||
export const handler: Handler = async function handler(_event, _context) {
|
||||
export const handler: Handler = async function handler() {
|
||||
return createPlaygroundResponse('codesandbox');
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
createPlaygroundDocumentationResponse,
|
||||
} from '../functionUtils/playgroundUtils';
|
||||
|
||||
export const handler: Handler = async (event, _context) => {
|
||||
export const handler: Handler = async (event) => {
|
||||
const playgroundName = readPlaygroundName(event);
|
||||
return playgroundName
|
||||
? createPlaygroundResponse(playgroundName)
|
||||
|
|
|
@ -9,6 +9,6 @@ import type {Handler} from '@netlify/functions';
|
|||
|
||||
import {createPlaygroundResponse} from '../functionUtils/playgroundUtils';
|
||||
|
||||
export const handler: Handler = async function handler(_event, _context) {
|
||||
export const handler: Handler = async function handler() {
|
||||
return createPlaygroundResponse('stackblitz');
|
||||
};
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import shell from 'shelljs';
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
|
||||
import sharp from 'sharp';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
|
|
1
jest/snapshotPathNormalizer.ts
vendored
1
jest/snapshotPathNormalizer.ts
vendored
|
@ -4,7 +4,6 @@
|
|||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
|
||||
// Forked from https://github.com/tribou/jest-serializer-path/blob/master/lib/index.js
|
||||
// Added some project-specific handlers
|
||||
|
|
|
@ -162,7 +162,7 @@ export default async function mdxLoader(
|
|||
|
||||
// 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
|
||||
const isMDXPartial = options.isMDXPartial && options.isMDXPartial(filePath);
|
||||
const isMDXPartial = options.isMDXPartial?.(filePath);
|
||||
if (isMDXPartial && hasFrontMatter) {
|
||||
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.
|
||||
|
|
|
@ -76,7 +76,7 @@ export default function plugin(options: PluginOptions = {}): Transformer {
|
|||
return (root) => {
|
||||
const headings: TOCItem[] = [];
|
||||
|
||||
visit(root, 'heading', (child: Heading, _index, parent) => {
|
||||
visit(root, 'heading', (child: Heading, index, parent) => {
|
||||
const value = toString(child);
|
||||
|
||||
// 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 targetIndex = getOrCreateExistingTargetIndex(children, name);
|
||||
|
||||
if (headings && headings.length) {
|
||||
if (headings.length) {
|
||||
children[targetIndex]!.value = `export const ${name} = ${stringifyObject(
|
||||
headings,
|
||||
)};`;
|
||||
|
|
|
@ -17,7 +17,7 @@ import type {Code, Parent} from 'mdast';
|
|||
// See https://github.com/facebook/docusaurus/pull/4278
|
||||
export default function plugin(this: Processor): Transformer {
|
||||
return (root) => {
|
||||
visit(root, 'code', (node: Code, _index, parent) => {
|
||||
visit(root, 'code', (node: Code, index, parent) => {
|
||||
if (node.lang === 'mdx-code-block') {
|
||||
const newChildren = (this.parse(node.value) as Parent).children;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ async function walk(dir: string): Promise<string[]> {
|
|||
for (const file of list) {
|
||||
const fullPath = `${dir}/${file}`;
|
||||
const stat = await fs.stat(fullPath);
|
||||
if (stat && stat.isDirectory()) {
|
||||
if (stat.isDirectory()) {
|
||||
results.push(...(await walk(fullPath)));
|
||||
} else {
|
||||
results.push(fullPath);
|
||||
|
|
|
@ -31,9 +31,7 @@ describe('normalizePluginOptions', () => {
|
|||
});
|
||||
|
||||
it('overrides all default options with valid user options', () => {
|
||||
const createRedirects: Options['createRedirects'] = (
|
||||
_routePath: string,
|
||||
) => [];
|
||||
const createRedirects: Options['createRedirects'] = () => [];
|
||||
expect(
|
||||
testValidate({
|
||||
fromExtensions: ['exe', 'zip'],
|
||||
|
|
|
@ -41,7 +41,7 @@ const UserOptionsSchema = Joi.object<PluginOptions>({
|
|||
redirects: Joi.array()
|
||||
.items(RedirectPluginOptionValidation)
|
||||
.default(DEFAULT_OPTIONS.redirects),
|
||||
createRedirects: Joi.function().arity(1),
|
||||
createRedirects: Joi.function().maxArity(1),
|
||||
}).default(DEFAULT_OPTIONS);
|
||||
|
||||
export function validateOptions({
|
||||
|
|
|
@ -45,7 +45,7 @@ async function generateBlogFeed({
|
|||
const {url: siteUrl, baseUrl, title, favicon} = siteConfig;
|
||||
const blogBaseUrl = normalizeUrl([siteUrl, baseUrl, routeBasePath]);
|
||||
|
||||
const updated = blogPosts[0] && blogPosts[0].metadata.date;
|
||||
const updated = blogPosts[0]?.metadata.date;
|
||||
|
||||
const feed = new Feed({
|
||||
id: blogBaseUrl,
|
||||
|
|
|
@ -34,5 +34,5 @@ export default function markdownLoader(
|
|||
finalContent = truncate(finalContent, markdownLoaderOptions.truncateMarker);
|
||||
}
|
||||
|
||||
return callback && callback(null, finalContent);
|
||||
return callback?.(null, finalContent);
|
||||
}
|
||||
|
|
|
@ -745,9 +745,7 @@ describe('site with custom sidebar items generator', () => {
|
|||
}
|
||||
|
||||
it('sidebarItemsGenerator is called with appropriate data', async () => {
|
||||
const customSidebarItemsGeneratorMock = jest.fn(
|
||||
async (_arg: SidebarItemsGeneratorOptionArgs) => [],
|
||||
);
|
||||
const customSidebarItemsGeneratorMock = jest.fn(async () => []);
|
||||
const {siteDir} = await loadSite(customSidebarItemsGeneratorMock);
|
||||
|
||||
const generatorArg: SidebarItemsGeneratorOptionArgs =
|
||||
|
|
|
@ -16,7 +16,5 @@ export default function markdownLoader(
|
|||
const fileString = source;
|
||||
const callback = this.async();
|
||||
const options = this.getOptions();
|
||||
return (
|
||||
callback && callback(null, linkify(fileString, this.resourcePath, options))
|
||||
);
|
||||
return callback?.(null, linkify(fileString, this.resourcePath, options));
|
||||
}
|
||||
|
|
|
@ -118,26 +118,24 @@ function getSidebarTranslationFileContent(
|
|||
},
|
||||
]);
|
||||
|
||||
if (category.link) {
|
||||
if (category.link.type === 'generated-index') {
|
||||
if (category.link.title) {
|
||||
entries.push([
|
||||
`sidebar.${sidebarName}.category.${category.label}.link.generated-index.title`,
|
||||
{
|
||||
message: category.link.title,
|
||||
description: `The generated-index page title for category ${category.label} in sidebar ${sidebarName}`,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (category.link.description) {
|
||||
entries.push([
|
||||
`sidebar.${sidebarName}.category.${category.label}.link.generated-index.description`,
|
||||
{
|
||||
message: category.link.description,
|
||||
description: `The generated-index page description for category ${category.label} in sidebar ${sidebarName}`,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (category.link?.type === 'generated-index') {
|
||||
if (category.link.title) {
|
||||
entries.push([
|
||||
`sidebar.${sidebarName}.category.${category.label}.link.generated-index.title`,
|
||||
{
|
||||
message: category.link.title,
|
||||
description: `The generated-index page title for category ${category.label} in sidebar ${sidebarName}`,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (category.link.description) {
|
||||
entries.push([
|
||||
`sidebar.${sidebarName}.category.${category.label}.link.generated-index.description`,
|
||||
{
|
||||
message: category.link.description,
|
||||
description: `The generated-index page description for category ${category.label} in sidebar ${sidebarName}`,
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,5 +18,5 @@ export default function markdownLoader(
|
|||
// TODO provide additional md processing here? like interlinking pages?
|
||||
// fileString = linkify(fileString)
|
||||
|
||||
return callback && callback(null, fileString);
|
||||
return callback?.(null, fileString);
|
||||
}
|
||||
|
|
|
@ -39,9 +39,7 @@ function PluginContent({
|
|||
<div>
|
||||
{Object.entries(pluginContent)
|
||||
// filter plugin instances with no content
|
||||
.filter(
|
||||
([_pluginId, pluginInstanceContent]) => !!pluginInstanceContent,
|
||||
)
|
||||
.filter(([, pluginInstanceContent]) => !!pluginInstanceContent)
|
||||
.map(([pluginId, pluginInstanceContent]) => (
|
||||
<PluginInstanceContent
|
||||
key={pluginId}
|
||||
|
@ -61,7 +59,7 @@ export default function DebugContent({allContent}: Props): JSX.Element {
|
|||
<div>
|
||||
{Object.entries(allContent)
|
||||
// filter plugins with no content
|
||||
.filter(([_pluginName, pluginContent]) =>
|
||||
.filter(([, pluginContent]) =>
|
||||
Object.values(pluginContent).some(
|
||||
(instanceContent) => !!instanceContent,
|
||||
),
|
||||
|
|
|
@ -79,7 +79,7 @@ function isStandaloneDisplayMode() {
|
|||
const OfflineModeActivationStrategiesImplementations = {
|
||||
always: () => true,
|
||||
mobile: () => window.innerWidth <= MAX_MOBILE_WIDTH,
|
||||
saveData: () => !!(navigator.connection && navigator.connection.saveData),
|
||||
saveData: () => !!navigator.connection?.saveData,
|
||||
appInstalled: async () => {
|
||||
const installedEventFired = await isAppInstalledEventFired();
|
||||
const installedRelatedApps = await isAppInstalledRelatedApps();
|
||||
|
|
|
@ -137,7 +137,7 @@ function getPossibleURLs(url) {
|
|||
});
|
||||
}
|
||||
|
||||
const type = event.data && event.data.type;
|
||||
const type = event.data?.type;
|
||||
|
||||
if (type === 'SKIP_WAITING') {
|
||||
self.skipWaiting();
|
||||
|
|
|
@ -833,11 +833,8 @@ declare module '@theme/IconExternalLink' {
|
|||
}
|
||||
|
||||
declare module '@theme/TagsListByLetter' {
|
||||
export type TagsListItem = Readonly<{
|
||||
name: string;
|
||||
permalink: string;
|
||||
count: number;
|
||||
}>;
|
||||
import type {TagsListItem} from '@docusaurus/theme-common';
|
||||
|
||||
export interface Props {
|
||||
readonly tags: readonly TagsListItem[];
|
||||
}
|
||||
|
@ -853,7 +850,7 @@ declare module '@theme/TagsListInline' {
|
|||
}
|
||||
|
||||
declare module '@theme/Tag' {
|
||||
import type {TagsListItem} from '@theme/TagsListByLetter';
|
||||
import type {TagsListItem} from '@docusaurus/theme-common';
|
||||
import type {Optional} from 'utility-types';
|
||||
|
||||
export interface Props extends Optional<TagsListItem, 'count'> {}
|
||||
|
|
|
@ -234,9 +234,7 @@ function DocSidebarItemHtml({
|
|||
)}
|
||||
key={index}
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: value,
|
||||
}}
|
||||
dangerouslySetInnerHTML={{__html: value}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,9 +14,7 @@ export default function FooterCopyright({copyright}: Props): JSX.Element {
|
|||
className="footer__copyright"
|
||||
// Developer provided the HTML, so assume it's safe.
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: copyright,
|
||||
}}
|
||||
dangerouslySetInnerHTML={{__html: copyright}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,9 +18,7 @@ function ColumnLinkItem({item}: {item: ColumnItemType}) {
|
|||
className="footer__item"
|
||||
// Developer provided the HTML, so assume it's safe.
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.html,
|
||||
}}
|
||||
dangerouslySetInnerHTML={{__html: item.html}}
|
||||
/>
|
||||
) : (
|
||||
<li key={item.href || item.to} className="footer__item">
|
||||
|
|
|
@ -19,9 +19,7 @@ function SimpleLinkItem({item}: {item: Props['links'][number]}) {
|
|||
className="footer__link-item"
|
||||
// Developer provided the HTML, so assume it's safe.
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.html,
|
||||
}}
|
||||
dangerouslySetInnerHTML={{__html: item.html}}
|
||||
/>
|
||||
) : (
|
||||
<LinkItem item={item} />
|
||||
|
|
|
@ -41,7 +41,7 @@ function DefaultNavbarItemDesktop({
|
|||
|
||||
function DefaultNavbarItemMobile({
|
||||
className,
|
||||
isDropdownItem: _isDropdownItem,
|
||||
isDropdownItem,
|
||||
...props
|
||||
}: DesktopOrMobileNavBarItemProps) {
|
||||
return (
|
||||
|
@ -53,7 +53,7 @@ function DefaultNavbarItemMobile({
|
|||
|
||||
export default function DefaultNavbarItem({
|
||||
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): JSX.Element {
|
||||
const Comp = mobile ? DefaultNavbarItemMobile : DefaultNavbarItemDesktop;
|
||||
|
|
|
@ -124,7 +124,7 @@ function DropdownNavbarItemDesktop({
|
|||
function DropdownNavbarItemMobile({
|
||||
items,
|
||||
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
|
||||
}: DesktopOrMobileNavBarItemProps) {
|
||||
const localPathname = useLocalPathname();
|
||||
|
|
|
@ -5,26 +5,25 @@
|
|||
* 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 {
|
||||
DocSidebarItemsExpandedStateProvider,
|
||||
useDocSidebarItemsExpandedState,
|
||||
} 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 {useAlternatePageUtils} from './utils/useAlternatePageUtils';
|
||||
|
@ -63,14 +62,14 @@ export {useLocationChange} from './utils/useLocationChange';
|
|||
|
||||
export {usePrevious} from './utils/usePrevious';
|
||||
|
||||
export {useCollapsible, Collapsible} from './components/Collapsible';
|
||||
export type {
|
||||
UseCollapsibleConfig,
|
||||
UseCollapsibleReturns,
|
||||
export {
|
||||
useCollapsible,
|
||||
Collapsible,
|
||||
type UseCollapsibleConfig,
|
||||
type UseCollapsibleReturns,
|
||||
} from './components/Collapsible';
|
||||
|
||||
export {default as Details} from './components/Details';
|
||||
export type {DetailsProps} from './components/Details';
|
||||
export {default as Details, type DetailsProps} from './components/Details';
|
||||
|
||||
export {
|
||||
MobileSecondaryMenuProvider,
|
||||
|
@ -97,13 +96,19 @@ export {
|
|||
|
||||
export {useLocalPathname} from './utils/useLocalPathname';
|
||||
|
||||
export {translateTagsPageTitle, listTagsByLetters} from './utils/tagsUtils';
|
||||
export type {TagLetterEntry} from './utils/tagsUtils';
|
||||
export {
|
||||
translateTagsPageTitle,
|
||||
listTagsByLetters,
|
||||
type TagLetterEntry,
|
||||
type TagsListItem,
|
||||
} from './utils/tagsUtils';
|
||||
|
||||
export {useHistoryPopHandler} from './utils/historyUtils';
|
||||
|
||||
export {default as useTOCHighlight} from './utils/useTOCHighlight';
|
||||
export type {TOCHighlightConfig} from './utils/useTOCHighlight';
|
||||
export {
|
||||
default as useTOCHighlight,
|
||||
type TOCHighlightConfig,
|
||||
} from './utils/useTOCHighlight';
|
||||
|
||||
export {
|
||||
useFilteredAndTreeifiedTOC,
|
||||
|
|
|
@ -199,14 +199,12 @@ function getBreadcrumbs({
|
|||
function extract(items: PropSidebar) {
|
||||
for (const item of items) {
|
||||
if (
|
||||
item.type === 'category' &&
|
||||
(isSamePath(item.href, pathname) || extract(item.items))
|
||||
(item.type === 'category' &&
|
||||
(isSamePath(item.href, pathname) || extract(item.items))) ||
|
||||
(item.type === 'link' && isSamePath(item.href, pathname))
|
||||
) {
|
||||
breadcrumbs.push(item);
|
||||
return true;
|
||||
} else if (item.type === 'link' && isSamePath(item.href, pathname)) {
|
||||
breadcrumbs.push(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|||
export function useTitleFormatter(title?: string | undefined): string {
|
||||
const {siteConfig} = useDocusaurusContext();
|
||||
const {title: siteTitle, titleDelimiter} = siteConfig;
|
||||
return title && title.trim().length
|
||||
return title?.trim().length
|
||||
? `${title.trim()} ${titleDelimiter} ${siteTitle}`
|
||||
: siteTitle;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,11 @@ export const translateTagsPageTitle = (): string =>
|
|||
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[]}>;
|
||||
|
||||
|
|
|
@ -8,10 +8,8 @@
|
|||
import {useEffect, useRef} from 'react';
|
||||
import {useThemeConfig} from './useThemeConfig';
|
||||
|
||||
/*
|
||||
TODO make the hardcoded theme-classic classnames configurable
|
||||
(or add them to ThemeClassNames?)
|
||||
*/
|
||||
// TODO make the hardcoded theme-classic classnames configurable (or add them
|
||||
// to ThemeClassNames?)
|
||||
|
||||
// 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
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
// 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
|
||||
// functions in the Jest test without using `await import`
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
// @ts-check
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
|
||||
import logger from '@docusaurus/logger';
|
||||
import path from 'path';
|
||||
|
|
|
@ -49,7 +49,6 @@ export async function getDataFileData<T>(
|
|||
const unsafeContent = Yaml.load(contentString);
|
||||
return validate(unsafeContent);
|
||||
} 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.`;
|
||||
throw err;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ export function createExcerpt(fileString: string): string | undefined {
|
|||
let inCode = false;
|
||||
let lastCodeFence = '';
|
||||
|
||||
/* eslint-disable no-continue */
|
||||
for (const fileLine of fileLines) {
|
||||
// Skip empty line.
|
||||
if (!fileLine.trim()) {
|
||||
|
|
|
@ -50,7 +50,6 @@ export function normalizeUrl(rawUrls: string[]): string {
|
|||
if (i === urls.length - 1 && hasEndingSlash) {
|
||||
resultArray.push('/');
|
||||
}
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,8 +72,7 @@ export default async function beforeCli() {
|
|||
* @param {import('update-notifier').UpdateInfo} update
|
||||
*/
|
||||
function ignoreUpdate(update) {
|
||||
const isCanaryRelease =
|
||||
update && update.current && update.current.startsWith('0.0.0');
|
||||
const isCanaryRelease = update?.current?.startsWith('0.0.0');
|
||||
return isCanaryRelease;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,7 @@ export default function ComponentCreator(
|
|||
if (chunkRegistry) {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
optsLoader[key] = chunkRegistry[0];
|
||||
optsModules.push(chunkRegistry[1]);
|
||||
optsWebpack.push(chunkRegistry[2]);
|
||||
optsModules.push(chunkRegistry[1], chunkRegistry[2]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -75,7 +74,7 @@ export default function ComponentCreator(
|
|||
const nonDefaultKeys = Object.keys(loaded[key]).filter(
|
||||
(k) => k !== 'default',
|
||||
);
|
||||
if (nonDefaultKeys && nonDefaultKeys.length) {
|
||||
if (nonDefaultKeys?.length) {
|
||||
nonDefaultKeys.forEach((nonDefaultKey) => {
|
||||
val[keyPath[keyPath.length - 1]!][nonDefaultKey] =
|
||||
loaded[key][nonDefaultKey];
|
||||
|
|
|
@ -26,20 +26,20 @@ function statusTable(): string {
|
|||
head: ['Status', 'CLI option', 'Description'],
|
||||
});
|
||||
|
||||
table.push({
|
||||
[tableStatusLabel('safe')]: [
|
||||
'',
|
||||
`
|
||||
table.push(
|
||||
{
|
||||
[tableStatusLabel('safe')]: [
|
||||
'',
|
||||
`
|
||||
This component is safe to swizzle and was designed for this purpose.
|
||||
The swizzled component is retro-compatible with minor version upgrades.
|
||||
`,
|
||||
],
|
||||
});
|
||||
|
||||
table.push({
|
||||
[tableStatusLabel('unsafe')]: [
|
||||
logger.code('--danger'),
|
||||
`
|
||||
],
|
||||
},
|
||||
{
|
||||
[tableStatusLabel('unsafe')]: [
|
||||
logger.code('--danger'),
|
||||
`
|
||||
This component is unsafe to swizzle, but you can still do it!
|
||||
Warning: we may release breaking changes within minor version upgrades.
|
||||
You will have to upgrade your component manually and maintain it over time.
|
||||
|
@ -49,17 +49,17 @@ ${logger.green(
|
|||
)}: your customization can't be done in a ${tableStatusLabel('safe')} way?
|
||||
Report it here: https://github.com/facebook/docusaurus/discussions/5468
|
||||
`,
|
||||
],
|
||||
});
|
||||
|
||||
table.push({
|
||||
[tableStatusLabel('forbidden')]: [
|
||||
'',
|
||||
`
|
||||
],
|
||||
},
|
||||
{
|
||||
[tableStatusLabel('forbidden')]: [
|
||||
'',
|
||||
`
|
||||
This component is not meant to be swizzled.
|
||||
`,
|
||||
],
|
||||
});
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
return table.toString();
|
||||
}
|
||||
|
@ -69,33 +69,34 @@ function actionsTable(): string {
|
|||
head: ['Actions', 'CLI option', 'Description'],
|
||||
});
|
||||
|
||||
table.push({
|
||||
[logger.bold('Wrap')]: [
|
||||
logger.code('--wrap'),
|
||||
`
|
||||
table.push(
|
||||
{
|
||||
[logger.bold('Wrap')]: [
|
||||
logger.code('--wrap'),
|
||||
`
|
||||
Creates a wrapper around the original theme component.
|
||||
Allows rendering other components before/after the original theme component.
|
||||
|
||||
${logger.green('Tip')}: prefer ${logger.code(
|
||||
'--wrap',
|
||||
)} whenever possible to reduce the amount of code to maintain.
|
||||
'--wrap',
|
||||
)} whenever possible to reduce the amount of code to maintain.
|
||||
`,
|
||||
],
|
||||
});
|
||||
|
||||
table.push({
|
||||
[logger.bold('Eject')]: [
|
||||
logger.code('--eject'),
|
||||
`
|
||||
],
|
||||
},
|
||||
{
|
||||
[logger.bold('Eject')]: [
|
||||
logger.code('--eject'),
|
||||
`
|
||||
Ejects the full source code of the original theme component.
|
||||
Allows overriding of the original component entirely with your own UI and logic.
|
||||
|
||||
${logger.green('Tip')}: ${logger.code(
|
||||
'--eject',
|
||||
)} can be useful for completely redesigning a component.
|
||||
'--eject',
|
||||
)} can be useful for completely redesigning a component.
|
||||
`,
|
||||
],
|
||||
});
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
return table.toString();
|
||||
}
|
||||
|
|
|
@ -168,13 +168,10 @@ describe('normalizeConfig', () => {
|
|||
['this/should/work', {too: 'yes'}],
|
||||
],
|
||||
],
|
||||
[
|
||||
'should accept function for plugin',
|
||||
[function plugin(_context, _options) {}],
|
||||
],
|
||||
['should accept function for plugin', [function plugin() {}]],
|
||||
[
|
||||
'should accept [function, object] for plugin',
|
||||
[[(_context, _options) => {}, {it: 'should work'}]],
|
||||
[[() => {}, {it: 'should work'}]],
|
||||
],
|
||||
])(`%s for the input of: %p`, (_message, plugins) => {
|
||||
expect(() => {
|
||||
|
@ -209,13 +206,10 @@ describe('normalizeConfig', () => {
|
|||
['this/should/work', {too: 'yes'}],
|
||||
],
|
||||
],
|
||||
[
|
||||
'should accept function for theme',
|
||||
[function theme(_context, _options) {}],
|
||||
],
|
||||
['should accept function for theme', [function 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) => {
|
||||
expect(() => {
|
||||
|
|
|
@ -190,8 +190,10 @@ async function filterExistingFileLinks({
|
|||
// -> /outDir/javadoc/index.html
|
||||
const filePathsToTry: string[] = [baseFilePath];
|
||||
if (!path.extname(baseFilePath)) {
|
||||
filePathsToTry.push(`${baseFilePath}.html`);
|
||||
filePathsToTry.push(path.join(baseFilePath, 'index.html'));
|
||||
filePathsToTry.push(
|
||||
`${baseFilePath}.html`,
|
||||
path.join(baseFilePath, 'index.html'),
|
||||
);
|
||||
}
|
||||
|
||||
for (const file of filePathsToTry) {
|
||||
|
|
|
@ -277,7 +277,7 @@ function createMDXFallbackPlugin({
|
|||
path.resolve(siteDir, dir),
|
||||
),
|
||||
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
|
||||
remarkPlugins: [admonitions],
|
||||
},
|
||||
|
@ -341,8 +341,10 @@ export default ${JSON.stringify(siteConfig, null, 2)};
|
|||
`,
|
||||
);
|
||||
|
||||
plugins.push(createBootstrapPlugin({siteDir, siteConfig}));
|
||||
plugins.push(createMDXFallbackPlugin({siteDir, siteConfig}));
|
||||
plugins.push(
|
||||
createBootstrapPlugin({siteDir, siteConfig}),
|
||||
createMDXFallbackPlugin({siteDir, siteConfig}),
|
||||
);
|
||||
|
||||
// Load client modules.
|
||||
const clientModules = loadClientModules(plugins);
|
||||
|
|
|
@ -308,10 +308,9 @@ ${sourceWarningPart(path.node)}`);
|
|||
),
|
||||
)
|
||||
.pop();
|
||||
const isJSXText = singleChildren && singleChildren.isJSXText();
|
||||
const isJSXText = singleChildren?.isJSXText();
|
||||
const isJSXExpressionContainer =
|
||||
singleChildren &&
|
||||
singleChildren.isJSXExpressionContainer() &&
|
||||
singleChildren?.isJSXExpressionContainer() &&
|
||||
(singleChildren.get('expression') as NodePath).evaluate().confident;
|
||||
|
||||
if (isJSXText || isJSXExpressionContainer) {
|
||||
|
|
|
@ -23,7 +23,7 @@ function testStylelintRule(config, tests) {
|
|||
const checkTestCaseContent = (testCase) =>
|
||||
testCase.description || testCase.code || 'no description';
|
||||
|
||||
if (tests.accept && tests.accept.length) {
|
||||
if (tests.accept?.length) {
|
||||
describe('accept cases', () => {
|
||||
tests.accept.forEach((testCase) => {
|
||||
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', () => {
|
||||
tests.reject.forEach((testCase) => {
|
||||
it(`${checkTestCaseContent(testCase)}`, async () => {
|
||||
|
|
|
@ -120,7 +120,6 @@ for (const componentName of componentNames) {
|
|||
logger.warn(
|
||||
`${componentName} is marked as forbidden for action ${action} => skipping`,
|
||||
);
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import path from 'path';
|
|||
import imageSize from 'image-size';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace jest {
|
||||
interface Matchers<R> {
|
||||
toHaveGoodDimensions: () => R;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import {MDXProvider} from '@mdx-js/react';
|
||||
import Link from '@docusaurus/Link';
|
||||
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 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';
|
||||
|
||||
export default {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 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';
|
||||
|
||||
export default {
|
||||
|
|
Loading…
Add table
Reference in a new issue