⬆️(dependency) upgrade eslint to v9

We upgraded ESLint to version 9 in the
eslint-config-impress package.
We rename it to eslint-plugin-docs.
This commit is contained in:
Anthony LC
2025-08-08 14:43:25 +02:00
parent 25783182b8
commit 3688591dd1
24 changed files with 520 additions and 334 deletions

View File

@@ -1,21 +0,0 @@
const common = require('./common');
module.exports = {
root: true,
settings: {
react: {
version: 'detect',
},
},
extends: [
'plugin:prettier/recommended',
'plugin:import/recommended',
'plugin:react/recommended',
],
rules: common.globalRules,
parserOptions: {
sourceType: 'module',
ecmaVersion: 'latest',
},
ignorePatterns: ['node_modules'],
};

View File

@@ -1,76 +0,0 @@
const eslintTS = [
{
files: ['*.ts', '*.tsx'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
'sort-imports': [
'error',
{
ignoreDeclarationSort: true,
},
],
},
},
{
files: ['*.d.ts'],
rules: {
'no-unused-vars': 'off',
},
},
];
const globalRules = {
'block-scoped-var': 'error',
curly: ['error', 'all'],
'import/no-duplicates': ['error', { considerQueryString: false }],
'import/order': [
'error',
{
alphabetize: {
order: 'asc',
},
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
pathGroups: [
{
pattern: '@/**',
group: 'internal',
},
],
pathGroupsExcludedImportTypes: ['builtin'],
'newlines-between': 'always',
warnOnUnassignedImports: true,
},
],
'no-alert': 'error',
'no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
'no-var': 'error',
'react/jsx-curly-brace-presence': [
'error',
{ props: 'never', children: 'never', propElementValues: 'always' },
],
'sort-imports': [
'error',
{
ignoreDeclarationSort: true,
},
],
};
module.exports = { eslintTS, globalRules };

View File

@@ -1,51 +0,0 @@
const common = require('./common');
module.exports = {
extends: ['plugin:prettier/recommended', 'plugin:react/recommended'],
rules: common.globalRules,
settings: {
react: {
version: 'detect',
},
},
overrides: [
...common.eslintTS,
{
files: ['*.spec.*', '*.test.*', '**/__mock__/**/*'],
plugins: ['jest'],
extends: ['plugin:jest/recommended', 'plugin:testing-library/react'],
rules: {
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'testing-library/no-await-sync-events': [
'error',
{ eventModules: ['fire-event'] },
],
'testing-library/await-async-events': [
'error',
{
eventModule: 'userEvent',
},
],
'testing-library/no-manual-cleanup': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
'react/display-name': 0,
'jest/expect-expect': 'error',
'@typescript-eslint/unbound-method': 'off',
'jest/unbound-method': 'error',
'react/react-in-jsx-scope': 'off',
},
},
],
ignorePatterns: ['node_modules'],
};

View File

@@ -1,40 +0,0 @@
const common = require('./common');
module.exports = {
extends: [
'next',
'plugin:prettier/recommended',
'plugin:@tanstack/eslint-plugin-query/recommended',
'plugin:jsx-a11y/recommended',
],
parserOptions: {
babelOptions: {
presets: [require.resolve('next/babel')],
},
},
settings: {
'jsx-a11y': {
polymorphicPropName: 'as',
components: {
Input: 'input',
Button: 'button',
Box: 'div',
Text: 'span',
Select: 'select',
},
},
},
rules: {
...common.globalRules,
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
},
overrides: [
...common.eslintTS,
{
files: ['*.spec.*', '*.test.*', '**/__mock__/**/*'],
extends: ['impress/jest'],
},
],
ignorePatterns: ['node_modules'],
};

View File

@@ -1,36 +0,0 @@
const common = require('./common');
module.exports = {
extends: ['next', 'plugin:prettier/recommended'],
settings: {
react: {
version: 'detect',
},
},
parserOptions: {
babelOptions: {
presets: [require.resolve('next/babel')],
},
},
rules: { ...common.globalRules, '@next/next/no-html-link-for-pages': 'off' },
overrides: [
...common.eslintTS,
{
files: ['**/*.ts'],
rules: {
'@typescript-eslint/no-unsafe-member-access': 'off',
},
},
{
files: ['*.spec.*', '*.test.*', '**/__mock__/**/*'],
extends: ['plugin:playwright/recommended'],
plugins: ['playwright'],
rules: {
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
],
ignorePatterns: ['node_modules'],
};

View File

@@ -0,0 +1,91 @@
const js = require('@eslint/js');
const nextPlugin = require('@next/eslint-plugin-next');
const tanstackQuery = require('@tanstack/eslint-plugin-query');
const { defineConfig } = require('eslint/config');
const importPlugin = require('eslint-plugin-import');
const jsxA11y = require('eslint-plugin-jsx-a11y');
const prettier = require('eslint-plugin-prettier');
const react = require('eslint-plugin-react');
const reactHooks = require('eslint-plugin-react-hooks');
const globalRules = {
'block-scoped-var': 'error',
curly: ['error', 'all'],
'import/no-duplicates': ['error', { considerQueryString: false }],
'import/order': [
'error',
{
alphabetize: {
order: 'asc',
},
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
pathGroups: [
{
pattern: '@/**',
group: 'internal',
},
],
pathGroupsExcludedImportTypes: ['builtin'],
'newlines-between': 'always',
warnOnUnassignedImports: true,
},
],
'no-alert': 'error',
'no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
'no-var': 'error',
'react/jsx-curly-brace-presence': [
'error',
{ props: 'never', children: 'never', propElementValues: 'always' },
],
};
// Base configuration
const baseConfig = defineConfig({
plugins: {
prettier,
import: importPlugin,
react,
'react-hooks': reactHooks,
'jsx-a11y': jsxA11y,
'@next/next': nextPlugin,
'@tanstack/query': tanstackQuery,
js,
},
extends: ['js/recommended'],
settings: {
'jsx-a11y': {
polymorphicPropName: 'as',
components: {
Input: 'input',
Button: 'button',
Box: 'div',
Text: 'span',
Select: 'select',
},
},
},
rules: {
...globalRules,
'no-undef': 'off',
'prettier/prettier': 'error',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
'@tanstack/query/exhaustive-deps': 'error',
'@tanstack/query/no-rest-destructuring': 'warn',
'@tanstack/query/stable-query-client': 'error',
'jsx-a11y/alt-text': 'error',
'jsx-a11y/aria-props': 'error',
'jsx-a11y/aria-proptypes': 'error',
'jsx-a11y/aria-unsupported-elements': 'error',
'jsx-a11y/role-has-required-aria-props': 'error',
'jsx-a11y/role-supports-aria-props': 'error',
},
linterOptions: {
reportUnusedDisableDirectives: 'error',
},
});
module.exports = { baseConfig };

View File

@@ -0,0 +1,23 @@
import { defineConfig } from '@eslint/config-helpers';
import docsPlugin from 'eslint-plugin-docs';
const eslintConfig = defineConfig([
{
files: ['**/*.js', '**/*.mjs'],
plugins: {
docs: docsPlugin,
},
extends: ['docs/base'],
languageOptions: {
parserOptions: {
tsconfigRootDir: import.meta.dirname,
project: ['./tsconfig.json'],
},
},
rules: {
'@next/next/no-html-link-for-pages': 'off',
},
},
]);
export default eslintConfig;

View File

@@ -0,0 +1,20 @@
import { ESLint } from 'eslint';
interface PluginMeta {
name: string;
version: string;
namespace: string;
}
interface PluginConfig {
meta: PluginMeta;
configs: {
base: ESLint.ConfigData[];
next: ESLint.ConfigData[];
test: ESLint.ConfigData[];
playwright: ESLint.ConfigData[];
};
}
declare const plugin: PluginConfig;
export = plugin;

View File

@@ -0,0 +1,28 @@
const { baseConfig } = require('./base');
const pkg = require('./package.json');
const { playwrightConfig } = require('./playwright');
const { testConfig } = require('./test');
const { typescriptConfig, declarationConfig } = require('./typescript');
const plugin = {
meta: {
name: pkg.name,
version: pkg.version,
namespace: 'docs',
},
configs: {},
};
Object.assign(plugin.configs, {
base: [baseConfig],
next: [baseConfig, typescriptConfig, declarationConfig, testConfig],
test: [testConfig],
playwright: [
baseConfig,
typescriptConfig,
declarationConfig,
playwrightConfig,
],
});
module.exports = plugin;

View File

@@ -1,16 +1,24 @@
{
"name": "eslint-config-impress",
"name": "eslint-plugin-docs",
"version": "3.6.0",
"license": "MIT",
"main": "index.js",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin"
],
"scripts": {
"lint": "eslint --ext .js ."
"lint": "eslint"
},
"peerDependencies": {
"eslint": ">=9.0.0"
},
"dependencies": {
"@next/eslint-plugin-next": "15.5.2",
"@tanstack/eslint-plugin-query": "5.83.1",
"@typescript-eslint/eslint-plugin": "*",
"@typescript-eslint/parser": "*",
"eslint": "*",
"eslint-config-next": "15.5.2",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-import": "2.32.0",
@@ -18,7 +26,9 @@
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-playwright": "2.2.2",
"eslint-plugin-prettier": "5.5.4",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-testing-library": "7.6.6",
"eslint-plugin-vitest": "0.5.4",
"prettier": "3.6.2"
}
}

View File

@@ -0,0 +1,37 @@
const typescriptEslint = require('@typescript-eslint/eslint-plugin');
const typescriptParser = require('@typescript-eslint/parser');
const playwright = require('eslint-plugin-playwright');
const playwrightConfig = {
plugins: {
'@typescript-eslint': typescriptEslint,
playwright,
},
languageOptions: {
parser: typescriptParser,
parserOptions: {
project: true,
},
},
files: [
'**/*.spec.ts',
'**/*.test.ts',
'**/__mock__/**/*',
'**/auth.setup.ts',
],
rules: {
...playwright.configs['flat/recommended'].rules,
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'playwright/no-force-option': 'off',
'playwright/no-wait-for-timeout': 'off',
'playwright/no-conditional-in-test': 'off',
'playwright/no-skipped-test': 'off',
'playwright/expect-expect': 'error',
'playwright/no-conditional-expect': 'error',
},
};
module.exports = { playwrightConfig };

View File

@@ -0,0 +1,71 @@
const typescriptEslint = require('@typescript-eslint/eslint-plugin');
const typescriptParser = require('@typescript-eslint/parser');
const jest = require('eslint-plugin-jest');
const testingLibrary = require('eslint-plugin-testing-library');
const vitest = require('eslint-plugin-vitest');
const testConfig = {
files: [
'*.spec.*',
'*.test.*',
'**/__tests__/**/*',
'**/__mock__/**/*',
'**/__mocks__/**/*',
],
languageOptions: {
parser: typescriptParser,
parserOptions: {
project: true,
},
globals: {
describe: 'readonly',
it: 'readonly',
test: 'readonly',
expect: 'readonly',
beforeEach: 'readonly',
afterEach: 'readonly',
beforeAll: 'readonly',
afterAll: 'readonly',
jest: 'readonly',
},
},
plugins: {
'@typescript-eslint': typescriptEslint,
jest,
vitest,
'testing-library': testingLibrary,
},
rules: {
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
'@typescript-eslint/unbound-method': 'off',
'jest/unbound-method': 'error',
'jest/expect-expect': 'error',
'testing-library/no-await-sync-events': [
'error',
{ eventModules: ['fire-event'] },
],
'testing-library/await-async-events': [
'error',
{
eventModule: 'userEvent',
},
],
'testing-library/no-manual-cleanup': 'off',
'react/display-name': 'off',
'react/react-in-jsx-scope': 'off',
},
};
module.exports = { testConfig };

View File

@@ -0,0 +1,44 @@
const typescriptEslint = require('@typescript-eslint/eslint-plugin');
const typescriptParser = require('@typescript-eslint/parser');
// TypeScript declaration files configuration
const declarationConfig = {
files: ['*.d.ts'],
rules: {
'no-unused-vars': 'off',
},
};
// TypeScript configuration
const typescriptConfig = {
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
project: true,
},
},
plugins: {
'@typescript-eslint': typescriptEslint,
},
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
'sort-imports': [
'error',
{
ignoreDeclarationSort: true,
},
],
// Turn off base rule as it can report incorrect errors
'no-unused-vars': 'off',
},
};
module.exports = { declarationConfig, typescriptConfig };

View File

@@ -14,7 +14,7 @@
"dependencies": {
"@types/jest": "30.0.0",
"@types/node": "*",
"eslint-config-impress": "*",
"eslint-plugin-docs": "*",
"eslint-plugin-import": "2.32.0",
"i18next-parser": "9.3.0",
"jest": "30.1.2",