chore(v2): Fix more linter warnings (#4450)

This commit is contained in:
Sam Zhou 2021-03-18 13:05:09 -04:00 committed by GitHub
parent 3422f80a9a
commit 83d043ecb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 116 additions and 85 deletions

View file

@ -65,6 +65,7 @@ module.exports = {
'jsx-a11y/no-noninteractive-element-interactions': WARNING,
'no-console': OFF,
'no-else-return': OFF,
'no-param-reassign': [WARNING, {props: false}],
'no-underscore-dangle': OFF,
curly: [WARNING, 'all'],
'react/jsx-closing-bracket-location': OFF, // Conflicts with Prettier.
@ -103,7 +104,6 @@ module.exports = {
'import/no-extraneous-dependencies': ERROR,
'no-useless-escape': WARNING,
'prefer-template': WARNING,
'no-param-reassign': WARNING,
'no-template-curly-in-string': WARNING,
'array-callback-return': WARNING,
camelcase: WARNING,

View file

@ -14,6 +14,7 @@ const readFile = util.promisify(fsCb.readFile);
type PackageJsonFile = {
file: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
content: any;
};

View file

@ -3,6 +3,7 @@
"version": "2.0.0-alpha.72",
"description": "Docusaurus Loader for MDX",
"main": "src/index.js",
"types": "src/index.d.ts",
"publishConfig": {
"access": "public"
},

View file

@ -0,0 +1,19 @@
/**
* 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.
*/
type RemarkOrRehypePlugin =
// eslint-disable-next-line @typescript-eslint/ban-types
[Function, Record<string, unknown>] | Function;
declare function docusaurusMdxLoader(fileString: string): string;
export interface RemarkAndRehypePluginOptions {
remarkPlugins: RemarkOrRehypePlugin[];
rehypePlugins: string[];
beforeDefaultRemarkPlugins: RemarkOrRehypePlugin[];
beforeDefaultRehypePlugins: RemarkOrRehypePlugin[];
}

View file

@ -9,6 +9,8 @@
const toString = require('mdast-util-to-string');
const visit = require('unist-util-visit');
// Destructuring require tslib
// eslint-disable-next-line prefer-destructuring
const toValue = require('../utils').toValue;
/** @typedef {import('@docusaurus/types').TOCItem} TOC */

View file

@ -13,6 +13,7 @@ import Color from 'color';
import {
ClassicPresetEntries,
SidebarEntry,
SidebarEntries,
VersionOneConfig,
VersionTwoConfig,
@ -584,9 +585,8 @@ function migrateVersionedSidebar(
return;
}
const newSidebar = Object.entries(sidebarEntries).reduce(
(topLevel: {[key: string]: any}, value) => {
(topLevel: SidebarEntries, value) => {
const key = value[0].replace(versionRegex, '');
// eslint-disable-next-line no-param-reassign
topLevel[key] = Object.entries(value[1]).reduce(
(
acc: {[key: string]: Array<Record<string, unknown> | string>},
@ -594,16 +594,14 @@ function migrateVersionedSidebar(
) => {
acc[
val[0].replace(versionRegex, '')
] = (val[1] as Array<any>).map((item) => {
] = (val[1] as Array<SidebarEntry>).map((item) => {
if (typeof item === 'string') {
return item.replace(versionRegex, '');
}
return {
type: 'category',
label: item.label,
ids: item.ids.map((id: string) =>
id.replace(versionRegex, ''),
),
ids: item.ids.map((id) => id.replace(versionRegex, '')),
};
});
return acc;
@ -618,14 +616,14 @@ function migrateVersionedSidebar(
});
sidebars.forEach((sidebar) => {
const newSidebar = Object.entries(sidebar.entries).reduce(
(acc: {[key: string]: any}, val) => {
(acc: SidebarEntries, val) => {
const key = `version-${sidebar.version}/${val[0]}`;
// eslint-disable-next-line prefer-destructuring
acc[key] = Object.entries(val[1]).map((value) => {
return {
type: 'category',
label: value[0],
items: (value[1] as Array<any>).map((sidebarItem) => {
items: (value[1] as Array<SidebarEntry>).map((sidebarItem) => {
if (typeof sidebarItem === 'string') {
return {
type: 'doc',
@ -756,7 +754,10 @@ function migratePackageFile(
newDir: string,
): void {
const packageFile = importFresh(`${siteDir}/package.json`) as {
[key: string]: any;
scripts?: Record<string, string>;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
[otherKey: string]: unknown;
};
packageFile.scripts = {
...packageFile.scripts,

View file

@ -21,6 +21,14 @@ export type ClassicPresetEntries = {
theme: {[key: string]: unknown};
};
export type SidebarEntry =
| string
| {
type: string;
label: string;
ids: string[];
};
export type SidebarEntries = {
[key: string]:
| Record<string, unknown>
@ -97,10 +105,10 @@ export type VersionOneConfig = {
organizationName?: string;
projectName?: string;
noIndex?: boolean;
headerLinks?: Array<any>;
headerLinks?: Array<{doc: string; href: string; label: string; page: string}>;
headerIcon?: string;
favicon?: string;
colors?: any;
colors?: {primaryColor: string};
copyright?: string;
editUrl?: string;
customDocsPath?: string;

View file

@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import fs from 'fs-extra';
import path from 'path';
import pluginContentBlog from '../index';

View file

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import type {RemarkAndRehypePluginOptions} from '@docusaurus/mdx-loader';
import {
BrokenMarkdownLink,
ContentPaths,
@ -33,7 +34,7 @@ export type EditUrlFunction = (editUrlParams: {
locale: string;
}) => string | undefined;
export interface PluginOptions {
export interface PluginOptions extends RemarkAndRehypePluginOptions {
id?: string;
path: string;
routeBasePath: string;
@ -47,16 +48,6 @@ export interface PluginOptions {
blogDescription: string;
blogSidebarCount: number | 'ALL';
blogSidebarTitle: string;
remarkPlugins: ([Function, Record<string, unknown>] | Function)[];
beforeDefaultRehypePlugins: (
| [Function, Record<string, unknown>]
| Function
)[];
beforeDefaultRemarkPlugins: (
| [Function, Record<string, unknown>]
| Function
)[];
rehypePlugins: string[];
truncateMarker: RegExp;
showReadingTime: boolean;
feedOptions: {

View file

@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import path from 'path';
import {isMatch} from 'picomatch';
import commander from 'commander';
@ -42,8 +44,8 @@ const defaultDocMetadata: Partial<DocMetadata> = {
const createFakeActions = (contentDir: string) => {
const routeConfigs: RouteConfig[] = [];
const dataContainer: any = {};
const globalDataContainer: any = {};
const dataContainer: Record<string, unknown> = {};
const globalDataContainer: {pluginName?: {pluginId: unknown}} = {};
const actions = {
addRoute: (config: RouteConfig) => {
@ -53,7 +55,7 @@ const createFakeActions = (contentDir: string) => {
dataContainer[name] = content;
return path.join(contentDir, name);
},
setGlobalData: (data: any) => {
setGlobalData: (data: unknown) => {
globalDataContainer.pluginName = {pluginId: data};
},
};

View file

@ -49,7 +49,8 @@ export function cliDocsVersionCommand(
// Since we are going to create `version-${version}` folder, we need to make
// sure it's a valid pathname.
if (/[<>:"\/\\|?*\x00-\x1F]/g.test(version)) {
// eslint-disable-next-line no-control-regex
if (/[<>:"|?*\x00-\x1F]/g.test(version)) {
throw new Error(
`${pluginIdLogPrefix}Invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0`,
);

View file

@ -121,7 +121,7 @@ export const getActiveDocContext = (
data.versions.forEach((version) => {
version.docs.forEach((doc) => {
if (doc.id === docId) {
result[version.name!] = doc;
result[version.name] = doc;
}
});
});
@ -157,7 +157,7 @@ export const getDocVersionSuggestions = (
const isNotOnLatestVersion = activeDocContext.activeVersion !== latestVersion;
const latestDocSuggestion: GlobalDoc | undefined = isNotOnLatestVersion
? activeDocContext?.alternateDocVersions[latestVersion.name!]
? activeDocContext?.alternateDocVersions[latestVersion.name]
: undefined;
const latestVersionSuggestion = isNotOnLatestVersion

View file

@ -78,7 +78,7 @@ function normalizeCategoryShorthand(
function assertItem<K extends string>(
item: Record<string, unknown>,
keys: K[],
): asserts item is Record<K, any> {
): asserts item is Record<K, never> {
const unknownKeys = Object.keys(item).filter(
// @ts-expect-error: key is always string
(key) => !keys.includes(key as string) && key !== 'type',
@ -272,9 +272,7 @@ export function collectSidebarsDocIds(
});
}
export function createSidebarsUtils(
sidebars: Sidebars,
): Record<string, Function> {
export function createSidebarsUtils(sidebars: Sidebars) {
const sidebarNameToDocIds = collectSidebarsDocIds(sidebars);
function getFirstDocIdOfFirstSidebar(): string | undefined {

View file

@ -8,6 +8,7 @@
// eslint-disable-next-line spaced-comment
/// <reference types="@docusaurus/module-type-aliases" />
import type {RemarkAndRehypePluginOptions} from '@docusaurus/mdx-loader';
import {
BrokenMarkdownLink as IBrokenMarkdownLink,
ContentPaths,
@ -72,21 +73,12 @@ export type VersionsOptions = {
export type PluginOptions = MetadataOptions &
PathOptions &
VersionsOptions & {
VersionsOptions &
RemarkAndRehypePluginOptions & {
id: string;
include: string[];
docLayoutComponent: string;
docItemComponent: string;
remarkPlugins: ([Function, Record<string, unknown>] | Function)[];
rehypePlugins: string[];
beforeDefaultRemarkPlugins: (
| [Function, Record<string, unknown>]
| Function
)[];
beforeDefaultRehypePlugins: (
| [Function, Record<string, unknown>]
| Function
)[];
admonitions: Record<string, unknown>;
disableVersioning: boolean;
excludeNextVersionDocs?: boolean;

View file

@ -5,23 +5,15 @@
* LICENSE file in the root directory of this source tree.
*/
export interface PluginOptions {
import type {RemarkAndRehypePluginOptions} from '@docusaurus/mdx-loader';
export interface PluginOptions extends RemarkAndRehypePluginOptions {
id?: string;
path: string;
routeBasePath: string;
include: string[];
exclude: string[];
mdxPageComponent: string;
remarkPlugins: ([Function, Record<string, unknown>] | Function)[];
rehypePlugins: string[];
beforeDefaultRemarkPlugins: (
| [Function, Record<string, unknown>]
| Function
)[];
beforeDefaultRehypePlugins: (
| [Function, Record<string, unknown>]
| Function
)[];
admonitions: Record<string, unknown>;
}

View file

@ -5,11 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
import {Plugin} from '@docusaurus/types';
import {DocusaurusContext, Plugin} from '@docusaurus/types';
import {ThemeConfig} from '@docusaurus/theme-common';
import {getTranslationFiles, translateThemeConfig} from './translations';
import path from 'path';
import Module from 'module';
import postcss from 'postcss';
import postcss, {Root as PostCssRoot} from 'postcss';
import rtlcss from 'rtlcss';
import {readDefaultCodeTranslationMessages} from '@docusaurus/utils';
@ -73,14 +74,15 @@ type PluginOptions = {
};
export default function docusaurusThemeClassic(
context: any, // TODO: LoadContext is missing some of properties
context: DocusaurusContext, // TODO: LoadContext is missing some of properties
options: PluginOptions,
): Plugin<void> {
const {
siteConfig: {themeConfig},
siteConfig: {themeConfig: roughlyTypedThemeConfig},
i18n: {currentLocale, localeConfigs},
} = context;
const {colorMode, prism: {additionalLanguages = []} = {}} = themeConfig || {};
const themeConfig = (roughlyTypedThemeConfig || {}) as ThemeConfig;
const {colorMode, prism: {additionalLanguages = []} = {}} = themeConfig;
const {customCss} = options || {};
const {direction} = localeConfigs[currentLocale];
@ -143,10 +145,7 @@ export default function docusaurusThemeClassic(
return {
stats: {
warningsFilter: [
// The TS def does not allow function for array item :(
useDocsWarningFilter as any,
],
warningsFilter: useDocsWarningFilter,
},
plugins: [
new ContextReplacementPlugin(
@ -164,12 +163,12 @@ export default function docusaurusThemeClassic(
const resolvedInfimaFile = require.resolve(
getInfimaCSSFile(direction),
);
function isInfimaCSSFile(file) {
function isInfimaCSSFile(file?: string) {
return file === resolvedInfimaFile;
}
return function (root: any) {
const file = root?.source.input.file;
return function (root: PostCssRoot) {
const file = root?.source?.input.file;
// Skip Infima as we are using the its RTL version.
if (isInfimaCSSFile(file)) {

View file

@ -125,7 +125,7 @@ export default function CodeBlock({
if (metastring && codeBlockTitleRegex.test(metastring)) {
// Tested above
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, prefer-destructuring
codeBlockTitle = metastring.match(codeBlockTitleRegex)![1];
}

View file

@ -33,8 +33,8 @@ function SkipToContent(): JSX.Element {
};
useEffect(() => {
if (!location.hash) {
programmaticFocus(containerRef.current!);
if (!location.hash && containerRef.current) {
programmaticFocus(containerRef.current);
}
}, [location.pathname]);

View file

@ -12,9 +12,9 @@ function useTOCHighlight(
linkActiveClassName: string,
topOffset: number,
): void {
const [lastActiveLink, setLastActiveLink] = useState<HTMLAnchorElement>(
undefined!,
);
const [lastActiveLink, setLastActiveLink] = useState<
HTMLAnchorElement | undefined
>(undefined);
useEffect(() => {
function setActiveLink() {

View file

@ -197,6 +197,7 @@ async function updateCodeTranslations() {
const {baseFile, localesFiles} = await getCodeTranslationFiles();
const baseFileMessages = await updateBaseFile(baseFile);
// eslint-disable-next-line no-restricted-syntax
for (const localeFile of localesFiles) {
logSection(`Will update ${path.basename(localeFile)}`);
// eslint-disable-next-line no-await-in-loop

View file

@ -114,7 +114,7 @@ export type I18n = {
export interface DocusaurusContext {
siteConfig: DocusaurusConfig;
siteMetadata: DocusaurusSiteMetadata;
globalData: Record<string, any>;
globalData: Record<string, unknown>;
i18n: I18n;
codeTranslations: Record<string, string>;
isClient: boolean;
@ -187,7 +187,7 @@ export type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
export interface Props extends LoadContext, InjectedHtmlTags {
routes: RouteConfig[];
routesPaths: string[];
plugins: Plugin<any>[];
plugins: Plugin<unknown>[];
}
/**
@ -199,6 +199,7 @@ export interface PropsPostBuild extends Props {
export interface PluginContentLoadedActions {
addRoute(config: RouteConfig): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
createData(name: string, data: any): Promise<string>;
setGlobalData<T = unknown>(data: T): void;
}
@ -212,7 +213,7 @@ export type AllContent = Record<
>;
// TODO improve type (not exposed by postcss-loader)
export type PostCssOptions = Record<string, any> & {plugins: any[]};
export type PostCssOptions = Record<string, unknown> & {plugins: unknown[]};
export interface Plugin<T> {
name: string;

View file

@ -8,13 +8,13 @@ exports[`validation schemas AdmonitionsSchema: for value=null 1`] = `"\\"value\\
exports[`validation schemas AdmonitionsSchema: for value=true 1`] = `"\\"value\\" must be of type object"`;
exports[`validation schemas PluginIdSchema: for value="/docs" 1`] = `"\\"value\\" with value \\"/docs\\" fails to match the required pattern: /^[a-zA-Z_\\\\-]+$/"`;
exports[`validation schemas PluginIdSchema: for value="/docs" 1`] = `"\\"value\\" with value \\"/docs\\" fails to match the required pattern: /^[a-zA-Z_-]+$/"`;
exports[`validation schemas PluginIdSchema: for value="do cs" 1`] = `"\\"value\\" with value \\"do cs\\" fails to match the required pattern: /^[a-zA-Z_\\\\-]+$/"`;
exports[`validation schemas PluginIdSchema: for value="do cs" 1`] = `"\\"value\\" with value \\"do cs\\" fails to match the required pattern: /^[a-zA-Z_-]+$/"`;
exports[`validation schemas PluginIdSchema: for value="do/cs" 1`] = `"\\"value\\" with value \\"do/cs\\" fails to match the required pattern: /^[a-zA-Z_\\\\-]+$/"`;
exports[`validation schemas PluginIdSchema: for value="do/cs" 1`] = `"\\"value\\" with value \\"do/cs\\" fails to match the required pattern: /^[a-zA-Z_-]+$/"`;
exports[`validation schemas PluginIdSchema: for value="docs/" 1`] = `"\\"value\\" with value \\"docs/\\" fails to match the required pattern: /^[a-zA-Z_\\\\-]+$/"`;
exports[`validation schemas PluginIdSchema: for value="docs/" 1`] = `"\\"value\\" with value \\"docs/\\" fails to match the required pattern: /^[a-zA-Z_-]+$/"`;
exports[`validation schemas PluginIdSchema: for value=[] 1`] = `"\\"value\\" must be a string"`;

View file

@ -8,7 +8,7 @@ import * as Joi from 'joi';
import {isValidPathname} from '@docusaurus/utils';
export const PluginIdSchema = Joi.string()
.regex(/^[a-zA-Z_\-]+$/)
.regex(/^[a-zA-Z_-]+$/)
// duplicate core constant, otherwise cyclic dependency is created :(
.default('default');

View file

@ -147,7 +147,7 @@ export function posixPath(str: string): string {
// This way, Jest tests can run more reliably on any computer/CI
// on both Unix/Windows
// For Windows users this is not perfect (as they see / instead of \) but it's probably good enough
export function toMessageRelativeFilePath(filePath: string) {
export function toMessageRelativeFilePath(filePath: string): string {
return posixPath(path.relative(process.cwd(), filePath));
}
@ -208,6 +208,7 @@ export function createExcerpt(fileString: string): string | undefined {
const fileLines = fileString.trimLeft().split('\n');
/* eslint-disable no-continue */
// eslint-disable-next-line no-restricted-syntax
for (const fileLine of fileLines) {
// Skip empty line.
if (!fileLine.trim()) {
@ -491,6 +492,7 @@ export async function mapAsyncSequencial<T extends unknown, R extends unknown>(
action: (t: T) => Promise<R>,
): Promise<R[]> {
const results: R[] = [];
// eslint-disable-next-line no-restricted-syntax
for (const t of array) {
// eslint-disable-next-line no-await-in-loop
const result = await action(t);
@ -503,6 +505,7 @@ export async function findAsyncSequential<T>(
array: T[],
predicate: (t: T) => Promise<boolean>,
): Promise<T | undefined> {
// eslint-disable-next-line no-restricted-syntax
for (const t of array) {
// eslint-disable-next-line no-await-in-loop
if (await predicate(t)) {
@ -621,6 +624,7 @@ export async function readDefaultCodeTranslationMessages({
// Return the content of the first file that match
// fr_FR.json => fr.json => nothing
// eslint-disable-next-line no-restricted-syntax
for (const fileName of fileNamesToTry) {
const filePath = path.resolve(dirPath, `${fileName}.json`);

View file

@ -14,7 +14,7 @@ export function getAllDuplicateRoutes(
const allRoutes: string[] = getAllFinalRoutes(pluginsRouteConfigs).map(
(routeConfig) => routeConfig.path,
);
const seenRoutes: Record<string, any> = {};
const seenRoutes: Record<string, boolean> = {};
return allRoutes.filter((route) => {
if (Object.prototype.hasOwnProperty.call(seenRoutes, route)) {
return true;

View file

@ -23,7 +23,7 @@ export function getAllFinalRoutes(routeConfig: RouteConfig[]): RouteConfig[] {
export async function safeGlobby(
patterns: string[],
options?: globby.GlobbyOptions,
) {
): Promise<string[]> {
// Required for Windows support, as paths using \ should not be used by globby
// (also using the windows hard drive prefix like c: is not a good idea)
const globPaths = patterns.map((dirPath) =>

View file

@ -273,8 +273,24 @@ export function compile(config: Configuration[]): Promise<Stats.ToJsonOutput> {
type AssetFolder = 'images' | 'files' | 'fonts' | 'medias';
type FileLoaderUtils = {
loaders: {
file: (options: {folder: AssetFolder}) => Loader;
url: (options: {folder: AssetFolder}) => Loader;
inlineMarkdownImageFileLoader: string;
inlineMarkdownLinkFileLoader: string;
};
rules: {
images: () => RuleSetRule;
fonts: () => RuleSetRule;
media: () => RuleSetRule;
svg: () => RuleSetRule;
otherAssets: () => RuleSetRule;
};
};
// Inspired by https://github.com/gatsbyjs/gatsby/blob/8e6e021014da310b9cc7d02e58c9b3efe938c665/packages/gatsby/src/utils/webpack-utils.ts#L447
export function getFileLoaderUtils(): Record<string, any> {
export function getFileLoaderUtils(): FileLoaderUtils {
// files/images < 10kb will be inlined as base64 strings directly in the html
const urlLoaderLimit = 10000;