diff --git a/.eslintignore b/.eslintignore index b0c14dbeea5f..d7a04f48d5f3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,5 @@ __fixtures__ +__mocks__ dist node_modules .yarn diff --git a/admin/scripts/generateExamples.js b/admin/scripts/generateExamples.js index 0c29c39bba31..de99e750490b 100644 --- a/admin/scripts/generateExamples.js +++ b/admin/scripts/generateExamples.js @@ -5,19 +5,27 @@ * LICENSE file in the root directory of this source tree. */ +// @ts-check + import fs from 'fs-extra'; import shell from 'shelljs'; -const NODE_MAJOR_VERSION = parseInt(process.versions.node.split('.')[0], 10); +const NODE_MAJOR_VERSION = parseInt( + /** @type {string} */ (process.versions.node.split('.')[0]), + 10, +); if (NODE_MAJOR_VERSION < 16) { throw new Error( 'This generateExamples Docusaurus script requires at least Node.js 16 and npm 7. See why here: https://github.com/facebook/docusaurus/pull/5722#issuecomment-948847891', ); } -// Generate one example per init template -// We use those generated examples as CodeSandbox projects -// See https://github.com/facebook/docusaurus/issues/1699 +/** + * Generate one example per init template + * We use those generated examples as CodeSandbox projects + * See https://github.com/facebook/docusaurus/issues/1699 + * @param {string} template + */ async function generateTemplateExample(template) { try { console.log( @@ -103,6 +111,12 @@ async function generateTemplateExample(template) { * Button visible here: https://jamstack.org/generators/ */ function updateStarters() { + /** + * @param {Object} param0 + * @param {string} param0.subfolder + * @param {string} param0.remote + * @param {string} param0.remoteBranch + */ function forcePushGitSubtree({subfolder, remote, remoteBranch}) { console.log(''); // See https://stackoverflow.com/questions/33172857/how-do-i-force-a-subtree-push-to-overwrite-remote-changes diff --git a/packages/create-docusaurus/bin/index.js b/packages/create-docusaurus/bin/index.js index b4b6d47c5ec9..328495345270 100755 --- a/packages/create-docusaurus/bin/index.js +++ b/packages/create-docusaurus/bin/index.js @@ -45,24 +45,12 @@ program \`custom\`: enter your custom git clone command. We will prompt you for it.`, ) .description('Initialize website.') - .action( - ( - siteName, - template, - rootDir = '.', - {packageManager, skipInstall, typescript, gitStrategy} = {}, - ) => { - // See https://github.com/facebook/docusaurus/pull/6860 - import('../lib/index.js').then(({default: init}) => { - init(path.resolve(rootDir), siteName, template, { - packageManager, - skipInstall, - typescript, - gitStrategy, - }); - }); - }, - ); + .action((siteName, template, rootDir, options) => { + // See https://github.com/facebook/docusaurus/pull/6860 + import('../lib/index.js').then(({default: init}) => { + init(path.resolve(rootDir ?? '.'), siteName, template, options); + }); + }); program.parse(process.argv); diff --git a/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts index f671d6f517f8..2d5ba57c2b78 100644 --- a/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/headings/__tests__/index.test.ts @@ -14,6 +14,7 @@ import toString from 'mdast-util-to-string'; import visit from 'unist-util-visit'; import slug from '../index'; import type {Plugin} from 'unified'; +import type {Parent} from 'unist'; function process(doc: string, plugins: Plugin[] = []) { const processor = remark().use({plugins: [...plugins, slug]}); @@ -58,11 +59,8 @@ describe('headings remark plugin', () => { it('does not overwrite `data` on headings', () => { const result = process('# Normal\n', [ - () => { - function transform(tree) { - tree.children[0].data = {foo: 'bar'}; - } - return transform; + () => (root) => { + (root as Parent).children[0]!.data = {foo: 'bar'}; }, ]); const expected = u('root', [ @@ -81,11 +79,10 @@ describe('headings remark plugin', () => { it('does not overwrite `data.hProperties` on headings', () => { const result = process('# Normal\n', [ - () => { - function transform(tree) { - tree.children[0].data = {hProperties: {className: ['foo']}}; - } - return transform; + () => (root) => { + (root as Parent).children[0]!.data = { + hProperties: {className: ['foo']}, + }; }, ]); const expected = u('root', [ @@ -111,12 +108,9 @@ describe('headings remark plugin', () => { '## Something also', ].join('\n\n'), [ - () => { - function transform(tree) { - tree.children[1].data = {hProperties: {id: 'here'}}; - tree.children[3].data = {hProperties: {id: 'something'}}; - } - return transform; + () => (root) => { + (root as Parent).children[1]!.data = {hProperties: {id: 'here'}}; + (root as Parent).children[3]!.data = {hProperties: {id: 'something'}}; }, ], ); @@ -270,9 +264,9 @@ describe('headings remark plugin', () => { # {#text-after} custom ID `); - const headers = []; + const headers: {text: string; id: string}[] = []; visit(result, 'heading', (node) => { - headers.push({text: toString(node), id: node.data.id}); + headers.push({text: toString(node), id: node.data!.id as string}); }); expect(headers).toEqual([ diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap index fbd3fcc125c8..b87c1cd50d75 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap @@ -75,50 +75,6 @@ exports[`toc remark plugin exports even with existing name 1`] = ` " `; -exports[`toc remark plugin exports with custom name 1`] = ` -"export const customName = [ - { - value: 'Endi', - id: 'endi', - level: 3 - }, - { - value: 'Endi', - id: 'endi-1', - level: 2 - }, - { - value: 'Yangshun', - id: 'yangshun', - level: 3 - }, - { - value: 'I ♥ unicode.', - id: 'i--unicode', - level: 2 - } -]; - -### Endi - -\`\`\`md -## This is ignored -\`\`\` - -## Endi - -Lorem ipsum - -### Yangshun - -Some content here - -## I ♥ unicode. - -export const c = 1; -" -`; - exports[`toc remark plugin handles empty headings 1`] = ` "export const toc = []; diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts index b3fd7babac76..43b627c8b1dc 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/index.test.ts @@ -12,13 +12,13 @@ import vfile from 'to-vfile'; import plugin from '../index'; import headings from '../../headings/index'; -const processFixture = async (name, options?) => { +const processFixture = async (name: string) => { const filePath = path.join(__dirname, '__fixtures__', `${name}.md`); const file = await vfile.read(filePath); const result = await remark() .use(headings) .use(mdx) - .use(plugin, options) + .use(plugin) .process(file); return result.toString(); @@ -45,14 +45,6 @@ describe('toc remark plugin', () => { expect(result).toMatchSnapshot(); }); - it('exports with custom name', async () => { - const options = { - name: 'customName', - }; - const result = await processFixture('just-content', options); - expect(result).toMatchSnapshot(); - }); - it('inserts below imports', async () => { const result = await processFixture('insert-below-imports'); expect(result).toMatchSnapshot(); diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/index.ts b/packages/docusaurus-mdx-loader/src/remark/toc/index.ts index 1850a2b9c7a4..5e6c694dc339 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/toc/index.ts @@ -23,15 +23,13 @@ const parseOptions: ParserOptions = { sourceType: 'module', }; +const name = 'toc'; + const isImport = (child: Node): child is Literal => child.type === 'import'; const hasImports = (index: number) => index > -1; const isExport = (child: Node): child is Literal => child.type === 'export'; -type PluginOptions = { - name?: string; -}; - -const isTarget = (child: Literal, name: string) => { +const isTarget = (child: Literal) => { let found = false; const ast = parse(child.value, parseOptions); traverse(ast, { @@ -44,14 +42,14 @@ const isTarget = (child: Literal, name: string) => { return found; }; -const getOrCreateExistingTargetIndex = (children: Node[], name: string) => { +const getOrCreateExistingTargetIndex = (children: Node[]) => { let importsIndex = -1; let targetIndex = -1; children.forEach((child, index) => { if (isImport(child)) { importsIndex = index; - } else if (isExport(child) && isTarget(child, name)) { + } else if (isExport(child) && isTarget(child)) { targetIndex = index; } }); @@ -70,9 +68,7 @@ const getOrCreateExistingTargetIndex = (children: Node[], name: string) => { return targetIndex; }; -export default function plugin(options: PluginOptions = {}): Transformer { - const name = options.name || 'toc'; - +export default function plugin(): Transformer { return (root) => { const headings: TOCItem[] = []; @@ -91,7 +87,7 @@ export default function plugin(options: PluginOptions = {}): Transformer { }); }); const {children} = root as Parent; - const targetIndex = getOrCreateExistingTargetIndex(children, name); + const targetIndex = getOrCreateExistingTargetIndex(children); if (headings.length) { children[targetIndex]!.value = `export const ${name} = ${stringifyObject( diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts index 15fac36b29cb..94a0c7475580 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts @@ -10,16 +10,19 @@ import path from 'path'; import remark from 'remark'; import mdx from 'remark-mdx'; import vfile from 'to-vfile'; -import plugin from '../index'; +import plugin, {type PluginOptions} from '../index'; import headings from '../../headings/index'; -const processFixture = async (name, options) => { +const processFixture = async ( + name: string, + options: Partial, +) => { const filePath = path.join(__dirname, `__fixtures__/${name}.md`); const file = await vfile.read(filePath); const result = await remark() .use(headings) .use(mdx) - .use(plugin, {...options, filePath}) + .use(plugin, {siteDir: __dirname, staticDirs: [], ...options}) .process(file); return result.toString(); diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts index d9608d13ed07..d6988b71ef4d 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts @@ -27,7 +27,7 @@ const { loaders: {inlineMarkdownImageFileLoader}, } = getFileLoaderUtils(); -type PluginOptions = { +export type PluginOptions = { staticDirs: string[]; siteDir: string; }; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts index 65aac94fb322..e4511f827484 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts @@ -10,9 +10,9 @@ import remark from 'remark'; import mdx from 'remark-mdx'; import vfile from 'to-vfile'; import plugin from '..'; -import transformImage from '../../transformImage'; +import transformImage, {type PluginOptions} from '../../transformImage'; -const processFixture = async (name: string, options?) => { +const processFixture = async (name: string, options?: PluginOptions) => { const filePath = path.join(__dirname, `__fixtures__/${name}.md`); const staticDirs = [ path.join(__dirname, '__fixtures__/static'), @@ -24,7 +24,6 @@ const processFixture = async (name: string, options?) => { .use(transformImage, {...options, filePath, staticDirs}) .use(plugin, { ...options, - filePath, staticDirs, siteDir: path.join(__dirname, '__fixtures__'), }) diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts index 22d52587e1fb..9c9f2004ba7d 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts @@ -25,7 +25,7 @@ const { loaders: {inlineMarkdownLinkFileLoader}, } = getFileLoaderUtils(); -type PluginOptions = { +export type PluginOptions = { staticDirs: string[]; siteDir: string; }; diff --git a/packages/docusaurus-migrate/src/deps.d.ts b/packages/docusaurus-migrate/src/deps.d.ts index ca55197f76d4..cab75c696fa2 100644 --- a/packages/docusaurus-migrate/src/deps.d.ts +++ b/packages/docusaurus-migrate/src/deps.d.ts @@ -5,6 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -declare module '@mapbox/hast-util-to-jsx'; +declare module '@mapbox/hast-util-to-jsx' { + import type {Node} from 'unist'; -declare module 'hast-util-to-string'; + export default function toJsx(node: Node): string; +} + +declare module 'hast-util-to-string' { + import type {Node} from 'unist'; + + export default function toString(node: Node): string; +} diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts index ec29bdcf8b87..bb1f1c70a071 100644 Binary files a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts and b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts differ diff --git a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts index 8d85a4d376aa..e7c9d7dcb1b0 100644 --- a/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-classic/src/__tests__/validateThemeConfig.test.ts @@ -11,6 +11,7 @@ import {normalizeThemeConfig} from '@docusaurus/utils-validation'; import theme from 'prism-react-renderer/themes/github'; import darkTheme from 'prism-react-renderer/themes/dracula'; import {ThemeConfigSchema, DEFAULT_CONFIG} from '../validateThemeConfig'; +import type {ThemeConfig} from '@docusaurus/theme-common'; function testValidateThemeConfig(partialThemeConfig: {[key: string]: unknown}) { return normalizeThemeConfig(ThemeConfigSchema, { @@ -656,7 +657,7 @@ describe('themeConfig', () => { }); describe('color mode config', () => { - const withDefaultValues = (colorMode) => + const withDefaultValues = (colorMode: ThemeConfig['colorMode']) => _.merge({}, DEFAULT_CONFIG.colorMode, colorMode); it('switch config', () => { diff --git a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts index 9bdf1a8d9da8..d5bdb78e53e7 100644 --- a/packages/docusaurus-theme-classic/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-classic/src/validateThemeConfig.ts @@ -7,12 +7,10 @@ import defaultPrismTheme from 'prism-react-renderer/themes/palenight'; import {Joi, URISchema} from '@docusaurus/utils-validation'; -import type { - ThemeConfig, - ThemeConfigValidationContext, -} from '@docusaurus/types'; +import type {ThemeConfig} from '@docusaurus/theme-common'; +import type {ThemeConfigValidationContext} from '@docusaurus/types'; -const DEFAULT_DOCS_CONFIG = { +const DEFAULT_DOCS_CONFIG: ThemeConfig['docs'] = { versionPersistence: 'localStorage', sidebar: { hideable: false, @@ -31,13 +29,13 @@ const DocsSchema = Joi.object({ }).default(DEFAULT_DOCS_CONFIG.sidebar), }).default(DEFAULT_DOCS_CONFIG); -const DEFAULT_COLOR_MODE_CONFIG = { +const DEFAULT_COLOR_MODE_CONFIG: ThemeConfig['colorMode'] = { defaultMode: 'light', disableSwitch: false, respectPrefersColorScheme: false, }; -export const DEFAULT_CONFIG = { +export const DEFAULT_CONFIG: ThemeConfig = { colorMode: DEFAULT_COLOR_MODE_CONFIG, docs: DEFAULT_DOCS_CONFIG, metadata: [], @@ -301,8 +299,9 @@ const CustomCssSchema = Joi.alternatives() .try(Joi.array().items(Joi.string().required()), Joi.string().required()) .optional(); -export const ThemeConfigSchema = Joi.object({ +export const ThemeConfigSchema = Joi.object({ // TODO temporary (@alpha-58) + // @ts-expect-error: forbidden disableDarkMode: Joi.any().forbidden().messages({ 'any.unknown': 'disableDarkMode theme config is deprecated. Please use the new colorMode attribute. You likely want: config.themeConfig.colorMode.disableSwitch = true', diff --git a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts index 03cf74d4ff1a..111468e5ea88 100644 --- a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts +++ b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts @@ -32,7 +32,7 @@ export type NavbarLogo = { // TODO improve export type Navbar = { - style: 'dark' | 'primary'; + style?: 'dark' | 'primary'; hideOnScroll: boolean; title?: string; items: NavbarItem[]; diff --git a/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts index af6b72731932..2a286cca2f93 100644 --- a/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-live-codeblock/src/__tests__/validateThemeConfig.test.ts @@ -6,9 +6,13 @@ */ import {validateThemeConfig, DEFAULT_CONFIG} from '../validateThemeConfig'; +import type {Joi} from '@docusaurus/utils-validation'; -function testValidateThemeConfig(themeConfig) { - function validate(schema, cfg) { +function testValidateThemeConfig(themeConfig: {[key: string]: unknown}) { + function validate( + schema: Joi.ObjectSchema<{[key: string]: unknown}>, + cfg: {[key: string]: unknown}, + ) { const {value, error} = schema.validate(cfg, { convert: false, }); diff --git a/packages/docusaurus-theme-search-algolia/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-search-algolia/src/__tests__/validateThemeConfig.test.ts index 23be336647ec..9fc315e1c3ba 100644 --- a/packages/docusaurus-theme-search-algolia/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-search-algolia/src/__tests__/validateThemeConfig.test.ts @@ -9,7 +9,10 @@ import {validateThemeConfig, DEFAULT_CONFIG} from '../validateThemeConfig'; import type {Joi} from '@docusaurus/utils-validation'; function testValidateThemeConfig(themeConfig: {[key: string]: unknown}) { - function validate(schema: Joi.Schema, cfg: {[key: string]: unknown}) { + function validate( + schema: Joi.ObjectSchema<{[key: string]: unknown}>, + cfg: {[key: string]: unknown}, + ) { const {value, error} = schema.validate(cfg, { convert: false, }); diff --git a/packages/docusaurus-theme-search-algolia/src/theme/SearchPage/index.tsx b/packages/docusaurus-theme-search-algolia/src/theme/SearchPage/index.tsx index 7be755278b12..b10d82f207b9 100644 --- a/packages/docusaurus-theme-search-algolia/src/theme/SearchPage/index.tsx +++ b/packages/docusaurus-theme-search-algolia/src/theme/SearchPage/index.tsx @@ -237,10 +237,14 @@ function SearchPageContent(): JSX.Element { url, _highlightResult: {hierarchy}, _snippetResult: snippet = {}, + }: { + url: string; + _highlightResult: {hierarchy: {[key: string]: {value: string}}}; + _snippetResult: {content?: {value: string}}; }) => { const parsedURL = new URL(url); const titles = Object.keys(hierarchy).map((key) => - sanitizeValue(hierarchy[key].value), + sanitizeValue(hierarchy[key]!.value), ); return { diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 990bdf0d4277..ee4151930eee 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -480,19 +480,19 @@ export type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[]; export type ValidationSchema = Joi.ObjectSchema; -export type Validate = ( - validationSchema: ValidationSchema, - options: T, -) => U; +export type Validate = ( + validationSchema: ValidationSchema, + options: In, +) => Out; -export type OptionValidationContext = { - validate: Validate; - options: T; +export type OptionValidationContext = { + validate: Validate; + options: In; }; -export type ThemeConfigValidationContext = { - validate: Validate; - themeConfig: Partial; +export type ThemeConfigValidationContext = { + validate: Validate; + themeConfig: In; }; export type Plugin = { diff --git a/packages/docusaurus/src/client/exports/ComponentCreator.tsx b/packages/docusaurus/src/client/exports/ComponentCreator.tsx index 77439b36425a..476d73febcf9 100644 --- a/packages/docusaurus/src/client/exports/ComponentCreator.tsx +++ b/packages/docusaurus/src/client/exports/ComponentCreator.tsx @@ -12,6 +12,7 @@ import registry from '@generated/registry'; import Loading from '@theme/Loading'; import flat from '../flat'; import {RouteContextProvider} from '../routeContext'; +import type {RouteContext} from '@docusaurus/types'; declare global { interface NodeRequire { @@ -71,14 +72,21 @@ export default function ComponentCreator( loader, modules, webpack: () => optsWebpack, - render(loaded, props) { + render( + loaded: {[keyPath: string]: {[exportedName: string]: unknown}}, + props, + ) { // `loaded` will be a map from key path (as returned from the flattened // chunk names) to the modules loaded from the loaders. We now have to // restore the chunk names' previous shape from this flat record. // We do so by taking advantage of the existing `chunkNames` and replacing // each chunk name with its loaded module, so we don't create another // object from scratch. - const loadedModules = JSON.parse(JSON.stringify(chunkNames)); + const loadedModules = JSON.parse(JSON.stringify(chunkNames)) as { + __comp?: React.ComponentType; + __context?: RouteContext; + [propName: string]: unknown; + }; Object.entries(loaded).forEach(([keyPath, loadedModule]) => { // JSON modules are also loaded as `{ default: ... }` (`import()` // semantics) but we just want to pass the actual value to props. @@ -100,7 +108,8 @@ export default function ComponentCreator( Object.keys(loadedModule) .filter((k) => k !== 'default') .forEach((nonDefaultKey) => { - chunk[nonDefaultKey] = loadedModule[nonDefaultKey]; + (chunk as {[key: string]: unknown})[nonDefaultKey] = + loadedModule[nonDefaultKey]; }); } // We now have this chunk prepared. Go down the key path and replace the @@ -108,15 +117,15 @@ export default function ComponentCreator( let val = loadedModules; const keyPaths = keyPath.split('.'); keyPaths.slice(0, -1).forEach((k) => { - val = val[k]; + val = val[k] as {[propName: string]: unknown}; }); val[keyPaths[keyPaths.length - 1]!] = chunk; }); /* eslint-disable no-underscore-dangle */ - const Component = loadedModules.__comp; + const Component = loadedModules.__comp!; delete loadedModules.__comp; - const routeContext = loadedModules.__context; + const routeContext = loadedModules.__context!; delete loadedModules.__context; /* eslint-enable no-underscore-dangle */ diff --git a/packages/stylelint-copyright/src/__tests__/index.test.ts b/packages/stylelint-copyright/src/__tests__/index.test.ts index f48b0499c67e..4d0f865e153d 100644 --- a/packages/stylelint-copyright/src/__tests__/index.test.ts +++ b/packages/stylelint-copyright/src/__tests__/index.test.ts @@ -7,11 +7,9 @@ /* eslint-disable jest/no-conditional-expect */ import path from 'path'; -import stylelint, {type LinterResult} from 'stylelint'; +import stylelint from 'stylelint'; import rule from '../index'; -const {ruleName} = rule; - declare global { namespace jest { interface Matchers { @@ -20,29 +18,44 @@ declare global { } } -function getOutputCss(output: LinterResult) { +type TestSuite = { + ruleName: string; + fix: boolean; + accept: TestCase[]; + reject: TestCase[]; +}; + +type TestCase = { + code: string; + description?: string; + fixed?: string; + message?: string; + line?: number; + column?: number; +}; + +function getOutputCss(output: stylelint.LinterResult) { // eslint-disable-next-line no-underscore-dangle - const result = output.results[0]._postcssResult; - return result.root.toString(result.opts.syntax); + const result = output.results[0]!._postcssResult!; + return result.root.toString(result.opts!.syntax); } -function testStylelintRule(config, tests) { +function testStylelintRule(config: stylelint.Config, tests: TestSuite) { describe(`${tests.ruleName}`, () => { - const checkTestCaseContent = (testCase) => - testCase.description || testCase.code || 'no description'; + const checkTestCaseContent = (testCase: TestCase) => + testCase.description || testCase.code; if (tests.accept?.length) { describe('accept cases', () => { tests.accept.forEach((testCase) => { it(`${checkTestCaseContent(testCase)}`, async () => { - const options = { + const options: stylelint.LinterOptions = { code: testCase.code, config, - syntax: tests.syntax, }; const output = await stylelint.lint(options); - expect(output.results[0].warnings).toEqual([]); + expect(output.results[0]!.warnings).toEqual([]); if (!tests.fix) { return; } @@ -61,12 +74,11 @@ function testStylelintRule(config, tests) { const options = { code: testCase.code, config, - syntax: tests.syntax, }; const output = await stylelint.lint(options); - const {warnings} = output.results[0]; - const warning = warnings[0]; + const {warnings} = output.results[0]!; + const warning = warnings[0]!; expect(warnings.length).toBeGreaterThanOrEqual(1); expect(testCase).toHaveMessage(); if (testCase.message != null) { @@ -95,7 +107,7 @@ function testStylelintRule(config, tests) { } expect.extend({ - toHaveMessage(testCase) { + toHaveMessage(testCase: TestCase) { if (testCase.message == null) { return { message: () => @@ -118,11 +130,11 @@ testStylelintRule( { plugins: [path.join(__dirname, '../../lib/index.js')], rules: { - [ruleName]: [true, {header: '*\n * Copyright'}], + [rule.ruleName]: [true, {header: '*\n * Copyright'}], }, }, { - ruleName, + ruleName: rule.ruleName, fix: true, accept: [ { diff --git a/tsconfig.json b/tsconfig.json index 0f5b1868c98c..34195b64e138 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -53,9 +53,11 @@ }, "exclude": [ "node_modules", + "coverage/**", "**/lib/**/*", "website/**", "**/__mocks__/**/*", + "**/__fixtures__/**/*", "examples/**", "packages/create-docusaurus/templates/**" ]