diff --git a/.cspell.json b/.cspell.json index b8e07af48645..fc8261d05b0a 100644 --- a/.cspell.json +++ b/.cspell.json @@ -6,6 +6,7 @@ ".github/workflows/**", ".vscode/*.json", "**/*.{json,snap}", + "**/eslint.config.js", "**/**/CHANGELOG.md", "**/**/CONTRIBUTORS.md", "**/**/TSLINT_RULE_ALTERNATIVES.md", diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 1e5cc6e0083b..000000000000 --- a/.eslintignore +++ /dev/null @@ -1,18 +0,0 @@ -node_modules -dist -jest.config.js -fixtures -coverage -__snapshots__ -.docusaurus -build - -packages/eslint-plugin-tslint/tests - -packages/website/**/*.js -packages/website/**/*.d.ts -packages/website-eslint/**/*.js -packages/website-eslint/**/*.d.ts - -# Files copied as part of the build -packages/types/src/generated/**/*.ts diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index ee9dba8c4d05..000000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,380 +0,0 @@ -module.exports = { - root: true, - plugins: [ - '@typescript-eslint', - '@typescript-eslint/internal', - 'deprecation', - 'eslint-comments', - 'eslint-plugin', - 'import', - 'jest', - 'simple-import-sort', - 'unicorn', - ], - env: { - es6: true, - node: true, - }, - extends: [ - 'eslint:recommended', - 'plugin:eslint-plugin/recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], - parserOptions: { - sourceType: 'module', - project: [ - './tsconfig.eslint.json', - './packages/*/tsconfig.json', - './tests/integration/tsconfig.json', - /** - * We are currently in the process of transitioning to nx's out of the box structure and - * so need to manually specify converted packages' tsconfig.build.json and tsconfig.spec.json - * files here for now in addition to the tsconfig.json glob pattern. - * - * TODO(#4665): Clean this up once all packages have been transitioned. - */ - './packages/scope-manager/tsconfig.build.json', - './packages/scope-manager/tsconfig.spec.json', - ], - allowAutomaticSingleRunInference: true, - tsconfigRootDir: __dirname, - warnOnUnsupportedTypeScriptVersion: false, - EXPERIMENTAL_useSourceOfProjectReferenceRedirect: false, - cacheLifetime: { - // we pretty well never create/change tsconfig structure - so need to ever evict the cache - // in the rare case that we do - just need to manually restart their IDE. - glob: 'Infinity', - }, - }, - rules: { - // make sure we're not leveraging any deprecated APIs - 'deprecation/deprecation': 'error', - - // - // our plugin :D - // - - '@typescript-eslint/ban-ts-comment': [ - 'error', - { - 'ts-expect-error': 'allow-with-description', - 'ts-ignore': true, - 'ts-nocheck': true, - 'ts-check': false, - minimumDescriptionLength: 5, - }, - ], - '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], - '@typescript-eslint/consistent-type-imports': [ - 'error', - { prefer: 'type-imports', disallowTypeAnnotations: true }, - ], - '@typescript-eslint/explicit-function-return-type': 'error', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-empty-function': [ - 'error', - { allow: ['arrowFunctions'] }, - ], - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/prefer-for-of': 'error', - '@typescript-eslint/prefer-nullish-coalescing': 'error', - '@typescript-eslint/prefer-optional-chain': 'error', - '@typescript-eslint/unbound-method': 'off', - '@typescript-eslint/prefer-as-const': 'error', - '@typescript-eslint/restrict-template-expressions': [ - 'error', - { - allowNumber: true, - allowBoolean: true, - allowAny: true, - allowNullish: true, - allowRegExp: true, - }, - ], - '@typescript-eslint/no-unused-vars': [ - 'warn', - { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }, - ], - - // - // Internal repo rules - // - - '@typescript-eslint/internal/no-poorly-typed-ts-props': 'error', - '@typescript-eslint/internal/no-typescript-default-import': 'error', - '@typescript-eslint/internal/prefer-ast-types-enum': 'error', - - // - // eslint-base - // - - curly: ['error', 'all'], - eqeqeq: [ - 'error', - 'always', - { - null: 'never', - }, - ], - 'no-mixed-operators': 'error', - 'no-console': 'error', - 'no-process-exit': 'error', - 'no-fallthrough': [ - 'warn', - { commentPattern: '.*intentional fallthrough.*' }, - ], - - // - // eslint-plugin-eslint-comment - // - - // require a eslint-enable comment for every eslint-disable comment - 'eslint-comments/disable-enable-pair': [ - 'error', - { - allowWholeFile: true, - }, - ], - // disallow a eslint-enable comment for multiple eslint-disable comments - 'eslint-comments/no-aggregating-enable': 'error', - // disallow duplicate eslint-disable comments - 'eslint-comments/no-duplicate-disable': 'error', - // disallow eslint-disable comments without rule names - 'eslint-comments/no-unlimited-disable': 'error', - // disallow unused eslint-disable comments - 'eslint-comments/no-unused-disable': 'error', - // disallow unused eslint-enable comments - 'eslint-comments/no-unused-enable': 'error', - // disallow ESLint directive-comments - 'eslint-comments/no-use': [ - 'error', - { - allow: [ - 'eslint-disable', - 'eslint-disable-line', - 'eslint-disable-next-line', - 'eslint-enable', - ], - }, - ], - - // - // eslint-plugin-import - // - - // disallow non-import statements appearing before import statements - 'import/first': 'error', - // Require a newline after the last import/require in a group - 'import/newline-after-import': 'error', - // Forbid import of modules using absolute paths - 'import/no-absolute-path': 'error', - // disallow AMD require/define - 'import/no-amd': 'error', - // forbid default exports - we want to standardize on named exports so that imported names are consistent - 'import/no-default-export': 'error', - // disallow imports from duplicate paths - 'import/no-duplicates': 'error', - // Forbid the use of extraneous packages - 'import/no-extraneous-dependencies': [ - 'error', - { - devDependencies: true, - peerDependencies: true, - optionalDependencies: false, - }, - ], - // Forbid mutable exports - 'import/no-mutable-exports': 'error', - // Prevent importing the default as if it were named - 'import/no-named-default': 'error', - // Prohibit named exports - 'import/no-named-export': 'off', // we want everything to be a named export - // Forbid a module from importing itself - 'import/no-self-import': 'error', - // Require modules with a single export to use a default export - 'import/prefer-default-export': 'off', // we want everything to be named - - // enforce a sort order across the codebase - 'simple-import-sort/imports': 'error', - - 'one-var': ['error', 'never'], - - 'unicorn/no-typeof-undefined': 'error', - }, - overrides: [ - // all test files - { - files: [ - './packages/*/tests/**/*.spec.ts', - './packages/*/tests/**/*.test.ts', - './packages/*/tests/**/spec.ts', - './packages/*/tests/**/test.ts', - './packages/parser/tests/**/*.ts', - './tests/integration/**/*.test.ts', - './tests/integration/integration-test-base.ts', - './tests/integration/pack-packages.ts', - ], - env: { - 'jest/globals': true, - }, - rules: { - '@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', - 'eslint-plugin/consistent-output': 'off', // Might eventually be removed from `eslint-plugin/recommended`: https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/issues/284 - 'jest/no-disabled-tests': 'warn', - 'jest/no-focused-tests': 'error', - 'jest/no-alias-methods': 'error', - 'jest/no-identical-title': 'error', - 'jest/no-jasmine-globals': 'error', - 'jest/no-test-prefixes': 'error', - 'jest/no-done-callback': 'error', - 'jest/no-test-return-statement': 'error', - 'jest/prefer-to-be': 'warn', - 'jest/prefer-to-contain': 'warn', - 'jest/prefer-to-have-length': 'warn', - 'jest/prefer-spy-on': 'error', - 'jest/valid-expect': 'error', - 'jest/no-deprecated-functions': 'error', - }, - }, - // test utility scripts and website js files - { - files: ['tests/**/*.js'], - rules: { - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/restrict-plus-operands': 'off', - }, - }, - // plugin source files - { - files: [ - './packages/eslint-plugin-internal/**/*.ts', - './packages/eslint-plugin-tslint/**/*.ts', - './packages/eslint-plugin/**/*.ts', - ], - rules: { - '@typescript-eslint/internal/no-typescript-estree-import': 'error', - }, - }, - // plugin rule source files - { - files: [ - './packages/eslint-plugin-internal/src/rules/**/*.ts', - './packages/eslint-plugin-tslint/src/rules/**/*.ts', - './packages/eslint-plugin/src/configs/**/*.ts', - './packages/eslint-plugin/src/rules/**/*.ts', - ], - rules: { - 'eslint-plugin/require-meta-docs-description': [ - 'error', - { pattern: '^(Enforce|Require|Disallow) .+[^. ]$' }, - ], - - // specifically for rules - default exports makes the tooling easier - 'import/no-default-export': 'off', - - 'no-restricted-syntax': [ - 'error', - { - selector: - 'ExportDefaultDeclaration Property[key.name="create"] MemberExpression[object.name="context"][property.name="options"]', - message: - "Retrieve options from create's second parameter so that defaultOptions are applied.", - }, - ], - }, - }, - // plugin rule tests - { - files: [ - './packages/eslint-plugin-internal/tests/rules/**/*.test.ts', - './packages/eslint-plugin-tslint/tests/rules/**/*.test.ts', - './packages/eslint-plugin/tests/rules/**/*.test.ts', - './packages/eslint-plugin/tests/eslint-rules/**/*.test.ts', - ], - rules: { - '@typescript-eslint/internal/plugin-test-formatting': 'error', - }, - }, - // files which list all the things - { - files: ['./packages/eslint-plugin/src/rules/index.ts'], - rules: { - // enforce alphabetical ordering - 'sort-keys': 'error', - 'import/order': ['error', { alphabetize: { order: 'asc' } }], - }, - }, - // tools and tests - { - files: ['**/tools/**/*.ts', '**/tests/**/*.ts'], - rules: { - // allow console logs in tools and tests - 'no-console': 'off', - }, - }, - // generated files - { - files: [ - './packages/scope-manager/src/lib/*.ts', - './packages/eslint-plugin/src/configs/*.ts', - ], - rules: { - '@typescript-eslint/internal/no-poorly-typed-ts-props': 'off', - '@typescript-eslint/internal/no-typescript-default-import': 'off', - '@typescript-eslint/internal/prefer-ast-types-enum': 'off', - }, - }, - // ast spec specific standardization - { - files: ['./packages/ast-spec/src/**/*.ts'], - rules: { - // disallow ALL unused vars - '@typescript-eslint/no-unused-vars': 'error', - '@typescript-eslint/sort-type-constituents': 'error', - }, - }, - { - files: ['rollup.config.ts'], - rules: { - 'import/no-default-export': 'off', - }, - }, - { - files: ['./packages/website/'], - extends: [ - 'plugin:jsx-a11y/recommended', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - ], - plugins: ['jsx-a11y', 'react', 'react-hooks'], - rules: { - 'react/jsx-no-target-blank': 'off', - 'react/no-unescaped-entities': 'off', - '@typescript-eslint/internal/prefer-ast-types-enum': 'off', - 'react-hooks/exhaustive-deps': 'off', // TODO: enable it later - }, - settings: { - react: { - version: 'detect', - }, - }, - }, - { - files: ['./packages/website/src/**/*.{ts,tsx}'], - rules: { - 'import/no-default-export': 'off', - // allow console logs in the website to help with debugging things in production - 'no-console': 'off', - }, - }, - ], -}; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000000..47fc531712b4 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,421 @@ +// const typescriptESLint = require('@typescript-eslint/eslint-plugin'); +const typeScriptESLintInternal = require('@typescript-eslint/eslint-plugin-internal'); +const deprecation = require('eslint-plugin-deprecation'); +const eslintComments = require('eslint-plugin-eslint-comments'); +// const eslintPlugin = require('eslint-plugin-eslint-plugin'); +const importPlugin = require('eslint-plugin-import'); +const jest = require('eslint-plugin-jest'); +const simpleImportSort = require('eslint-plugin-simple-import-sort'); +const unicorn = require('eslint-plugin-unicorn'); +const globals = require('globals'); +const { FlatCompat } = require('@eslint/eslintrc'); +const js = require('@eslint/js'); + +const eslintrc = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, +}); + +module.exports = [ + { + ignores: [ + '**/node_modules', + '**/dist', + '**/jest.config.js', + '**/fixtures', + '**/coverage', + '**/__snapshots__', + '**/.docusaurus', + '**/build', + + 'packages/eslint-plugin-tslint/tests', + + 'packages/website/**/*.js', + 'packages/website/**/*.d.ts', + 'packages/website-eslint/**/*.js', + 'packages/website-eslint/**/*.d.ts', + + // Files copied as part of the build + 'packages/types/src/generated/**/*.ts', + ], + }, + js.configs.recommended, + ...eslintrc.extends( + 'plugin:eslint-plugin/recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + ), + { + plugins: { + // '@typescript-eslint': typescriptESLint, + '@typescript-eslint/internal': typeScriptESLintInternal, + deprecation, + 'eslint-comments': eslintComments, + // 'eslint-plugin': eslintPlugin, + import: importPlugin, + jest, + 'simple-import-sort': simpleImportSort, + unicorn, + }, + languageOptions: { + sourceType: 'module', + globals: { + ...globals.node, + }, + parserOptions: { + project: [ + './tsconfig.eslint.json', + './packages/*/tsconfig.json', + './tests/integration/tsconfig.json', + /** + * We are currently in the process of transitioning to nx's out of the box structure and + * so need to manually specify converted packages' tsconfig.build.json and tsconfig.spec.json + * files here for now in addition to the tsconfig.json glob pattern. + * + * TODO(#4665): Clean this up once all packages have been transitioned. + */ + './packages/scope-manager/tsconfig.build.json', + './packages/scope-manager/tsconfig.spec.json', + ], + allowAutomaticSingleRunInference: true, + tsconfigRootDir: __dirname, + warnOnUnsupportedTypeScriptVersion: false, + EXPERIMENTAL_useSourceOfProjectReferenceRedirect: false, + cacheLifetime: { + // we pretty well never create/change tsconfig structure - so need to ever evict the cache + // in the rare case that we do - just need to manually restart their IDE. + glob: 'Infinity', + }, + }, + }, + rules: { + // make sure we're not leveraging any deprecated APIs + 'deprecation/deprecation': 'error', + + // + // our plugin :D + // + + '@typescript-eslint/ban-ts-comment': [ + 'error', + { + 'ts-expect-error': 'allow-with-description', + 'ts-ignore': true, + 'ts-nocheck': true, + 'ts-check': false, + minimumDescriptionLength: 5, + }, + ], + '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], + '@typescript-eslint/consistent-type-imports': [ + 'error', + { prefer: 'type-imports', disallowTypeAnnotations: true }, + ], + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-empty-function': [ + 'error', + { allow: ['arrowFunctions'] }, + ], + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-nullish-coalescing': 'error', + '@typescript-eslint/prefer-optional-chain': 'error', + '@typescript-eslint/unbound-method': 'off', + '@typescript-eslint/prefer-as-const': 'error', + '@typescript-eslint/restrict-template-expressions': [ + 'error', + { + allowNumber: true, + allowBoolean: true, + allowAny: true, + allowNullish: true, + allowRegExp: true, + }, + ], + '@typescript-eslint/no-unused-vars': [ + 'warn', + { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }, + ], + + // + // Internal repo rules + // + + '@typescript-eslint/internal/no-poorly-typed-ts-props': 'error', + '@typescript-eslint/internal/no-typescript-default-import': 'error', + '@typescript-eslint/internal/prefer-ast-types-enum': 'error', + + // + // eslint-base + // + + curly: ['error', 'all'], + eqeqeq: [ + 'error', + 'always', + { + null: 'never', + }, + ], + 'no-mixed-operators': 'error', + 'no-console': 'error', + 'no-process-exit': 'error', + 'no-fallthrough': [ + 'warn', + { commentPattern: '.*intentional fallthrough.*' }, + ], + + // + // eslint-plugin-eslint-comment + // + + // require a eslint-enable comment for every eslint-disable comment + 'eslint-comments/disable-enable-pair': [ + 'error', + { + allowWholeFile: true, + }, + ], + // disallow a eslint-enable comment for multiple eslint-disable comments + 'eslint-comments/no-aggregating-enable': 'error', + // disallow duplicate eslint-disable comments + 'eslint-comments/no-duplicate-disable': 'error', + // disallow eslint-disable comments without rule names + 'eslint-comments/no-unlimited-disable': 'error', + // disallow unused eslint-disable comments + 'eslint-comments/no-unused-disable': 'error', + // disallow unused eslint-enable comments + 'eslint-comments/no-unused-enable': 'error', + // disallow ESLint directive-comments + 'eslint-comments/no-use': [ + 'error', + { + allow: [ + 'eslint-disable', + 'eslint-disable-line', + 'eslint-disable-next-line', + 'eslint-enable', + ], + }, + ], + + // + // eslint-plugin-import + // + + // disallow non-import statements appearing before import statements + 'import/first': 'error', + // Require a newline after the last import/require in a group + 'import/newline-after-import': 'error', + // Forbid import of modules using absolute paths + 'import/no-absolute-path': 'error', + // disallow AMD require/define + 'import/no-amd': 'error', + // forbid default exports - we want to standardize on named exports so that imported names are consistent + 'import/no-default-export': 'error', + // disallow imports from duplicate paths + 'import/no-duplicates': 'error', + // Forbid the use of extraneous packages + 'import/no-extraneous-dependencies': [ + 'error', + { + devDependencies: true, + peerDependencies: true, + optionalDependencies: false, + }, + ], + // Forbid mutable exports + 'import/no-mutable-exports': 'error', + // Prevent importing the default as if it were named + 'import/no-named-default': 'error', + // Prohibit named exports + 'import/no-named-export': 'off', // we want everything to be a named export + // Forbid a module from importing itself + 'import/no-self-import': 'error', + // Require modules with a single export to use a default export + 'import/prefer-default-export': 'off', // we want everything to be named + + // enforce a sort order across the codebase + 'simple-import-sort/imports': 'error', + + 'one-var': ['error', 'never'], + + 'unicorn/no-typeof-undefined': 'error', + }, + }, + + // all test files + { + files: [ + './packages/*/tests/**/*.spec.ts', + './packages/*/tests/**/*.test.ts', + './packages/*/tests/**/spec.ts', + './packages/*/tests/**/test.ts', + './packages/parser/tests/**/*.ts', + './tests/integration/**/*.test.ts', + './tests/integration/integration-test-base.ts', + './tests/integration/pack-packages.ts', + ], + languageOptions: { + globals: jest.environments.globals.globals, + }, + rules: { + '@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', + 'eslint-plugin/consistent-output': 'off', // Might eventually be removed from `eslint-plugin/recommended`: https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/issues/284 + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + 'jest/no-alias-methods': 'error', + 'jest/no-identical-title': 'error', + 'jest/no-jasmine-globals': 'error', + 'jest/no-test-prefixes': 'error', + 'jest/no-done-callback': 'error', + 'jest/no-test-return-statement': 'error', + 'jest/prefer-to-be': 'warn', + 'jest/prefer-to-contain': 'warn', + 'jest/prefer-to-have-length': 'warn', + 'jest/prefer-spy-on': 'error', + 'jest/valid-expect': 'error', + 'jest/no-deprecated-functions': 'error', + }, + }, + // test utility scripts and website js files + { + files: ['tests/**/*.js'], + rules: { + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/restrict-plus-operands': 'off', + }, + }, + // plugin source files + { + files: [ + './packages/eslint-plugin-internal/**/*.ts', + './packages/eslint-plugin-tslint/**/*.ts', + './packages/eslint-plugin/**/*.ts', + ], + rules: { + '@typescript-eslint/internal/no-typescript-estree-import': 'error', + }, + }, + // plugin rule source files + { + files: [ + './packages/eslint-plugin-internal/src/rules/**/*.ts', + './packages/eslint-plugin-tslint/src/rules/**/*.ts', + './packages/eslint-plugin/src/configs/**/*.ts', + './packages/eslint-plugin/src/rules/**/*.ts', + ], + rules: { + 'eslint-plugin/require-meta-docs-description': [ + 'error', + { pattern: '^(Enforce|Require|Disallow) .+[^. ]$' }, + ], + + // specifically for rules - default exports makes the tooling easier + 'import/no-default-export': 'off', + + 'no-restricted-syntax': [ + 'error', + { + selector: + 'ExportDefaultDeclaration Property[key.name="create"] MemberExpression[object.name="context"][property.name="options"]', + message: + "Retrieve options from create's second parameter so that defaultOptions are applied.", + }, + ], + }, + }, + // plugin rule tests + { + files: [ + './packages/eslint-plugin-internal/tests/rules/**/*.test.ts', + './packages/eslint-plugin-tslint/tests/rules/**/*.test.ts', + './packages/eslint-plugin/tests/rules/**/*.test.ts', + './packages/eslint-plugin/tests/eslint-rules/**/*.test.ts', + ], + rules: { + '@typescript-eslint/internal/plugin-test-formatting': 'error', + }, + }, + // files which list all the things + { + files: ['./packages/eslint-plugin/src/rules/index.ts'], + rules: { + // enforce alphabetical ordering + 'sort-keys': 'error', + 'import/order': ['error', { alphabetize: { order: 'asc' } }], + }, + }, + // tools and tests + { + files: ['**/tools/**/*.ts', '**/tests/**/*.ts'], + rules: { + // allow console logs in tools and tests + 'no-console': 'off', + }, + }, + // generated files + { + files: [ + './packages/scope-manager/src/lib/*.ts', + './packages/eslint-plugin/src/configs/*.ts', + ], + rules: { + '@typescript-eslint/internal/no-poorly-typed-ts-props': 'off', + '@typescript-eslint/internal/no-typescript-default-import': 'off', + '@typescript-eslint/internal/prefer-ast-types-enum': 'off', + }, + }, + // ast spec specific standardization + { + files: ['./packages/ast-spec/src/**/*.ts'], + rules: { + // disallow ALL unused vars + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/sort-type-constituents': 'error', + }, + }, + { + files: ['rollup.config.ts'], + rules: { + 'import/no-default-export': 'off', + }, + }, + { + files: ['./packages/website/'], + extends: [ + 'plugin:jsx-a11y/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + ], + plugins: ['jsx-a11y', 'react', 'react-hooks'], + rules: { + 'react/jsx-no-target-blank': 'off', + 'react/no-unescaped-entities': 'off', + '@typescript-eslint/internal/prefer-ast-types-enum': 'off', + 'react-hooks/exhaustive-deps': 'off', // TODO: enable it later + }, + settings: { + react: { + version: 'detect', + }, + }, + }, + { + files: ['./packages/website/src/**/*.{ts,tsx}'], + rules: { + 'import/no-default-export': 'off', + // allow console logs in the website to help with debugging things in production + 'no-console': 'off', + }, + }, +]; diff --git a/nx.json b/nx.json index 5485f361c5ae..d6c98a4f6849 100644 --- a/nx.json +++ b/nx.json @@ -24,11 +24,7 @@ "outputs": ["{projectRoot}/coverage"] }, "lint": { - "inputs": [ - "default", - "{workspaceRoot}/.eslintrc.js", - "{workspaceRoot}/.eslintignore" - ] + "inputs": ["default", "{workspaceRoot}/eslint.config.js"] } }, "namedInputs": { diff --git a/package.json b/package.json index 3f881e0dc75c..e6fbbf16a973 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,8 @@ "@babel/eslint-parser": "^7.19.1", "@babel/parser": "^7.21.2", "@babel/types": "^7.20.2", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "^8.36.0", "@nx/jest": "16.3.2", "@nx/linter": "16.3.2", "@nx/workspace": "16.3.2", @@ -81,7 +83,7 @@ "cross-fetch": "^3.1.5", "cspell": "^6.0.0", "downlevel-dts": ">=0.11.0", - "eslint": "^8.15.0", + "eslint": "^8.42.0", "eslint-plugin-deprecation": "^1.3.2", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-plugin": "^5.0.1", @@ -91,6 +93,7 @@ "eslint-plugin-unicorn": "^46.0.0", "execa": "5.1.1", "glob": "^8.0.1", + "globals": "^13.20.0", "husky": "^8.0.1", "jest": "29.4.3", "jest-diff": "^29.0.3", diff --git a/packages/ast-spec/project.json b/packages/ast-spec/project.json index c47c9d17693e..a414f8a789d7 100644 --- a/packages/ast-spec/project.json +++ b/packages/ast-spec/project.json @@ -16,7 +16,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/ast-spec/**/*.ts"] + "lintFilePatterns": ["packages/ast-spec/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/eslint-plugin-internal/project.json b/packages/eslint-plugin-internal/project.json index 9bab48c84608..5f022bd701b7 100644 --- a/packages/eslint-plugin-internal/project.json +++ b/packages/eslint-plugin-internal/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/eslint-plugin-internal/**/*.ts"] + "lintFilePatterns": ["packages/eslint-plugin-internal/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/eslint-plugin-tslint/project.json b/packages/eslint-plugin-tslint/project.json index 4aa7c89f3e32..ccca0acc18fe 100644 --- a/packages/eslint-plugin-tslint/project.json +++ b/packages/eslint-plugin-tslint/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/eslint-plugin-tslint/**/*.ts"] + "lintFilePatterns": ["packages/eslint-plugin-tslint/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/eslint-plugin/project.json b/packages/eslint-plugin/project.json index af5479a4cd92..f13ecec59914 100644 --- a/packages/eslint-plugin/project.json +++ b/packages/eslint-plugin/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/eslint-plugin/**/*.ts"] + "lintFilePatterns": ["packages/eslint-plugin/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/experimental-utils/project.json b/packages/experimental-utils/project.json index 161d4ae0ae7f..65515a97e0a7 100644 --- a/packages/experimental-utils/project.json +++ b/packages/experimental-utils/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/experimental-utils/**/*.ts"] + "lintFilePatterns": ["packages/experimental-utils/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/parser/project.json b/packages/parser/project.json index 0d1cbfa5d3de..771bd5e33783 100644 --- a/packages/parser/project.json +++ b/packages/parser/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/parser/**/*.ts"] + "lintFilePatterns": ["packages/parser/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/scope-manager/project.json b/packages/scope-manager/project.json index d1b6277c58b6..21de248d1359 100644 --- a/packages/scope-manager/project.json +++ b/packages/scope-manager/project.json @@ -53,7 +53,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/scope-manager/**/*.ts"] + "lintFilePatterns": ["packages/scope-manager/**/*.ts"], + + "eslintConfig": "eslint.config.js" } }, "test": { diff --git a/packages/type-utils/project.json b/packages/type-utils/project.json index 61009bf861ba..907b32181e96 100644 --- a/packages/type-utils/project.json +++ b/packages/type-utils/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/type-utils/**/*.ts"] + "lintFilePatterns": ["packages/type-utils/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/types/project.json b/packages/types/project.json index f7f93a0c31af..dd5f3b6a6236 100644 --- a/packages/types/project.json +++ b/packages/types/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/types/**/*.ts"] + "lintFilePatterns": ["packages/types/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/typescript-estree/project.json b/packages/typescript-estree/project.json index 70995a648144..e5ce7c07a9fd 100644 --- a/packages/typescript-estree/project.json +++ b/packages/typescript-estree/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/typescript-estree/**/*.ts"] + "lintFilePatterns": ["packages/typescript-estree/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/utils/project.json b/packages/utils/project.json index b754b7029b30..0c565d0348b8 100644 --- a/packages/utils/project.json +++ b/packages/utils/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/utils/**/*.ts"] + "lintFilePatterns": ["packages/utils/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/visitor-keys/project.json b/packages/visitor-keys/project.json index 0be46ea16cd2..818ecd0756cd 100644 --- a/packages/visitor-keys/project.json +++ b/packages/visitor-keys/project.json @@ -8,7 +8,9 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/visitor-keys/**/*.ts"] + "lintFilePatterns": ["packages/visitor-keys/**/*.ts"], + + "eslintConfig": "eslint.config.js" } } } diff --git a/packages/website/.eslintrc.js b/packages/website/.eslintrc.js deleted file mode 100644 index 323ce34a38d7..000000000000 --- a/packages/website/.eslintrc.js +++ /dev/null @@ -1,33 +0,0 @@ -module.exports = { - extends: [ - '../../.eslintrc.js', - 'plugin:jsx-a11y/recommended', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - ], - plugins: ['jsx-a11y', 'react', 'react-hooks'], - overrides: [ - { - files: [ - './*.config.*', - './src/pages/*.tsx', - './src/components/**/*.tsx', - './src/components/hooks/*.ts', - ], - rules: { - 'import/no-default-export': 'off', - }, - }, - ], - rules: { - 'react/jsx-no-target-blank': 'off', - 'react/no-unescaped-entities': 'off', - '@typescript-eslint/internal/prefer-ast-types-enum': 'off', - 'react/jsx-curly-brace-presence': 'error', - }, - settings: { - react: { - version: 'detect', - }, - }, -}; diff --git a/packages/website/eslint.config.js b/packages/website/eslint.config.js new file mode 100644 index 000000000000..60cc93ec8234 --- /dev/null +++ b/packages/website/eslint.config.js @@ -0,0 +1,47 @@ +const baseConfig = require('../../eslint.config.js'); +// const jsxA11y = require('eslint-plugin-jsx-a11y'); +// const react = require('eslint-plugin-react'); +// const reactHooks = require('eslint-plugin-react-hooks'); +const { FlatCompat } = require('@eslint/eslintrc'); + +const eslintrc = new FlatCompat({ + baseDirectory: __dirname, +}); + +module.exports = [ + ...baseConfig, + ...eslintrc.extends( + 'plugin:jsx-a11y/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + ), + { + // plugins: { + // react, + // 'react-hooks': reactHooks, + // 'jsx-a11y': jsxA11y, + // }, + rules: { + 'react/jsx-no-target-blank': 'off', + 'react/no-unescaped-entities': 'off', + '@typescript-eslint/internal/prefer-ast-types-enum': 'off', + 'react/jsx-curly-brace-presence': 'error', + }, + settings: { + react: { + version: 'detect', + }, + }, + }, + { + files: [ + './*.config.*', + './src/pages/*.tsx', + './src/components/**/*.tsx', + './src/components/hooks/*.ts', + ], + rules: { + 'import/no-default-export': 'off', + }, + }, +]; diff --git a/packages/website/project.json b/packages/website/project.json index 75d5246593d1..8d93d3f27cfb 100644 --- a/packages/website/project.json +++ b/packages/website/project.json @@ -8,7 +8,8 @@ "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/website/**/*.ts"] + "lintFilePatterns": ["packages/website/**/*.ts"], + "eslintConfig": "packages/website/eslint.config.js" } } } diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 36b912142b9a..43d746624ff2 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -7,7 +7,7 @@ "extends": "./tsconfig.base.json", "include": [ "tools/**/*.ts", - ".eslintrc.js", + "eslint.config.js", "jest.config.base.js", "jest.config.js", "jest.preset.js" diff --git a/yarn.lock b/yarn.lock index dabaa778923e..b9155a242e5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2582,11 +2582,31 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.2" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + "@eslint/js@8.39.0": version "8.39.0" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng== +"@eslint/js@8.42.0", "@eslint/js@^8.36.0": + version "8.42.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.42.0.tgz#484a1d638de2911e6f5a30c12f49c7e4a3270fb6" + integrity sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw== + "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" @@ -2604,6 +2624,15 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + "@humanwhocodes/config-array@^0.11.8": version "0.11.8" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" @@ -7427,7 +7456,12 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz#c7f0f956124ce677047ddbc192a68f999454dedc" integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== -eslint@*, eslint@^8.15.0: +eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@*: version "8.39.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.39.0.tgz#7fd20a295ef92d43809e914b70c39fd5a23cf3f1" integrity sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og== @@ -7473,6 +7507,51 @@ eslint@*, eslint@^8.15.0: strip-json-comments "^3.1.0" text-table "^0.2.0" +eslint@^8.42.0: + version "8.42.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.42.0.tgz#7bebdc3a55f9ed7167251fe7259f75219cade291" + integrity sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.3" + "@eslint/js" "8.42.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.5.2" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + espree@^9.5.1: version "9.5.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.1.tgz#4f26a4d5f18905bf4f2e0bd99002aab807e96dd4" @@ -7482,6 +7561,15 @@ espree@^9.5.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.0" +espree@^9.5.2: + version "9.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -8377,7 +8465,7 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.19.0: +globals@^13.19.0, globals@^13.20.0: version "13.20.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== @@ -8453,6 +8541,11 @@ grapheme-splitter@^1.0.4: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798"