diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 6d8b03647d5c..000000000000 --- a/.eslintignore +++ /dev/null @@ -1,24 +0,0 @@ -__fixtures__ -__mocks__ -dist -node_modules -.yarn -.history -build -coverage -examples/ - -packages/lqip-loader/lib/ -packages/docusaurus/lib/ -packages/docusaurus-*/lib/* -packages/eslint-plugin/lib/ -packages/stylelint-copyright/lib/ - -packages/create-docusaurus/lib/* -packages/create-docusaurus/templates/facebook - -website/_dogfooding/_swizzle_theme_tests -website/_dogfooding/_asset-tests/badSyntax.js - - -packages/docusaurus-plugin-ideal-image/src/theme/IdealImageLegacy diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 61bde859a1c5..000000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,555 +0,0 @@ -/** - * 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. - */ - -const OFF = 0; -const WARNING = 1; -const ERROR = 2; - -// Prevent importing lodash, usually for browser bundle size reasons -const LodashImportPatterns = ['lodash', 'lodash.**', 'lodash/**']; - -// Prevent importing content plugins, usually for coupling reasons -const ContentPluginsImportPatterns = [ - '@docusaurus/plugin-content-blog', - '@docusaurus/plugin-content-blog/**', - // TODO fix theme-common => docs dependency issue - // '@docusaurus/plugin-content-docs', - // '@docusaurus/plugin-content-docs/**', - '@docusaurus/plugin-content-pages', - '@docusaurus/plugin-content-pages/**', -]; - -module.exports = { - root: true, - env: { - browser: true, - commonjs: true, - node: true, - }, - parser: '@typescript-eslint/parser', - parserOptions: { - // tsconfigRootDir: __dirname, - // project: ['./tsconfig.base.json', './website/tsconfig.base.json'], - }, - globals: { - JSX: true, - }, - extends: [ - 'eslint:recommended', - 'plugin:react-hooks/recommended', - - 'plugin:@vitest/legacy-recommended', - - 'airbnb', - 'plugin:@typescript-eslint/recommended', - // 'plugin:@typescript-eslint/recommended-requiring-type-checking', - // 'plugin:@typescript-eslint/strict', - 'plugin:regexp/recommended', - 'prettier', - 'plugin:@docusaurus/all', - ], - settings: { - 'import/resolver': { - node: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, - }, - }, - reportUnusedDisableDirectives: true, - plugins: [ - 'react-compiler', - 'react-hooks', - 'header', - '@vitest', - '@typescript-eslint', - 'regexp', - '@docusaurus', - ], - rules: { - 'react-compiler/react-compiler': ERROR, - 'react/jsx-uses-react': OFF, // JSX runtime: automatic - 'react/react-in-jsx-scope': OFF, // JSX runtime: automatic - 'array-callback-return': WARNING, - camelcase: WARNING, - 'class-methods-use-this': OFF, // It's a way of allowing private variables. - curly: [WARNING, 'all'], - 'global-require': WARNING, - 'lines-between-class-members': OFF, - 'max-classes-per-file': OFF, - 'max-len': [ - WARNING, - { - code: Infinity, // Code width is already enforced by Prettier/oxfmt - tabWidth: 2, - comments: 80, - ignoreUrls: true, - ignorePattern: '(eslint-disable|@)', - }, - ], - 'arrow-body-style': OFF, - 'no-await-in-loop': OFF, - 'no-case-declarations': WARNING, - 'no-console': OFF, - 'no-constant-binary-expression': ERROR, - 'no-continue': OFF, - 'no-control-regex': WARNING, - 'no-else-return': OFF, - 'no-empty': [WARNING, {allowEmptyCatch: true}], - 'no-lonely-if': WARNING, - 'no-nested-ternary': WARNING, - 'no-param-reassign': [WARNING, {props: false}], - 'no-prototype-builtins': WARNING, - 'no-restricted-exports': OFF, - 'no-restricted-properties': [ - ERROR, - .../** @type {[string, string][]} */ ([ - // TODO: TS doesn't make Boolean a narrowing function yet, - // so filter(Boolean) is problematic type-wise - // ['compact', 'Array#filter(Boolean)'], - ['concat', 'Array#concat'], - ['drop', 'Array#slice(n)'], - ['dropRight', 'Array#slice(0, -n)'], - ['fill', 'Array#fill'], - ['filter', 'Array#filter'], - ['find', 'Array#find'], - ['findIndex', 'Array#findIndex'], - ['first', 'foo[0]'], - ['flatten', 'Array#flat'], - ['flattenDeep', 'Array#flat(Infinity)'], - ['flatMap', 'Array#flatMap'], - ['fromPairs', 'Object.fromEntries'], - ['head', 'foo[0]'], - ['indexOf', 'Array#indexOf'], - ['initial', 'Array#slice(0, -1)'], - ['join', 'Array#join'], - // Unfortunately there's no great alternative to _.last yet - // Candidates: foo.slice(-1)[0]; foo[foo.length - 1] - // Array#at is ES2022; could replace _.nth as well - // ['last'], - ['map', 'Array#map'], - ['reduce', 'Array#reduce'], - ['reverse', 'Array#reverse'], - ['slice', 'Array#slice'], - ['take', 'Array#slice(0, n)'], - ['takeRight', 'Array#slice(-n)'], - ['tail', 'Array#slice(1)'], - ]).map(([property, alternative]) => ({ - object: '_', - property, - message: `Use ${alternative} instead.`, - })), - ...[ - 'readdirSync', - 'readFileSync', - 'statSync', - 'lstatSync', - 'existsSync', - 'pathExistsSync', - 'realpathSync', - 'mkdirSync', - 'mkdirpSync', - 'mkdirsSync', - 'writeFileSync', - 'writeJsonSync', - 'outputFileSync', - 'outputJsonSync', - 'moveSync', - 'copySync', - 'copyFileSync', - 'ensureFileSync', - 'ensureDirSync', - 'ensureLinkSync', - 'ensureSymlinkSync', - 'unlinkSync', - 'removeSync', - 'emptyDirSync', - ].map((property) => ({ - object: 'fs', - property, - message: 'Do not use sync fs methods.', - })), - ], - 'no-restricted-syntax': [ - WARNING, - // Copied from airbnb, removed for...of statement, added export all - { - selector: 'ForInStatement', - message: - 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.', - }, - { - selector: 'LabeledStatement', - message: - 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.', - }, - { - selector: 'WithStatement', - message: - '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.', - }, - { - selector: 'ExportAllDeclaration', - message: - "Export all does't work well if imported in ESM due to how they are transpiled, and they can also lead to unexpected exposure of internal methods.", - }, - // TODO make an internal plugin to ensure this - // { - // selector: - // @ 'ExportDefaultDeclaration > Identifier, ExportNamedDeclaration[source=null] > ExportSpecifier', - // message: 'Export in one statement' - // }, - ...['path', 'fs-extra', 'webpack', 'lodash'].map((m) => ({ - selector: `ImportDeclaration[importKind=value]:has(Literal[value=${m}]) > ImportSpecifier[importKind=value]`, - message: - 'Default-import this, both for readability and interoperability with ESM', - })), - ], - 'no-template-curly-in-string': WARNING, - 'no-unused-expressions': [ - WARNING, - {allowTaggedTemplates: true, allowShortCircuit: true}, - ], - 'no-useless-escape': WARNING, - 'no-void': [ERROR, {allowAsStatement: true}], - 'prefer-destructuring': OFF, - 'prefer-named-capture-group': WARNING, - 'prefer-template': WARNING, - yoda: WARNING, - - 'header/header': [ - ERROR, - 'block', - [ - '*', - ' * 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.', - ' ', - ], - ], - - 'import/extensions': OFF, - // This rule doesn't yet support resolving .js imports when the actual file - // is .ts. Plus it's not all that useful when our code is fully TS-covered. - 'import/no-unresolved': [ - OFF, - { - // Ignore certain webpack aliases because they can't be resolved - ignore: [ - '^@theme', - '^@docusaurus', - '^@generated', - '^@site', - '^@testing-utils', - ], - }, - ], - 'import/order': [ - WARNING, - { - groups: [ - 'builtin', - 'external', - 'internal', - ['parent', 'sibling', 'index'], - 'type', - ], - pathGroups: [ - // always put css import to the last, ref: - // https://github.com/import-js/eslint-plugin-import/issues/1239 - { - pattern: '*.+(css|sass|less|scss|pcss|styl)', - group: 'unknown', - patternOptions: {matchBase: true}, - position: 'after', - }, - {pattern: 'vitest', group: 'builtin', position: 'before'}, - {pattern: 'react', group: 'builtin', position: 'before'}, - {pattern: 'react-dom', group: 'builtin', position: 'before'}, - {pattern: 'react-dom/**', group: 'builtin', position: 'before'}, - {pattern: 'stream', group: 'builtin', position: 'before'}, - {pattern: 'fs-extra', group: 'builtin'}, - {pattern: 'lodash', group: 'external', position: 'before'}, - {pattern: 'clsx', group: 'external', position: 'before'}, - // 'Bit weird to not use the `import/internal-regex` option, but this - // way, we can make `import type { Props } from "@theme/*"` appear - // before `import styles from "styles.module.css"`, which is what we - // always did. This should be removable once we stop using ambient - // module declarations for theme aliases. - {pattern: '@theme/**', group: 'internal'}, - {pattern: '@site/**', group: 'internal'}, - {pattern: '@theme-init/**', group: 'internal'}, - {pattern: '@theme-original/**', group: 'internal'}, - ], - pathGroupsExcludedImportTypes: [], - // example: let `import './nprogress.css';` after importing others - // in `packages/docusaurus-theme-classic/src/nprogress.ts` - // see more: https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#warnonunassignedimports-truefalse - warnOnUnassignedImports: true, - }, - ], - 'import/prefer-default-export': OFF, - - '@vitest/consistent-test-it': WARNING, - '@vitest/expect-expect': OFF, - '@vitest/no-large-snapshots': [ - WARNING, - {maxSize: Infinity, inlineMaxSize: 50}, - ], - '@vitest/no-test-return-statement': ERROR, - '@vitest/prefer-expect-resolves': WARNING, - '@vitest/prefer-lowercase-title': [WARNING, {ignore: ['describe']}], - '@vitest/prefer-spy-on': WARNING, - '@vitest/prefer-to-be': OFF, - '@vitest/prefer-to-have-length': WARNING, - '@vitest/require-top-level-describe': ERROR, - '@vitest/valid-title': [ - ERROR, - { - mustNotMatch: { - it: [ - '^should|\\.$', - 'Titles should not begin with "should" or end with a full-stop', - ], - }, - }, - ], - - 'jsx-a11y/click-events-have-key-events': WARNING, - 'jsx-a11y/no-noninteractive-element-interactions': WARNING, - 'jsx-a11y/html-has-lang': OFF, - - 'react-hooks/rules-of-hooks': ERROR, - 'react-hooks/exhaustive-deps': ERROR, - - // Sometimes we do need the props as a whole, e.g. when spreading - 'react/destructuring-assignment': OFF, - 'react/function-component-definition': [ - WARNING, - { - namedComponents: 'function-declaration', - unnamedComponents: 'arrow-function', - }, - ], - 'react/jsx-filename-extension': OFF, - 'react/jsx-key': [ERROR, {checkFragmentShorthand: true}], - 'react/jsx-no-useless-fragment': [ERROR, {allowExpressions: true}], - 'react/jsx-props-no-spreading': OFF, - 'react/no-array-index-key': OFF, // We build a static site, and nearly all components don't change. - 'react/no-unstable-nested-components': [WARNING, {allowAsProps: true}], - 'react/prefer-stateless-function': WARNING, - 'react/prop-types': OFF, - 'react/require-default-props': [ERROR, {ignoreFunctionalComponents: true}], - - '@typescript-eslint/consistent-type-definitions': OFF, - '@typescript-eslint/require-await': OFF, - - '@typescript-eslint/ban-ts-comment': [ - ERROR, - {'ts-expect-error': 'allow-with-description'}, - ], - '@typescript-eslint/consistent-indexed-object-style': OFF, - '@typescript-eslint/consistent-type-imports': [ - WARNING, - {disallowTypeAnnotations: false}, - ], - '@typescript-eslint/explicit-module-boundary-types': WARNING, - '@typescript-eslint/method-signature-style': ERROR, - '@typescript-eslint/no-empty-function': OFF, - '@typescript-eslint/no-empty-interface': [ - ERROR, - { - allowSingleExtends: true, - }, - ], - '@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, - {functions: false, classes: false, variables: true}, - ], - '@typescript-eslint/no-non-null-assertion': OFF, - 'no-redeclare': OFF, - '@typescript-eslint/no-redeclare': ERROR, - 'no-shadow': OFF, - '@typescript-eslint/no-shadow': ERROR, - 'no-unused-vars': OFF, - // 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, - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - }, - ], - '@typescript-eslint/prefer-optional-chain': ERROR, - '@docusaurus/no-html-links': ERROR, - '@docusaurus/prefer-docusaurus-heading': ERROR, - '@docusaurus/no-untranslated-text': [ - WARNING, - { - ignoredStrings: [ - '·', - '-', - '—', - '×', - '​', // zwj: ​ - '@', - 'WebContainers', - 'Twitter', - 'X', - 'GitHub', - 'Dev.to', - '1.x', - ], - }, - ], - }, - overrides: [ - { - files: ['packages/docusaurus/src/client/**/*.{js,ts,tsx}'], - rules: { - 'no-restricted-imports': [ - 'error', - { - patterns: [ - ...LodashImportPatterns, - ...ContentPluginsImportPatterns, - // Prevent importing server code in client bundle - '**/../babel/**', - '**/../server/**', - '**/../commands/**', - '**/../webpack/**', - ], - }, - ], - }, - }, - { - files: [ - 'packages/docusaurus-theme-common/src/**/*.{js,ts,tsx}', - 'packages/docusaurus-utils-common/src/**/*.{js,ts,tsx}', - ], - excludedFiles: '*.test.{js,ts,tsx}', - rules: { - 'no-restricted-imports': [ - 'error', - { - patterns: [ - ...LodashImportPatterns, - ...ContentPluginsImportPatterns, - ], - }, - ], - }, - }, - { - files: ['packages/docusaurus-*/src/theme/**/*.{js,ts,tsx}'], - excludedFiles: '*.test.{js,ts,tsx}', - rules: { - 'no-restricted-imports': [ - 'error', - { - patterns: LodashImportPatterns.concat( - // Prevents relative imports between React theme components - [ - '../**', - './**', - // Allows relative styles module import with consistent filename - '!./styles.module.css', - ], - ), - }, - ], - }, - }, - { - files: [ - 'packages/docusaurus-*/src/theme/**/*.{js,ts,tsx}', - 'packages/docusaurus/src/client/theme-fallback/**/*.{js,ts,tsx}', - ], - rules: { - 'import/no-named-export': ERROR, - }, - }, - { - files: ['packages/create-docusaurus/templates/**/*.{js,ts,tsx}'], - rules: { - 'header/header': OFF, - 'global-require': OFF, - '@typescript-eslint/no-var-requires': OFF, - '@docusaurus/no-untranslated-text': OFF, - }, - }, - { - files: ['*.d.ts'], - rules: { - 'import/no-duplicates': OFF, - }, - }, - { - files: ['*.{ts,tsx}'], - rules: { - 'no-undef': OFF, - 'import/no-import-module-exports': OFF, - }, - }, - { - files: ['*.{js,mjs,cjs}'], - rules: { - // Make JS code directly runnable in Node. - '@typescript-eslint/no-var-requires': OFF, - '@typescript-eslint/explicit-module-boundary-types': OFF, - }, - }, - { - files: [ - '**/__tests__/**', - 'packages/docusaurus-plugin-debug/**', - 'website/_dogfooding/**', - ], - rules: { - '@docusaurus/no-untranslated-text': OFF, - }, - }, - { - // Internal files where extraneous deps don't matter much at long as - // they run - files: [ - '*.test.{js,ts,tsx}', - '**/__tests__/**', - 'admin/**', - 'test/**', - 'website/**', - 'packages/docusaurus-theme-common/removeThemeInternalReexport.mjs', - 'packages/docusaurus-theme-translations/update.mjs', - 'packages/docusaurus-theme-translations/src/utils.ts', - ], - rules: { - 'import/no-extraneous-dependencies': OFF, - }, - }, - { - files: ['packages/eslint-plugin/**/*.{js,ts}'], - extends: ['plugin:eslint-plugin/recommended'], - }, - { - files: [ - 'packages/docusaurus-plugin-debug/**', - 'packages/docusaurus/src/**', - ], - rules: { - '@docusaurus/prefer-docusaurus-heading': OFF, - }, - }, - ], -}; diff --git a/.gitattributes b/.gitattributes index 7f6e48fc5d26..c809e70abfc4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -39,6 +39,6 @@ test/** linguist-vendored admin/** linguist-documentation website/** linguist-documentation packages/create-docusaurus/templates/** linguist-vendored -.eslintrc.* linguist-vendored +eslint.config.* linguist-vendored vitest.config.* linguist-vendored .stylelintrc.* linguist-vendored diff --git a/.syncpackrc.ts b/.syncpackrc.ts index c80893e549cd..a945b1b4db3d 100644 --- a/.syncpackrc.ts +++ b/.syncpackrc.ts @@ -30,6 +30,12 @@ export default { ], versionGroups: [ + // TODO temporary, need to upgrade jiti deps + { + dependencies: ['jiti'], + isIgnored: true, + }, + { label: 'Ignore * deps in type-alias packages', packages: [ diff --git a/eslint.config.ts b/eslint.config.ts new file mode 100644 index 000000000000..4b352d3d8f0d --- /dev/null +++ b/eslint.config.ts @@ -0,0 +1,107 @@ +/** + * 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. + */ +import {defineConfig, globalIgnores} from 'eslint/config'; +import tseslint from 'typescript-eslint'; +import globals from 'globals'; +import js from '@eslint/js'; +import react from 'eslint-plugin-react'; +import reactHooks from 'eslint-plugin-react-hooks'; +// @ts-expect-error: no types provided +import header from 'eslint-plugin-header'; +import importPlugin from 'eslint-plugin-import'; +import vitest from '@vitest/eslint-plugin'; +// @ts-expect-error: no types provided +import jsxA11y from 'eslint-plugin-jsx-a11y'; +import docusaurus from '@docusaurus/eslint-plugin'; +import regexp from 'eslint-plugin-regexp'; +import prettier from 'eslint-config-prettier/flat'; + +import rules from './eslint.rules'; + +const plugins = defineConfig([ + js.configs.recommended, + tseslint.configs.recommended, + react.configs.flat.recommended, + reactHooks.configs.flat.recommended, + importPlugin.flatConfigs.recommended, + vitest.configs.recommended, + jsxA11y.flatConfigs.recommended, + regexp.configs['flat/recommended'], + prettier, + docusaurus.configs.flat.all, + + // TODO replace by maintained plugin? + // See https://github.com/facebook/docusaurus/pull/11803 + // This adapts the legacy plugin to flat config + { + plugins: { + header: { + meta: { + name: 'eslint-plugin-header', + version: 'whatever', + namespace: 'header', + }, + rules: header.rules, + }, + }, + }, +]); + +const ignores = globalIgnores([ + '**/.docusaurus/**', + '**/__fixtures__/**', + '__mocks__', + 'dist', + 'node_modules', + '.yarn', + '.history', + 'build', + 'coverage', + 'examples/', + 'packages/lqip-loader/lib/*', + 'packages/docusaurus/lib/*', + 'packages/docusaurus-*/lib/*', + 'packages/eslint-plugin/lib/', + 'packages/stylelint-copyright/lib/', + 'packages/create-docusaurus/lib/*', + 'packages/create-docusaurus/templates/facebook', + 'website/i18n', + 'website/_dogfooding/_swizzle_theme_tests', + 'website/_dogfooding/_asset-tests/badSyntax.js', + 'packages/docusaurus-plugin-ideal-image/src/theme/IdealImageLegacy', +]); + +export default defineConfig(plugins, rules, ignores, { + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.node, + ...globals.commonjs, + JSX: true, + }, + parserOptions: { + // projectService: true, + }, + }, + + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + }, + react: { + version: '19', + }, + }, + + linterOptions: { + reportUnusedDisableDirectives: true, + }, +}); diff --git a/eslint.rules.ts b/eslint.rules.ts new file mode 100644 index 000000000000..900d65821331 --- /dev/null +++ b/eslint.rules.ts @@ -0,0 +1,532 @@ +/** + * 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. + */ + +import {defineConfig} from 'eslint/config'; +import eslintPlugin from 'eslint-plugin-eslint-plugin'; + +const OFF = 0; +const WARNING = 1; +const ERROR = 2; + +// Prevent importing lodash, usually for browser bundle size reasons +const LodashImportPatterns = ['lodash', 'lodash.**', 'lodash/**']; + +// Prevent importing content plugins, usually for coupling reasons +const ContentPluginsImportPatterns = [ + '@docusaurus/plugin-content-blog', + '@docusaurus/plugin-content-blog/**', + // TODO fix theme-common => docs dependency issue + // '@docusaurus/plugin-content-docs', + // '@docusaurus/plugin-content-docs/**', + '@docusaurus/plugin-content-pages', + '@docusaurus/plugin-content-pages/**', +]; + +export default defineConfig( + { + rules: { + 'array-callback-return': WARNING, + camelcase: WARNING, + 'class-methods-use-this': OFF, // It's a way of allowing private variables. + curly: [WARNING, 'all'], + 'global-require': OFF, // Deprecated, @typescript-eslint/no-require-import is enough + 'no-alert': WARNING, + 'lines-between-class-members': OFF, + 'max-classes-per-file': OFF, + 'max-len': [ + WARNING, + { + code: Infinity, // Code width is already enforced by Prettier/oxfmt + tabWidth: 2, + comments: 80, + ignoreUrls: true, + ignorePattern: '(eslint-disable|@)', + }, + ], + 'arrow-body-style': OFF, + 'no-await-in-loop': OFF, + 'no-case-declarations': WARNING, + 'no-console': OFF, + 'no-constant-binary-expression': ERROR, + 'no-continue': OFF, + 'no-control-regex': WARNING, + 'no-else-return': OFF, + 'no-empty': [WARNING, {allowEmptyCatch: true}], + 'no-lonely-if': WARNING, + 'no-nested-ternary': WARNING, + 'no-param-reassign': [WARNING, {props: false}], + 'no-prototype-builtins': WARNING, + 'no-restricted-exports': OFF, + 'no-restricted-properties': [ + ERROR, + .../** @type {[string, string][]} */ ([ + // TODO: TS doesn't make Boolean a narrowing function yet, + // so filter(Boolean) is problematic type-wise + // ['compact', 'Array#filter(Boolean)'], + ['concat', 'Array#concat'], + ['drop', 'Array#slice(n)'], + ['dropRight', 'Array#slice(0, -n)'], + ['fill', 'Array#fill'], + ['filter', 'Array#filter'], + ['find', 'Array#find'], + ['findIndex', 'Array#findIndex'], + ['first', 'foo[0]'], + ['flatten', 'Array#flat'], + ['flattenDeep', 'Array#flat(Infinity)'], + ['flatMap', 'Array#flatMap'], + ['fromPairs', 'Object.fromEntries'], + ['head', 'foo[0]'], + ['indexOf', 'Array#indexOf'], + ['initial', 'Array#slice(0, -1)'], + ['join', 'Array#join'], + // Unfortunately there's no great alternative to _.last yet + // Candidates: foo.slice(-1)[0]; foo[foo.length - 1] + // Array#at is ES2022; could replace _.nth as well + // ['last'], + ['map', 'Array#map'], + ['reduce', 'Array#reduce'], + ['reverse', 'Array#reverse'], + ['slice', 'Array#slice'], + ['take', 'Array#slice(0, n)'], + ['takeRight', 'Array#slice(-n)'], + ['tail', 'Array#slice(1)'], + ]).map(([property, alternative]) => ({ + object: '_', + property, + message: `Use ${alternative} instead.`, + })), + ...[ + 'readdirSync', + 'readFileSync', + 'statSync', + 'lstatSync', + 'existsSync', + 'pathExistsSync', + 'realpathSync', + 'mkdirSync', + 'mkdirpSync', + 'mkdirsSync', + 'writeFileSync', + 'writeJsonSync', + 'outputFileSync', + 'outputJsonSync', + 'moveSync', + 'copySync', + 'copyFileSync', + 'ensureFileSync', + 'ensureDirSync', + 'ensureLinkSync', + 'ensureSymlinkSync', + 'unlinkSync', + 'removeSync', + 'emptyDirSync', + ].map((property) => ({ + object: 'fs', + property, + message: 'Do not use sync fs methods.', + })), + ], + 'no-restricted-syntax': [ + WARNING, + // Copied from airbnb, removed for...of statement, added export all + { + selector: 'ForInStatement', + message: + 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.', + }, + { + selector: 'LabeledStatement', + message: + 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.', + }, + { + selector: 'WithStatement', + message: + '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.', + }, + { + selector: 'ExportAllDeclaration', + message: + "Export all does't work well if imported in ESM due to how they are transpiled, and they can also lead to unexpected exposure of internal methods.", + }, + // TODO make an internal plugin to ensure this + // { + // selector: + // @ 'ExportDefaultDeclaration > Identifier, ExportNamedDeclaration[source=null] > ExportSpecifier', + // message: 'Export in one statement' + // }, + ...['path', 'fs-extra', 'webpack', 'lodash'].map((m) => ({ + selector: `ImportDeclaration[importKind=value]:has(Literal[value=${m}]) > ImportSpecifier[importKind=value]`, + message: + 'Default-import this, both for readability and interoperability with ESM', + })), + ], + 'no-template-curly-in-string': WARNING, + 'no-unused-expressions': OFF, + 'no-useless-escape': WARNING, + 'no-void': [ERROR, {allowAsStatement: true}], + 'prefer-destructuring': OFF, + 'prefer-named-capture-group': WARNING, + 'prefer-template': WARNING, + yoda: WARNING, + + /* + TODO fix + 'header/header': [ + ERROR, + 'block', + [ + '*', + ' * 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.', + ' ', + ], + ], + + */ + + 'import/extensions': OFF, + // This rule doesn't yet support resolving .js imports when the actual file + // is .ts. Plus it's not all that useful when our code is fully TS-covered. + 'import/no-unresolved': [ + OFF, + { + // Ignore certain webpack aliases because they can't be resolved + ignore: [ + '^@theme', + '^@docusaurus', + '^@generated', + '^@site', + '^@testing-utils', + ], + }, + ], + 'import/order': [ + WARNING, + { + groups: [ + 'builtin', + 'external', + 'internal', + ['parent', 'sibling', 'index'], + 'type', + ], + pathGroups: [ + // always put css import to the last, ref: + // https://github.com/import-js/eslint-plugin-import/issues/1239 + { + pattern: '*.+(css|sass|less|scss|pcss|styl)', + group: 'unknown', + patternOptions: {matchBase: true}, + position: 'after', + }, + {pattern: 'vitest', group: 'builtin', position: 'before'}, + {pattern: 'react', group: 'builtin', position: 'before'}, + {pattern: 'react-dom', group: 'builtin', position: 'before'}, + {pattern: 'react-dom/**', group: 'builtin', position: 'before'}, + {pattern: 'stream', group: 'builtin', position: 'before'}, + {pattern: 'fs-extra', group: 'builtin'}, + {pattern: 'lodash', group: 'external', position: 'before'}, + {pattern: 'clsx', group: 'external', position: 'before'}, + // 'Bit weird to not use the `import/internal-regex` option, but this + // way, we can make `import type { Props } from "@theme/*"` appear + // before `import styles from "styles.module.css"`, which is what we + // always did. This should be removable once we stop using ambient + // module declarations for theme aliases. + {pattern: '@theme/**', group: 'internal'}, + {pattern: '@site/**', group: 'internal'}, + {pattern: '@theme-init/**', group: 'internal'}, + {pattern: '@theme-original/**', group: 'internal'}, + ], + pathGroupsExcludedImportTypes: [], + // example: let `import './nprogress.css';` after importing others + // in `packages/docusaurus-theme-classic/src/nprogress.ts` + // see more: https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#warnonunassignedimports-truefalse + warnOnUnassignedImports: true, + }, + ], + 'import/prefer-default-export': OFF, + + 'vitest/consistent-test-it': WARNING, + 'vitest/expect-expect': OFF, + 'vitest/no-large-snapshots': [ + WARNING, + {maxSize: Infinity, inlineMaxSize: 50}, + ], + 'vitest/no-test-return-statement': ERROR, + 'vitest/prefer-expect-resolves': WARNING, + 'vitest/prefer-lowercase-title': [WARNING, {ignore: ['describe']}], + 'vitest/prefer-spy-on': WARNING, + 'vitest/prefer-to-be': OFF, + 'vitest/prefer-to-have-length': WARNING, + 'vitest/require-top-level-describe': ERROR, + 'vitest/valid-title': [ + ERROR, + { + mustNotMatch: { + it: [ + '^should|\\.$', + 'Titles should not begin with "should" or end with a full-stop', + ], + }, + }, + ], + + 'jsx-a11y/click-events-have-key-events': WARNING, + 'jsx-a11y/no-noninteractive-element-interactions': WARNING, + 'jsx-a11y/html-has-lang': OFF, + + // Sometimes we do need the props as a whole, e.g. when spreading + 'react/destructuring-assignment': OFF, + 'react/function-component-definition': [ + WARNING, + { + namedComponents: 'function-declaration', + unnamedComponents: 'arrow-function', + }, + ], + 'react/jsx-filename-extension': OFF, + 'react/jsx-key': [ERROR, {checkFragmentShorthand: true}], + 'react/jsx-no-useless-fragment': [ERROR, {allowExpressions: true}], + 'react/jsx-props-no-spreading': OFF, + 'react/no-array-index-key': OFF, // We build a static site, and nearly all components don't change. + 'react/no-unstable-nested-components': [WARNING, {allowAsProps: true}], + 'react/prefer-stateless-function': WARNING, + 'react/prop-types': OFF, + 'react/require-default-props': [ + ERROR, + {ignoreFunctionalComponents: true}, + ], + 'react/jsx-uses-react': OFF, // JSX runtime: automatic + 'react/react-in-jsx-scope': OFF, // JSX runtime: automatic + 'react-hooks/set-state-in-effect': WARNING, // TODO re-enable later? + 'react-hooks/rules-of-hooks': ERROR, + 'react-hooks/exhaustive-deps': ERROR, + + '@typescript-eslint/no-empty-object-type': OFF, + '@typescript-eslint/prefer-optional-chain': OFF, + '@typescript-eslint/consistent-type-definitions': OFF, + '@typescript-eslint/require-await': OFF, + '@typescript-eslint/no-explicit-any': WARNING, + '@typescript-eslint/no-unused-expressions': [ + WARNING, + {allowTaggedTemplates: true, allowShortCircuit: true}, + ], + + '@typescript-eslint/ban-ts-comment': [ + ERROR, + {'ts-expect-error': 'allow-with-description'}, + ], + '@typescript-eslint/consistent-indexed-object-style': OFF, + '@typescript-eslint/consistent-type-imports': [ + WARNING, + {disallowTypeAnnotations: false}, + ], + '@typescript-eslint/explicit-module-boundary-types': WARNING, + '@typescript-eslint/method-signature-style': ERROR, + '@typescript-eslint/no-empty-function': OFF, + '@typescript-eslint/no-empty-interface': [ + ERROR, + { + allowSingleExtends: true, + }, + ], + '@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, + {functions: false, classes: false, variables: true}, + ], + '@typescript-eslint/no-non-null-assertion': OFF, + 'no-redeclare': OFF, + '@typescript-eslint/no-redeclare': ERROR, + 'no-shadow': OFF, + '@typescript-eslint/no-shadow': ERROR, + 'no-unused-vars': OFF, + // 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, + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + '@docusaurus/no-html-links': ERROR, + '@docusaurus/prefer-docusaurus-heading': ERROR, + '@docusaurus/no-untranslated-text': [ + WARNING, + { + ignoredStrings: [ + '·', + '-', + '—', + '×', + '​', // zwj: ​ + '@', + 'WebContainers', + 'Twitter', + 'X', + 'GitHub', + 'Dev.to', + '1.x', + ], + }, + ], + }, + }, + + { + files: ['packages/docusaurus/src/client/**/*.{js,ts,tsx}'], + rules: { + 'no-restricted-imports': [ + ERROR, + { + patterns: [ + ...LodashImportPatterns, + ...ContentPluginsImportPatterns, + // Prevent importing server code in client bundle + '**/../babel/**', + '**/../server/**', + '**/../commands/**', + '**/../webpack/**', + ], + }, + ], + }, + }, + { + files: [ + 'packages/docusaurus-theme-common/src/**/*.{js,ts,tsx}', + 'packages/docusaurus-utils-common/src/**/*.{js,ts,tsx}', + ], + ignores: ['**/*.test.{js,ts,tsx}', '**/__tests__/**'], + rules: { + 'no-restricted-imports': [ + ERROR, + { + patterns: [...LodashImportPatterns, ...ContentPluginsImportPatterns], + }, + ], + }, + }, + { + files: ['packages/docusaurus-*/src/theme/**/*.{js,ts,tsx}'], + ignores: ['**/*.test.{js,ts,tsx}', '**/__tests__/**'], + rules: { + 'no-restricted-imports': [ + ERROR, + { + patterns: LodashImportPatterns.concat( + // Prevents relative imports between React theme components + [ + '../**', + './**', + // Allows relative styles module import with consistent filename + '!./styles.module.css', + ], + ), + }, + ], + }, + }, + { + files: [ + 'packages/docusaurus-*/src/theme/**/*.{js,ts,tsx}', + 'packages/docusaurus/src/client/theme-fallback/**/*.{js,ts,tsx}', + ], + rules: { + 'import/no-named-export': ERROR, + }, + }, + { + files: ['packages/create-docusaurus/templates/**/*.{js,ts,tsx}'], + rules: { + 'header/header': OFF, + 'global-require': OFF, + '@typescript-eslint/no-require-imports': WARNING, + '@typescript-eslint/no-var-requires': OFF, + '@docusaurus/no-untranslated-text': OFF, + }, + }, + { + files: ['*.d.ts'], + rules: { + 'import/no-duplicates': OFF, + }, + }, + { + files: ['*.{ts,tsx}'], + rules: { + 'no-undef': OFF, + 'import/no-import-module-exports': OFF, + }, + }, + { + files: ['*.{js,mjs,cjs}'], + rules: { + // Make JS code directly runnable in Node. + '@typescript-eslint/no-var-requires': OFF, + '@typescript-eslint/explicit-module-boundary-types': OFF, + }, + }, + { + files: [ + '**/__tests__/**', + 'packages/docusaurus-plugin-debug/**', + 'website/_dogfooding/**', + ], + rules: { + '@docusaurus/no-untranslated-text': OFF, + }, + }, + { + // Internal files where extraneous deps don't matter much at long as + // they run + files: [ + '*.test.{js,ts,tsx}', + '**/__tests__/**', + 'admin/**', + 'test/**', + 'website/**', + 'packages/docusaurus-theme-common/removeThemeInternalReexport.mjs', + 'packages/docusaurus-theme-translations/update.mjs', + 'packages/docusaurus-theme-translations/src/utils.ts', + ], + rules: { + 'import/no-extraneous-dependencies': OFF, + }, + }, + + // Website-specific rules + { + files: ['website/**'], + rules: { + '@typescript-eslint/no-require-imports': OFF, + }, + }, + + { + files: ['packages/eslint-plugin/**/*.{js,ts}'], + ...eslintPlugin.configs.recommended, + }, + + { + files: [ + 'packages/docusaurus-plugin-debug/**', + 'packages/docusaurus/src/**', + ], + rules: { + '@docusaurus/prefer-docusaurus-heading': OFF, + }, + }, +); diff --git a/package.json b/package.json index b6a2458bcc8f..d01524cc45f3 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "devDependencies": { "@ai-sdk/react": "^2.0.30", "@crowdin/cli": "^4.14.2", + "@eslint/js": "^10.0.1", "@swc/core": "^1.15.32", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -90,34 +91,35 @@ "@types/react": "^19.2.14", "@types/semver": "^7.7.1", "@types/shelljs": "^0.8.12", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", + "@vitejs/plugin-react": "^5.0.0", + "@vitest/eslint-plugin": "^1.6.17", "cross-env": "^10.1.0", "cspell": "^8.18.1", - "eslint": "^8.45.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-prettier": "^8.8.0", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-eslint-plugin": "^7.3.3", "eslint-plugin-header": "^3.1.1", - "eslint-plugin-import": "^2.27.5", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.32.2", - "eslint-plugin-react-compiler": "^19.0.0-beta-40c6c23-20250301", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-regexp": "^1.15.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jsx-a11y": "^6.10.2", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-regexp": "^3.1.0", + "globals": "^17.6.0", "husky": "^9.1.7", "image-size": "^2.0.2", "jest-serializer-ansi-escapes": "^5.0.0", "jest-serializer-react-helmet-async": "^1.0.21", + "jiti": "^2.7.0", "jsdom": "^25.0.1", "lerna": "^7.4.2", "lerna-changelog": "^2.2.0", "lint-staged": "^17.0.2", "lockfile-lint": "^5.0.0", "npm-run-all": "^4.1.5", + "oxfmt": "^0.47.0", "patch-package": "^8.0.1", "pkg-pr-new": "^0.0.68", "postinstall-postinstall": "^2.1.0", - "oxfmt": "^0.47.0", "react": "^19.2.5", "react-dom": "^19.2.5", "rimraf": "^3.0.2", @@ -128,9 +130,8 @@ "stylelint-config-standard": "^29.0.0", "syncpack": "^14.3.1", "typescript": "~6.0.3", - "vitest": "^4.0.0", - "@vitejs/plugin-react": "^5.0.0", - "@vitest/eslint-plugin": "^1.4.0" + "typescript-eslint": "^8.59.3", + "vitest": "^4.0.0" }, "resolutions": { "**/pretty-format/react-is": "^19.2.0", diff --git a/packages/docusaurus-babel/src/preset.ts b/packages/docusaurus-babel/src/preset.ts index cbbeb2207423..6a8b6a539373 100644 --- a/packages/docusaurus-babel/src/preset.ts +++ b/packages/docusaurus-babel/src/preset.ts @@ -57,7 +57,7 @@ function getTransformOptions(isServer: boolean): TransformOptions { // By default, it assumes @babel/runtime@7.0.0. Since we use >7.0.0, // better to explicitly specify the version so that it can reuse the // helper better. See https://github.com/babel/babel/issues/10261 - // eslint-disable-next-line @typescript-eslint/no-var-requires, global-require + // eslint-disable-next-line @typescript-eslint/no-require-imports version: (require('@babel/runtime/package.json') as {version: string}) .version, regenerator: true, diff --git a/packages/docusaurus-bundler/src/minifyHtml.ts b/packages/docusaurus-bundler/src/minifyHtml.ts index 8c564986f8aa..226fb08f2ba2 100644 --- a/packages/docusaurus-bundler/src/minifyHtml.ts +++ b/packages/docusaurus-bundler/src/minifyHtml.ts @@ -62,7 +62,7 @@ async function getTerserMinifier(): Promise { return {code, warnings: []}; } catch (err) { throw new Error(`HTML minification failed (Terser)`, { - cause: err as Error, + cause: err, }); } }, @@ -116,7 +116,7 @@ async function getSwcMinifier(): Promise { }; } catch (err) { throw new Error(`HTML minification failed (SWC)`, { - cause: err as Error, + cause: err, }); } }, diff --git a/packages/docusaurus-faster/src/index.ts b/packages/docusaurus-faster/src/index.ts index 27cc387a7ad4..dd3832d29e50 100644 --- a/packages/docusaurus-faster/src/index.ts +++ b/packages/docusaurus-faster/src/index.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import Rspack from '@rspack/core'; +import {rspack as Rspack} from '@rspack/core'; import * as lightningcss from 'lightningcss'; import browserslist from 'browserslist'; import {minify as swcHtmlMinifier} from '@swc/html'; diff --git a/packages/docusaurus-mdx-loader/src/__tests__/frontMatter.test.ts b/packages/docusaurus-mdx-loader/src/__tests__/frontMatter.test.ts index 6b93b43f4a2b..5ecfe820df96 100644 --- a/packages/docusaurus-mdx-loader/src/__tests__/frontMatter.test.ts +++ b/packages/docusaurus-mdx-loader/src/__tests__/frontMatter.test.ts @@ -25,14 +25,14 @@ function testField(params: { ErrorMessage: string, ][]; }) { - // eslint-disable-next-line @vitest/require-top-level-describe + // eslint-disable-next-line vitest/require-top-level-describe test(`[${params.prefix}] accept valid values`, () => { params.validFrontMatters.forEach((frontMatter) => { expect(validateMDXFrontMatter(frontMatter)).toEqual(frontMatter); }); }); - // eslint-disable-next-line @vitest/require-top-level-describe + // eslint-disable-next-line vitest/require-top-level-describe test(`[${params.prefix}] convert valid values`, () => { params.convertibleFrontMatter?.forEach( ([convertibleFrontMatter, convertedFrontMatter]) => { @@ -43,7 +43,7 @@ function testField(params: { ); }); - // eslint-disable-next-line @vitest/require-top-level-describe + // eslint-disable-next-line vitest/require-top-level-describe test(`[${params.prefix}] throw error for values`, () => { params.invalidFrontMatters?.forEach(([frontMatter, message]) => { try { @@ -56,7 +56,7 @@ function testField(params: { )}`, ); } catch (err) { - // eslint-disable-next-line @vitest/no-conditional-expect + // eslint-disable-next-line vitest/no-conditional-expect expect((err as Error).message).toMatch( new RegExp(escapeStringRegexp(message)), ); diff --git a/packages/docusaurus-mdx-loader/src/utils.ts b/packages/docusaurus-mdx-loader/src/utils.ts index 30ed0506fe4c..17a8ae9ffe1f 100644 --- a/packages/docusaurus-mdx-loader/src/utils.ts +++ b/packages/docusaurus-mdx-loader/src/utils.ts @@ -128,7 +128,7 @@ export async function compileToJSX({ error.message }\nDetails:\n${errorDetails}`, // TODO error cause doesn't seem to be used by Webpack stats.errors :s - {cause: error}, + {cause: errorUnknown}, ); } } diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index 5876e364848d..4ab1e21a54e4 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -260,7 +260,6 @@ declare module '@docusaurus/Translate' { } declare module '@docusaurus/router' { - // eslint-disable-next-line import/no-extraneous-dependencies export {useHistory, useLocation, Redirect, matchPath} from 'react-router-dom'; } @@ -352,7 +351,6 @@ declare module '@docusaurus/Noop' { } declare module '@docusaurus/renderRoutes' { - // eslint-disable-next-line import/no-extraneous-dependencies import {renderRoutes} from 'react-router-config'; export default renderRoutes; diff --git a/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts b/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts index 697a04eaace0..eca89823a2e7 100644 --- a/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts +++ b/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts @@ -101,7 +101,7 @@ function validateCollectedRedirects( if (to.startsWith('/')) { try { return decodeURI(new URL(to, 'https://example.com').pathname); - } catch (e) {} + } catch {} } return undefined; }) diff --git a/packages/docusaurus-plugin-client-redirects/src/createRedirectPageContent.ts b/packages/docusaurus-plugin-client-redirects/src/createRedirectPageContent.ts index 3cdf1b7f6e14..5cd0f935804c 100644 --- a/packages/docusaurus-plugin-client-redirects/src/createRedirectPageContent.ts +++ b/packages/docusaurus-plugin-client-redirects/src/createRedirectPageContent.ts @@ -28,7 +28,7 @@ function searchAnchorForwarding(toUrl: string): boolean { const url = new URL(toUrl, 'https://example.com'); const containsSearchOrAnchor = url.search || url.hash; return !containsSearchOrAnchor; - } catch (e) { + } catch { return false; } } diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts index eebe88d1ed88..b071886e5f6d 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/frontMatter.test.ts @@ -53,7 +53,7 @@ function testField(params: { )}`, ); } catch (err) { - // eslint-disable-next-line @vitest/no-conditional-expect + // eslint-disable-next-line vitest/no-conditional-expect expect((err as Error).message).toMatch( new RegExp(escapeRegexp(message)), ); diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 4c9b4c46e908..a30480b84025 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -415,7 +415,7 @@ export async function generateBlogPosts( } catch (err) { throw new Error( `Processing of blog source file path=${blogSourceFile} failed.`, - {cause: err as Error}, + {cause: err}, ); } } diff --git a/packages/docusaurus-plugin-content-blog/src/feed.ts b/packages/docusaurus-plugin-content-blog/src/feed.ts index 1803c43b5e3e..0a1bfe4e7a89 100644 --- a/packages/docusaurus-plugin-content-blog/src/feed.ts +++ b/packages/docusaurus-plugin-content-blog/src/feed.ts @@ -323,7 +323,7 @@ async function createBlogFeedFile({ await fs.outputFile(outputPath, feedContent); } catch (err) { throw new Error(`Generating ${feedType} feed failed.`, { - cause: err as Error, + cause: err, }); } } diff --git a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts index 244eb565f90a..9a6002776734 100644 --- a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts @@ -4,6 +4,8 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ +/* eslint-disable camelcase */ + import { ContentVisibilitySchema, FrontMatterLastUpdateSchema, diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 944a113c0aad..3f47050be68b 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -7,8 +7,7 @@ /// declare module '@docusaurus/plugin-content-blog' { - import type {LoadedMDXContent} from '@docusaurus/mdx-loader'; - import type {MDXOptions} from '@docusaurus/mdx-loader'; + import type {LoadedMDXContent, MDXOptions} from '@docusaurus/mdx-loader'; import type { FrontMatterTag, TagMetadata, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/frontMatter.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/frontMatter.test.ts index dde2e3f1cd0e..5a166fc071f3 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/frontMatter.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/frontMatter.test.ts @@ -22,14 +22,14 @@ function testField(params: { ErrorMessage: string, ][]; }) { - // eslint-disable-next-line @vitest/require-top-level-describe + // eslint-disable-next-line vitest/require-top-level-describe test(`[${params.prefix}] accept valid values`, () => { params.validFrontMatters.forEach((frontMatter) => { expect(validateDocFrontMatter(frontMatter)).toEqual(frontMatter); }); }); - // eslint-disable-next-line @vitest/require-top-level-describe + // eslint-disable-next-line vitest/require-top-level-describe test(`[${params.prefix}] convert valid values`, () => { params.convertibleFrontMatter?.forEach( ([convertibleFrontMatter, convertedFrontMatter]) => { @@ -40,7 +40,7 @@ function testField(params: { ); }); - // eslint-disable-next-line @vitest/require-top-level-describe + // eslint-disable-next-line vitest/require-top-level-describe test(`[${params.prefix}] throw error for values`, () => { params.invalidFrontMatters?.forEach(([frontMatter, message]) => { try { @@ -53,7 +53,7 @@ function testField(params: { )}`, ); } catch (err) { - // eslint-disable-next-line @vitest/no-conditional-expect + // eslint-disable-next-line vitest/no-conditional-expect expect((err as Error).message).toMatch( new RegExp(escapeRegexp(message)), ); diff --git a/packages/docusaurus-plugin-content-docs/src/client/index.ts b/packages/docusaurus-plugin-content-docs/src/client/index.ts index 3751b4424b3b..f714d06412f7 100644 --- a/packages/docusaurus-plugin-content-docs/src/client/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/client/index.ts @@ -138,7 +138,7 @@ export const useDocsData = (pluginId: string | undefined): GlobalPluginData => { `You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled${ pluginId === 'Default' ? '' : ` (pluginId=${pluginId}` }`, - {cause: error as Error}, + {cause: error}, ); } }; diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index b8f02ba5b014..06704fbff1dd 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -258,7 +258,7 @@ export async function processDocMetadata(args: { } catch (err) { throw new Error( `Can't process doc metadata for doc at path path=${args.docFile.filePath} in version name=${args.versionMetadata.versionName}`, - {cause: err as Error}, + {cause: err}, ); } } diff --git a/packages/docusaurus-plugin-content-docs/src/frontMatter.ts b/packages/docusaurus-plugin-content-docs/src/frontMatter.ts index 0526a5f6b5b7..091b7aef9cf2 100644 --- a/packages/docusaurus-plugin-content-docs/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-docs/src/frontMatter.ts @@ -4,6 +4,8 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ +/* eslint-disable camelcase */ + import { JoiFrontMatter as Joi, // Custom instance for front matter URISchema, diff --git a/packages/docusaurus-plugin-content-pages/src/content.ts b/packages/docusaurus-plugin-content-pages/src/content.ts index c3ae1b18e8c6..1ddc6eeb5616 100644 --- a/packages/docusaurus-plugin-content-pages/src/content.ts +++ b/packages/docusaurus-plugin-content-pages/src/content.ts @@ -80,7 +80,7 @@ export async function loadPagesContent( } catch (err) { throw new Error( `Processing of page source file path=${relativeSource} failed.`, - {cause: err as Error}, + {cause: err}, ); } } diff --git a/packages/docusaurus-plugin-content-pages/src/frontMatter.ts b/packages/docusaurus-plugin-content-pages/src/frontMatter.ts index d68923d89ea8..3f0db8e02ca8 100644 --- a/packages/docusaurus-plugin-content-pages/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-pages/src/frontMatter.ts @@ -14,6 +14,7 @@ import { FrontMatterLastUpdateSchema, } from '@docusaurus/utils-validation'; import type {PageFrontMatter} from '@docusaurus/plugin-content-pages'; +/* eslint-disable camelcase */ const PageFrontMatterSchema = Joi.object({ // See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398 diff --git a/packages/docusaurus-plugin-ideal-image/src/index.ts b/packages/docusaurus-plugin-ideal-image/src/index.ts index 66c3c92c44d7..49c0332328f0 100644 --- a/packages/docusaurus-plugin-ideal-image/src/index.ts +++ b/packages/docusaurus-plugin-ideal-image/src/index.ts @@ -67,7 +67,7 @@ export default function pluginIdealImage( options: { // Don't emit for server-side rendering emitFile: !isServer, - // eslint-disable-next-line global-require + // eslint-disable-next-line @typescript-eslint/no-require-imports adapter: require('@docusaurus/responsive-loader/sharp'), name: 'assets/ideal-img/[name].[hash:hex:7].[width].[ext]', ...loaderOptions, diff --git a/packages/docusaurus-plugin-pwa/src/registerSw.ts b/packages/docusaurus-plugin-pwa/src/registerSw.ts index 69a6cf3d8246..5237ec35c14e 100644 --- a/packages/docusaurus-plugin-pwa/src/registerSw.ts +++ b/packages/docusaurus-plugin-pwa/src/registerSw.ts @@ -74,7 +74,7 @@ async function getIsAppInstalledRelatedApps() { try { const relatedApps = await navigator.getInstalledRelatedApps(); return relatedApps.some((app) => app.platform === 'webapp'); - } catch (e) { + } catch { // Error might be thrown when Docusaurus is embedded in an iframe: // registerSW failed DOMException: Failed to execute 'getInstalledRelatedApps' on 'Navigator': getInstalledRelatedApps() is only supported in top-level browsing contexts. return false; diff --git a/packages/docusaurus-plugin-pwa/src/sw.ts b/packages/docusaurus-plugin-pwa/src/sw.ts index b910278b9fa9..505e2970e4e6 100644 --- a/packages/docusaurus-plugin-pwa/src/sw.ts +++ b/packages/docusaurus-plugin-pwa/src/sw.ts @@ -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 no-restricted-globals */ import {PrecacheController, type PrecacheEntry} from 'workbox-precaching'; @@ -62,7 +61,6 @@ function getPossibleURLs(url: string) { (async () => { const params = parseSwParams(); - // eslint-disable-next-line no-underscore-dangle const precacheManifest = ( self as typeof globalThis & {__WB_MANIFEST: (string | PrecacheEntry)[]} ).__WB_MANIFEST; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 8dd8f87f8a19..644511d7d881 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -499,8 +499,7 @@ declare module '@theme/CodeBlock/Buttons/WordWrapButton' { } declare module '@theme/CodeBlock/Container' { - import type {ReactNode} from 'react'; - import type {ComponentProps} from 'react'; + import type {ReactNode, ComponentProps} from 'react'; export default function CodeBlockContainer({ as: As, diff --git a/packages/docusaurus-theme-classic/src/theme/Admonition/index.tsx b/packages/docusaurus-theme-classic/src/theme/Admonition/index.tsx index 4968a26bad2b..a306721ed0a7 100644 --- a/packages/docusaurus-theme-classic/src/theme/Admonition/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Admonition/index.tsx @@ -24,5 +24,6 @@ function getAdmonitionTypeComponent(type: string): ComponentType { export default function Admonition(unprocessedProps: Props): ReactNode { const props = processAdmonitionProps(unprocessedProps); const AdmonitionTypeComponent = getAdmonitionTypeComponent(props.type); + // eslint-disable-next-line react-hooks/static-components return ; } diff --git a/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/Content/index.tsx b/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/Content/index.tsx index c007f3a33a10..bc772b00f3f9 100644 --- a/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/Content/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/AnnouncementBar/Content/index.tsx @@ -19,7 +19,6 @@ export default function AnnouncementBarContent(props: Props): ReactNode { {...props} className={clsx(styles.content, props.className)} // Developer provided the HTML, so assume it's safe. - // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{__html: content}} /> ); diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/index.tsx index dec2ddd8f22a..ffc45fc87b12 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/index.tsx @@ -17,7 +17,7 @@ import styles from './styles.module.css'; // TODO Docusaurus v4: remove useless forwardRef const Pre = React.forwardRef>( - (props, ref) => { + function Pre(props, ref) { return (
   );
diff --git a/packages/docusaurus-theme-classic/src/theme/Footer/Copyright/index.tsx b/packages/docusaurus-theme-classic/src/theme/Footer/Copyright/index.tsx
index 85314920b9d8..92c9ef21bdcf 100644
--- a/packages/docusaurus-theme-classic/src/theme/Footer/Copyright/index.tsx
+++ b/packages/docusaurus-theme-classic/src/theme/Footer/Copyright/index.tsx
@@ -13,7 +13,6 @@ export default function FooterCopyright({copyright}: Props): ReactNode {
     
); diff --git a/packages/docusaurus-theme-classic/src/theme/Footer/Links/MultiColumn/index.tsx b/packages/docusaurus-theme-classic/src/theme/Footer/Links/MultiColumn/index.tsx index 570ec445544e..e80d43041ba3 100644 --- a/packages/docusaurus-theme-classic/src/theme/Footer/Links/MultiColumn/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Footer/Links/MultiColumn/index.tsx @@ -19,7 +19,6 @@ function ColumnLinkItem({item}: {item: ColumnItemType}) {
  • ) : ( diff --git a/packages/docusaurus-theme-classic/src/theme/Footer/Links/Simple/index.tsx b/packages/docusaurus-theme-classic/src/theme/Footer/Links/Simple/index.tsx index 5286cf43049a..09d9d18a2bf3 100644 --- a/packages/docusaurus-theme-classic/src/theme/Footer/Links/Simple/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Footer/Links/Simple/index.tsx @@ -19,7 +19,6 @@ function SimpleLinkItem({item}: {item: Props['links'][number]}) { ) : ( diff --git a/packages/docusaurus-theme-classic/src/theme/prism-include-languages.ts b/packages/docusaurus-theme-classic/src/theme/prism-include-languages.ts index 2b8fdce6aa02..569225cf7e5f 100644 --- a/packages/docusaurus-theme-classic/src/theme/prism-include-languages.ts +++ b/packages/docusaurus-theme-classic/src/theme/prism-include-languages.ts @@ -29,10 +29,10 @@ export default function prismIncludeLanguages( additionalLanguages.forEach((lang) => { if (lang === 'php') { - // eslint-disable-next-line global-require + // eslint-disable-next-line @typescript-eslint/no-require-imports require('prismjs/components/prism-markup-templating.js'); } - // eslint-disable-next-line global-require, import/no-dynamic-require + // eslint-disable-next-line @typescript-eslint/no-require-imports require(`prismjs/components/prism-${lang}`); }); diff --git a/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx b/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx index b2287431ecf6..e283cbd2e588 100644 --- a/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx +++ b/packages/docusaurus-theme-common/src/components/Collapsible/index.tsx @@ -123,7 +123,6 @@ function useCollapseAnimation({ return undefined; } - // eslint-disable-next-line react-compiler/react-compiler el.style.willChange = 'height'; function startAnimation() { diff --git a/packages/docusaurus-theme-common/src/components/ThemedComponent/index.tsx b/packages/docusaurus-theme-common/src/components/ThemedComponent/index.tsx index 5c58cd3a9dd4..fa96eded7260 100644 --- a/packages/docusaurus-theme-common/src/components/ThemedComponent/index.tsx +++ b/packages/docusaurus-theme-common/src/components/ThemedComponent/index.tsx @@ -12,9 +12,7 @@ import {useColorMode} from '../../contexts/colorMode'; import styles from './styles.module.css'; -const AllThemes = ['light', 'dark'] as const; - -type Theme = (typeof AllThemes)[number]; +type Theme = 'light' | 'dark'; type RenderFn = ({ theme, diff --git a/packages/docusaurus-theme-common/src/index.ts b/packages/docusaurus-theme-common/src/index.ts index 1c9e15f1dcb8..66083cee973c 100644 --- a/packages/docusaurus-theme-common/src/index.ts +++ b/packages/docusaurus-theme-common/src/index.ts @@ -13,19 +13,19 @@ import {DEFAULT_SEARCH_TAG} from './utils/searchUtils'; // This is public API surface that we need to keep for v3 // See https://github.com/facebook/docusaurus/pull/10316 export function useCurrentSidebarCategory(...args: unknown[]): unknown { - // eslint-disable-next-line @typescript-eslint/no-var-requires + // eslint-disable-next-line @typescript-eslint/no-require-imports return require('@docusaurus/plugin-content-docs/client').useCurrentSidebarCategory( ...args, ); } export function filterDocCardListItems(...args: unknown[]): unknown { - // eslint-disable-next-line @typescript-eslint/no-var-requires + // eslint-disable-next-line @typescript-eslint/no-require-imports return require('@docusaurus/plugin-content-docs/client').filterDocCardListItems( ...args, ); } export function useDocsPreferredVersion(...args: unknown[]): unknown { - // eslint-disable-next-line @typescript-eslint/no-var-requires + // eslint-disable-next-line @typescript-eslint/no-require-imports return require('@docusaurus/plugin-content-docs/client').useDocsPreferredVersion( ...args, ); @@ -33,7 +33,7 @@ export function useDocsPreferredVersion(...args: unknown[]): unknown { export function useContextualSearchFilters() { const {i18n} = useDocusaurusContext(); const docsTags = - // eslint-disable-next-line @typescript-eslint/no-var-requires, react-compiler/react-compiler + // eslint-disable-next-line @typescript-eslint/no-require-imports require('@docusaurus/plugin-content-docs/client').useDocsContextualSearchTags(); const tags = [DEFAULT_SEARCH_TAG, ...docsTags]; return {locale: i18n.currentLocale, tags}; diff --git a/packages/docusaurus-theme-common/src/utils/reactUtils.tsx b/packages/docusaurus-theme-common/src/utils/reactUtils.tsx index 80e349e3ba8f..eefad69bf7a5 100644 --- a/packages/docusaurus-theme-common/src/utils/reactUtils.tsx +++ b/packages/docusaurus-theme-common/src/utils/reactUtils.tsx @@ -52,7 +52,7 @@ export function usePrevious(value: T): T | undefined { // TODO need to fix this React Compiler lint error // probably requires changing the API though - // eslint-disable-next-line react-compiler/react-compiler + // eslint-disable-next-line react-hooks/refs return ref.current; } @@ -84,7 +84,7 @@ export function useShallowMemoObject(obj: O): O { const deps = Object.entries(obj); // Sort by keys to make it order-insensitive deps.sort((a, b) => a[0].localeCompare(b[0])); - // eslint-disable-next-line react-compiler/react-compiler,react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps,react-hooks/use-memo return useMemo(() => obj, deps.flat()); } @@ -105,14 +105,16 @@ type SimpleProvider = ComponentType<{children: ReactNode}>; */ export function composeProviders(providers: SimpleProvider[]): SimpleProvider { // Creates a single React component: it's cheaper to compose JSX elements - return ({children}) => ( - <> - {providers.reduceRight( - (element, CurrentProvider) => ( - {element} - ), - children, - )} - - ); + return function ComposedProvider({children}: {children: ReactNode}) { + return ( + <> + {providers.reduceRight( + (element, CurrentProvider) => ( + {element} + ), + children, + )} + + ); + }; } diff --git a/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx b/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx index 1bedef66e4f9..110b7b833966 100644 --- a/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx +++ b/packages/docusaurus-theme-common/src/utils/scrollUtils.tsx @@ -124,7 +124,6 @@ export function useScrollPosition( window.addEventListener('scroll', handleScroll, opts); return () => window.removeEventListener('scroll', handleScroll, opts); - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [dynamicEffect, scrollEventsEnabledRef, ...deps]); } diff --git a/packages/docusaurus-theme-mermaid/src/client/index.ts b/packages/docusaurus-theme-mermaid/src/client/index.ts index 51a143387e34..ebb57f4ace43 100644 --- a/packages/docusaurus-theme-mermaid/src/client/index.ts +++ b/packages/docusaurus-theme-mermaid/src/client/index.ts @@ -42,7 +42,9 @@ function useMermaidId(): string { // It could work thanks to https://github.com/facebook/react/pull/32001 // return useId(); // tried that, doesn't work ('#d:re:' is not a valid selector.) - return useState(`mermaid-svg-${Math.round(Math.random() * 10000000)}`)[0]; + return useState( + () => `mermaid-svg-${Math.round(Math.random() * 10000000)}`, + )[0]; } async function renderMermaid({ diff --git a/packages/docusaurus-theme-mermaid/src/client/loadMermaid.ts b/packages/docusaurus-theme-mermaid/src/client/loadMermaid.ts index 47a6c7b3e847..48e017cea284 100644 --- a/packages/docusaurus-theme-mermaid/src/client/loadMermaid.ts +++ b/packages/docusaurus-theme-mermaid/src/client/loadMermaid.ts @@ -9,7 +9,6 @@ import type {Mermaid} from 'mermaid'; declare global { // Global variable provided by bundler DefinePlugin - /* eslint-disable-next-line no-underscore-dangle */ const __DOCUSAURUS_MERMAID_LAYOUT_ELK_ENABLED__: boolean; } diff --git a/packages/docusaurus-theme-mermaid/src/index.ts b/packages/docusaurus-theme-mermaid/src/index.ts index 622c6b2ef72b..df02c1f58a1b 100644 --- a/packages/docusaurus-theme-mermaid/src/index.ts +++ b/packages/docusaurus-theme-mermaid/src/index.ts @@ -16,7 +16,7 @@ async function isElkLayoutPackageAvailable() { try { await import('@mermaid-js/layout-elk'); return true; - } catch (e) { + } catch { return false; } } diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index dd0fe66231d2..21fb67063cef 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -33,7 +33,6 @@ function MermaidRenderResult({
    ); diff --git a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx index 821d1d1d6671..eb3ab9153569 100644 --- a/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx +++ b/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx @@ -140,6 +140,7 @@ function useResultsFooterComponent({ }): DocSearchProps['resultsFooterComponent'] { return useMemo( () => + // eslint-disable-next-line react/display-name ({state}) => , [closeModal], ); @@ -286,6 +287,8 @@ function DocSearch({externalUrlRegex, ...props}: DocSearchV4Props) { {isOpen && DocSearchModal && + // TODO fix this + // eslint-disable-next-line react-hooks/refs searchContainer.current && createPortal( , + + // TODO fix this + // eslint-disable-next-line react-hooks/refs searchContainer.current, )} 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 fb275f506b69..e573d6e7981d 100644 --- a/packages/docusaurus-theme-search-algolia/src/theme/SearchPage/index.tsx +++ b/packages/docusaurus-theme-search-algolia/src/theme/SearchPage/index.tsx @@ -372,7 +372,7 @@ function SearchPageContent(): ReactNode { ExecutionEnvironment.canUseIntersectionObserver && new IntersectionObserver( // TODO need to fix this React Compiler lint error - // eslint-disable-next-line react-compiler/react-compiler + // eslint-disable-next-line react-hooks/refs (entries) => { const { isIntersecting, @@ -536,7 +536,6 @@ function SearchPageContent(): ReactNode { key={index} className="breadcrumbs__item" // Developer provided the HTML, so assume it's safe. - // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{__html: html}} /> ))} @@ -548,7 +547,6 @@ function SearchPageContent(): ReactNode {

    )} diff --git a/packages/docusaurus-theme-translations/src/__tests__/__fixtures__/theme/index.js b/packages/docusaurus-theme-translations/src/__tests__/__fixtures__/theme/index.js index 80b33a00c39d..49cc658148e6 100644 --- a/packages/docusaurus-theme-translations/src/__tests__/__fixtures__/theme/index.js +++ b/packages/docusaurus-theme-translations/src/__tests__/__fixtures__/theme/index.js @@ -1,5 +1,6 @@ import Translate from '@docusaurus/Translate'; export default function Foo() { + // eslint-disable-next-line @docusaurus/string-literal-i18n-messages,no-undef return {index}; } diff --git a/packages/docusaurus-theme-translations/src/__tests__/utils.test.ts b/packages/docusaurus-theme-translations/src/__tests__/utils.test.ts index 840a39fae899..775a83f5804e 100644 --- a/packages/docusaurus-theme-translations/src/__tests__/utils.test.ts +++ b/packages/docusaurus-theme-translations/src/__tests__/utils.test.ts @@ -19,7 +19,7 @@ describe('extractThemeCodeMessages', () => { Some warnings were found! Translate content could not be extracted. It has to be a static string and use optional but static props, like text. - File: packages/docusaurus-theme-translations/src/__tests__/__fixtures__/theme/index.js at line 4 + File: packages/docusaurus-theme-translations/src/__tests__/__fixtures__/theme/index.js at line 5 Full code: {index} ] `); diff --git a/packages/docusaurus-types/src/swizzle.d.ts b/packages/docusaurus-types/src/swizzle.d.ts index a440c4238af6..cbb3d93b6882 100644 --- a/packages/docusaurus-types/src/swizzle.d.ts +++ b/packages/docusaurus-types/src/swizzle.d.ts @@ -35,10 +35,8 @@ export type WrapperProps< > = T extends JSXElementConstructor ? unknown extends P - ? // eslint-disable-next-line @typescript-eslint/ban-types - {} + ? {} : P : T extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[T] - : // eslint-disable-next-line @typescript-eslint/ban-types - {}; + : {}; diff --git a/packages/docusaurus-utils-validation/src/validationSchemas.ts b/packages/docusaurus-utils-validation/src/validationSchemas.ts index 0edd9de0b98a..f1c79abcf34f 100644 --- a/packages/docusaurus-utils-validation/src/validationSchemas.ts +++ b/packages/docusaurus-utils-validation/src/validationSchemas.ts @@ -72,7 +72,6 @@ export const URISchema = Joi.alternatives( return helpers.error('any.invalid'); } try { - // eslint-disable-next-line no-new new URL(String(val)); return val; } catch { diff --git a/packages/docusaurus-utils/src/constants.ts b/packages/docusaurus-utils/src/constants.ts index 5039d6989b00..773e8930d703 100644 --- a/packages/docusaurus-utils/src/constants.ts +++ b/packages/docusaurus-utils/src/constants.ts @@ -18,7 +18,7 @@ export const NODE_MINOR_VERSION = parseInt( /** Docusaurus core version. */ export const DOCUSAURUS_VERSION = - // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires + // eslint-disable-next-line @typescript-eslint/no-require-imports (require('../package.json') as {version: string}).version; /** diff --git a/packages/docusaurus-utils/src/dataFileUtils.ts b/packages/docusaurus-utils/src/dataFileUtils.ts index 8c07f2dd4975..b0ef397fcec4 100644 --- a/packages/docusaurus-utils/src/dataFileUtils.ts +++ b/packages/docusaurus-utils/src/dataFileUtils.ts @@ -64,7 +64,7 @@ export async function readDataFile(params: DataFileParams): Promise { process.cwd(), filePath, )} looks invalid (not Yaml nor JSON).`; - throw new Error(msg, {cause: err as Error}); + throw new Error(msg, {cause: err}); } } diff --git a/packages/docusaurus-utils/src/vcs/gitUtils.ts b/packages/docusaurus-utils/src/vcs/gitUtils.ts index ac7d0cbe96f1..7ca4919fd673 100644 --- a/packages/docusaurus-utils/src/vcs/gitUtils.ts +++ b/packages/docusaurus-utils/src/vcs/gitUtils.ts @@ -39,7 +39,7 @@ const GitCommandQueue = new PQueue({ const realHasGitFn = () => { try { return execa.sync('git', ['--version']).exitCode === 0; - } catch (error) { + } catch { return false; } }; diff --git a/packages/docusaurus-utils/src/webpackUtils.ts b/packages/docusaurus-utils/src/webpackUtils.ts index 5ccca490841f..8fbb51ced9ce 100644 --- a/packages/docusaurus-utils/src/webpackUtils.ts +++ b/packages/docusaurus-utils/src/webpackUtils.ts @@ -18,7 +18,6 @@ export type WebpackCompilerName = 'server' | 'client'; export function getWebpackLoaderCompilerName( context: LoaderContext, ): WebpackCompilerName { - // eslint-disable-next-line no-underscore-dangle const compilerName = context._compiler?.name; switch (compilerName) { case 'server': diff --git a/packages/docusaurus/src/client/__tests__/browserContext.test.tsx b/packages/docusaurus/src/client/__tests__/browserContext.test.tsx index 399fbe792ea3..7acede6bd93a 100644 --- a/packages/docusaurus/src/client/__tests__/browserContext.test.tsx +++ b/packages/docusaurus/src/client/__tests__/browserContext.test.tsx @@ -18,7 +18,7 @@ describe('BrowserContextProvider', () => { ), }); - // eslint-disable-next-line @vitest/no-commented-out-tests + // eslint-disable-next-line vitest/no-commented-out-tests /* TODO it seems not really possible to test before hydration anymore See https://github.com/testing-library/react-testing-library/issues/1120 diff --git a/packages/docusaurus/src/client/exports/ComponentCreator.tsx b/packages/docusaurus/src/client/exports/ComponentCreator.tsx index b5e70812b594..f9794daf2737 100644 --- a/packages/docusaurus/src/client/exports/ComponentCreator.tsx +++ b/packages/docusaurus/src/client/exports/ComponentCreator.tsx @@ -116,14 +116,12 @@ export default function ComponentCreator( val[keyPaths[keyPaths.length - 1]!] = chunk; }); - /* eslint-disable no-underscore-dangle */ const Component = loadedModules.__comp!; delete loadedModules.__comp; const routeContext = loadedModules.__context!; delete loadedModules.__context; const routeProps = loadedModules.__props; delete loadedModules.__props; - /* eslint-enable no-underscore-dangle */ // Is there any way to put this RouteContextProvider upper in the tree? return ( diff --git a/packages/docusaurus/src/client/exports/__tests__/Link.test.tsx b/packages/docusaurus/src/client/exports/__tests__/Link.test.tsx index 4283303d0cce..fce2c970b6a8 100644 --- a/packages/docusaurus/src/client/exports/__tests__/Link.test.tsx +++ b/packages/docusaurus/src/client/exports/__tests__/Link.test.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ // @vitest-environment jsdom -/* eslint-disable jsx-a11y/anchor-is-valid */ + import {describe, expect, it, vi} from 'vitest'; import React, {type ReactNode} from 'react'; import {render as renderRTL} from '@testing-library/react'; diff --git a/packages/docusaurus/src/client/exports/isInternalUrl.ts b/packages/docusaurus/src/client/exports/isInternalUrl.ts index 6335ae003e61..6685e6cbd95b 100644 --- a/packages/docusaurus/src/client/exports/isInternalUrl.ts +++ b/packages/docusaurus/src/client/exports/isInternalUrl.ts @@ -9,7 +9,7 @@ // Spec: https://datatracker.ietf.org/doc/html/rfc3986#section-3.1 // In particular: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) export function hasProtocol(url: string): boolean { - return /^(?:[A-Za-z][A-Za-z\d+.-]*:|\/\/)/.test(url); + return /^(?:[A-Z][A-Z\d+.-]*:|\/\/)/i.test(url); } export default function isInternalUrl(url?: string): boolean { diff --git a/packages/docusaurus/src/commands/build/buildLocale.ts b/packages/docusaurus/src/commands/build/buildLocale.ts index 483f347d1127..bb04fedd038c 100644 --- a/packages/docusaurus/src/commands/build/buildLocale.ts +++ b/packages/docusaurus/src/commands/build/buildLocale.ts @@ -19,15 +19,15 @@ import { executePluginsConfigureWebpack, } from '../../webpack/configure'; import {executeSSG} from '../../ssg/ssgExecutor'; +import clearPath from '../utils/clearPath'; +import {isAutomaticBaseUrlLocalizationDisabled} from './buildUtils'; +import type {BuildCLIOptions} from './build'; +import type {SiteCollectedData} from '../../common'; import type { ConfigureWebpackUtils, LoadedPlugin, Props, } from '@docusaurus/types'; -import type {SiteCollectedData} from '../../common'; -import {BuildCLIOptions} from './build'; -import clearPath from '../utils/clearPath'; -import {isAutomaticBaseUrlLocalizationDisabled} from './buildUtils'; export type BuildLocaleParams = { siteDir: string; diff --git a/packages/docusaurus/src/commands/build/buildUtils.ts b/packages/docusaurus/src/commands/build/buildUtils.ts index 4421c2646d89..fcbcfebf7267 100644 --- a/packages/docusaurus/src/commands/build/buildUtils.ts +++ b/packages/docusaurus/src/commands/build/buildUtils.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {BuildCLIOptions} from './build'; +import type {BuildCLIOptions} from './build'; /** * We disable locale path localization if CLI has a single "--locale" option diff --git a/packages/docusaurus/src/commands/deploy.ts b/packages/docusaurus/src/commands/deploy.ts index 2891ca9bd423..22f40c915c68 100644 --- a/packages/docusaurus/src/commands/deploy.ts +++ b/packages/docusaurus/src/commands/deploy.ts @@ -288,7 +288,7 @@ You can also set the deploymentBranch property in docusaurus.config.js .`); ); } else if (commitResults.exitCode === 0) { // The commit might return a non-zero value when site is up to date. - let websiteURL = ''; + let websiteURL; if (githubHost === 'github.com') { websiteURL = projectName.includes('.github.io') ? `https://${organizationName}.github.io/` @@ -297,12 +297,8 @@ You can also set the deploymentBranch property in docusaurus.config.js .`); // GitHub enterprise hosting. websiteURL = `https://${githubHost}/pages/${organizationName}/${projectName}/`; } - try { - exec(`echo "Website is live at ${websiteURL}."`, {failfast: true}); - process.exit(0); - } catch (err) { - throw new Error(`Failed to execute command: ${err}`); - } + exec(`echo "Website is live at ${websiteURL}."`, {failfast: true}); + process.exit(0); } }; diff --git a/packages/docusaurus/src/commands/serve.ts b/packages/docusaurus/src/commands/serve.ts index 23d8694aa9dc..72276268fa80 100644 --- a/packages/docusaurus/src/commands/serve.ts +++ b/packages/docusaurus/src/commands/serve.ts @@ -76,7 +76,7 @@ export async function serve( if (baseUrl !== '/') { // Not super robust, but should be good enough for our use case // See https://github.com/facebook/docusaurus/pull/10090 - const looksLikeAsset = !!req.url.match(/\.[a-zA-Z\d]{1,4}$/); + const looksLikeAsset = !!req.url.match(/\.[a-z\d]{1,4}$/i); if (!looksLikeAsset) { const normalizedUrl = applyTrailingSlash(req.url, { trailingSlash, diff --git a/packages/docusaurus/src/commands/start/webpack.ts b/packages/docusaurus/src/commands/start/webpack.ts index 722198d84ba4..1dfd8f90250d 100644 --- a/packages/docusaurus/src/commands/start/webpack.ts +++ b/packages/docusaurus/src/commands/start/webpack.ts @@ -9,6 +9,7 @@ import path from 'path'; import merge from 'webpack-merge'; import {formatStatsErrorMessage, printStatsWarnings} from '@docusaurus/bundler'; import logger from '@docusaurus/logger'; +// eslint-disable-next-line import/default import WebpackDevServer from 'webpack-dev-server'; import evalSourceMapMiddleware from '../utils/legacy/evalSourceMapMiddleware'; import {createPollingOptions} from './watcher'; diff --git a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts index 5a65ad14d5d8..5b2bd3a96656 100644 --- a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts +++ b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts @@ -65,13 +65,13 @@ class MockExitError extends Error { function createExitMock() { let mock: MockInstance<(code?: number) => never>; - /* eslint-disable-next-line @vitest/require-top-level-describe */ + /* eslint-disable-next-line vitest/require-top-level-describe */ beforeEach(async () => { mock = vi.spyOn(process, 'exit').mockImplementation((code) => { - throw new MockExitError(code!); + throw new MockExitError(code as number); }) as MockInstance<(code?: number) => never>; }); - /* eslint-disable-next-line @vitest/require-top-level-describe */ + /* eslint-disable-next-line vitest/require-top-level-describe */ afterEach(async () => { mock.mockRestore(); }); diff --git a/packages/docusaurus/src/server/codegen/codegenRoutes.ts b/packages/docusaurus/src/server/codegen/codegenRoutes.ts index db494a67224f..0ff14a413686 100644 --- a/packages/docusaurus/src/server/codegen/codegenRoutes.ts +++ b/packages/docusaurus/src/server/codegen/codegenRoutes.ts @@ -131,7 +131,6 @@ ${indent(parts.join(',\n'))} const isModule = (value: unknown): value is Module => typeof value === 'string' || (typeof value === 'object' && - // eslint-disable-next-line no-underscore-dangle !!(value as {[key: string]: unknown} | null)?.__import); /** diff --git a/packages/docusaurus/src/server/i18n.ts b/packages/docusaurus/src/server/i18n.ts index c048e3e8c94d..81cd3728e8aa 100644 --- a/packages/docusaurus/src/server/i18n.ts +++ b/packages/docusaurus/src/server/i18n.ts @@ -24,7 +24,7 @@ function inferLanguageDisplayName(locale: string) { type: 'language', fallback: 'code', }).of(l)!; - } catch (e) { + } catch { // This is to compensate "of()" that is a bit strict // Looks like starting Node 22, this locale throws: "en-US-u-ca-buddhist" // RangeError: invalid_argument diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/docusaurus.config.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/docusaurus.config.js index a5c414a7ef7e..3556bc0a0ac8 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/docusaurus.config.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/docusaurus.config.js @@ -12,16 +12,16 @@ module.exports = { baseUrl: '/', favicon: 'img/favicon.ico', plugins: [ - function (context, options) { + function (_context, _options) { return {name: 'first-plugin'}; }, [ - function (context, options) { + function (_context, _options) { return {name: 'second-plugin'}; }, {it: 'should work'}, ], - function (context, options) { + function (_context, _options) { // it's ok for a plugin to self-disable return null; }, diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js index 4e49b55a8235..a285e874ae26 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js @@ -1,9 +1,9 @@ -module.exports = function (context, options) { +module.exports = function (_context, _options) { return { name: 'third-plugin', }; }; -module.exports.validateThemeConfig = function ({validate, themeConfig}) { +module.exports.validateThemeConfig = function (_params) { return {a: 1}; }; diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin4.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin4.js index 8417ead8257b..f75e92a1a5ca 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin4.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin4.js @@ -1,4 +1,4 @@ -module.exports = function (context, options) { +module.exports = function (_context, _options) { return { name: 'fourth-plugin', }; diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/pluginEsm.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/pluginEsm.js index 992e09998877..b04824f8c549 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/pluginEsm.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/pluginEsm.js @@ -1,6 +1,6 @@ import {Joi} from '@docusaurus/utils-validation'; -export default function (context, options) { +export default function (_context, _options) { return { name: 'plugin-esm', }; diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-undefined-plugin/docusaurus.config.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-undefined-plugin/docusaurus.config.js index 7136240d8bde..e5f99ac2b407 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-undefined-plugin/docusaurus.config.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-undefined-plugin/docusaurus.config.js @@ -12,7 +12,7 @@ module.exports = { baseUrl: '/', favicon: 'img/favicon.ico', plugins: [ - function (context, options) { + function (_context, _options) { return undefined; }, ], diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-unnamed-plugin/docusaurus.config.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-unnamed-plugin/docusaurus.config.js index 98da91910299..2d827adb6d7a 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-unnamed-plugin/docusaurus.config.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-unnamed-plugin/docusaurus.config.js @@ -12,7 +12,7 @@ module.exports = { baseUrl: '/', favicon: 'img/favicon.ico', plugins: [ - function (context, options) { + function (_context, _options) { return {noname: 'on-purpose'}; }, ], diff --git a/packages/docusaurus/src/server/siteMetadata.ts b/packages/docusaurus/src/server/siteMetadata.ts index 3c52df408725..18c96da3be52 100644 --- a/packages/docusaurus/src/server/siteMetadata.ts +++ b/packages/docusaurus/src/server/siteMetadata.ts @@ -18,7 +18,7 @@ async function loadPackageJsonVersion( packageJsonPath: string, ): Promise { if (await fs.pathExists(packageJsonPath)) { - // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require + // eslint-disable-next-line @typescript-eslint/no-require-imports return (require(packageJsonPath) as {version?: string}).version; } return undefined; @@ -27,7 +27,7 @@ async function loadPackageJsonVersion( async function loadPackageJsonName( packageJsonPath: string, ): Promise { - // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require + // eslint-disable-next-line @typescript-eslint/no-require-imports return (require(packageJsonPath) as {name?: string}).name; } diff --git a/packages/docusaurus/src/ssg/ssgWorkerThread.ts b/packages/docusaurus/src/ssg/ssgWorkerThread.ts index 91b0aa08d1f6..3f9299a30f29 100644 --- a/packages/docusaurus/src/ssg/ssgWorkerThread.ts +++ b/packages/docusaurus/src/ssg/ssgWorkerThread.ts @@ -10,7 +10,6 @@ import logger, {PerfLogger} from '@docusaurus/logger'; import {loadSSGRenderer, type SSGResult} from './ssgRenderer.js'; import type {SSGParams} from './ssgParams.js'; -// eslint-disable-next-line no-underscore-dangle const workerId = process?.__tinypool_state__?.workerId; if (!workerId) { throw new Error('SSG Worker Thread not executing in Tinypool context?'); diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 11fdd26017e4..d1cd1b3b839e 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -27,8 +27,7 @@ "tslib": "^2.6.0" }, "devDependencies": { - "@typescript-eslint/rule-tester": "^8.59.3", - "eslint-plugin-eslint-plugin": "^6.5.0" + "@typescript-eslint/rule-tester": "^8.59.3" }, "peerDependencies": { "eslint": ">=8.57.0" diff --git a/packages/eslint-plugin/src/rules/no-html-links.ts b/packages/eslint-plugin/src/rules/no-html-links.ts index 0738bb42cfe4..157b49b5f40c 100644 --- a/packages/eslint-plugin/src/rules/no-html-links.ts +++ b/packages/eslint-plugin/src/rules/no-html-links.ts @@ -25,7 +25,7 @@ function isFullyResolvedUrl(urlString: string): boolean { if (url.protocol) { return true; } - } catch (e) {} + } catch {} return false; } @@ -42,12 +42,15 @@ export default createRule({ type: 'object', properties: { ignoreFullyResolved: { + description: + 'Set to true will not report any tags with absolute URLs including a protocol.', type: 'boolean', }, }, additionalProperties: false, }, ], + defaultOptions: [{ignoreFullyResolved: false}], messages: { link: `Do not use an \`\` element to navigate. Use the \`\` component from \`@docusaurus/Link\` instead. See: ${docsUrl}`, }, diff --git a/packages/eslint-plugin/src/rules/no-untranslated-text.ts b/packages/eslint-plugin/src/rules/no-untranslated-text.ts index d20dee892061..6286af226ec3 100644 --- a/packages/eslint-plugin/src/rules/no-untranslated-text.ts +++ b/packages/eslint-plugin/src/rules/no-untranslated-text.ts @@ -24,6 +24,7 @@ export default createRule({ 'enforce text labels in JSX to be wrapped by translate calls', recommended: false, }, + schema: [ { type: 'object', @@ -33,11 +34,18 @@ export default createRule({ items: { type: 'string', }, + description: + 'Text labels that only contain strings in this list will not be reported.', }, }, additionalProperties: false, }, ], + defaultOptions: [ + { + ignoredStrings: [], + }, + ], messages: { translateChildren: 'All text labels in JSX should be wrapped by translate calls', diff --git a/packages/lqip-loader/src/index.ts b/packages/lqip-loader/src/index.ts index 66d828fffb80..ede3ad0d5f5e 100644 --- a/packages/lqip-loader/src/index.ts +++ b/packages/lqip-loader/src/index.ts @@ -27,7 +27,7 @@ export default async function lqipLoader( content, ); - let source = ''; + let source: string; if (contentIsUrlExport) { source = content.match( @@ -35,7 +35,7 @@ export default async function lqipLoader( )!.groups!.source!; } else { if (!contentIsFileExport) { - // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires + // eslint-disable-next-line @typescript-eslint/no-require-imports const fileLoader = require('file-loader') as LoaderModule['default']; // @ts-expect-error: type is a bit unwieldy... content = fileLoader!.call(this, contentBuffer) as string; diff --git a/packages/lqip-loader/src/lqip.ts b/packages/lqip-loader/src/lqip.ts index 929e53ba6a9e..2bfa03ff2fe3 100644 --- a/packages/lqip-loader/src/lqip.ts +++ b/packages/lqip-loader/src/lqip.ts @@ -9,7 +9,7 @@ import path from 'path'; import logger from '@docusaurus/logger'; import sharp from 'sharp'; -// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require +// eslint-disable-next-line @typescript-eslint/no-require-imports const {version} = require('../package.json') as {version: string}; const ERROR_EXT = `Error: Input file is missing or uses unsupported image format, lqip v${version}`; diff --git a/packages/stylelint-copyright/src/__tests__/index.test.ts b/packages/stylelint-copyright/src/__tests__/index.test.ts index e0daa8122a7b..e785ef0aca64 100644 --- a/packages/stylelint-copyright/src/__tests__/index.test.ts +++ b/packages/stylelint-copyright/src/__tests__/index.test.ts @@ -27,7 +27,6 @@ type TestCase = { }; 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); } @@ -71,15 +70,15 @@ function testStylelintRule(config: stylelint.Config, tests: TestSuite) { expect(warnings.length).toBeGreaterThanOrEqual(1); expect(testCase.message).not.toBeNull(); if (testCase.message != null) { - // eslint-disable-next-line @vitest/no-conditional-expect + // eslint-disable-next-line vitest/no-conditional-expect expect(warning.text).toBe(testCase.message); } if (testCase.line != null) { - // eslint-disable-next-line @vitest/no-conditional-expect + // eslint-disable-next-line vitest/no-conditional-expect expect(warning.line).toBe(testCase.line); } if (testCase.column != null) { - // eslint-disable-next-line @vitest/no-conditional-expect + // eslint-disable-next-line vitest/no-conditional-expect expect(warning.column).toBe(testCase.column); } if (!tests.fix) { diff --git a/project-words.txt b/project-words.txt index 10e4269bd81d..7b303b9f7d49 100644 --- a/project-words.txt +++ b/project-words.txt @@ -179,6 +179,7 @@ microdata Milnes Mindmap mindmap +mkdirs mkdn mkdocs mkdown @@ -225,6 +226,7 @@ Paraiso paraiso pathinfo paularmstrong +pcss perfetto pftrace philpl @@ -308,6 +310,7 @@ stackoverflow Stormkit Strikethrough strikethroughs +styl Subdeps sublabel sublicensable diff --git a/test/snapshotPathNormalizer.ts b/test/snapshotPathNormalizer.ts index 0b31cd0ea15d..55e550db03d3 100644 --- a/test/snapshotPathNormalizer.ts +++ b/test/snapshotPathNormalizer.ts @@ -43,7 +43,7 @@ function readPathsForNormalization() { try { // eslint-disable-next-line no-restricted-properties return fs.realpathSync(pathname); - } catch (err) { + } catch { return pathname; } } @@ -122,7 +122,7 @@ function normalizeString(value: string): string { (val) => val.split(escapePath(cwd)).join(''), // Remove win32 drive letters, C:\ -> \ - (val) => val.replace(/[a-zA-Z]:\\/g, '\\'), + (val) => val.replace(/[a-z]:\\/gi, '\\'), // Remove duplicate backslashes created from escapePath (val) => val.replace(/\\\\/g, '\\'), diff --git a/tsconfig.base.json b/tsconfig.base.json index 43b39e34593a..7a004aa4ffa7 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -58,7 +58,7 @@ "allowJs": true, "skipLibCheck": true // @types/webpack and webpack/types.d.ts are not the same thing }, - "include": ["./**/*", "./**/.eslintrc.js"], + "include": ["./**/*", "./**/eslint.config.*"], "exclude": [ "node_modules", "coverage/**", diff --git a/website/_dogfooding/_pages tests/crashTest.tsx b/website/_dogfooding/_pages tests/crashTest.tsx index 43904c9411c9..9408d4ced540 100644 --- a/website/_dogfooding/_pages tests/crashTest.tsx +++ b/website/_dogfooding/_pages tests/crashTest.tsx @@ -26,7 +26,7 @@ function boomParent() { try { return boomRoot(); } catch (err) { - throw new Error('Boom parent', {cause: err as Error}); + throw new Error('Boom parent', {cause: err}); } } diff --git a/website/_dogfooding/_pages tests/history-tests.tsx b/website/_dogfooding/_pages tests/history-tests.tsx index 77e8a56a8096..7cb8ebfd7248 100644 --- a/website/_dogfooding/_pages tests/history-tests.tsx +++ b/website/_dogfooding/_pages tests/history-tests.tsx @@ -14,7 +14,6 @@ function BlockNavigation() { const history = useHistory(); useEffect(() => { return history.block(() => { - // eslint-disable-next-line no-alert alert('navigation blocked successfully'); return false; }); diff --git a/website/_dogfooding/_pages tests/style-isolation/index.tsx b/website/_dogfooding/_pages tests/style-isolation/index.tsx index 96ac21117114..a5571c54fac0 100644 --- a/website/_dogfooding/_pages tests/style-isolation/index.tsx +++ b/website/_dogfooding/_pages tests/style-isolation/index.tsx @@ -85,7 +85,6 @@ function ExamplesTable() { - {/* eslint-disable-next-line */} @@ -133,7 +132,6 @@ function ExamplesTable() { - {/* eslint-disable-next-line */} diff --git a/website/blog/2022/08-01-announcing-docusaurus-2.0/ShowcaseCarousel.tsx b/website/blog/2022/08-01-announcing-docusaurus-2.0/ShowcaseCarousel.tsx index 8a43e7b97223..a36f1ba4eb58 100644 --- a/website/blog/2022/08-01-announcing-docusaurus-2.0/ShowcaseCarousel.tsx +++ b/website/blog/2022/08-01-announcing-docusaurus-2.0/ShowcaseCarousel.tsx @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -/* eslint-disable global-require */ - import React, {type ComponentProps, type ReactNode, useRef} from 'react'; import clsx from 'clsx'; diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 6568c81b3c75..82a7ba2e23d0 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ import path from 'path'; +// eslint-disable-next-line import/default import npm2yarn from '@docusaurus/remark-plugin-npm2yarn'; import remarkMath from 'remark-math'; import rehypeKatex from 'rehype-katex'; @@ -674,7 +675,6 @@ export default async function createConfigAsync() { // TODO Docusaurus v4: remove after we drop DocSearch v3 // temporary, for DocSearch v3/v4 conditional Ask AI integration // see https://github.com/facebook/docusaurus/pull/11327 - // eslint-disable-next-line @typescript-eslint/no-var-requires,global-require ...(require('@docsearch/react').version.startsWith('4.') ? { askAi: { diff --git a/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx b/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx index f0b9dc340e36..a23c2362ae9d 100644 --- a/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx +++ b/website/src/components/NavbarItems/CustomDogfoodNavbarItem.tsx @@ -22,7 +22,6 @@ export default function CustomDogfoodNavbarItem(props: { return (