diff --git a/components/Embed/index.tsx b/components/Embed/index.tsx index f2171450f..6bfcd835d 100644 --- a/components/Embed/index.tsx +++ b/components/Embed/index.tsx @@ -1,3 +1,5 @@ +/* eslint-disable no-param-reassign */ +/* eslint-disable react/jsx-props-no-spreading */ import React from 'react'; interface FaviconProps { diff --git a/components/Glossary/index.tsx b/components/Glossary/index.tsx index 077561fb6..c69876f7a 100644 --- a/components/Glossary/index.tsx +++ b/components/Glossary/index.tsx @@ -5,7 +5,6 @@ import React, { useContext } from 'react'; import GlossaryContext from '../../contexts/GlossaryTerms'; - interface Props extends React.PropsWithChildren { term?: string; terms: GlossaryTerm[]; @@ -32,9 +31,11 @@ const Glossary = ({ children, term: termProp, terms }: Props) => { ); }; -const GlossaryWithContext = props => { +const GlossaryWithContext = (props: Omit) => { const terms = useContext(GlossaryContext); return terms ? : {props.term}; }; -export { Glossary, GlossaryWithContext as default, GlossaryContext }; +export { Glossary, GlossaryContext }; + +export default GlossaryWithContext; diff --git a/components/HTMLBlock/index.tsx b/components/HTMLBlock/index.tsx index 876423abf..525e960c4 100644 --- a/components/HTMLBlock/index.tsx +++ b/components/HTMLBlock/index.tsx @@ -10,12 +10,20 @@ const extractScripts = (html: string = ''): [string, () => void] => { scripts.push(match[1]); } const cleaned = html.replace(MATCH_SCRIPT_TAGS, ''); + // eslint-disable-next-line no-eval return [cleaned, () => scripts.map(js => window.eval(js))]; }; -const HTMLBlock = ({ children = '', runScripts, safeMode = false }) => { +interface Props { + children: React.ReactElement | string; + runScripts?: boolean | string; + safeMode?: boolean; +} + +const HTMLBlock = ({ children = '', runScripts, safeMode = false }: Props) => { let html = children; - runScripts = typeof runScripts !== 'boolean' ? (runScripts === 'true') : runScripts; + // eslint-disable-next-line no-param-reassign + runScripts = typeof runScripts !== 'boolean' ? runScripts === 'true' : runScripts; if (typeof html !== 'string') html = renderToStaticMarkup(html); const [cleanedHtml, exec] = extractScripts(html); diff --git a/components/Heading/index.tsx b/components/Heading/index.tsx index bf64cfc38..614ec8cad 100644 --- a/components/Heading/index.tsx +++ b/components/Heading/index.tsx @@ -26,6 +26,10 @@ const Heading = ({ tag: Tag = 'h3', depth = 3, id, children, ...attrs }: Props) ); }; -const CreateHeading = (depth: Depth) => (props: Props) => ; +const CreateHeading = (depth: Depth) => { + const HeadingWithDepth = (props: Props) => ; + + return HeadingWithDepth; +}; export default CreateHeading; diff --git a/components/Image/index.tsx b/components/Image/index.tsx index f68f17289..5a4060fa4 100644 --- a/components/Image/index.tsx +++ b/components/Image/index.tsx @@ -37,6 +37,7 @@ const Image = (Props: ImageProps) => { const handleKeyDown = ({ key, metaKey: cmd }: React.KeyboardEvent) => { const cmdKey = cmd ? 'cmd+' : ''; + // eslint-disable-next-line no-param-reassign key = `${cmdKey}${key.toLowerCase()}`; switch (key) { @@ -49,6 +50,7 @@ const Image = (Props: ImageProps) => { case 'enter': // OPEN if (!lightbox) setLightbox(true); + break; default: } }; diff --git a/components/Tabs/index.tsx b/components/Tabs/index.tsx index d8b67b62a..e0221c3ae 100644 --- a/components/Tabs/index.tsx +++ b/components/Tabs/index.tsx @@ -2,32 +2,39 @@ import React, { useState } from 'react'; import './style.scss'; -export const Tab = ({ children }) => { - return ( -
- {children} -
- ) +export const Tab = ({ children }: React.PropsWithChildren) => { + return
{children}
; +}; + +interface TabsProps { + children?: React.ReactElement[]; } -const Tabs = ({ children }) => { +const Tabs = ({ children }: TabsProps) => { const [activeTab, setActiveTab] = useState(0); return (
-
- {children && children[activeTab]} -
+
{children && children[activeTab]}
); }; diff --git a/errors/mdx-syntax-error.ts b/errors/mdx-syntax-error.ts index b647d5519..1f6b871a9 100644 --- a/errors/mdx-syntax-error.ts +++ b/errors/mdx-syntax-error.ts @@ -22,5 +22,6 @@ export default class MdxSyntaxError extends SyntaxError { super(messages.join('\n')); this.original = error; + this.name = 'MdxSyntaxError'; } } diff --git a/example/RenderError.tsx b/example/RenderError.tsx index d187ede6e..15411e46c 100644 --- a/example/RenderError.tsx +++ b/example/RenderError.tsx @@ -18,7 +18,7 @@ class RenderError extends React.Component, State> { return { hasError: true, message: `${error.message}${error.stack}` }; } - componentDidCatch(error: any, info: { componentStack: any }) { + static componentDidCatch(error: Error, info: { componentStack: string }) { console.error(error, info.componentStack); } diff --git a/lib/compile.ts b/lib/compile.ts index 04a39c601..45916497d 100644 --- a/lib/compile.ts +++ b/lib/compile.ts @@ -6,7 +6,7 @@ import remarkGfm from 'remark-gfm'; import MdxSyntaxError from '../errors/mdx-syntax-error'; import { rehypeToc } from '../processor/plugin/toc'; -import { defaultTransforms, variablesTransformer } from '../processor/transform'; +import { defaultTransforms } from '../processor/transform'; import { rehypePlugins } from './ast-processor'; diff --git a/lib/exports.ts b/lib/exports.ts index fb372e4b0..01d188789 100644 --- a/lib/exports.ts +++ b/lib/exports.ts @@ -51,30 +51,27 @@ const exports = (doc: string) => { const body = node.data?.estree.body; if (!body) return; - for (const child of body) { - if (child.type === 'ExportNamedDeclaration') { + body.forEach(child => { + if (child.type === 'ExportNamedDeclaration') { // There are three types of ExportNamedDeclaration that we need to consider: VariableDeclaration, FunctionDeclaration, ClassDeclaration const declaration = child.declaration; - // FunctionDeclaration and ClassDeclaration have the same structure + + // FunctionDeclaration and ClassDeclaration have the same structure if (declaration.type !== 'VariableDeclaration') { // Note: declaration.id.type is always 'Identifier' for FunctionDeclarations and ClassDeclarations set.add(declaration.id.name); - } - else { - const declarations = declaration.declarations; - for (const declaration of declarations) { - const id = declaration.id; + } else { + declaration.declarations.forEach(({ id }) => { if (id.type === 'Identifier') { set.add(id.name); - } - } + } + }); } } - } - + }); }); return Array.from(set); }; -export default exports; \ No newline at end of file +export default exports; diff --git a/lib/mdast.ts b/lib/mdast.ts index 11c6723cd..270b5c311 100644 --- a/lib/mdast.ts +++ b/lib/mdast.ts @@ -1,8 +1,9 @@ import type { MdastOpts } from './ast-processor'; +import type { Root } from 'mdast'; import astProcessor from './ast-processor'; -const mdast: any = (text: string, opts: MdastOpts = {}) => { +const mdast = (text: string, opts: MdastOpts = {}): Root => { const processor = astProcessor(opts); const tree = processor.parse(text); diff --git a/lib/mdastV6.ts b/lib/mdastV6.ts index 7910d1ae4..7e22f664f 100644 --- a/lib/mdastV6.ts +++ b/lib/mdastV6.ts @@ -1,10 +1,12 @@ +import type { Root } from 'mdast'; + import migrationTransformers from '../processor/migration'; const migrationNormalize = (doc: string) => { return doc.replaceAll(/^($/gms, '$1-->'); }; -const mdastV6: any = (doc: string, { rdmd }) => { +const mdastV6 = (doc: string, { rdmd }): Root => { const [_normalizedDoc] = rdmd.setup(doc); const normalizedDoc = migrationNormalize(_normalizedDoc); diff --git a/lib/mdx.ts b/lib/mdx.ts index 65972ee6a..5c88880ff 100644 --- a/lib/mdx.ts +++ b/lib/mdx.ts @@ -1,3 +1,5 @@ +import type { Root } from 'mdast'; + import rehypeRemark from 'rehype-remark'; import remarkGfm from 'remark-gfm'; import remarkMdx from 'remark-mdx'; @@ -7,7 +9,7 @@ import { unified } from 'unified'; import compilers from '../processor/compile'; import { compatabilityTransfomer, divTransformer, readmeToMdx, tablesToJsx } from '../processor/transform'; -export const mdx = (tree: any, { hast = false, ...opts } = {}) => { +export const mdx = (tree: Root, { hast = false, ...opts } = {}) => { const processor = unified() .use(hast ? rehypeRemark : undefined) .use(remarkMdx) diff --git a/lib/plain.ts b/lib/plain.ts index 387c7366e..acf0fb243 100644 --- a/lib/plain.ts +++ b/lib/plain.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-use-before-define */ import type { Nodes, Parents } from 'hast'; import hast from './hast'; @@ -54,6 +55,9 @@ function one(node: Nodes, opts: Options) { return [title, body].filter(Boolean).join(' '); } + default: { + return ''; + } } } diff --git a/lib/run.tsx b/lib/run.tsx index 7be1596e3..47c1d2187 100644 --- a/lib/run.tsx +++ b/lib/run.tsx @@ -2,14 +2,14 @@ import type { Depth } from '../components/Heading'; import type { GlossaryTerm } from '../contexts/GlossaryTerms'; import type { CustomComponents, RMDXModule } from '../types'; import type { Variables } from '../utils/user'; -import type { RunOptions, UseMdxComponents} from '@mdx-js/mdx'; +import type { RunOptions, UseMdxComponents } from '@mdx-js/mdx'; +import type { MDXComponents } from 'mdx/types'; import { run as mdxRun } from '@mdx-js/mdx'; import Variable from '@readme/variable'; import React from 'react'; import * as runtime from 'react/jsx-runtime'; - import * as Components from '../components'; import Contexts from '../contexts'; import { tocToMdx } from '../processor/plugin/toc'; @@ -29,7 +29,7 @@ const makeUseMDXComponents = (more: ReturnType = {}): UseMdxCo const headings = Array.from({ length: 6 }).reduce((map, _, index) => { map[`h${index + 1}`] = Components.Heading((index + 1) as Depth); return map; - }, {}); + }, {}) as MDXComponents; const components = { ...Components, @@ -43,18 +43,19 @@ const makeUseMDXComponents = (more: ReturnType = {}): UseMdxCo 'html-block': Components.HTMLBlock, 'image-block': Components.Image, 'table-of-contents': Components.TableOfContents, - // @ts-expect-error ...headings, ...more, }; + // @ts-expect-error I'm not sure how to coerce the correct type return () => components; }; const run = async (string: string, _opts: RunOpts = {}) => { - const { Fragment } = runtime as any; + const { Fragment } = runtime; const { components = {}, terms, variables, baseUrl, imports = {}, ...opts } = _opts; const executedComponents = Object.entries(components).reduce((memo, [tag, mod]) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { default: Content, toc, Toc, ...rest } = mod; memo[tag] = Content; @@ -78,6 +79,7 @@ const run = async (string: string, _opts: RunOpts = {}) => { } as RunOptions) as Promise; }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { Toc: _Toc, toc, default: Content, ...exports } = await exec(string); const tocMdx = tocToMdx(toc, components); diff --git a/processor/compile/compatibility.ts b/processor/compile/compatibility.ts index d31ab4c53..203086b2a 100644 --- a/processor/compile/compatibility.ts +++ b/processor/compile/compatibility.ts @@ -1,4 +1,4 @@ -import type { Html, Image, Node, Nodes } from 'mdast'; +import type { Html, Node, Nodes } from 'mdast'; import type { FigCaption, Figure, ImageBlock } from 'types'; import { toMarkdown } from 'mdast-util-to-markdown'; @@ -6,13 +6,24 @@ import { toMarkdown } from 'mdast-util-to-markdown'; import { NodeTypes } from '../../enums'; import { formatProps } from '../utils'; +interface EditorGlossary { + children: [{ type: 'text'; value: string }]; + data: { hName: 'Glossary'; hProperties: { term: string } }; + type: NodeTypes.glossary; +} + +interface CompatEmbed { + data: { hProperties: Record }; + html: string; + type: 'embed'; +} + type CompatNodes = + | CompatEmbed + | EditorGlossary + | Figure | Html - | { children: [{ type: 'text'; value: string }]; data: { hName: 'Glossary' }; type: NodeTypes.glossary } - | { children: [Image, { children: [{ type: 'text'; value: string }]; type: 'figcaption' }]; type: 'figure' } | { data: { hProperties: { className: string[] } }; type: 'i' } - | { data: { hProperties: { term: string } }; type: NodeTypes.glossary } - | { data: { hProperties: Record }; type: 'embed' } | { tag: string; type: NodeTypes.reusableContent } | { type: 'escape'; value: string } | { type: 'yaml'; value: string }; @@ -24,7 +35,7 @@ type CompatNodes = * as html, and serialize it back as xml! * */ -const html = (node: Html) => { +const compileHtml = (node: Html) => { const string = node.value.replaceAll(//gms, '{/*$1*/}'); return string; @@ -53,7 +64,7 @@ const figureToImageBlock = (node: Figure) => { return ``; }; -const embedToEmbedBlock = (node: any) => { +const embedToEmbedBlock = (node: CompatEmbed) => { const { html, ...embed } = node.data.hProperties; const attributes = { ...embed, @@ -64,13 +75,14 @@ const embedToEmbedBlock = (node: any) => { const compatibility = (node: CompatNodes) => { switch (node.type) { - case NodeTypes.glossary: + case NodeTypes.glossary: { const term = node.data?.hProperties?.term || node.children[0].value; return `${term}`; + } case NodeTypes.reusableContent: return `<${node.tag} />`; case 'html': - return html(node); + return compileHtml(node); case 'escape': return `\\${node.value}`; case 'figure':