From 40ecd254e1b45b7dc3d10c45c678d2c6a21900f3 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 15 Nov 2023 20:50:01 +1030 Subject: [PATCH] feat: add support for flat configs --- .eslintrc.js | 4 +- .../ISSUE_TEMPLATE/07-enhancement-other.yaml | 1 + .github/renovate.json5 | 5 + .github/workflows/ci.yml | 1 + .github/workflows/semantic-pr-titles.yml | 1 + .vscode/settings.json | 2 + docs/packages/Core.mdx | 12 + eslint.config.js | 494 ++++++++++++++++++ package.json | 10 +- packages/ast-spec/project.json | 3 +- packages/core/LICENSE | 21 + packages/core/README.md | 12 + packages/core/jest.config.js | 8 + packages/core/package.json | 82 +++ packages/core/project.json | 15 + packages/core/src/configs/all.ts | 201 +++++++ packages/core/src/configs/base.ts | 14 + .../core/src/configs/disable-type-checked.ts | 64 +++ .../core/src/configs/eslint-recommended.ts | 36 ++ .../src/configs/recommended-type-checked.ts | 64 +++ packages/core/src/configs/recommended.ts | 43 ++ .../core/src/configs/strict-type-checked.ts | 85 +++ packages/core/src/configs/strict.ts | 53 ++ .../src/configs/stylistic-type-checked.ts | 45 ++ packages/core/src/configs/stylistic.ts | 39 ++ packages/core/src/index.ts | 46 ++ packages/core/tsconfig.build.json | 11 + packages/core/tsconfig.json | 10 + packages/eslint-plugin-internal/index.d.ts | 9 + packages/eslint-plugin-internal/package.json | 1 + packages/eslint-plugin-internal/project.json | 3 +- packages/eslint-plugin-internal/src/index.ts | 10 + packages/eslint-plugin-internal/tsconfig.json | 2 +- packages/eslint-plugin-tslint/project.json | 3 +- packages/eslint-plugin/index.d.ts | 6 +- packages/eslint-plugin/package.json | 2 +- packages/eslint-plugin/project.json | 3 +- packages/eslint-plugin/src/configs/all.ts | 2 +- packages/eslint-plugin/src/configs/base.ts | 7 - .../src/configs/disable-type-checked.ts | 2 + .../src/configs/eslint-recommended.ts | 2 + packages/eslint-plugin/src/index.ts | 10 + packages/integration-tests/project.json | 5 +- packages/parser/project.json | 3 +- packages/repo-tools/package.json | 8 +- packages/repo-tools/project.json | 3 +- .../src/generate-configs.mts} | 173 +++--- ...tributors.ts => generate-contributors.mts} | 12 +- .../src/{generate-lib.ts => generate-lib.mts} | 37 +- ...rate-sponsors.ts => generate-sponsors.mts} | 4 +- packages/repo-tools/src/paths.mts | 13 + packages/repo-tools/tsconfig.build.json | 3 + .../project.json | 3 +- packages/scope-manager/project.json | 3 +- packages/type-utils/project.json | 3 +- packages/types/project.json | 3 +- packages/typescript-estree/project.json | 5 +- packages/utils/project.json | 3 +- packages/utils/src/ts-eslint/Config.ts | 13 +- packages/utils/src/ts-eslint/Parser.ts | 2 +- packages/visitor-keys/project.json | 3 +- packages/visitor-keys/src/visitor-keys.ts | 2 +- packages/website-eslint/package.json | 2 +- packages/website-eslint/project.json | 3 +- packages/website/project.json | 3 +- tsconfig.base.json | 2 +- tsconfig.eslint.json => tsconfig.json | 2 + typings/eslint-plugin-eslint-comments.d.ts | 14 + typings/eslint-plugin-eslint-plugin.d.ts | 19 + typings/eslint-plugin-import.d.ts | 21 + typings/eslint-plugin-jest.d.ts | 21 + typings/eslint-plugin-jsx-a11y.d.ts | 15 + typings/eslint-plugin-react-hooks.d.ts | 14 + typings/eslint-plugin-react.d.ts | 16 + typings/eslint-plugin-simple-import-sort.d.ts | 8 + typings/eslint-plugin-unicorn.d.ts | 15 + typings/eslint__eslintrc.d.ts | 22 + typings/eslint__js.d.ts | 11 + yarn.lock | 162 +++++- 79 files changed, 1927 insertions(+), 168 deletions(-) create mode 100644 docs/packages/Core.mdx create mode 100644 eslint.config.js create mode 100644 packages/core/LICENSE create mode 100644 packages/core/README.md create mode 100644 packages/core/jest.config.js create mode 100644 packages/core/package.json create mode 100644 packages/core/project.json create mode 100644 packages/core/src/configs/all.ts create mode 100644 packages/core/src/configs/base.ts create mode 100644 packages/core/src/configs/disable-type-checked.ts create mode 100644 packages/core/src/configs/eslint-recommended.ts create mode 100644 packages/core/src/configs/recommended-type-checked.ts create mode 100644 packages/core/src/configs/recommended.ts create mode 100644 packages/core/src/configs/strict-type-checked.ts create mode 100644 packages/core/src/configs/strict.ts create mode 100644 packages/core/src/configs/stylistic-type-checked.ts create mode 100644 packages/core/src/configs/stylistic.ts create mode 100644 packages/core/src/index.ts create mode 100644 packages/core/tsconfig.build.json create mode 100644 packages/core/tsconfig.json create mode 100644 packages/eslint-plugin-internal/index.d.ts rename packages/{eslint-plugin/tools/generate-configs.ts => repo-tools/src/generate-configs.mts} (60%) rename packages/repo-tools/src/{generate-contributors.ts => generate-contributors.mts} (96%) rename packages/repo-tools/src/{generate-lib.ts => generate-lib.mts} (95%) rename packages/repo-tools/src/{generate-sponsors.ts => generate-sponsors.mts} (97%) create mode 100644 packages/repo-tools/src/paths.mts rename tsconfig.eslint.json => tsconfig.json (87%) create mode 100644 typings/eslint-plugin-eslint-comments.d.ts create mode 100644 typings/eslint-plugin-eslint-plugin.d.ts create mode 100644 typings/eslint-plugin-import.d.ts create mode 100644 typings/eslint-plugin-jest.d.ts create mode 100644 typings/eslint-plugin-jsx-a11y.d.ts create mode 100644 typings/eslint-plugin-react-hooks.d.ts create mode 100644 typings/eslint-plugin-react.d.ts create mode 100644 typings/eslint-plugin-simple-import-sort.d.ts create mode 100644 typings/eslint-plugin-unicorn.d.ts create mode 100644 typings/eslint__eslintrc.d.ts create mode 100644 typings/eslint__js.d.ts diff --git a/.eslintrc.js b/.eslintrc.js index 400ed10c4aaa..7f91a899c747 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,7 +26,7 @@ module.exports = { parserOptions: { sourceType: 'module', project: [ - './tsconfig.eslint.json', + './tsconfig.json', './packages/*/tsconfig.json', /** * We are currently in the process of transitioning to nx's out of the box structure and @@ -301,6 +301,7 @@ module.exports = { './packages/eslint-plugin-internal/src/rules/**/*.ts', './packages/eslint-plugin-tslint/src/rules/**/*.ts', './packages/eslint-plugin/src/configs/**/*.ts', + './packages/core/src/configs/**/*.ts', './packages/eslint-plugin/src/rules/**/*.ts', ], rules: { @@ -362,6 +363,7 @@ module.exports = { files: [ './packages/scope-manager/src/lib/*.ts', './packages/eslint-plugin/src/configs/*.ts', + './packages/core/src/configs/*.ts', ], rules: { '@typescript-eslint/internal/no-poorly-typed-ts-props': 'off', diff --git a/.github/ISSUE_TEMPLATE/07-enhancement-other.yaml b/.github/ISSUE_TEMPLATE/07-enhancement-other.yaml index 2d586fc7c8ba..4207a8c43529 100644 --- a/.github/ISSUE_TEMPLATE/07-enhancement-other.yaml +++ b/.github/ISSUE_TEMPLATE/07-enhancement-other.yaml @@ -24,6 +24,7 @@ body: description: Select the package against which you want to report the bug. options: - ast-spec + - core - eslint-plugin-tslint - parser - scope-manager diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 255a9a7bc38a..bed1f941a209 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -78,6 +78,11 @@ matchPackagePrefixes: ['@types/jest', 'jest', '@jest'], groupName: 'jest', }, + { + matchPackageNames: ['eslint'], + matchPackagePrefixes: ['@eslint'], + groupName: 'eslint', + }, ], postUpdateOptions: [ // run yarn dedupe to cleanup the lockfile after updates diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85bc721a243a..8090364fa53d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -163,6 +163,7 @@ jobs: package: [ 'ast-spec', + 'core', 'eslint-plugin', 'eslint-plugin-internal', 'eslint-plugin-tslint', diff --git a/.github/workflows/semantic-pr-titles.yml b/.github/workflows/semantic-pr-titles.yml index 3ebb03d6fb2a..ffbc98317fd2 100644 --- a/.github/workflows/semantic-pr-titles.yml +++ b/.github/workflows/semantic-pr-titles.yml @@ -27,6 +27,7 @@ jobs: scopes: | deps ast-spec + core eslint-plugin eslint-plugin-internal eslint-plugin-tslint diff --git a/.vscode/settings.json b/.vscode/settings.json index 896fbaebbb3a..ac5f882cbc0e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,8 @@ "typescript", "typescriptreact" ], + // required to make the extension pickup the flat config + "eslint.experimental.useFlatConfig": true, // When enabled, will trim trailing whitespace when saving a file. "files.trimTrailingWhitespace": true, diff --git a/docs/packages/Core.mdx b/docs/packages/Core.mdx new file mode 100644 index 000000000000..d20d5dcd33df --- /dev/null +++ b/docs/packages/Core.mdx @@ -0,0 +1,12 @@ +--- +id: core +sidebar_label: core +--- + +# `@typescript-eslint/core` + +> Tooling which enables you to use TypeScript with ESLint + +This package is the main entrypoint that you can use to consume our tooling with ESLint. + +// TODO(bradzacher) - docs on using the tooling diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000000..fb97e03958fe --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,494 @@ +// @ts-check + +const { FlatCompat } = require('@eslint/eslintrc'); +const deprecationPlugin = require('eslint-plugin-deprecation'); +const eslintCommentsPlugin = require('eslint-plugin-eslint-comments'); +const eslintPluginPlugin = require('eslint-plugin-eslint-plugin'); +const importPlugin = require('eslint-plugin-import'); +const jestPlugin = require('eslint-plugin-jest'); +const simpleImportSortPlugin = require('eslint-plugin-simple-import-sort'); +const unicornPlugin = require('eslint-plugin-unicorn'); +const eslintJs = require('@eslint/js'); +const tseslint = require('@typescript-eslint/core'); +const tseslintInternalPlugin = require('@typescript-eslint/eslint-plugin-internal'); +const globals = require('globals'); +// const jsxA11yPlugin = require('eslint-plugin-jsx-a11y'); +// const reactPlugin = require('eslint-plugin-react'); +// const reactHooksPlugin = require('eslint-plugin-react-hooks'); + +const compat = new FlatCompat({ baseDirectory: __dirname }); + +const config = tseslint.flatConfig( + { + // config with just ignores is the replacement for `.eslintignore` + ignores: [ + 'jest.config.js', + 'node_modules', + 'dist', + 'fixtures', + 'coverage', + '__snapshots__', + '.docusaurus', + 'build', + // Files copied as part of the build + 'packages/types/src/generated/**/*.ts', + // Playground types downloaded from the web + 'packages/website/src/vendor', + // see the file header in eslint-base.test.js for more info + 'packages/rule-tester/tests/eslint-base', + ], + }, + // { files: ["**/*.{ts,tsx,cts,mts}"] }, + eslintJs.configs.recommended, + ...compat.config(eslintPluginPlugin.configs.recommended), + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + { + plugins: { + '@typescript-eslint': tseslint.plugin, + '@typescript-eslint/internal': tseslintInternalPlugin, + deprecation: deprecationPlugin, + 'eslint-comments': eslintCommentsPlugin, + 'eslint-plugin': eslintPluginPlugin, + import: importPlugin, + jest: jestPlugin, + 'simple-import-sort': simpleImportSortPlugin, + unicorn: unicornPlugin, + }, + languageOptions: { + globals: { + ...globals.es2020, + ...globals.node, + }, + parserOptions: { + sourceType: 'module', + project: [ + 'tsconfig.json', + 'packages/*/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', + + // TODO(#7338): Investigate enabling these soon ✨ + '@typescript-eslint/no-unnecessary-condition': 'off', + '@typescript-eslint/no-dynamic-delete': 'off', + '@typescript-eslint/prefer-nullish-coalescing': 'off', + + // TODO(#7130): Investigate changing these in or removing these from presets + '@typescript-eslint/no-confusing-void-expression': 'off', + '@typescript-eslint/prefer-string-starts-ends-with': 'off', + + // + // 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-imports': [ + 'error', + { prefer: 'type-imports', disallowTypeAnnotations: true }, + ], + '@typescript-eslint/explicit-function-return-type': [ + 'error', + { allowIIFEs: true }, + ], + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/prefer-literal-enum-member': [ + 'error', + { + allowBitwiseExpressions: true, + }, + ], + '@typescript-eslint/unbound-method': 'off', + '@typescript-eslint/restrict-template-expressions': [ + 'error', + { + allowNumber: true, + allowBoolean: true, + allowAny: true, + allowNullish: true, + allowRegExp: true, + }, + ], + '@typescript-eslint/no-unused-vars': [ + 'error', + { 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', + }, + ], + 'logical-assignment-operators': 'error', + 'no-else-return': 'error', + 'no-mixed-operators': 'error', + 'no-console': 'error', + 'no-process-exit': 'error', + 'no-fallthrough': [ + 'error', + { 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', + 'global', + ], + }, + ], + + // + // 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', + }, + }, + // TODO(bradzacher) - migrate this to a flat config + // https://discord.com/channels/688543509199716507/1174310123791990866 + // TODO(bradzacher) - this is currently broken + // https://github.com/eslint/eslint/issues/17820 + ...compat.config({ + overrides: [ + { + files: ['*.js'], + extends: ['plugin:@typescript-eslint/disable-type-checked'], + rules: { + // turn off other type-aware rules + 'deprecation/deprecation': 'off', + '@typescript-eslint/internal/no-poorly-typed-ts-props': 'off', + + // turn off rules that don't apply to JS code + '@typescript-eslint/explicit-function-return-type': 'off', + }, + }, + ], + }), + // all test files + { + files: [ + 'packages/*/tests/**/*.spec.ts', + 'packages/*/tests/**/*.test.ts', + 'packages/*/tests/**/spec.ts', + 'packages/*/tests/**/test.ts', + 'packages/parser/tests/**/*.ts', + 'packages/integration-tests/tools/integration-test-base.ts', + 'packages/integration-tests/tools/pack-packages.ts', + ], + languageOptions: { + globals: { + ...jestPlugin.environments.globals.globals, + }, + }, + rules: { + '@typescript-eslint/no-empty-function': [ + 'error', + { allow: ['arrowFunctions'] }, + ], + '@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': 'error', + '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': 'error', + 'jest/prefer-to-contain': 'error', + 'jest/prefer-to-have-length': 'error', + '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/core/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/**/*.*t*', + '**/tests/**/*.ts', + 'packages/repo-tools/**/*.*t*', + 'packages/integration-tests/**/*.*t*', + ], + 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', + 'packages/core/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: ['packages/ast-spec/**/*.ts'], + rules: { + 'no-restricted-imports': [ + 'error', + { + name: '@typescript-eslint/typescript-estree', + message: + 'To prevent nx build errors, all `typescript-estree` imports should be done via `packages/ast-spec/tests/util/parsers/typescript-estree-import.ts`.', + }, + ], + }, + }, + { + files: ['rollup.config.ts'], + rules: { + 'import/no-default-export': 'off', + }, + }, + // TODO(bradzacher) - migrate this to a flat config + // https://discord.com/channels/688543509199716507/1174310123791990866 + ...compat.config({ + overrides: [ + { + files: ['packages/website/**/*.{ts,tsx,mts,cts,js,jsx}'], + extends: [ + 'plugin:jsx-a11y/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + ], + plugins: ['jsx-a11y', 'react', 'react-hooks'], + // plugins: { + // 'jsx-a11y': jsxA11yPlugin, + // react: reactPlugin, + // 'react-hooks': reactHooksPlugin, + // }, + rules: { + '@typescript-eslint/internal/prefer-ast-types-enum': 'off', + 'import/no-default-export': 'off', + 'react/jsx-no-target-blank': 'off', + 'react/no-unescaped-entities': 'off', + 'react-hooks/exhaustive-deps': 'warn', // 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', + }, + }, + { + files: ['packages/website-eslint/src/mock/**/*.js', '*.d.ts'], + rules: { + // mocks and declaration files have to mirror their original package + 'import/no-default-export': 'off', + }, + }, +); +module.exports = config; diff --git a/package.json b/package.json index 1e3f4731429e..5aecb60f7f15 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "clean": "lerna clean -y && nx run-many --target=clean", "format": "prettier --write .", "generate-breaking-changes": "npx nx run eslint-plugin:generate-breaking-changes", - "generate-configs": "npx nx run eslint-plugin:generate:configs", + "generate-configs": "npx nx run repo-tools:generate:configs", "generate-contributors": "npx nx run repo-tools:generate-contributors", "generate-sponsors": "npx nx run repo-tools:generate-sponsors", "generate-website-dts": "npx nx run website:generate-website-dts", @@ -59,6 +59,8 @@ "@babel/eslint-parser": "^7.23.3", "@babel/parser": "^7.23.3", "@babel/types": "^7.23.3", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "^8.55.0", "@nx/eslint": "17.1.2", "@nx/jest": "17.1.2", "@nx/workspace": "17.1.2", @@ -77,11 +79,14 @@ "@types/node": "^20.0.0", "@types/semver": "^7.5.0", "@types/tmp": "^0.2.3", + "@typescript-eslint/core": "6.13.2", + "@typescript-eslint/eslint-plugin-internal": "6.13.2", "console-fail-test": "^0.2.3", + "cross-env": "^7.0.3", "cross-fetch": "^4.0.0", "cspell": "^7.0.0", "downlevel-dts": ">=0.11.0", - "eslint": "^8.47.0", + "eslint": "^8.55.0", "eslint-plugin-deprecation": "^2.0.0", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-plugin": "^5.1.0", @@ -94,6 +99,7 @@ "eslint-plugin-unicorn": "^48.0.1", "execa": "7.1.1", "glob": "^10.3.3", + "globals": "^13.23.0", "husky": "^8.0.3", "jest": "29.7.0", "jest-diff": "^29.6.2", diff --git a/packages/ast-spec/project.json b/packages/ast-spec/project.json index 5fd981a73030..429a84f17318 100644 --- a/packages/ast-spec/project.json +++ b/packages/ast-spec/project.json @@ -16,8 +16,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/ast-spec/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/ast-spec/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/core/LICENSE b/packages/core/LICENSE new file mode 100644 index 000000000000..a1164108d4d6 --- /dev/null +++ b/packages/core/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 typescript-eslint and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/core/README.md b/packages/core/README.md new file mode 100644 index 000000000000..6807ddad66d2 --- /dev/null +++ b/packages/core/README.md @@ -0,0 +1,12 @@ +# `@typescript-eslint/core` + +> Tooling which enables you to use TypeScript with ESLint + +[![NPM Version](https://img.shields.io/npm/v/@typescript-eslint/core.svg?style=flat-square)](https://www.npmjs.com/package/@typescript-eslint/core) +[![NPM Downloads](https://img.shields.io/npm/dm/@typescript-eslint/core.svg?style=flat-square)](https://www.npmjs.com/package/@typescript-eslint/core) + +👉 See **https://typescript-eslint.io/packages/core** for documentation on this package. + +> See https://typescript-eslint.io for general documentation on typescript-eslint, the tooling that allows you to run ESLint and Prettier on TypeScript code. + + diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js new file mode 100644 index 000000000000..5a7d0fc5112b --- /dev/null +++ b/packages/core/jest.config.js @@ -0,0 +1,8 @@ +'use strict'; + +// @ts-check +/** @type {import('@jest/types').Config.InitialOptions} */ +module.exports = { + ...require('../../jest.config.base.js'), + testRegex: './tests/lib/.+\\.ts$', +}; diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 000000000000..63d916d6503a --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,82 @@ +{ + "name": "@typescript-eslint/core", + "version": "6.13.2", + "description": "Tooling which enables you to use TypeScript with ESLint", + "files": [ + "dist", + "_ts4.3", + "README.md", + "LICENSE" + ], + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/typescript-eslint/typescript-eslint.git", + "directory": "packages/core" + }, + "bugs": { + "url": "https://github.com/typescript-eslint/typescript-eslint/issues" + }, + "license": "BSD-2-Clause", + "keywords": [ + "ast", + "ecmascript", + "javascript", + "typescript", + "parser", + "syntax", + "eslint", + "eslintplugin", + "eslint-plugin" + ], + "scripts": { + "build": "tsc -b tsconfig.build.json", + "postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3", + "clean": "tsc -b tsconfig.build.json --clean", + "postclean": "rimraf dist && rimraf _ts4.3 && rimraf coverage", + "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore", + "lint": "nx lint", + "test": "jest --coverage", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "dependencies": { + "@typescript-eslint/eslint-plugin": "6.13.2", + "@typescript-eslint/parser": "6.13.2" + }, + "devDependencies": { + "downlevel-dts": "*", + "jest": "29.7.0", + "prettier": "^3.0.3", + "rimraf": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "typesVersions": { + "<4.7": { + "*": [ + "_ts4.3/*" + ] + } + } +} diff --git a/packages/core/project.json b/packages/core/project.json new file mode 100644 index 000000000000..89a69a351dc9 --- /dev/null +++ b/packages/core/project.json @@ -0,0 +1,15 @@ +{ + "name": "core", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "type": "library", + "implicitDependencies": [], + "targets": { + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["packages/core/**/*.{mts,cts,ts,tsx}"] + } + } + } +} diff --git a/packages/core/src/configs/all.ts b/packages/core/src/configs/all.ts new file mode 100644 index 000000000000..787104e28ab7 --- /dev/null +++ b/packages/core/src/configs/all.ts @@ -0,0 +1,201 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import baseConfig from './base'; +import eslintRecommendedConfig from './eslint-recommended'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.ConfigArray => [ + baseConfig(plugin, parser), + eslintRecommendedConfig(plugin, parser), + { + rules: { + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/array-type': 'error', + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-tslint-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'block-spacing': 'off', + '@typescript-eslint/block-spacing': 'error', + 'brace-style': 'off', + '@typescript-eslint/brace-style': 'error', + '@typescript-eslint/class-literal-property-style': 'error', + 'class-methods-use-this': 'off', + '@typescript-eslint/class-methods-use-this': 'error', + 'comma-dangle': 'off', + '@typescript-eslint/comma-dangle': 'error', + 'comma-spacing': 'off', + '@typescript-eslint/comma-spacing': 'error', + '@typescript-eslint/consistent-generic-constructors': 'error', + '@typescript-eslint/consistent-indexed-object-style': 'error', + '@typescript-eslint/consistent-type-assertions': 'error', + '@typescript-eslint/consistent-type-definitions': 'error', + '@typescript-eslint/consistent-type-exports': 'error', + '@typescript-eslint/consistent-type-imports': 'error', + 'default-param-last': 'off', + '@typescript-eslint/default-param-last': 'error', + 'dot-notation': 'off', + '@typescript-eslint/dot-notation': 'error', + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/explicit-member-accessibility': 'error', + '@typescript-eslint/explicit-module-boundary-types': 'error', + 'func-call-spacing': 'off', + '@typescript-eslint/func-call-spacing': 'error', + indent: 'off', + '@typescript-eslint/indent': 'error', + 'init-declarations': 'off', + '@typescript-eslint/init-declarations': 'error', + 'key-spacing': 'off', + '@typescript-eslint/key-spacing': 'error', + 'keyword-spacing': 'off', + '@typescript-eslint/keyword-spacing': 'error', + 'lines-around-comment': 'off', + '@typescript-eslint/lines-around-comment': 'error', + 'lines-between-class-members': 'off', + '@typescript-eslint/lines-between-class-members': 'error', + 'max-params': 'off', + '@typescript-eslint/max-params': 'error', + '@typescript-eslint/member-delimiter-style': 'error', + '@typescript-eslint/member-ordering': 'error', + '@typescript-eslint/method-signature-style': 'error', + '@typescript-eslint/naming-convention': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-base-to-string': 'error', + '@typescript-eslint/no-confusing-non-null-assertion': 'error', + '@typescript-eslint/no-confusing-void-expression': 'error', + 'no-dupe-class-members': 'off', + '@typescript-eslint/no-dupe-class-members': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-duplicate-type-constituents': 'error', + '@typescript-eslint/no-dynamic-delete': 'error', + 'no-empty-function': 'off', + '@typescript-eslint/no-empty-function': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + 'no-extra-parens': 'off', + '@typescript-eslint/no-extra-parens': 'error', + 'no-extra-semi': 'off', + '@typescript-eslint/no-extra-semi': 'error', + '@typescript-eslint/no-extraneous-class': 'error', + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-for-in-array': 'error', + 'no-implied-eval': 'off', + '@typescript-eslint/no-implied-eval': 'error', + '@typescript-eslint/no-import-type-side-effects': 'error', + '@typescript-eslint/no-inferrable-types': 'error', + 'no-invalid-this': 'off', + '@typescript-eslint/no-invalid-this': 'error', + '@typescript-eslint/no-invalid-void-type': 'error', + 'no-loop-func': 'off', + '@typescript-eslint/no-loop-func': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + 'no-magic-numbers': 'off', + '@typescript-eslint/no-magic-numbers': 'error', + '@typescript-eslint/no-meaningless-void-operator': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-mixed-enums': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + 'no-redeclare': 'off', + '@typescript-eslint/no-redeclare': 'error', + '@typescript-eslint/no-redundant-type-constituents': 'error', + '@typescript-eslint/no-require-imports': 'error', + 'no-restricted-imports': 'off', + '@typescript-eslint/no-restricted-imports': 'error', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 'error', + '@typescript-eslint/no-this-alias': 'error', + 'no-throw-literal': 'off', + '@typescript-eslint/no-throw-literal': 'error', + '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error', + '@typescript-eslint/no-unnecessary-condition': 'error', + '@typescript-eslint/no-unnecessary-qualifier': 'error', + '@typescript-eslint/no-unnecessary-type-arguments': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-argument': 'error', + '@typescript-eslint/no-unsafe-assignment': 'error', + '@typescript-eslint/no-unsafe-call': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + '@typescript-eslint/no-unsafe-enum-comparison': 'error', + '@typescript-eslint/no-unsafe-member-access': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + '@typescript-eslint/no-unsafe-unary-minus': 'error', + 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + 'no-use-before-define': 'off', + '@typescript-eslint/no-use-before-define': 'error', + 'no-useless-constructor': 'off', + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/no-useless-empty-export': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/non-nullable-type-assertion-style': 'error', + 'object-curly-spacing': 'off', + '@typescript-eslint/object-curly-spacing': 'error', + 'padding-line-between-statements': 'off', + '@typescript-eslint/padding-line-between-statements': 'error', + '@typescript-eslint/parameter-properties': 'error', + '@typescript-eslint/prefer-as-const': 'error', + 'prefer-destructuring': 'off', + '@typescript-eslint/prefer-destructuring': 'error', + '@typescript-eslint/prefer-enum-initializers': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-function-type': 'error', + '@typescript-eslint/prefer-includes': 'error', + '@typescript-eslint/prefer-literal-enum-member': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + '@typescript-eslint/prefer-nullish-coalescing': 'error', + '@typescript-eslint/prefer-optional-chain': 'error', + '@typescript-eslint/prefer-readonly': 'error', + '@typescript-eslint/prefer-readonly-parameter-types': 'error', + '@typescript-eslint/prefer-reduce-type-parameter': 'error', + '@typescript-eslint/prefer-regexp-exec': 'error', + '@typescript-eslint/prefer-return-this-type': 'error', + '@typescript-eslint/prefer-string-starts-ends-with': 'error', + '@typescript-eslint/prefer-ts-expect-error': 'error', + '@typescript-eslint/promise-function-async': 'error', + quotes: 'off', + '@typescript-eslint/quotes': 'error', + '@typescript-eslint/require-array-sort-compare': 'error', + 'require-await': 'off', + '@typescript-eslint/require-await': 'error', + '@typescript-eslint/restrict-plus-operands': 'error', + '@typescript-eslint/restrict-template-expressions': 'error', + 'no-return-await': 'off', + '@typescript-eslint/return-await': 'error', + semi: 'off', + '@typescript-eslint/semi': 'error', + '@typescript-eslint/sort-type-constituents': 'error', + 'space-before-blocks': 'off', + '@typescript-eslint/space-before-blocks': 'error', + 'space-before-function-paren': 'off', + '@typescript-eslint/space-before-function-paren': 'error', + 'space-infix-ops': 'off', + '@typescript-eslint/space-infix-ops': 'error', + '@typescript-eslint/strict-boolean-expressions': 'error', + '@typescript-eslint/switch-exhaustiveness-check': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/type-annotation-spacing': 'error', + '@typescript-eslint/typedef': 'error', + '@typescript-eslint/unbound-method': 'error', + '@typescript-eslint/unified-signatures': 'error', + }, + }, +]; diff --git a/packages/core/src/configs/base.ts b/packages/core/src/configs/base.ts new file mode 100644 index 000000000000..a25249a18225 --- /dev/null +++ b/packages/core/src/configs/base.ts @@ -0,0 +1,14 @@ +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.Config => ({ + languageOptions: { + parser, + parserOptions: { sourceType: 'module' }, + }, + plugins: { + '@typescript-eslint': plugin, + }, +}); diff --git a/packages/core/src/configs/disable-type-checked.ts b/packages/core/src/configs/disable-type-checked.ts new file mode 100644 index 000000000000..0e642b79a97a --- /dev/null +++ b/packages/core/src/configs/disable-type-checked.ts @@ -0,0 +1,64 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +export default ( + _plugin: FlatConfig.Plugin, + _parser: FlatConfig.Parser, +): FlatConfig.Config => ({ + rules: { + '@typescript-eslint/await-thenable': 'off', + '@typescript-eslint/consistent-type-exports': 'off', + '@typescript-eslint/dot-notation': 'off', + '@typescript-eslint/naming-convention': 'off', + '@typescript-eslint/no-base-to-string': 'off', + '@typescript-eslint/no-confusing-void-expression': 'off', + '@typescript-eslint/no-duplicate-type-constituents': 'off', + '@typescript-eslint/no-floating-promises': 'off', + '@typescript-eslint/no-for-in-array': 'off', + '@typescript-eslint/no-implied-eval': 'off', + '@typescript-eslint/no-meaningless-void-operator': 'off', + '@typescript-eslint/no-misused-promises': 'off', + '@typescript-eslint/no-mixed-enums': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off', + '@typescript-eslint/no-throw-literal': 'off', + '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'off', + '@typescript-eslint/no-unnecessary-condition': 'off', + '@typescript-eslint/no-unnecessary-qualifier': 'off', + '@typescript-eslint/no-unnecessary-type-arguments': 'off', + '@typescript-eslint/no-unnecessary-type-assertion': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-enum-comparison': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unsafe-unary-minus': 'off', + '@typescript-eslint/non-nullable-type-assertion-style': 'off', + '@typescript-eslint/prefer-destructuring': 'off', + '@typescript-eslint/prefer-includes': 'off', + '@typescript-eslint/prefer-nullish-coalescing': 'off', + '@typescript-eslint/prefer-optional-chain': 'off', + '@typescript-eslint/prefer-readonly': 'off', + '@typescript-eslint/prefer-readonly-parameter-types': 'off', + '@typescript-eslint/prefer-reduce-type-parameter': 'off', + '@typescript-eslint/prefer-regexp-exec': 'off', + '@typescript-eslint/prefer-return-this-type': 'off', + '@typescript-eslint/prefer-string-starts-ends-with': 'off', + '@typescript-eslint/promise-function-async': 'off', + '@typescript-eslint/require-array-sort-compare': 'off', + '@typescript-eslint/require-await': 'off', + '@typescript-eslint/restrict-plus-operands': 'off', + '@typescript-eslint/restrict-template-expressions': 'off', + '@typescript-eslint/return-await': 'off', + '@typescript-eslint/strict-boolean-expressions': 'off', + '@typescript-eslint/switch-exhaustiveness-check': 'off', + '@typescript-eslint/unbound-method': 'off', + }, + languageOptions: { parserOptions: { project: null, program: null } }, +}); diff --git a/packages/core/src/configs/eslint-recommended.ts b/packages/core/src/configs/eslint-recommended.ts new file mode 100644 index 000000000000..768a53a712dc --- /dev/null +++ b/packages/core/src/configs/eslint-recommended.ts @@ -0,0 +1,36 @@ +// NOTE: keep this in sync with packages/eslint-plugin/src/configs/eslint-recommended.ts +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +/** + * This is a compatibility ruleset that: + * - disables rules from eslint:recommended which are already handled by TypeScript. + * - enables rules that make sense due to TS's typechecking / transpilation. + */ +export default ( + _plugin: FlatConfig.Plugin, + _parser: FlatConfig.Parser, +): FlatConfig.Config => ({ + files: ['*.ts', '*.tsx', '*.mts', '*.cts'], + rules: { + 'constructor-super': 'off', // ts(2335) & ts(2377) + 'getter-return': 'off', // ts(2378) + 'no-const-assign': 'off', // ts(2588) + 'no-dupe-args': 'off', // ts(2300) + 'no-dupe-class-members': 'off', // ts(2393) & ts(2300) + 'no-dupe-keys': 'off', // ts(1117) + 'no-func-assign': 'off', // ts(2630) + 'no-import-assign': 'off', // ts(2632) & ts(2540) + 'no-new-symbol': 'off', // ts(7009) + 'no-obj-calls': 'off', // ts(2349) + 'no-redeclare': 'off', // ts(2451) + 'no-setter-return': 'off', // ts(2408) + 'no-this-before-super': 'off', // ts(2376) & ts(17009) + 'no-undef': 'off', // ts(2304) & ts(2552) + 'no-unreachable': 'off', // ts(7027) + 'no-unsafe-negation': 'off', // ts(2365) & ts(2322) & ts(2358) + 'no-var': 'error', // ts transpiles let/const to var, so no need for vars any more + 'prefer-const': 'error', // ts provides better types with const + 'prefer-rest-params': 'error', // ts provides better types with rest args over arguments + 'prefer-spread': 'error', // ts transpiles spread to apply, so no need for manual apply + }, +}); diff --git a/packages/core/src/configs/recommended-type-checked.ts b/packages/core/src/configs/recommended-type-checked.ts new file mode 100644 index 000000000000..7d9ac811e1c7 --- /dev/null +++ b/packages/core/src/configs/recommended-type-checked.ts @@ -0,0 +1,64 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import baseConfig from './base'; +import eslintRecommendedConfig from './eslint-recommended'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.ConfigArray => [ + baseConfig(plugin, parser), + eslintRecommendedConfig(plugin, parser), + { + rules: { + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-base-to-string': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-duplicate-type-constituents': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-for-in-array': 'error', + 'no-implied-eval': 'off', + '@typescript-eslint/no-implied-eval': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-redundant-type-constituents': 'error', + '@typescript-eslint/no-this-alias': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-argument': 'error', + '@typescript-eslint/no-unsafe-assignment': 'error', + '@typescript-eslint/no-unsafe-call': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + '@typescript-eslint/no-unsafe-enum-comparison': 'error', + '@typescript-eslint/no-unsafe-member-access': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-as-const': 'error', + 'require-await': 'off', + '@typescript-eslint/require-await': 'error', + '@typescript-eslint/restrict-plus-operands': 'error', + '@typescript-eslint/restrict-template-expressions': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/unbound-method': 'error', + }, + }, +]; diff --git a/packages/core/src/configs/recommended.ts b/packages/core/src/configs/recommended.ts new file mode 100644 index 000000000000..ae5103d9fea8 --- /dev/null +++ b/packages/core/src/configs/recommended.ts @@ -0,0 +1,43 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import baseConfig from './base'; +import eslintRecommendedConfig from './eslint-recommended'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.ConfigArray => [ + baseConfig(plugin, parser), + eslintRecommendedConfig(plugin, parser), + { + rules: { + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-this-alias': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-as-const': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + }, + }, +]; diff --git a/packages/core/src/configs/strict-type-checked.ts b/packages/core/src/configs/strict-type-checked.ts new file mode 100644 index 000000000000..0060c3d6ebea --- /dev/null +++ b/packages/core/src/configs/strict-type-checked.ts @@ -0,0 +1,85 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import baseConfig from './base'; +import eslintRecommendedConfig from './eslint-recommended'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.ConfigArray => [ + baseConfig(plugin, parser), + eslintRecommendedConfig(plugin, parser), + { + rules: { + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-base-to-string': 'error', + '@typescript-eslint/no-confusing-void-expression': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-duplicate-type-constituents': 'error', + '@typescript-eslint/no-dynamic-delete': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + '@typescript-eslint/no-extraneous-class': 'error', + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-for-in-array': 'error', + 'no-implied-eval': 'off', + '@typescript-eslint/no-implied-eval': 'error', + '@typescript-eslint/no-invalid-void-type': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + '@typescript-eslint/no-meaningless-void-operator': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-mixed-enums': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-redundant-type-constituents': 'error', + '@typescript-eslint/no-this-alias': 'error', + 'no-throw-literal': 'off', + '@typescript-eslint/no-throw-literal': 'error', + '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error', + '@typescript-eslint/no-unnecessary-condition': 'error', + '@typescript-eslint/no-unnecessary-type-arguments': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-argument': 'error', + '@typescript-eslint/no-unsafe-assignment': 'error', + '@typescript-eslint/no-unsafe-call': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + '@typescript-eslint/no-unsafe-enum-comparison': 'error', + '@typescript-eslint/no-unsafe-member-access': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + 'no-useless-constructor': 'off', + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-as-const': 'error', + '@typescript-eslint/prefer-includes': 'error', + '@typescript-eslint/prefer-literal-enum-member': 'error', + '@typescript-eslint/prefer-reduce-type-parameter': 'error', + '@typescript-eslint/prefer-return-this-type': 'error', + '@typescript-eslint/prefer-ts-expect-error': 'error', + 'require-await': 'off', + '@typescript-eslint/require-await': 'error', + '@typescript-eslint/restrict-plus-operands': 'error', + '@typescript-eslint/restrict-template-expressions': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/unbound-method': 'error', + '@typescript-eslint/unified-signatures': 'error', + }, + }, +]; diff --git a/packages/core/src/configs/strict.ts b/packages/core/src/configs/strict.ts new file mode 100644 index 000000000000..e54b7d07322e --- /dev/null +++ b/packages/core/src/configs/strict.ts @@ -0,0 +1,53 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import baseConfig from './base'; +import eslintRecommendedConfig from './eslint-recommended'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.ConfigArray => [ + baseConfig(plugin, parser), + eslintRecommendedConfig(plugin, parser), + { + rules: { + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-dynamic-delete': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + '@typescript-eslint/no-extraneous-class': 'error', + '@typescript-eslint/no-invalid-void-type': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-this-alias': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + 'no-useless-constructor': 'off', + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-as-const': 'error', + '@typescript-eslint/prefer-literal-enum-member': 'error', + '@typescript-eslint/prefer-ts-expect-error': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/unified-signatures': 'error', + }, + }, +]; diff --git a/packages/core/src/configs/stylistic-type-checked.ts b/packages/core/src/configs/stylistic-type-checked.ts new file mode 100644 index 000000000000..3923973100b3 --- /dev/null +++ b/packages/core/src/configs/stylistic-type-checked.ts @@ -0,0 +1,45 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import baseConfig from './base'; +import eslintRecommendedConfig from './eslint-recommended'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.ConfigArray => [ + baseConfig(plugin, parser), + eslintRecommendedConfig(plugin, parser), + { + rules: { + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/array-type': 'error', + '@typescript-eslint/ban-tslint-comment': 'error', + '@typescript-eslint/class-literal-property-style': 'error', + '@typescript-eslint/consistent-generic-constructors': 'error', + '@typescript-eslint/consistent-indexed-object-style': 'error', + '@typescript-eslint/consistent-type-assertions': 'error', + '@typescript-eslint/consistent-type-definitions': 'error', + 'dot-notation': 'off', + '@typescript-eslint/dot-notation': 'error', + '@typescript-eslint/no-confusing-non-null-assertion': 'error', + 'no-empty-function': 'off', + '@typescript-eslint/no-empty-function': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-inferrable-types': 'error', + '@typescript-eslint/non-nullable-type-assertion-style': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-function-type': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + '@typescript-eslint/prefer-nullish-coalescing': 'error', + '@typescript-eslint/prefer-optional-chain': 'error', + '@typescript-eslint/prefer-string-starts-ends-with': 'error', + }, + }, +]; diff --git a/packages/core/src/configs/stylistic.ts b/packages/core/src/configs/stylistic.ts new file mode 100644 index 000000000000..4db1a78f9a0a --- /dev/null +++ b/packages/core/src/configs/stylistic.ts @@ -0,0 +1,39 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import baseConfig from './base'; +import eslintRecommendedConfig from './eslint-recommended'; + +export default ( + plugin: FlatConfig.Plugin, + parser: FlatConfig.Parser, +): FlatConfig.ConfigArray => [ + baseConfig(plugin, parser), + eslintRecommendedConfig(plugin, parser), + { + rules: { + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/array-type': 'error', + '@typescript-eslint/ban-tslint-comment': 'error', + '@typescript-eslint/class-literal-property-style': 'error', + '@typescript-eslint/consistent-generic-constructors': 'error', + '@typescript-eslint/consistent-indexed-object-style': 'error', + '@typescript-eslint/consistent-type-assertions': 'error', + '@typescript-eslint/consistent-type-definitions': 'error', + '@typescript-eslint/no-confusing-non-null-assertion': 'error', + 'no-empty-function': 'off', + '@typescript-eslint/no-empty-function': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-inferrable-types': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-function-type': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + }, + }, +]; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts new file mode 100644 index 000000000000..96de841dafd1 --- /dev/null +++ b/packages/core/src/index.ts @@ -0,0 +1,46 @@ +import pluginBase from '@typescript-eslint/eslint-plugin'; +import * as parserBase from '@typescript-eslint/parser'; +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import allConfig from './configs/all'; +import baseConfig from './configs/base'; +import disableTypeCheckedConfig from './configs/disable-type-checked'; +import eslintRecommendedConfig from './configs/eslint-recommended'; +import recommendedConfig from './configs/recommended'; +import recommendedTypeCheckedConfig from './configs/recommended-type-checked'; +import strictConfig from './configs/strict'; +import strictTypeCheckedConfig from './configs/strict-type-checked'; +import stylisticConfig from './configs/stylistic'; +import stylisticTypeCheckedConfig from './configs/stylistic-type-checked'; + +const parser: FlatConfig.Parser = { + meta: parserBase.meta, + parseForESLint: parserBase.parseForESLint, +}; + +const plugin: FlatConfig.Plugin = { + meta: pluginBase.meta, + rules: pluginBase.rules, +}; + +function flatConfig(...config: FlatConfig.ConfigArray): FlatConfig.ConfigArray { + return config; +} + +export = { + flatConfig, + configs: { + all: allConfig(plugin, parser), + base: baseConfig(plugin, parser), + disableTypeChecked: disableTypeCheckedConfig(plugin, parser), + eslintRecommended: eslintRecommendedConfig(plugin, parser), + recommended: recommendedConfig(plugin, parser), + recommendedTypeChecked: recommendedTypeCheckedConfig(plugin, parser), + strict: strictConfig(plugin, parser), + strictTypeChecked: strictTypeCheckedConfig(plugin, parser), + stylistic: stylisticConfig(plugin, parser), + stylisticTypeChecked: stylisticTypeCheckedConfig(plugin, parser), + }, + parser, + plugin, +}; diff --git a/packages/core/tsconfig.build.json b/packages/core/tsconfig.build.json new file mode 100644 index 000000000000..8833d225ce3c --- /dev/null +++ b/packages/core/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./dist", + "rootDir": "./src", + "resolveJsonModule": true + }, + "include": ["src"], + "references": [{ "path": "../parser/tsconfig.build.json" }] +} diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json new file mode 100644 index 000000000000..ac9e78203f68 --- /dev/null +++ b/packages/core/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.build.json", + "compilerOptions": { + "composite": false, + "rootDir": "." + }, + "include": ["src", "tests", "tools"], + "exclude": ["tests/fixtures"], + "references": [{ "path": "../parser/tsconfig.build.json" }] +} diff --git a/packages/eslint-plugin-internal/index.d.ts b/packages/eslint-plugin-internal/index.d.ts new file mode 100644 index 000000000000..8c2962c75da3 --- /dev/null +++ b/packages/eslint-plugin-internal/index.d.ts @@ -0,0 +1,9 @@ +import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + +import type rules from './rules'; + +declare const cjsExport: { + meta: FlatConfig.PluginMeta; + rules: typeof rules; +}; +export = cjsExport; diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 686955db3d65..c9922c79f79b 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -3,6 +3,7 @@ "version": "6.13.2", "private": true, "main": "dist/index.js", + "types": "index.d.ts", "scripts": { "build": "tsc -b tsconfig.build.json", "clean": "tsc -b tsconfig.build.json --clean", diff --git a/packages/eslint-plugin-internal/project.json b/packages/eslint-plugin-internal/project.json index 6444c3fc3b68..92ff328d871c 100644 --- a/packages/eslint-plugin-internal/project.json +++ b/packages/eslint-plugin-internal/project.json @@ -10,8 +10,7 @@ "options": { "lintFilePatterns": [ "packages/eslint-plugin-internal/**/*.{mts,cts,ts,tsx}" - ], - "ignorePath": ".eslintignore" + ] } } } diff --git a/packages/eslint-plugin-internal/src/index.ts b/packages/eslint-plugin-internal/src/index.ts index 0802acef98a8..cb15326b4dfe 100644 --- a/packages/eslint-plugin-internal/src/index.ts +++ b/packages/eslint-plugin-internal/src/index.ts @@ -1,5 +1,15 @@ import rules from './rules'; +// note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder +const { name, version } = require('../package.json') as { + name: string; + version: string; +}; + export = { rules, + meta: { + name, + version, + }, }; diff --git a/packages/eslint-plugin-internal/tsconfig.json b/packages/eslint-plugin-internal/tsconfig.json index cc78ba59388e..83713e5c8bf0 100644 --- a/packages/eslint-plugin-internal/tsconfig.json +++ b/packages/eslint-plugin-internal/tsconfig.json @@ -5,6 +5,6 @@ "target": "ES2022", "rootDir": "." }, - "include": ["src", "typings", "tests"], + "include": ["src", "typings", "tests", "index.d.ts"], "references": [{ "path": "../utils/tsconfig.build.json" }] } diff --git a/packages/eslint-plugin-tslint/project.json b/packages/eslint-plugin-tslint/project.json index f7efe38324c8..cfbc1f56a455 100644 --- a/packages/eslint-plugin-tslint/project.json +++ b/packages/eslint-plugin-tslint/project.json @@ -10,8 +10,7 @@ "options": { "lintFilePatterns": [ "packages/eslint-plugin-tslint/**/*.{mts,cts,ts,tsx}" - ], - "ignorePath": ".eslintignore" + ] } } } diff --git a/packages/eslint-plugin/index.d.ts b/packages/eslint-plugin/index.d.ts index 30f22e9b09ef..756a025eb97d 100644 --- a/packages/eslint-plugin/index.d.ts +++ b/packages/eslint-plugin/index.d.ts @@ -1,9 +1,13 @@ -import type { ClassicConfig } from '@typescript-eslint/utils/ts-eslint'; +import type { + ClassicConfig, + FlatConfig, +} from '@typescript-eslint/utils/ts-eslint'; import type rules from './rules'; declare const cjsExport: { configs: Record; + meta: FlatConfig.PluginMeta; rules: typeof rules; }; export = cjsExport; diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 61a13aefcc98..32188f23f758 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -49,7 +49,7 @@ "postclean": "rimraf dist && rimraf coverage", "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore", "generate:breaking-changes": "yarn tsx tools/generate-breaking-changes.mts", - "generate:configs": "yarn tsx tools/generate-configs.ts", + "generate:configs": "npx nx run repo-tools:generate-configs", "lint": "npx nx lint", "test": "jest --coverage --logHeapUsage", "test-single": "jest --no-coverage", diff --git a/packages/eslint-plugin/project.json b/packages/eslint-plugin/project.json index b8d631c03265..aa2413fe347c 100644 --- a/packages/eslint-plugin/project.json +++ b/packages/eslint-plugin/project.json @@ -8,8 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/eslint-plugin/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/eslint-plugin/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/eslint-plugin/src/configs/all.ts b/packages/eslint-plugin/src/configs/all.ts index 7717b386cc9f..5142a24bd540 100644 --- a/packages/eslint-plugin/src/configs/all.ts +++ b/packages/eslint-plugin/src/configs/all.ts @@ -143,9 +143,9 @@ export = { '@typescript-eslint/padding-line-between-statements': 'error', '@typescript-eslint/parameter-properties': 'error', '@typescript-eslint/prefer-as-const': 'error', - '@typescript-eslint/prefer-enum-initializers': 'error', 'prefer-destructuring': 'off', '@typescript-eslint/prefer-destructuring': 'error', + '@typescript-eslint/prefer-enum-initializers': 'error', '@typescript-eslint/prefer-for-of': 'error', '@typescript-eslint/prefer-function-type': 'error', '@typescript-eslint/prefer-includes': 'error', diff --git a/packages/eslint-plugin/src/configs/base.ts b/packages/eslint-plugin/src/configs/base.ts index 628ed42b760c..652bf9db1eea 100644 --- a/packages/eslint-plugin/src/configs/base.ts +++ b/packages/eslint-plugin/src/configs/base.ts @@ -1,10 +1,3 @@ -// THIS CODE WAS AUTOMATICALLY GENERATED -// DO NOT EDIT THIS CODE BY HAND -// SEE https://typescript-eslint.io/linting/configs -// -// For developers working in the typescript-eslint monorepo: -// You can regenerate it using `yarn generate:configs` - export = { parser: '@typescript-eslint/parser', parserOptions: { sourceType: 'module' }, diff --git a/packages/eslint-plugin/src/configs/disable-type-checked.ts b/packages/eslint-plugin/src/configs/disable-type-checked.ts index 38a7ffd079d8..4bacae681569 100644 --- a/packages/eslint-plugin/src/configs/disable-type-checked.ts +++ b/packages/eslint-plugin/src/configs/disable-type-checked.ts @@ -34,7 +34,9 @@ export = { '@typescript-eslint/no-unsafe-enum-comparison': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unsafe-unary-minus': 'off', '@typescript-eslint/non-nullable-type-assertion-style': 'off', + '@typescript-eslint/prefer-destructuring': 'off', '@typescript-eslint/prefer-includes': 'off', '@typescript-eslint/prefer-nullish-coalescing': 'off', '@typescript-eslint/prefer-optional-chain': 'off', diff --git a/packages/eslint-plugin/src/configs/eslint-recommended.ts b/packages/eslint-plugin/src/configs/eslint-recommended.ts index a1cdae8759d2..41c8546116f1 100644 --- a/packages/eslint-plugin/src/configs/eslint-recommended.ts +++ b/packages/eslint-plugin/src/configs/eslint-recommended.ts @@ -1,3 +1,5 @@ +// NOTE: keep this in sync with packages/core/src/configs/eslint-recommended.ts + /** * This is a compatibility ruleset that: * - disables rules from eslint:recommended which are already handled by TypeScript. diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index ece2bb0a20fc..40f159cb0e41 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -10,6 +10,12 @@ import stylistic from './configs/stylistic'; import stylisticTypeChecked from './configs/stylistic-type-checked'; import rules from './rules'; +// note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder +const { name, version } = require('../package.json') as { + name: string; + version: string; +}; + export = { configs: { all, @@ -25,5 +31,9 @@ export = { stylistic, 'stylistic-type-checked': stylisticTypeChecked, }, + meta: { + name, + version, + }, rules, }; diff --git a/packages/integration-tests/project.json b/packages/integration-tests/project.json index d7498a1f1f82..48ec1a59e70d 100644 --- a/packages/integration-tests/project.json +++ b/packages/integration-tests/project.json @@ -8,10 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": [ - "packages/integration-tests/**/*.{mts,cts,ts,tsx}" - ], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/integration-tests/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/parser/project.json b/packages/parser/project.json index 8e3886a5e83a..4ec306f27beb 100644 --- a/packages/parser/project.json +++ b/packages/parser/project.json @@ -8,8 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/parser/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/parser/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 6983d1967aeb..b362e0d1ec2a 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -5,9 +5,10 @@ "scripts": { "//": "NOTE: intentionally no build step in this package", "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore", - "generate-contributors": "tsx ./src/generate-contributors.ts", - "generate-sponsors": "tsx ./src/generate-sponsors.ts", - "generate-lib": "tsx ./src/generate-lib.ts", + "generate-configs": "tsx ./src/generate-configs.mts", + "generate-contributors": "tsx ./src/generate-contributors.mts", + "generate-sponsors": "tsx ./src/generate-sponsors.mts", + "generate-lib": "tsx ./src/generate-lib.mts", "lint": "npx nx lint", "postinstall-script": "tsx ./src/postinstall.mts", "test": "jest --coverage", @@ -16,6 +17,7 @@ "devDependencies": { "@nx/devkit": "*", "@prettier/sync": "*", + "cross-env": "*", "cross-fetch": "*", "execa": "*", "prettier": "^3.0.3", diff --git a/packages/repo-tools/project.json b/packages/repo-tools/project.json index 1fd46121ddc5..e94f033ac582 100644 --- a/packages/repo-tools/project.json +++ b/packages/repo-tools/project.json @@ -8,8 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/repo-tools/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/repo-tools/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/repo-tools/src/generate-configs.mts similarity index 60% rename from packages/eslint-plugin/tools/generate-configs.ts rename to packages/repo-tools/src/generate-configs.mts index fb60d86449b9..f6fc564c8011 100644 --- a/packages/eslint-plugin/tools/generate-configs.ts +++ b/packages/repo-tools/src/generate-configs.mts @@ -1,15 +1,17 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import eslintPlugin from '@typescript-eslint/eslint-plugin'; import type { ClassicConfig, + FlatConfig, Linter, RuleModule, RuleRecommendation, } from '@typescript-eslint/utils/ts-eslint'; -import * as fs from 'fs'; -import * as path from 'path'; import prettier from 'prettier'; -import * as url from 'url'; -import type RulesFile from '../src/rules'; +import { PACKAGES_CORE, PACKAGES_ESLINT_PLUGIN, REPO_ROOT } from './paths.mts'; // no need for us to bring in an entire dependency for a few simple terminal colors const chalk = { @@ -20,37 +22,38 @@ const chalk = { gray: (val: string): string => `\x1B[90m${val}\x1B[39m`, }; -interface RulesObject { - default: { - default: typeof RulesFile; - }; -} +const AUTO_GENERATED_COMMENT_LINES = [ + '// THIS CODE WAS AUTOMATICALLY GENERATED', + '// DO NOT EDIT THIS CODE BY HAND', + '// SEE https://typescript-eslint.io/linting/configs', + '//', + '// For developers working in the typescript-eslint monorepo:', + '// You can regenerate it using `yarn generate:configs`', + '', +] as const; + +const EXTENDS_MODULES = [ + { + name: 'baseConfig', + packageRelativePath: './configs/base', + moduleRelativePath: './base', + }, + { + name: 'eslintRecommendedConfig', + packageRelativePath: './configs/eslint-recommended', + moduleRelativePath: './eslint-recommended', + }, +] as const; +const CLASSIC_EXTENDS: readonly string[] = EXTENDS_MODULES.map( + mod => mod.packageRelativePath, +); async function main(): Promise { - // TODO: Standardize & simplify these tools/* scripts once v6 is more stable - // @ts-expect-error -- ts-node allows us to use import.meta - const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); - - const { - default: { default: rules }, - } = - // @ts-expect-error -- We don't support ESM imports of local code yet. - (await import('../dist/rules/index.js')) as RulesObject; - - function addAutoGeneratedComment(code: string): string { - return [ - '// THIS CODE WAS AUTOMATICALLY GENERATED', - '// DO NOT EDIT THIS CODE BY HAND', - '// SEE https://typescript-eslint.io/linting/configs', - '//', - '// For developers working in the typescript-eslint monorepo:', - '// You can regenerate it using `yarn generate:configs`', - '', - code, - ].join('\n'); + function addAutoGeneratedComment(code?: string): string { + return [...AUTO_GENERATED_COMMENT_LINES, code].join('\n'); } - const prettierConfig = await prettier.resolveConfig(__dirname); + const prettierConfig = await prettier.resolveConfig(REPO_ROOT); type LinterConfigRules = Record; @@ -60,12 +63,12 @@ async function main(): Promise { } const RULE_NAME_PREFIX = '@typescript-eslint/'; - const MAX_RULE_NAME_LENGTH = Object.keys(rules).reduce( + const MAX_RULE_NAME_LENGTH = Object.keys(eslintPlugin.rules).reduce( (acc, name) => Math.max(acc, name.length), 0, ); const BASE_RULES_TO_BE_OVERRIDDEN = new Map( - Object.entries(rules) + Object.entries(eslintPlugin.rules) .filter(([, rule]) => rule.meta.docs?.extendsBaseRule) .map( ([ruleName, rule]) => @@ -77,12 +80,11 @@ async function main(): Promise { ] as const, ), ); - const EXTENDS = ['./configs/base', './configs/eslint-recommended']; type RuleEntry = [string, RuleModule]; - const allRuleEntries: RuleEntry[] = Object.entries(rules).sort((a, b) => - a[0].localeCompare(b[0]), + const allRuleEntries: RuleEntry[] = Object.entries(eslintPlugin.rules).sort( + (a, b) => a[0].localeCompare(b[0]), ); interface RuleFilter { @@ -155,34 +157,97 @@ async function main(): Promise { const hyphens = '-'.repeat(35 - Math.ceil(name.length / 2)); console.log(chalk.blueBright(`\n${hyphens} ${name}.ts ${hyphens}`)); + const config = getConfig(); + + // + // 1. Classic Config - written to the eslint-plugin package + // These configs are just JSON blobs that we write as TS files + // + // note: we use `export =` because ESLint will import these configs via a commonjs import - const code = `export = ${JSON.stringify(getConfig())};`; - const configStr = await prettier.format(addAutoGeneratedComment(code), { + const classicCode = `export = ${JSON.stringify(config)};`; + const classicConfigStr = await prettier.format( + addAutoGeneratedComment(classicCode), + { + parser: 'typescript', + ...prettierConfig, + }, + ); + fs.writeFileSync( + path.join(PACKAGES_ESLINT_PLUGIN, 'src', 'configs', `${name}.ts`), + classicConfigStr, + ); + + // + // 2. Flat Config - written to the core package + // These configs are actual TS modules that import other configs + // + const flatCode: string[] = [ + ...AUTO_GENERATED_COMMENT_LINES, + "import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';", + '', + ]; + const flatExtends: string[] = []; + const flatConfig: FlatConfig.Config = { + rules: config.rules, + }; + if (config.extends) { + for (const extendPath of config.extends) { + const config = EXTENDS_MODULES.find( + mod => mod.packageRelativePath === extendPath, + ); + if (config == null) { + throw new Error("Couldn't find config"); + } + flatCode.push( + `import ${config.name} from '${config.moduleRelativePath}';`, + ); + flatExtends.push(config.name); + } + flatCode.push(''); + } + if (config.parserOptions) { + flatConfig.languageOptions ??= {}; + flatConfig.languageOptions.parserOptions = config.parserOptions; + } + + const flatConfigJson = JSON.stringify(flatConfig); + if (flatExtends.length > 0) { + flatCode.push( + 'export default (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray => [', + ...flatExtends.map(ext => `${ext}(plugin, parser),`), + flatConfigJson, + '];', + ); + } else { + flatCode.push( + `export default (_plugin: FlatConfig.Plugin, _parser: FlatConfig.Parser): FlatConfig.Config => (${flatConfigJson});`, + ); + } + const flatConfigStr = await prettier.format(flatCode.join('\n'), { parser: 'typescript', ...prettierConfig, }); fs.writeFileSync( - path.resolve(__dirname, `../src/configs/${name}.ts`), - configStr, + path.join(PACKAGES_CORE, 'src', 'configs', `${name}.ts`), + flatConfigStr, ); } interface ExtendedConfigSettings { - extraExtends?: readonly string[]; name: string; filters?: RuleFilter; ruleEntries: readonly RuleEntry[]; } async function writeExtendedConfig({ - extraExtends = [], filters: ruleFilter, name, ruleEntries, }: ExtendedConfigSettings): Promise { await writeConfig( () => ({ - extends: [...EXTENDS, ...extraExtends], + extends: [...CLASSIC_EXTENDS], rules: ruleEntries.reduce( (config, entry) => reducer(config, entry, ruleFilter), {}, @@ -200,28 +265,6 @@ async function main(): Promise { ); } - await writeConfig((): LinterConfig => { - const baseConfig: LinterConfig = { - parser: '@typescript-eslint/parser', - parserOptions: { - sourceType: 'module', - }, - plugins: ['@typescript-eslint'], - }; - - console.log(chalk.gray('Config values:')); - - const longestKey = Object.keys(baseConfig).reduce( - (previous, next) => Math.max(previous, next.length), - 0, - ); - for (const [key, value] of Object.entries(baseConfig)) { - console.log(' ', key.padEnd(longestKey), value); - } - - return baseConfig; - }, 'base'); - await writeExtendedConfig({ name: 'all', filters: { diff --git a/packages/repo-tools/src/generate-contributors.ts b/packages/repo-tools/src/generate-contributors.mts similarity index 96% rename from packages/repo-tools/src/generate-contributors.ts rename to packages/repo-tools/src/generate-contributors.mts index 92300d17ba1b..db9d72550c52 100644 --- a/packages/repo-tools/src/generate-contributors.ts +++ b/packages/repo-tools/src/generate-contributors.mts @@ -2,9 +2,12 @@ // https://developer.github.com/v3/repos/#list-contributors // this endpoint returns a list of contributors sorted by number of contributions +import fs from 'node:fs'; +import path from 'node:path'; + import fetch from 'cross-fetch'; -import * as fs from 'fs'; -import * as path from 'path'; + +import { REPO_ROOT } from './paths.mts'; const IGNORED_USERS = new Set([ 'dependabot[bot]', @@ -130,10 +133,7 @@ function writeTable(contributors: User[], perLine = 5): void { ); lines.push(''); - fs.writeFileSync( - path.join(__dirname, '../../../CONTRIBUTORS.md'), - lines.join('\n'), - ); + fs.writeFileSync(path.join(REPO_ROOT, 'CONTRIBUTORS.md'), lines.join('\n')); } async function main(): Promise { diff --git a/packages/repo-tools/src/generate-lib.ts b/packages/repo-tools/src/generate-lib.mts similarity index 95% rename from packages/repo-tools/src/generate-lib.ts rename to packages/repo-tools/src/generate-lib.mts index c9a0a722a02c..9f4bf761bf6f 100644 --- a/packages/repo-tools/src/generate-lib.ts +++ b/packages/repo-tools/src/generate-lib.mts @@ -1,3 +1,6 @@ +import fs from 'node:fs'; +import path from 'node:path'; + import prettier from '@prettier/sync'; import type { AnalyzeOptions, @@ -10,11 +13,11 @@ import { AST_TOKEN_TYPES } from '@typescript-eslint/types'; import type { TSESTreeOptions } from '@typescript-eslint/typescript-estree'; import { parse } from '@typescript-eslint/typescript-estree'; import { ESLint } from '@typescript-eslint/utils/ts-eslint'; -import * as fs from 'fs'; -import * as path from 'path'; import { rimraf } from 'rimraf'; import * as ts from 'typescript'; +import { PACKAGES_SCOPE_MANAGER, PACKAGES_TYPES, REPO_ROOT } from './paths.mts'; + function parseAndAnalyze( code: string, analyzeOptions: AnalyzeOptions, @@ -55,35 +58,13 @@ function addAutoGeneratedComment(code: string[]): string { } const PRETTIER_CONFIG = prettier.resolveConfig(__dirname); -const TS_LIB_FOLDER = path.resolve( - __dirname, - '..', - '..', - '..', - 'node_modules', - 'typescript', - 'lib', -); -const OUTPUT_FOLDER = path.resolve( - __dirname, - '..', - '..', - 'scope-manager', - 'src', - 'lib', -); -const TYPES_FILE = path.resolve( - __dirname, - '..', - '..', - 'types', - 'src', - 'lib.ts', -); +const TS_LIB_FOLDER = path.join(REPO_ROOT, 'node_modules', 'typescript', 'lib'); +const OUTPUT_FOLDER = path.join(PACKAGES_SCOPE_MANAGER, 'src', 'lib'); +const TYPES_FILE = path.join(PACKAGES_TYPES, 'src', 'lib.ts'); const BARREL_PATH = path.join(OUTPUT_FOLDER, 'index.ts'); const BASE_CONFIG_MODULE_NAME = 'base-config'; -const SHARED_CONFIG_MODULE = path.resolve( +const SHARED_CONFIG_MODULE = path.join( OUTPUT_FOLDER, `${BASE_CONFIG_MODULE_NAME}.ts`, ); diff --git a/packages/repo-tools/src/generate-sponsors.ts b/packages/repo-tools/src/generate-sponsors.mts similarity index 97% rename from packages/repo-tools/src/generate-sponsors.ts rename to packages/repo-tools/src/generate-sponsors.mts index e07e311ec67c..142029a61333 100644 --- a/packages/repo-tools/src/generate-sponsors.ts +++ b/packages/repo-tools/src/generate-sponsors.mts @@ -3,6 +3,8 @@ import * as fs from 'fs'; import * as path from 'path'; import prettier from 'prettier'; +import { PACKAGES_WEBSITE } from './paths.mts'; + const graphqlEndpoint = 'https://api.opencollective.com/graphql/v2'; const queries = { @@ -166,7 +168,7 @@ async function main(): Promise { }) .sort((a, b) => b.totalDonations - a.totalDonations); - const rcPath = path.resolve(__dirname, '../../website/data/sponsors.json'); + const rcPath = path.join(PACKAGES_WEBSITE, 'data', 'sponsors.json'); fs.writeFileSync(rcPath, await stringifyObject(rcPath, allSponsorsConfig)); } diff --git a/packages/repo-tools/src/paths.mts b/packages/repo-tools/src/paths.mts new file mode 100644 index 000000000000..1e6d101a2012 --- /dev/null +++ b/packages/repo-tools/src/paths.mts @@ -0,0 +1,13 @@ +import path from 'node:path'; +import url from 'node:url'; + +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); + +export const REPO_ROOT = path.resolve(__dirname, '..', '..', '..'); +export const PACKAGES = path.join(REPO_ROOT, 'packages'); + +export const PACKAGES_CORE = path.join(PACKAGES, 'core'); +export const PACKAGES_ESLINT_PLUGIN = path.join(PACKAGES, 'eslint-plugin'); +export const PACKAGES_SCOPE_MANAGER = path.join(PACKAGES, 'scope-manager'); +export const PACKAGES_TYPES = path.join(PACKAGES, 'types'); +export const PACKAGES_WEBSITE = path.join(PACKAGES, 'website'); diff --git a/packages/repo-tools/tsconfig.build.json b/packages/repo-tools/tsconfig.build.json index b9ac3e1b9770..992e2f19be74 100644 --- a/packages/repo-tools/tsconfig.build.json +++ b/packages/repo-tools/tsconfig.build.json @@ -1,6 +1,9 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { + // repo tools are executed with tsx + "allowImportingTsExtensions": true, + "noEmit": true, "composite": true, "outDir": "./dist", "rootDir": "./src", diff --git a/packages/rule-schema-to-typescript-types/project.json b/packages/rule-schema-to-typescript-types/project.json index ef69baa0b1c4..aec1aac4a026 100644 --- a/packages/rule-schema-to-typescript-types/project.json +++ b/packages/rule-schema-to-typescript-types/project.json @@ -10,8 +10,7 @@ "options": { "lintFilePatterns": [ "packages/rule-schema-to-typescript-types/**/*.{mts,cts,ts,tsx}" - ], - "ignorePath": ".eslintignore" + ] } } } diff --git a/packages/scope-manager/project.json b/packages/scope-manager/project.json index c2cfb9c5268d..57404d8be56f 100644 --- a/packages/scope-manager/project.json +++ b/packages/scope-manager/project.json @@ -53,8 +53,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/scope-manager/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/scope-manager/**/*.{mts,cts,ts,tsx}"] } }, "test": { diff --git a/packages/type-utils/project.json b/packages/type-utils/project.json index e928d931e50b..d0e7aae00be6 100644 --- a/packages/type-utils/project.json +++ b/packages/type-utils/project.json @@ -8,8 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/type-utils/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/type-utils/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/types/project.json b/packages/types/project.json index f106fdccab54..894995ce8c6a 100644 --- a/packages/types/project.json +++ b/packages/types/project.json @@ -8,8 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/types/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/types/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/typescript-estree/project.json b/packages/typescript-estree/project.json index cae10b5115f1..712ed6a03e6f 100644 --- a/packages/typescript-estree/project.json +++ b/packages/typescript-estree/project.json @@ -8,10 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": [ - "packages/typescript-estree/**/*.{mts,cts,ts,tsx}" - ], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/typescript-estree/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/utils/project.json b/packages/utils/project.json index e1f58d404355..83c47daae6c8 100644 --- a/packages/utils/project.json +++ b/packages/utils/project.json @@ -8,8 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/utils/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/utils/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/utils/src/ts-eslint/Config.ts b/packages/utils/src/ts-eslint/Config.ts index 534a41d0e07e..fac6b934bc62 100644 --- a/packages/utils/src/ts-eslint/Config.ts +++ b/packages/utils/src/ts-eslint/Config.ts @@ -131,6 +131,9 @@ export namespace FlatConfig { export type SeverityString = SharedConfig.SeverityString; export type SourceType = ParserOptionsTypes.SourceType | 'commonjs'; + export interface SharedConfigs { + [key: string]: Config; + } export interface PluginMeta { /** * The meta.name property should match the npm package name for your plugin. @@ -146,7 +149,7 @@ export namespace FlatConfig { * Shared configurations bundled with the plugin. * Users will reference these directly in their config (i.e. `plugin.configs.recommended`). */ - configs?: Record; + configs?: SharedConfigs; /** * Metadata about your plugin for easier debugging and more effective caching of plugins. */ @@ -165,7 +168,13 @@ export namespace FlatConfig { rules?: Record; } export interface Plugins { - [pluginAlias: string]: Plugin; + /** + * We intentionally omit the `configs` key from this object because it avoids + * type conflicts with old plugins that haven't updated their configs to flat configs yet. + * It's valid to reference these old plugins because ESLint won't access the + * `.config` property of a plugin when evaluating a flat config. + */ + [pluginAlias: string]: Omit; } export interface LinterOptions { diff --git a/packages/utils/src/ts-eslint/Parser.ts b/packages/utils/src/ts-eslint/Parser.ts index e709ef70df6c..1fa1a39000c8 100644 --- a/packages/utils/src/ts-eslint/Parser.ts +++ b/packages/utils/src/ts-eslint/Parser.ts @@ -66,6 +66,6 @@ export namespace Parser { // eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style export interface VisitorKeys { - [nodeType: string]: string[]; + [nodeType: string]: readonly string[]; } } diff --git a/packages/visitor-keys/project.json b/packages/visitor-keys/project.json index a8e8aa24d01c..ce0ed21517ac 100644 --- a/packages/visitor-keys/project.json +++ b/packages/visitor-keys/project.json @@ -8,8 +8,7 @@ "executor": "@nx/eslint:lint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["packages/visitor-keys/**/*.{mts,cts,ts,tsx}"], - "ignorePath": ".eslintignore" + "lintFilePatterns": ["packages/visitor-keys/**/*.{mts,cts,ts,tsx}"] } } } diff --git a/packages/visitor-keys/src/visitor-keys.ts b/packages/visitor-keys/src/visitor-keys.ts index 04aa32e5af20..d4297219a9cd 100644 --- a/packages/visitor-keys/src/visitor-keys.ts +++ b/packages/visitor-keys/src/visitor-keys.ts @@ -1,7 +1,7 @@ import type { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types'; import * as eslintVisitorKeys from 'eslint-visitor-keys'; -type VisitorKeys = Record; +type VisitorKeys = Record; type GetNodeTypeKeys = Exclude< keyof Extract, diff --git a/packages/website-eslint/package.json b/packages/website-eslint/package.json index 92a88a927fb2..94d0aaaeb800 100644 --- a/packages/website-eslint/package.json +++ b/packages/website-eslint/package.json @@ -27,7 +27,7 @@ "@typescript-eslint/utils": "6.13.2" }, "devDependencies": { - "@eslint/js": "8.53.0", + "@eslint/js": "*", "@typescript-eslint/eslint-plugin": "6.13.2", "@typescript-eslint/parser": "6.13.2", "@typescript-eslint/scope-manager": "6.13.2", diff --git a/packages/website-eslint/project.json b/packages/website-eslint/project.json index fbd7d76afe8f..fca9e1fa971a 100644 --- a/packages/website-eslint/project.json +++ b/packages/website-eslint/project.json @@ -11,8 +11,7 @@ "lintFilePatterns": [ "packages/website-eslint/**/*.{mts,cts,ts,tsx}", "packages/website-eslint/**/*.{mjs,cjs,js,jsx}" - ], - "ignorePath": ".eslintignore" + ] } } } diff --git a/packages/website/project.json b/packages/website/project.json index e256f9c0cb00..9c39fa7471c2 100644 --- a/packages/website/project.json +++ b/packages/website/project.json @@ -19,8 +19,7 @@ "lintFilePatterns": [ "packages/website/**/*.{mts,cts,ts,tsx}", "packages/website/**/*.{mjs,cjs,js,jsx}" - ], - "ignorePath": ".eslintignore" + ] } } } diff --git a/tsconfig.base.json b/tsconfig.base.json index fd7ed6a809f3..5b45dcddb0bf 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -7,7 +7,7 @@ "declarationMap": true, "esModuleInterop": true, "module": "Node16", - "moduleResolution": "node16", + "moduleResolution": "Node16", "noImplicitReturns": true, "pretty": true, "skipLibCheck": true, diff --git a/tsconfig.eslint.json b/tsconfig.json similarity index 87% rename from tsconfig.eslint.json rename to tsconfig.json index 36b912142b9a..36029ca2fd58 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.json @@ -6,8 +6,10 @@ }, "extends": "./tsconfig.base.json", "include": [ + "typings", "tools/**/*.ts", ".eslintrc.js", + "eslint.config.js", "jest.config.base.js", "jest.config.js", "jest.preset.js" diff --git a/typings/eslint-plugin-eslint-comments.d.ts b/typings/eslint-plugin-eslint-comments.d.ts new file mode 100644 index 000000000000..279a27f80faa --- /dev/null +++ b/typings/eslint-plugin-eslint-comments.d.ts @@ -0,0 +1,14 @@ +declare module 'eslint-plugin-eslint-comments' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + recommended: ClassicConfig.Config; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-eslint-plugin.d.ts b/typings/eslint-plugin-eslint-plugin.d.ts new file mode 100644 index 000000000000..f0afd05081f2 --- /dev/null +++ b/typings/eslint-plugin-eslint-plugin.d.ts @@ -0,0 +1,19 @@ +declare module 'eslint-plugin-eslint-plugin' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + all: ClassicConfig.Config; + recommended: ClassicConfig.Config; + rules: ClassicConfig.Config; + tests: ClassicConfig.Config; + 'rules-recommended': ClassicConfig.Config; + 'tests-recommended': ClassicConfig.Config; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-import.d.ts b/typings/eslint-plugin-import.d.ts new file mode 100644 index 000000000000..60742fad493a --- /dev/null +++ b/typings/eslint-plugin-import.d.ts @@ -0,0 +1,21 @@ +declare module 'eslint-plugin-import' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + recommended: ClassicConfig.Config; + errors: ClassicConfig.Config; + warnings: ClassicConfig.Config; + 'stage-0': ClassicConfig.Config; + react: ClassicConfig.Config; + 'react-native': ClassicConfig.Config; + electron: ClassicConfig.Config; + typescript: ClassicConfig.Config; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-jest.d.ts b/typings/eslint-plugin-jest.d.ts new file mode 100644 index 000000000000..c7ccc8577e89 --- /dev/null +++ b/typings/eslint-plugin-jest.d.ts @@ -0,0 +1,21 @@ +declare module 'eslint-plugin-jest' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + all: ClassicConfig.Config; + recommended: ClassicConfig.Config; + style: ClassicConfig.Config; + }; + environments: { + globals: { + globals: ClassicConfig.EnvironmentConfig; + }; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-jsx-a11y.d.ts b/typings/eslint-plugin-jsx-a11y.d.ts new file mode 100644 index 000000000000..d5fba291eb1f --- /dev/null +++ b/typings/eslint-plugin-jsx-a11y.d.ts @@ -0,0 +1,15 @@ +declare module 'eslint-plugin-jsx-a11y' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + recommended: ClassicConfig.Config; + strict: ClassicConfig.Config; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-react-hooks.d.ts b/typings/eslint-plugin-react-hooks.d.ts new file mode 100644 index 000000000000..ff5f964ccc0a --- /dev/null +++ b/typings/eslint-plugin-react-hooks.d.ts @@ -0,0 +1,14 @@ +declare module 'eslint-plugin-react-hooks' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + recommended: ClassicConfig.Config; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-react.d.ts b/typings/eslint-plugin-react.d.ts new file mode 100644 index 000000000000..d1199b9c6850 --- /dev/null +++ b/typings/eslint-plugin-react.d.ts @@ -0,0 +1,16 @@ +declare module 'eslint-plugin-react' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + recommended: ClassicConfig.Config; + all: ClassicConfig.Config; + 'jsx-runtime': ClassicConfig.Config; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-simple-import-sort.d.ts b/typings/eslint-plugin-simple-import-sort.d.ts new file mode 100644 index 000000000000..fd515a9f662b --- /dev/null +++ b/typings/eslint-plugin-simple-import-sort.d.ts @@ -0,0 +1,8 @@ +declare module 'eslint-plugin-simple-import-sort' { + import type { Linter } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint-plugin-unicorn.d.ts b/typings/eslint-plugin-unicorn.d.ts new file mode 100644 index 000000000000..fa0e2752590a --- /dev/null +++ b/typings/eslint-plugin-unicorn.d.ts @@ -0,0 +1,15 @@ +declare module 'eslint-plugin-unicorn' { + import type { + ClassicConfig, + Linter, + } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + recommended: ClassicConfig.Config; + all: ClassicConfig.Config; + }; + rules: NonNullable; + }; + export = exprt; +} diff --git a/typings/eslint__eslintrc.d.ts b/typings/eslint__eslintrc.d.ts new file mode 100644 index 000000000000..78462ba5c884 --- /dev/null +++ b/typings/eslint__eslintrc.d.ts @@ -0,0 +1,22 @@ +declare module '@eslint/eslintrc' { + import type { + ClassicConfig, + FlatConfig, + } from '@typescript-eslint/utils/ts-eslint'; + + declare class FlatCompat { + constructor(options?: { + baseDirectory?: string; + resolvePluginsRelativeTo?: string; + }); + + config(eslintrcConfig: ClassicConfig.Config): FlatConfig.ConfigArray; + env(envConfig: ClassicConfig.EnvironmentConfig): FlatConfig.ConfigArray; + extends(...configsToExtend: string[]): FlatConfig.ConfigArray; + plugins(...plugins: string[]): FlatConfig.ConfigArray; + } + declare const exprt: { + FlatCompat: typeof FlatCompat; + }; + export = exprt; +} diff --git a/typings/eslint__js.d.ts b/typings/eslint__js.d.ts new file mode 100644 index 000000000000..6e50127f6b4d --- /dev/null +++ b/typings/eslint__js.d.ts @@ -0,0 +1,11 @@ +declare module '@eslint/js' { + import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'; + + declare const exprt: { + configs: { + all: FlatConfig.Config; + recommended: FlatConfig.Config; + }; + }; + export = exprt; +} diff --git a/yarn.lock b/yarn.lock index e74659c009be..5e141a6d64d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3240,6 +3240,30 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/eslintrc@npm:2.1.4" + dependencies: + ajv: ^6.12.4 + debug: ^4.3.2 + espree: ^9.6.0 + 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 + checksum: 10957c7592b20ca0089262d8c2a8accbad14b4f6507e35416c32ee6b4dbf9cad67dfb77096bbd405405e9ada2b107f3797fe94362e1c55e0b09d6e90dd149127 + languageName: node + linkType: hard + +"@eslint/js@npm:*": + version: 8.53.0 + resolution: "@eslint/js@npm:8.53.0" + checksum: e0d5cfb0000aaee237c8e6d6d6e366faa60b1ef7f928ce17778373aa44d3b886368f6d5e1f97f913f0f16801aad016db8b8df78418c9d18825c15590328028af + languageName: node + linkType: hard + "@eslint/js@npm:8.48.0": version: 8.48.0 resolution: "@eslint/js@npm:8.48.0" @@ -3247,10 +3271,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.53.0": - version: 8.53.0 - resolution: "@eslint/js@npm:8.53.0" - checksum: e0d5cfb0000aaee237c8e6d6d6e366faa60b1ef7f928ce17778373aa44d3b886368f6d5e1f97f913f0f16801aad016db8b8df78418c9d18825c15590328028af +"@eslint/js@npm:8.55.0, @eslint/js@npm:^8.55.0": + version: 8.55.0 + resolution: "@eslint/js@npm:8.55.0" + checksum: fa33ef619f0646ed15649b0c2e313e4d9ccee8425884bdbfc78020d6b6b64c0c42fa9d83061d0e6158e1d4274f03f0f9008786540e2efab8fcdc48082259908c languageName: node linkType: hard @@ -3288,6 +3312,17 @@ __metadata: languageName: node linkType: hard +"@humanwhocodes/config-array@npm:^0.11.13": + version: 0.11.13 + resolution: "@humanwhocodes/config-array@npm:0.11.13" + dependencies: + "@humanwhocodes/object-schema": ^2.0.1 + debug: ^4.1.1 + minimatch: ^3.0.5 + checksum: f8ea57b0d7ed7f2d64cd3944654976829d9da91c04d9c860e18804729a33f7681f78166ef4c761850b8c324d362f7d53f14c5c44907a6b38b32c703ff85e4805 + languageName: node + linkType: hard + "@humanwhocodes/module-importer@npm:^1.0.1": version: 1.0.1 resolution: "@humanwhocodes/module-importer@npm:1.0.1" @@ -3302,6 +3337,13 @@ __metadata: languageName: node linkType: hard +"@humanwhocodes/object-schema@npm:^2.0.1": + version: 2.0.1 + resolution: "@humanwhocodes/object-schema@npm:2.0.1" + checksum: 24929487b1ed48795d2f08346a0116cc5ee4634848bce64161fb947109352c562310fd159fc64dda0e8b853307f5794605191a9547f7341158559ca3c8262a45 + languageName: node + linkType: hard + "@hutson/parse-repository-url@npm:^3.0.0": version: 3.0.2 resolution: "@hutson/parse-repository-url@npm:3.0.2" @@ -5819,7 +5861,26 @@ __metadata: languageName: unknown linkType: soft -"@typescript-eslint/eslint-plugin-internal@workspace:packages/eslint-plugin-internal": +"@typescript-eslint/core@6.13.2, @typescript-eslint/core@workspace:packages/core": + version: 0.0.0-use.local + resolution: "@typescript-eslint/core@workspace:packages/core" + dependencies: + "@typescript-eslint/eslint-plugin": 6.13.2 + "@typescript-eslint/parser": 6.13.2 + downlevel-dts: "*" + jest: 29.7.0 + prettier: ^3.0.3 + rimraf: "*" + typescript: "*" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + languageName: unknown + linkType: soft + +"@typescript-eslint/eslint-plugin-internal@6.13.2, @typescript-eslint/eslint-plugin-internal@workspace:packages/eslint-plugin-internal": version: 0.0.0-use.local resolution: "@typescript-eslint/eslint-plugin-internal@workspace:packages/eslint-plugin-internal" dependencies: @@ -5934,6 +5995,7 @@ __metadata: dependencies: "@nx/devkit": "*" "@prettier/sync": "*" + cross-env: "*" cross-fetch: "*" execa: "*" prettier: ^3.0.3 @@ -6056,6 +6118,8 @@ __metadata: "@babel/eslint-parser": ^7.23.3 "@babel/parser": ^7.23.3 "@babel/types": ^7.23.3 + "@eslint/eslintrc": ^2.1.4 + "@eslint/js": ^8.55.0 "@nx/eslint": 17.1.2 "@nx/jest": 17.1.2 "@nx/workspace": 17.1.2 @@ -6074,11 +6138,14 @@ __metadata: "@types/node": ^20.0.0 "@types/semver": ^7.5.0 "@types/tmp": ^0.2.3 + "@typescript-eslint/core": 6.13.2 + "@typescript-eslint/eslint-plugin-internal": 6.13.2 console-fail-test: ^0.2.3 + cross-env: ^7.0.3 cross-fetch: ^4.0.0 cspell: ^7.0.0 downlevel-dts: ">=0.11.0" - eslint: ^8.47.0 + eslint: ^8.55.0 eslint-plugin-deprecation: ^2.0.0 eslint-plugin-eslint-comments: ^3.2.0 eslint-plugin-eslint-plugin: ^5.1.0 @@ -6091,6 +6158,7 @@ __metadata: eslint-plugin-unicorn: ^48.0.1 execa: 7.1.1 glob: ^10.3.3 + globals: ^13.23.0 husky: ^8.0.3 jest: 29.7.0 jest-diff: ^29.6.2 @@ -6229,7 +6297,7 @@ __metadata: version: 0.0.0-use.local resolution: "@typescript-eslint/website-eslint@workspace:packages/website-eslint" dependencies: - "@eslint/js": 8.53.0 + "@eslint/js": "*" "@typescript-eslint/eslint-plugin": 6.13.2 "@typescript-eslint/parser": 6.13.2 "@typescript-eslint/scope-manager": 6.13.2 @@ -6248,6 +6316,13 @@ __metadata: languageName: unknown linkType: soft +"@ungap/structured-clone@npm:^1.2.0": + version: 1.2.0 + resolution: "@ungap/structured-clone@npm:1.2.0" + checksum: 4f656b7b4672f2ce6e272f2427d8b0824ed11546a601d8d5412b9d7704e83db38a8d9f402ecdf2b9063fc164af842ad0ec4a55819f621ed7e7ea4d1efcc74524 + languageName: node + linkType: hard + "@webassemblyjs/ast@npm:1.11.5, @webassemblyjs/ast@npm:^1.11.5": version: 1.11.5 resolution: "@webassemblyjs/ast@npm:1.11.5" @@ -8586,6 +8661,18 @@ __metadata: languageName: node linkType: hard +"cross-env@npm:*, cross-env@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-env@npm:7.0.3" + dependencies: + cross-spawn: ^7.0.1 + bin: + cross-env: src/bin/cross-env.js + cross-env-shell: src/bin/cross-env-shell.js + checksum: 26f2f3ea2ab32617f57effb70d329c2070d2f5630adc800985d8b30b56e8bf7f5f439dd3a0358b79cee6f930afc23cf8e23515f17ccfb30092c6b62c6b630a79 + languageName: node + linkType: hard + "cross-fetch@npm:*, cross-fetch@npm:^4.0.0": version: 4.0.0 resolution: "cross-fetch@npm:4.0.0" @@ -8604,7 +8691,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -10231,7 +10318,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:*, eslint@npm:^8.47.0": +"eslint@npm:*": version: 8.48.0 resolution: "eslint@npm:8.48.0" dependencies: @@ -10278,6 +10365,54 @@ __metadata: languageName: node linkType: hard +"eslint@npm:^8.55.0": + version: 8.55.0 + resolution: "eslint@npm:8.55.0" + dependencies: + "@eslint-community/eslint-utils": ^4.2.0 + "@eslint-community/regexpp": ^4.6.1 + "@eslint/eslintrc": ^2.1.4 + "@eslint/js": 8.55.0 + "@humanwhocodes/config-array": ^0.11.13 + "@humanwhocodes/module-importer": ^1.0.1 + "@nodelib/fs.walk": ^1.2.8 + "@ungap/structured-clone": ^1.2.0 + ajv: ^6.12.4 + 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.2 + eslint-visitor-keys: ^3.4.3 + espree: ^9.6.1 + 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 + 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.3 + strip-ansi: ^6.0.1 + text-table: ^0.2.0 + bin: + eslint: bin/eslint.js + checksum: 83f82a604559dc1faae79d28fdf3dfc9e592ca221052e2ea516e1b379b37e77e4597705a16880e2f5ece4f79087c1dd13fd7f6e9746f794a401175519db18b41 + languageName: node + linkType: hard + "espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" @@ -11490,6 +11625,15 @@ __metadata: languageName: node linkType: hard +"globals@npm:^13.23.0": + version: 13.23.0 + resolution: "globals@npm:13.23.0" + dependencies: + type-fest: ^0.20.2 + checksum: 194c97cf8d1ef6ba59417234c2386549c4103b6e5f24b1ff1952de61a4753e5d2069435ba629de711a6480b1b1d114a98e2ab27f85e966d5a10c319c3bbd3dc3 + languageName: node + linkType: hard + "globalthis@npm:^1.0.3": version: 1.0.3 resolution: "globalthis@npm:1.0.3"