Initial commit - Todo app frontend

This commit is contained in:
2026-01-28 16:46:44 +00:00
commit 95b816a2e6
15978 changed files with 2514406 additions and 0 deletions

21
node_modules/@typescript-eslint/eslint-plugin/LICENSE generated vendored Normal file
View File

@@ -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.

View File

@@ -0,0 +1,12 @@
# `@typescript-eslint/eslint-plugin`
An ESLint plugin which provides lint rules for TypeScript codebases.
[![NPM Version](https://img.shields.io/npm/v/@typescript-eslint/eslint-plugin.svg?style=flat-square)](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin)
[![NPM Downloads](https://img.shields.io/npm/dm/@typescript-eslint/eslint-plugin.svg?style=flat-square)](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin)
👉 See **https://typescript-eslint.io/getting-started** for our Getting Started docs.
> See https://typescript-eslint.io for general documentation on typescript-eslint, the tooling that allows you to run ESLint and Prettier on TypeScript code.
<!-- Local path for docs: docs/packages/ESLint_Plugin.mdx -->

View File

@@ -0,0 +1,10 @@
/**
* 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.
*/
declare const config: (style: "glob" | "minimatch") => {
files: string[];
rules: Record<string, "error" | "off" | "warn">;
};
export = config;

View File

@@ -0,0 +1,46 @@
"use strict";
// NOTE: this file is isolated to be shared across legacy and flat configs.
/**
* 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.
*/
const config = (style) => ({
files: style === 'glob'
? // classic configs use glob syntax
['*.ts', '*.tsx', '*.mts', '*.cts']
: // flat configs use minimatch syntax
['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],
rules: {
'constructor-super': 'off', // ts(2335) & ts(2377)
'getter-return': 'off', // ts(2378)
'no-class-assign': 'off', // ts(2629)
'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-native-nonconstructor': 'off', // ts(7009)
// "no-new-symbol" was deprecated in ESLint 9.0.0 and will be removed in
// ESLint v11.0.0. See:
// https://eslint.org/docs/latest/rules/no-new-symbol
// We need to keep the rule disabled until TSESLint drops support for
// ESlint 8. See:
// https://github.com/typescript-eslint/typescript-eslint/pull/8895
'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
'no-with': 'off', // ts(1101) & ts(2410)
'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
},
});
module.exports = config;

View File

@@ -0,0 +1,159 @@
declare const _default: {
extends: string[];
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/class-literal-property-style': "error";
'class-methods-use-this': "off";
'@typescript-eslint/class-methods-use-this': "error";
'@typescript-eslint/consistent-generic-constructors': "error";
'@typescript-eslint/consistent-indexed-object-style': "error";
'consistent-return': "off";
'@typescript-eslint/consistent-return': "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";
'init-declarations': "off";
'@typescript-eslint/init-declarations': "error";
'max-params': "off";
'@typescript-eslint/max-params': "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-array-delete': "error";
'@typescript-eslint/no-base-to-string': "error";
'@typescript-eslint/no-confusing-non-null-assertion': "error";
'@typescript-eslint/no-confusing-void-expression': "error";
'@typescript-eslint/no-deprecated': "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-object-type': "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-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-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-misused-spread': "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";
'@typescript-eslint/no-restricted-types': "error";
'no-shadow': "off";
'@typescript-eslint/no-shadow': "error";
'@typescript-eslint/no-this-alias': "error";
'@typescript-eslint/no-unnecessary-boolean-literal-compare': "error";
'@typescript-eslint/no-unnecessary-condition': "error";
'@typescript-eslint/no-unnecessary-parameter-property-assignment': "error";
'@typescript-eslint/no-unnecessary-qualifier': "error";
'@typescript-eslint/no-unnecessary-template-expression': "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-unnecessary-type-conversion': "error";
'@typescript-eslint/no-unnecessary-type-parameters': "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-function-type': "error";
'@typescript-eslint/no-unsafe-member-access': "error";
'@typescript-eslint/no-unsafe-return': "error";
'@typescript-eslint/no-unsafe-type-assertion': "error";
'@typescript-eslint/no-unsafe-unary-minus': "error";
'no-unused-expressions': "off";
'@typescript-eslint/no-unused-expressions': "error";
'no-unused-private-class-members': "off";
'@typescript-eslint/no-unused-private-class-members': "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-default-assignment': "error";
'@typescript-eslint/no-useless-empty-export': "error";
'@typescript-eslint/no-wrapper-object-types': "error";
'@typescript-eslint/non-nullable-type-assertion-style': "error";
'no-throw-literal': "off";
'@typescript-eslint/only-throw-error': "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-find': "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";
'prefer-promise-reject-errors': "off";
'@typescript-eslint/prefer-promise-reject-errors': "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/promise-function-async': "error";
'@typescript-eslint/related-getter-setter-pairs': "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";
'@typescript-eslint/strict-boolean-expressions': "error";
'@typescript-eslint/strict-void-return': "error";
'@typescript-eslint/switch-exhaustiveness-check': "error";
'@typescript-eslint/triple-slash-reference': "error";
'@typescript-eslint/unbound-method': "error";
'@typescript-eslint/unified-signatures': "error";
'@typescript-eslint/use-unknown-in-catch-callback-variable': "error";
};
};
export = _default;

View File

@@ -0,0 +1,165 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
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/class-literal-property-style': 'error',
'class-methods-use-this': 'off',
'@typescript-eslint/class-methods-use-this': 'error',
'@typescript-eslint/consistent-generic-constructors': 'error',
'@typescript-eslint/consistent-indexed-object-style': 'error',
'consistent-return': 'off',
'@typescript-eslint/consistent-return': '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',
'init-declarations': 'off',
'@typescript-eslint/init-declarations': 'error',
'max-params': 'off',
'@typescript-eslint/max-params': '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-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-non-null-assertion': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': '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-object-type': '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-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-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-misused-spread': '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',
'@typescript-eslint/no-restricted-types': 'error',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-parameter-property-assignment': 'error',
'@typescript-eslint/no-unnecessary-qualifier': 'error',
'@typescript-eslint/no-unnecessary-template-expression': '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-unnecessary-type-conversion': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': '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-function-type': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'@typescript-eslint/no-unsafe-type-assertion': 'error',
'@typescript-eslint/no-unsafe-unary-minus': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'no-unused-private-class-members': 'off',
'@typescript-eslint/no-unused-private-class-members': '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-default-assignment': 'error',
'@typescript-eslint/no-useless-empty-export': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': '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-find': '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',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': '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/promise-function-async': 'error',
'@typescript-eslint/related-getter-setter-pairs': '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',
'@typescript-eslint/strict-boolean-expressions': 'error',
'@typescript-eslint/strict-void-return': 'error',
'@typescript-eslint/switch-exhaustiveness-check': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/unified-signatures': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
},
};

View File

@@ -0,0 +1,8 @@
declare const _default: {
parser: string;
parserOptions: {
sourceType: "module";
};
plugins: string[];
};
export = _default;

View File

@@ -0,0 +1,6 @@
"use strict";
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: { sourceType: 'module' },
plugins: ['@typescript-eslint'],
};

View File

@@ -0,0 +1,71 @@
declare const _default: {
parserOptions: {
program: null;
project: false;
projectService: false;
};
rules: {
'@typescript-eslint/await-thenable': "off";
'@typescript-eslint/consistent-return': "off";
'@typescript-eslint/consistent-type-exports': "off";
'@typescript-eslint/dot-notation': "off";
'@typescript-eslint/naming-convention': "off";
'@typescript-eslint/no-array-delete': "off";
'@typescript-eslint/no-base-to-string': "off";
'@typescript-eslint/no-confusing-void-expression': "off";
'@typescript-eslint/no-deprecated': "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-misused-spread': "off";
'@typescript-eslint/no-mixed-enums': "off";
'@typescript-eslint/no-redundant-type-constituents': "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-template-expression': "off";
'@typescript-eslint/no-unnecessary-type-arguments': "off";
'@typescript-eslint/no-unnecessary-type-assertion': "off";
'@typescript-eslint/no-unnecessary-type-conversion': "off";
'@typescript-eslint/no-unnecessary-type-parameters': "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-type-assertion': "off";
'@typescript-eslint/no-unsafe-unary-minus': "off";
'@typescript-eslint/no-useless-default-assignment': "off";
'@typescript-eslint/non-nullable-type-assertion-style': "off";
'@typescript-eslint/only-throw-error': "off";
'@typescript-eslint/prefer-destructuring': "off";
'@typescript-eslint/prefer-find': "off";
'@typescript-eslint/prefer-includes': "off";
'@typescript-eslint/prefer-nullish-coalescing': "off";
'@typescript-eslint/prefer-optional-chain': "off";
'@typescript-eslint/prefer-promise-reject-errors': "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/related-getter-setter-pairs': "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/strict-void-return': "off";
'@typescript-eslint/switch-exhaustiveness-check': "off";
'@typescript-eslint/unbound-method': "off";
'@typescript-eslint/use-unknown-in-catch-callback-variable': "off";
};
};
export = _default;

View File

@@ -0,0 +1,73 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
parserOptions: { program: null, project: false, projectService: false },
rules: {
'@typescript-eslint/await-thenable': 'off',
'@typescript-eslint/consistent-return': 'off',
'@typescript-eslint/consistent-type-exports': 'off',
'@typescript-eslint/dot-notation': 'off',
'@typescript-eslint/naming-convention': 'off',
'@typescript-eslint/no-array-delete': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/no-confusing-void-expression': 'off',
'@typescript-eslint/no-deprecated': '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-misused-spread': 'off',
'@typescript-eslint/no-mixed-enums': 'off',
'@typescript-eslint/no-redundant-type-constituents': '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-template-expression': 'off',
'@typescript-eslint/no-unnecessary-type-arguments': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-unnecessary-type-conversion': 'off',
'@typescript-eslint/no-unnecessary-type-parameters': '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-type-assertion': 'off',
'@typescript-eslint/no-unsafe-unary-minus': 'off',
'@typescript-eslint/no-useless-default-assignment': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/only-throw-error': 'off',
'@typescript-eslint/prefer-destructuring': 'off',
'@typescript-eslint/prefer-find': 'off',
'@typescript-eslint/prefer-includes': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/prefer-promise-reject-errors': '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/related-getter-setter-pairs': '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/strict-void-return': 'off',
'@typescript-eslint/switch-exhaustiveness-check': 'off',
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'off',
},
};

View File

@@ -0,0 +1,12 @@
/**
* 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.
*/
declare const _default: {
overrides: {
files: string[];
rules: Record<string, "error" | "off" | "warn">;
}[];
};
export = _default;

View File

@@ -0,0 +1,13 @@
"use strict";
/**
* 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.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const eslint_recommended_raw_1 = __importDefault(require("../eslint-recommended-raw"));
module.exports = {
overrides: [(0, eslint_recommended_raw_1.default)('glob')],
};

View File

@@ -0,0 +1,33 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/await-thenable': "error";
'@typescript-eslint/no-array-delete': "error";
'@typescript-eslint/no-base-to-string': "error";
'@typescript-eslint/no-duplicate-type-constituents': "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-misused-promises': "error";
'@typescript-eslint/no-redundant-type-constituents': "error";
'@typescript-eslint/no-unnecessary-type-assertion': "error";
'@typescript-eslint/no-unsafe-argument': "error";
'@typescript-eslint/no-unsafe-assignment': "error";
'@typescript-eslint/no-unsafe-call': "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-throw-literal': "off";
'@typescript-eslint/only-throw-error': "error";
'prefer-promise-reject-errors': "off";
'@typescript-eslint/prefer-promise-reject-errors': "error";
'require-await': "off";
'@typescript-eslint/require-await': "error";
'@typescript-eslint/restrict-plus-operands': "error";
'@typescript-eslint/restrict-template-expressions': "error";
'@typescript-eslint/unbound-method': "error";
};
};
export = _default;

View File

@@ -0,0 +1,39 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-duplicate-type-constituents': '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-misused-promises': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': '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-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': 'error',
'@typescript-eslint/restrict-template-expressions': 'error',
'@typescript-eslint/unbound-method': 'error',
},
};

View File

@@ -0,0 +1,56 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/await-thenable': "error";
'@typescript-eslint/ban-ts-comment': "error";
'no-array-constructor': "off";
'@typescript-eslint/no-array-constructor': "error";
'@typescript-eslint/no-array-delete': "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-empty-object-type': "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";
'@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-require-imports': "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-function-type': "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";
'@typescript-eslint/no-wrapper-object-types': "error";
'no-throw-literal': "off";
'@typescript-eslint/only-throw-error': "error";
'@typescript-eslint/prefer-as-const': "error";
'@typescript-eslint/prefer-namespace-keyword': "error";
'prefer-promise-reject-errors': "off";
'@typescript-eslint/prefer-promise-reject-errors': "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";
};
};
export = _default;

View File

@@ -0,0 +1,62 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': 'error',
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-array-delete': '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-empty-object-type': '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',
'@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-require-imports': '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-function-type': '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',
'@typescript-eslint/no-wrapper-object-types': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': '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',
},
};

View File

@@ -0,0 +1,29 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/ban-ts-comment': "error";
'no-array-constructor': "off";
'@typescript-eslint/no-array-constructor': "error";
'@typescript-eslint/no-duplicate-enum-values': "error";
'@typescript-eslint/no-empty-object-type': "error";
'@typescript-eslint/no-explicit-any': "error";
'@typescript-eslint/no-extra-non-null-assertion': "error";
'@typescript-eslint/no-misused-new': "error";
'@typescript-eslint/no-namespace': "error";
'@typescript-eslint/no-non-null-asserted-optional-chain': "error";
'@typescript-eslint/no-require-imports': "error";
'@typescript-eslint/no-this-alias': "error";
'@typescript-eslint/no-unnecessary-type-constraint': "error";
'@typescript-eslint/no-unsafe-declaration-merging': "error";
'@typescript-eslint/no-unsafe-function-type': "error";
'no-unused-expressions': "off";
'@typescript-eslint/no-unused-expressions': "error";
'no-unused-vars': "off";
'@typescript-eslint/no-unused-vars': "error";
'@typescript-eslint/no-wrapper-object-types': "error";
'@typescript-eslint/prefer-as-const': "error";
'@typescript-eslint/prefer-namespace-keyword': "error";
'@typescript-eslint/triple-slash-reference': "error";
};
};
export = _default;

View File

@@ -0,0 +1,35 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
rules: {
'@typescript-eslint/ban-ts-comment': 'error',
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-duplicate-enum-values': 'error',
'@typescript-eslint/no-empty-object-type': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extra-non-null-assertion': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
'@typescript-eslint/no-unsafe-function-type': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
},
};

View File

@@ -0,0 +1,64 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/await-thenable': "error";
'@typescript-eslint/no-array-delete': "error";
'@typescript-eslint/no-base-to-string': "error";
'@typescript-eslint/no-confusing-void-expression': "error";
'@typescript-eslint/no-deprecated': "error";
'@typescript-eslint/no-duplicate-type-constituents': "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-meaningless-void-operator': "error";
'@typescript-eslint/no-misused-promises': "error";
'@typescript-eslint/no-misused-spread': "error";
'@typescript-eslint/no-mixed-enums': "error";
'@typescript-eslint/no-redundant-type-constituents': "error";
'@typescript-eslint/no-unnecessary-boolean-literal-compare': "error";
'@typescript-eslint/no-unnecessary-condition': "error";
'@typescript-eslint/no-unnecessary-template-expression': "error";
'@typescript-eslint/no-unnecessary-type-arguments': "error";
'@typescript-eslint/no-unnecessary-type-assertion': "error";
'@typescript-eslint/no-unnecessary-type-conversion': "error";
'@typescript-eslint/no-unnecessary-type-parameters': "error";
'@typescript-eslint/no-unsafe-argument': "error";
'@typescript-eslint/no-unsafe-assignment': "error";
'@typescript-eslint/no-unsafe-call': "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";
'@typescript-eslint/no-useless-default-assignment': "error";
'no-throw-literal': "off";
'@typescript-eslint/only-throw-error': "error";
'prefer-promise-reject-errors': "off";
'@typescript-eslint/prefer-promise-reject-errors': "error";
'@typescript-eslint/prefer-reduce-type-parameter': "error";
'@typescript-eslint/prefer-return-this-type': "error";
'@typescript-eslint/related-getter-setter-pairs': "error";
'require-await': "off";
'@typescript-eslint/require-await': "error";
'@typescript-eslint/restrict-plus-operands': ["error", {
allowAny: boolean;
allowBoolean: boolean;
allowNullish: boolean;
allowNumberAndString: boolean;
allowRegExp: boolean;
}];
'@typescript-eslint/restrict-template-expressions': ["error", {
allowAny: boolean;
allowBoolean: boolean;
allowNever: boolean;
allowNullish: boolean;
allowNumber: boolean;
allowRegExp: boolean;
}];
'no-return-await': "off";
'@typescript-eslint/return-await': ["error", string];
'@typescript-eslint/unbound-method': "error";
'@typescript-eslint/use-unknown-in-catch-callback-variable': "error";
};
};
export = _default;

View File

@@ -0,0 +1,79 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': 'error',
'@typescript-eslint/no-duplicate-type-constituents': '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-meaningless-void-operator': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-misused-spread': 'error',
'@typescript-eslint/no-mixed-enums': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-template-expression': 'error',
'@typescript-eslint/no-unnecessary-type-arguments': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unnecessary-type-conversion': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': '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',
'@typescript-eslint/no-useless-default-assignment': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/prefer-return-this-type': 'error',
'@typescript-eslint/related-getter-setter-pairs': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNullish: false,
allowNumberAndString: false,
allowRegExp: false,
},
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNever: false,
allowNullish: false,
allowNumber: false,
allowRegExp: false,
},
],
'no-return-await': 'off',
'@typescript-eslint/return-await': [
'error',
'error-handling-correctness-only',
],
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
},
};

View File

@@ -0,0 +1,98 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/await-thenable': "error";
'@typescript-eslint/ban-ts-comment': ["error", {
minimumDescriptionLength: number;
}];
'no-array-constructor': "off";
'@typescript-eslint/no-array-constructor': "error";
'@typescript-eslint/no-array-delete': "error";
'@typescript-eslint/no-base-to-string': "error";
'@typescript-eslint/no-confusing-void-expression': "error";
'@typescript-eslint/no-deprecated': "error";
'@typescript-eslint/no-duplicate-enum-values': "error";
'@typescript-eslint/no-duplicate-type-constituents': "error";
'@typescript-eslint/no-dynamic-delete': "error";
'@typescript-eslint/no-empty-object-type': "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";
'@typescript-eslint/no-meaningless-void-operator': "error";
'@typescript-eslint/no-misused-new': "error";
'@typescript-eslint/no-misused-promises': "error";
'@typescript-eslint/no-misused-spread': "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-require-imports': "error";
'@typescript-eslint/no-this-alias': "error";
'@typescript-eslint/no-unnecessary-boolean-literal-compare': "error";
'@typescript-eslint/no-unnecessary-condition': "error";
'@typescript-eslint/no-unnecessary-template-expression': "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-unnecessary-type-conversion': "error";
'@typescript-eslint/no-unnecessary-type-parameters': "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-function-type': "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-useless-constructor': "off";
'@typescript-eslint/no-useless-constructor': "error";
'@typescript-eslint/no-useless-default-assignment': "error";
'@typescript-eslint/no-wrapper-object-types': "error";
'no-throw-literal': "off";
'@typescript-eslint/only-throw-error': "error";
'@typescript-eslint/prefer-as-const': "error";
'@typescript-eslint/prefer-literal-enum-member': "error";
'@typescript-eslint/prefer-namespace-keyword': "error";
'prefer-promise-reject-errors': "off";
'@typescript-eslint/prefer-promise-reject-errors': "error";
'@typescript-eslint/prefer-reduce-type-parameter': "error";
'@typescript-eslint/prefer-return-this-type': "error";
'@typescript-eslint/related-getter-setter-pairs': "error";
'require-await': "off";
'@typescript-eslint/require-await': "error";
'@typescript-eslint/restrict-plus-operands': ["error", {
allowAny: boolean;
allowBoolean: boolean;
allowNullish: boolean;
allowNumberAndString: boolean;
allowRegExp: boolean;
}];
'@typescript-eslint/restrict-template-expressions': ["error", {
allowAny: boolean;
allowBoolean: boolean;
allowNever: boolean;
allowNullish: boolean;
allowNumber: boolean;
allowRegExp: boolean;
}];
'no-return-await': "off";
'@typescript-eslint/return-await': ["error", string];
'@typescript-eslint/triple-slash-reference': "error";
'@typescript-eslint/unbound-method': "error";
'@typescript-eslint/unified-signatures': "error";
'@typescript-eslint/use-unknown-in-catch-callback-variable': "error";
};
};
export = _default;

View File

@@ -0,0 +1,114 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': [
'error',
{ minimumDescriptionLength: 10 },
],
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': 'error',
'@typescript-eslint/no-duplicate-enum-values': 'error',
'@typescript-eslint/no-duplicate-type-constituents': 'error',
'@typescript-eslint/no-dynamic-delete': 'error',
'@typescript-eslint/no-empty-object-type': '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',
'@typescript-eslint/no-meaningless-void-operator': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-misused-spread': '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-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-template-expression': '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-unnecessary-type-conversion': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': '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-function-type': '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-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-useless-default-assignment': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-literal-enum-member': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/prefer-return-this-type': 'error',
'@typescript-eslint/related-getter-setter-pairs': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNullish: false,
allowNumberAndString: false,
allowRegExp: false,
},
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNever: false,
allowNullish: false,
allowNumber: false,
allowRegExp: false,
},
],
'no-return-await': 'off',
'@typescript-eslint/return-await': [
'error',
'error-handling-correctness-only',
],
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/unified-signatures': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
},
};

View File

@@ -0,0 +1,40 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/ban-ts-comment': ["error", {
minimumDescriptionLength: number;
}];
'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-empty-object-type': "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";
'@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-require-imports': "error";
'@typescript-eslint/no-this-alias': "error";
'@typescript-eslint/no-unnecessary-type-constraint': "error";
'@typescript-eslint/no-unsafe-declaration-merging': "error";
'@typescript-eslint/no-unsafe-function-type': "error";
'no-unused-expressions': "off";
'@typescript-eslint/no-unused-expressions': "error";
'no-unused-vars': "off";
'@typescript-eslint/no-unused-vars': "error";
'no-useless-constructor': "off";
'@typescript-eslint/no-useless-constructor': "error";
'@typescript-eslint/no-wrapper-object-types': "error";
'@typescript-eslint/prefer-as-const': "error";
'@typescript-eslint/prefer-literal-enum-member': "error";
'@typescript-eslint/prefer-namespace-keyword': "error";
'@typescript-eslint/triple-slash-reference': "error";
'@typescript-eslint/unified-signatures': "error";
};
};
export = _default;

View File

@@ -0,0 +1,47 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
rules: {
'@typescript-eslint/ban-ts-comment': [
'error',
{ minimumDescriptionLength: 10 },
],
'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-empty-object-type': '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',
'@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-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
'@typescript-eslint/no-unsafe-function-type': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-literal-enum-member': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unified-signatures': 'error',
},
};

View File

@@ -0,0 +1,15 @@
declare const _default: {
extends: string[];
rules: {
'dot-notation': "off";
'@typescript-eslint/dot-notation': "error";
'@typescript-eslint/non-nullable-type-assertion-style': "error";
'@typescript-eslint/prefer-find': "error";
'@typescript-eslint/prefer-includes': "error";
'@typescript-eslint/prefer-nullish-coalescing': "error";
'@typescript-eslint/prefer-optional-chain': "error";
'@typescript-eslint/prefer-regexp-exec': "error";
'@typescript-eslint/prefer-string-starts-ends-with': "error";
};
};
export = _default;

View File

@@ -0,0 +1,21 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
rules: {
'dot-notation': 'off',
'@typescript-eslint/dot-notation': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'@typescript-eslint/prefer-find': 'error',
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/prefer-regexp-exec': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
},
};

View File

@@ -0,0 +1,29 @@
declare const _default: {
extends: string[];
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-inferrable-types': "error";
'@typescript-eslint/non-nullable-type-assertion-style': "error";
'@typescript-eslint/prefer-find': "error";
'@typescript-eslint/prefer-for-of': "error";
'@typescript-eslint/prefer-function-type': "error";
'@typescript-eslint/prefer-includes': "error";
'@typescript-eslint/prefer-nullish-coalescing': "error";
'@typescript-eslint/prefer-optional-chain': "error";
'@typescript-eslint/prefer-regexp-exec': "error";
'@typescript-eslint/prefer-string-starts-ends-with': "error";
};
};
export = _default;

View File

@@ -0,0 +1,35 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
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-inferrable-types': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'@typescript-eslint/prefer-find': 'error',
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/prefer-function-type': 'error',
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/prefer-regexp-exec': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
},
};

View File

@@ -0,0 +1,20 @@
declare const _default: {
extends: string[];
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-inferrable-types': "error";
'@typescript-eslint/prefer-for-of': "error";
'@typescript-eslint/prefer-function-type': "error";
};
};
export = _default;

View File

@@ -0,0 +1,26 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
module.exports = {
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
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-inferrable-types': 'error',
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/prefer-function-type': 'error',
},
};

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* Enables each the rules provided as a part of typescript-eslint. Note that many rules are not applicable in all codebases, or are meant to be configured.
* @see {@link https://typescript-eslint.io/users/configs#all}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,179 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* Enables each the rules provided as a part of typescript-eslint. Note that many rules are not applicable in all codebases, or are meant to be configured.
* @see {@link https://typescript-eslint.io/users/configs#all}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/all',
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/class-literal-property-style': 'error',
'class-methods-use-this': 'off',
'@typescript-eslint/class-methods-use-this': 'error',
'@typescript-eslint/consistent-generic-constructors': 'error',
'@typescript-eslint/consistent-indexed-object-style': 'error',
'consistent-return': 'off',
'@typescript-eslint/consistent-return': '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',
'init-declarations': 'off',
'@typescript-eslint/init-declarations': 'error',
'max-params': 'off',
'@typescript-eslint/max-params': '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-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-non-null-assertion': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': '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-object-type': '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-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-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-misused-spread': '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',
'@typescript-eslint/no-restricted-types': 'error',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-parameter-property-assignment': 'error',
'@typescript-eslint/no-unnecessary-qualifier': 'error',
'@typescript-eslint/no-unnecessary-template-expression': '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-unnecessary-type-conversion': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': '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-function-type': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'@typescript-eslint/no-unsafe-type-assertion': 'error',
'@typescript-eslint/no-unsafe-unary-minus': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'no-unused-private-class-members': 'off',
'@typescript-eslint/no-unused-private-class-members': '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-default-assignment': 'error',
'@typescript-eslint/no-useless-empty-export': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': '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-find': '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',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': '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/promise-function-async': 'error',
'@typescript-eslint/related-getter-setter-pairs': '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',
'@typescript-eslint/strict-boolean-expressions': 'error',
'@typescript-eslint/strict-void-return': 'error',
'@typescript-eslint/switch-exhaustiveness-check': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/unified-signatures': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
},
},
];

View File

@@ -0,0 +1,8 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* A minimal ruleset that sets only the required parser and plugin options needed to run typescript-eslint.
* We don't recommend using this directly; instead, extend from an earlier recommended rule.
* @see {@link https://typescript-eslint.io/users/configs#base}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.Config;
export default _default;

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* A minimal ruleset that sets only the required parser and plugin options needed to run typescript-eslint.
* We don't recommend using this directly; instead, extend from an earlier recommended rule.
* @see {@link https://typescript-eslint.io/users/configs#base}
*/
exports.default = (plugin, parser) => ({
name: 'typescript-eslint/base',
languageOptions: {
parser,
sourceType: 'module',
},
plugins: {
'@typescript-eslint': plugin,
},
});

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* A utility ruleset that will disable type-aware linting and all type-aware rules available in our project.
* @see {@link https://typescript-eslint.io/users/configs#disable-type-checked}
*/
declare const _default: (_plugin: FlatConfig.Plugin, _parser: FlatConfig.Parser) => FlatConfig.Config;
export default _default;

View File

@@ -0,0 +1,81 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
Object.defineProperty(exports, "__esModule", { value: true });
/**
* A utility ruleset that will disable type-aware linting and all type-aware rules available in our project.
* @see {@link https://typescript-eslint.io/users/configs#disable-type-checked}
*/
exports.default = (_plugin, _parser) => ({
name: 'typescript-eslint/disable-type-checked',
rules: {
'@typescript-eslint/await-thenable': 'off',
'@typescript-eslint/consistent-return': 'off',
'@typescript-eslint/consistent-type-exports': 'off',
'@typescript-eslint/dot-notation': 'off',
'@typescript-eslint/naming-convention': 'off',
'@typescript-eslint/no-array-delete': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/no-confusing-void-expression': 'off',
'@typescript-eslint/no-deprecated': '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-misused-spread': 'off',
'@typescript-eslint/no-mixed-enums': 'off',
'@typescript-eslint/no-redundant-type-constituents': '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-template-expression': 'off',
'@typescript-eslint/no-unnecessary-type-arguments': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-unnecessary-type-conversion': 'off',
'@typescript-eslint/no-unnecessary-type-parameters': '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-type-assertion': 'off',
'@typescript-eslint/no-unsafe-unary-minus': 'off',
'@typescript-eslint/no-useless-default-assignment': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/only-throw-error': 'off',
'@typescript-eslint/prefer-destructuring': 'off',
'@typescript-eslint/prefer-find': 'off',
'@typescript-eslint/prefer-includes': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/prefer-promise-reject-errors': '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/related-getter-setter-pairs': '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/strict-void-return': 'off',
'@typescript-eslint/switch-exhaustiveness-check': 'off',
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'off',
},
languageOptions: {
parserOptions: { program: null, project: false, projectService: false },
},
});

View File

@@ -0,0 +1,9 @@
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.
* @see {@link https://typescript-eslint.io/users/configs/#eslint-recommended}
*/
declare const _default: (_plugin: FlatConfig.Plugin, _parser: FlatConfig.Parser) => FlatConfig.Config;
export default _default;

View File

@@ -0,0 +1,16 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const eslint_recommended_raw_1 = __importDefault(require("../eslint-recommended-raw"));
/**
* 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.
* @see {@link https://typescript-eslint.io/users/configs/#eslint-recommended}
*/
exports.default = (_plugin, _parser) => ({
...(0, eslint_recommended_raw_1.default)('minimatch'),
name: 'typescript-eslint/eslint-recommended',
});

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* A version of `recommended` that only contains type-checked rules and disables of any corresponding core ESLint rules.
* @see {@link https://typescript-eslint.io/users/configs#recommended-type-checked-only}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,53 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* A version of `recommended` that only contains type-checked rules and disables of any corresponding core ESLint rules.
* @see {@link https://typescript-eslint.io/users/configs#recommended-type-checked-only}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/recommended-type-checked-only',
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-duplicate-type-constituents': '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-misused-promises': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': '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-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': 'error',
'@typescript-eslint/restrict-template-expressions': 'error',
'@typescript-eslint/unbound-method': 'error',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* Contains all of `recommended` along with additional recommended rules that require type information.
* @see {@link https://typescript-eslint.io/users/configs#recommended-type-checked}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,76 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* Contains all of `recommended` along with additional recommended rules that require type information.
* @see {@link https://typescript-eslint.io/users/configs#recommended-type-checked}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/recommended-type-checked',
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': 'error',
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-array-delete': '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-empty-object-type': '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',
'@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-require-imports': '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-function-type': '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',
'@typescript-eslint/no-wrapper-object-types': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': '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',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* Recommended rules for code correctness that you can drop in without additional configuration.
* @see {@link https://typescript-eslint.io/users/configs#recommended}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,49 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* Recommended rules for code correctness that you can drop in without additional configuration.
* @see {@link https://typescript-eslint.io/users/configs#recommended}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/recommended',
rules: {
'@typescript-eslint/ban-ts-comment': 'error',
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-duplicate-enum-values': 'error',
'@typescript-eslint/no-empty-object-type': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extra-non-null-assertion': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
'@typescript-eslint/no-unsafe-function-type': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* A version of `strict` that only contains type-checked rules and disables of any corresponding core ESLint rules.
* @see {@link https://typescript-eslint.io/users/configs#strict-type-checked-only}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,93 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* A version of `strict` that only contains type-checked rules and disables of any corresponding core ESLint rules.
* @see {@link https://typescript-eslint.io/users/configs#strict-type-checked-only}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/strict-type-checked-only',
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': 'error',
'@typescript-eslint/no-duplicate-type-constituents': '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-meaningless-void-operator': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-misused-spread': 'error',
'@typescript-eslint/no-mixed-enums': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-template-expression': 'error',
'@typescript-eslint/no-unnecessary-type-arguments': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unnecessary-type-conversion': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': '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',
'@typescript-eslint/no-useless-default-assignment': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/prefer-return-this-type': 'error',
'@typescript-eslint/related-getter-setter-pairs': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNullish: false,
allowNumberAndString: false,
allowRegExp: false,
},
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNever: false,
allowNullish: false,
allowNumber: false,
allowRegExp: false,
},
],
'no-return-await': 'off',
'@typescript-eslint/return-await': [
'error',
'error-handling-correctness-only',
],
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* Contains all of `recommended`, `recommended-type-checked`, and `strict`, along with additional strict rules that require type information.
* @see {@link https://typescript-eslint.io/users/configs#strict-type-checked}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,128 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* Contains all of `recommended`, `recommended-type-checked`, and `strict`, along with additional strict rules that require type information.
* @see {@link https://typescript-eslint.io/users/configs#strict-type-checked}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/strict-type-checked',
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': [
'error',
{ minimumDescriptionLength: 10 },
],
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': 'error',
'@typescript-eslint/no-duplicate-enum-values': 'error',
'@typescript-eslint/no-duplicate-type-constituents': 'error',
'@typescript-eslint/no-dynamic-delete': 'error',
'@typescript-eslint/no-empty-object-type': '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',
'@typescript-eslint/no-meaningless-void-operator': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-misused-spread': '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-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-template-expression': '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-unnecessary-type-conversion': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': '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-function-type': '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-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-useless-default-assignment': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-literal-enum-member': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/prefer-return-this-type': 'error',
'@typescript-eslint/related-getter-setter-pairs': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNullish: false,
allowNumberAndString: false,
allowRegExp: false,
},
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNever: false,
allowNullish: false,
allowNumber: false,
allowRegExp: false,
},
],
'no-return-await': 'off',
'@typescript-eslint/return-await': [
'error',
'error-handling-correctness-only',
],
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/unified-signatures': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* Contains all of `recommended`, as well as additional strict rules that can also catch bugs.
* @see {@link https://typescript-eslint.io/users/configs#strict}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,61 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* Contains all of `recommended`, as well as additional strict rules that can also catch bugs.
* @see {@link https://typescript-eslint.io/users/configs#strict}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/strict',
rules: {
'@typescript-eslint/ban-ts-comment': [
'error',
{ minimumDescriptionLength: 10 },
],
'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-empty-object-type': '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',
'@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-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
'@typescript-eslint/no-unsafe-function-type': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-wrapper-object-types': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-literal-enum-member': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
'@typescript-eslint/unified-signatures': 'error',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* A version of `stylistic` that only contains type-checked rules and disables of any corresponding core ESLint rules.
* @see {@link https://typescript-eslint.io/users/configs#stylistic-type-checked-only}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,35 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* A version of `stylistic` that only contains type-checked rules and disables of any corresponding core ESLint rules.
* @see {@link https://typescript-eslint.io/users/configs#stylistic-type-checked-only}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/stylistic-type-checked-only',
rules: {
'dot-notation': 'off',
'@typescript-eslint/dot-notation': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'@typescript-eslint/prefer-find': 'error',
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/prefer-regexp-exec': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* Contains all of `stylistic`, along with additional stylistic rules that require type information.
* @see {@link https://typescript-eslint.io/users/configs#stylistic-type-checked}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,49 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* Contains all of `stylistic`, along with additional stylistic rules that require type information.
* @see {@link https://typescript-eslint.io/users/configs#stylistic-type-checked}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/stylistic-type-checked',
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-inferrable-types': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'@typescript-eslint/prefer-find': 'error',
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/prefer-function-type': 'error',
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/prefer-regexp-exec': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
},
},
];

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
/**
* Rules considered to be best practice for modern TypeScript codebases, but that do not impact program logic.
* @see {@link https://typescript-eslint.io/users/configs#stylistic}
*/
declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;
export default _default;

View File

@@ -0,0 +1,40 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `yarn generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* Rules considered to be best practice for modern TypeScript codebases, but that do not impact program logic.
* @see {@link https://typescript-eslint.io/users/configs#stylistic}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/stylistic',
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-inferrable-types': 'error',
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/prefer-function-type': 'error',
},
},
];

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const raw_plugin_1 = __importDefault(require("./raw-plugin"));
module.exports = raw_plugin_1.default.plugin;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const parserBase = __importStar(require("@typescript-eslint/parser"));
const all_1 = __importDefault(require("./configs/eslintrc/all"));
const base_1 = __importDefault(require("./configs/eslintrc/base"));
const disable_type_checked_1 = __importDefault(require("./configs/eslintrc/disable-type-checked"));
const eslint_recommended_1 = __importDefault(require("./configs/eslintrc/eslint-recommended"));
const recommended_1 = __importDefault(require("./configs/eslintrc/recommended"));
const recommended_type_checked_1 = __importDefault(require("./configs/eslintrc/recommended-type-checked"));
const recommended_type_checked_only_1 = __importDefault(require("./configs/eslintrc/recommended-type-checked-only"));
const strict_1 = __importDefault(require("./configs/eslintrc/strict"));
const strict_type_checked_1 = __importDefault(require("./configs/eslintrc/strict-type-checked"));
const strict_type_checked_only_1 = __importDefault(require("./configs/eslintrc/strict-type-checked-only"));
const stylistic_1 = __importDefault(require("./configs/eslintrc/stylistic"));
const stylistic_type_checked_1 = __importDefault(require("./configs/eslintrc/stylistic-type-checked"));
const stylistic_type_checked_only_1 = __importDefault(require("./configs/eslintrc/stylistic-type-checked-only"));
const all_2 = __importDefault(require("./configs/flat/all"));
const base_2 = __importDefault(require("./configs/flat/base"));
const disable_type_checked_2 = __importDefault(require("./configs/flat/disable-type-checked"));
const eslint_recommended_2 = __importDefault(require("./configs/flat/eslint-recommended"));
const recommended_2 = __importDefault(require("./configs/flat/recommended"));
const recommended_type_checked_2 = __importDefault(require("./configs/flat/recommended-type-checked"));
const recommended_type_checked_only_2 = __importDefault(require("./configs/flat/recommended-type-checked-only"));
const strict_2 = __importDefault(require("./configs/flat/strict"));
const strict_type_checked_2 = __importDefault(require("./configs/flat/strict-type-checked"));
const strict_type_checked_only_2 = __importDefault(require("./configs/flat/strict-type-checked-only"));
const stylistic_2 = __importDefault(require("./configs/flat/stylistic"));
const stylistic_type_checked_2 = __importDefault(require("./configs/flat/stylistic-type-checked"));
const stylistic_type_checked_only_2 = __importDefault(require("./configs/flat/stylistic-type-checked-only"));
const rules_1 = __importDefault(require("./rules"));
const parser = {
meta: parserBase.meta,
parseForESLint: parserBase.parseForESLint,
};
// 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');
const plugin = {
// not fully initialized yet.
// See https://eslint.org/docs/latest/extend/plugins#configs-in-plugins
configs: {
all: all_1.default,
base: base_1.default,
'disable-type-checked': disable_type_checked_1.default,
'eslint-recommended': eslint_recommended_1.default,
recommended: recommended_1.default,
/** @deprecated - please use "recommended-type-checked" instead. */
'recommended-requiring-type-checking': recommended_type_checked_1.default,
'recommended-type-checked': recommended_type_checked_1.default,
'recommended-type-checked-only': recommended_type_checked_only_1.default,
strict: strict_1.default,
'strict-type-checked': strict_type_checked_1.default,
'strict-type-checked-only': strict_type_checked_only_1.default,
stylistic: stylistic_1.default,
'stylistic-type-checked': stylistic_type_checked_1.default,
'stylistic-type-checked-only': stylistic_type_checked_only_1.default,
},
meta: {
name,
namespace: '@typescript-eslint',
version,
},
rules: rules_1.default,
};
// @ts-expect-error -- upstream type incompatibility stuff
const flatPlugin = plugin;
// included due to https://github.com/eslint/eslint/issues/19513
const flatConfigs = {
'flat/all': (0, all_2.default)(flatPlugin, parser),
'flat/base': (0, base_2.default)(flatPlugin, parser),
'flat/disable-type-checked': (0, disable_type_checked_2.default)(flatPlugin, parser),
'flat/eslint-recommended': (0, eslint_recommended_2.default)(flatPlugin, parser),
'flat/recommended': (0, recommended_2.default)(flatPlugin, parser),
'flat/recommended-type-checked': (0, recommended_type_checked_2.default)(flatPlugin, parser),
'flat/recommended-type-checked-only': (0, recommended_type_checked_only_2.default)(flatPlugin, parser),
'flat/strict': (0, strict_2.default)(flatPlugin, parser),
'flat/strict-type-checked': (0, strict_type_checked_2.default)(flatPlugin, parser),
'flat/strict-type-checked-only': (0, strict_type_checked_only_2.default)(flatPlugin, parser),
'flat/stylistic': (0, stylistic_2.default)(flatPlugin, parser),
'flat/stylistic-type-checked': (0, stylistic_type_checked_2.default)(flatPlugin, parser),
'flat/stylistic-type-checked-only': (0, stylistic_type_checked_only_2.default)(flatPlugin, parser),
};
Object.assign(plugin.configs, flatConfigs);
module.exports = {
flatConfigs,
parser,
plugin,
};

View File

@@ -0,0 +1,4 @@
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"adjacentSignature", [], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,124 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'adjacent-overload-signatures',
meta: {
type: 'suggestion',
docs: {
description: 'Require that function overload signatures be consecutive',
recommended: 'stylistic',
},
messages: {
adjacentSignature: 'All {{name}} signatures should be adjacent.',
},
schema: [],
},
defaultOptions: [],
create(context) {
/**
* Gets the name and attribute of the member being processed.
* @param member the member being processed.
* @returns the name and attribute of the member or null if it's a member not relevant to the rule.
*/
function getMemberMethod(member) {
switch (member.type) {
case utils_1.AST_NODE_TYPES.ExportDefaultDeclaration:
case utils_1.AST_NODE_TYPES.ExportNamedDeclaration: {
// export statements (e.g. export { a };)
// have no declarations, so ignore them
if (!member.declaration) {
return null;
}
return getMemberMethod(member.declaration);
}
case utils_1.AST_NODE_TYPES.TSDeclareFunction:
case utils_1.AST_NODE_TYPES.FunctionDeclaration: {
const name = member.id?.name ?? null;
if (name == null) {
return null;
}
return {
name,
type: util_1.MemberNameType.Normal,
callSignature: false,
};
}
case utils_1.AST_NODE_TYPES.TSMethodSignature:
case utils_1.AST_NODE_TYPES.MethodDefinition:
return {
...(0, util_1.getNameFromMember)(member, context.sourceCode),
callSignature: false,
static: member.static,
};
case utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration:
return {
name: 'call',
type: util_1.MemberNameType.Normal,
callSignature: true,
};
case utils_1.AST_NODE_TYPES.TSConstructSignatureDeclaration:
return {
name: 'new',
type: util_1.MemberNameType.Normal,
callSignature: false,
};
}
return null;
}
function isSameMethod(method1, method2) {
return (!!method2 &&
method1.name === method2.name &&
method1.static === method2.static &&
method1.callSignature === method2.callSignature &&
method1.type === method2.type);
}
function getMembers(node) {
switch (node.type) {
case utils_1.AST_NODE_TYPES.ClassBody:
case utils_1.AST_NODE_TYPES.Program:
case utils_1.AST_NODE_TYPES.TSModuleBlock:
case utils_1.AST_NODE_TYPES.TSInterfaceBody:
case utils_1.AST_NODE_TYPES.BlockStatement:
return node.body;
case utils_1.AST_NODE_TYPES.TSTypeLiteral:
return node.members;
}
}
function checkBodyForOverloadMethods(node) {
const members = getMembers(node);
let lastMethod = null;
const seenMethods = [];
members.forEach(member => {
const method = getMemberMethod(member);
if (method == null) {
lastMethod = null;
return;
}
const index = seenMethods.findIndex(seenMethod => isSameMethod(method, seenMethod));
if (index > -1 && !isSameMethod(method, lastMethod)) {
context.report({
node: member,
messageId: 'adjacentSignature',
data: {
name: `${method.static ? 'static ' : ''}${method.name}`,
},
});
}
else if (index === -1) {
seenMethods.push(method);
}
lastMethod = method;
});
}
return {
BlockStatement: checkBodyForOverloadMethods,
ClassBody: checkBodyForOverloadMethods,
Program: checkBodyForOverloadMethods,
TSInterfaceBody: checkBodyForOverloadMethods,
TSModuleBlock: checkBodyForOverloadMethods,
TSTypeLiteral: checkBodyForOverloadMethods,
};
},
});

View File

@@ -0,0 +1,12 @@
export type OptionString = 'array' | 'array-simple' | 'generic';
export type Options = [
{
default: OptionString;
readonly?: OptionString;
}
];
export type MessageIds = 'errorStringArray' | 'errorStringArrayReadonly' | 'errorStringArraySimple' | 'errorStringArraySimpleReadonly' | 'errorStringGeneric' | 'errorStringGenericSimple';
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,232 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
/**
* Check whatever node can be considered as simple
* @param node the node to be evaluated.
*/
function isSimpleType(node) {
switch (node.type) {
case utils_1.AST_NODE_TYPES.Identifier:
case utils_1.AST_NODE_TYPES.TSAnyKeyword:
case utils_1.AST_NODE_TYPES.TSBooleanKeyword:
case utils_1.AST_NODE_TYPES.TSNeverKeyword:
case utils_1.AST_NODE_TYPES.TSNumberKeyword:
case utils_1.AST_NODE_TYPES.TSBigIntKeyword:
case utils_1.AST_NODE_TYPES.TSObjectKeyword:
case utils_1.AST_NODE_TYPES.TSStringKeyword:
case utils_1.AST_NODE_TYPES.TSSymbolKeyword:
case utils_1.AST_NODE_TYPES.TSUnknownKeyword:
case utils_1.AST_NODE_TYPES.TSVoidKeyword:
case utils_1.AST_NODE_TYPES.TSNullKeyword:
case utils_1.AST_NODE_TYPES.TSArrayType:
case utils_1.AST_NODE_TYPES.TSUndefinedKeyword:
case utils_1.AST_NODE_TYPES.TSThisType:
case utils_1.AST_NODE_TYPES.TSQualifiedName:
return true;
case utils_1.AST_NODE_TYPES.TSTypeReference:
if (node.typeName.type === utils_1.AST_NODE_TYPES.Identifier &&
node.typeName.name === 'Array') {
if (!node.typeArguments) {
return true;
}
if (node.typeArguments.params.length === 1) {
return isSimpleType(node.typeArguments.params[0]);
}
}
else {
if (node.typeArguments) {
return false;
}
return isSimpleType(node.typeName);
}
return false;
default:
return false;
}
}
/**
* Check if node needs parentheses
* @param node the node to be evaluated.
*/
function typeNeedsParentheses(node) {
switch (node.type) {
case utils_1.AST_NODE_TYPES.TSTypeReference:
return typeNeedsParentheses(node.typeName);
case utils_1.AST_NODE_TYPES.TSUnionType:
case utils_1.AST_NODE_TYPES.TSFunctionType:
case utils_1.AST_NODE_TYPES.TSIntersectionType:
case utils_1.AST_NODE_TYPES.TSTypeOperator:
case utils_1.AST_NODE_TYPES.TSInferType:
case utils_1.AST_NODE_TYPES.TSConstructorType:
case utils_1.AST_NODE_TYPES.TSConditionalType:
return true;
case utils_1.AST_NODE_TYPES.Identifier:
return node.name === 'ReadonlyArray';
default:
return false;
}
}
exports.default = (0, util_1.createRule)({
name: 'array-type',
meta: {
type: 'suggestion',
docs: {
description: 'Require consistently using either `T[]` or `Array<T>` for arrays',
recommended: 'stylistic',
},
fixable: 'code',
messages: {
errorStringArray: "Array type using '{{className}}<{{type}}>' is forbidden. Use '{{readonlyPrefix}}{{type}}[]' instead.",
errorStringArrayReadonly: "Array type using '{{className}}<{{type}}>' is forbidden. Use '{{readonlyPrefix}}{{type}}' instead.",
errorStringArraySimple: "Array type using '{{className}}<{{type}}>' is forbidden for simple types. Use '{{readonlyPrefix}}{{type}}[]' instead.",
errorStringArraySimpleReadonly: "Array type using '{{className}}<{{type}}>' is forbidden for simple types. Use '{{readonlyPrefix}}{{type}}' instead.",
errorStringGeneric: "Array type using '{{readonlyPrefix}}{{type}}[]' is forbidden. Use '{{className}}<{{type}}>' instead.",
errorStringGenericSimple: "Array type using '{{readonlyPrefix}}{{type}}[]' is forbidden for non-simple types. Use '{{className}}<{{type}}>' instead.",
},
schema: [
{
type: 'object',
$defs: {
arrayOption: {
type: 'string',
enum: ['array', 'generic', 'array-simple'],
},
},
additionalProperties: false,
properties: {
default: {
$ref: '#/items/0/$defs/arrayOption',
description: 'The array type expected for mutable cases.',
},
readonly: {
$ref: '#/items/0/$defs/arrayOption',
description: 'The array type expected for readonly cases. If omitted, the value for `default` will be used.',
},
},
},
],
},
defaultOptions: [
{
default: 'array',
},
],
create(context, [options]) {
const defaultOption = options.default;
const readonlyOption = options.readonly ?? defaultOption;
/**
* @param node the node to be evaluated.
*/
function getMessageType(node) {
if (isSimpleType(node)) {
return context.sourceCode.getText(node);
}
return 'T';
}
return {
TSArrayType(node) {
const isReadonly = node.parent.type === utils_1.AST_NODE_TYPES.TSTypeOperator &&
node.parent.operator === 'readonly';
const currentOption = isReadonly ? readonlyOption : defaultOption;
if (currentOption === 'array' ||
(currentOption === 'array-simple' && isSimpleType(node.elementType))) {
return;
}
const messageId = currentOption === 'generic'
? 'errorStringGeneric'
: 'errorStringGenericSimple';
const errorNode = isReadonly ? node.parent : node;
context.report({
node: errorNode,
messageId,
data: {
type: getMessageType(node.elementType),
className: isReadonly ? 'ReadonlyArray' : 'Array',
readonlyPrefix: isReadonly ? 'readonly ' : '',
},
fix(fixer) {
const typeNode = node.elementType;
const arrayType = isReadonly ? 'ReadonlyArray' : 'Array';
return [
fixer.replaceTextRange([errorNode.range[0], typeNode.range[0]], `${arrayType}<`),
fixer.replaceTextRange([typeNode.range[1], errorNode.range[1]], '>'),
];
},
});
},
TSTypeReference(node) {
if (node.typeName.type !== utils_1.AST_NODE_TYPES.Identifier ||
!(node.typeName.name === 'Array' ||
node.typeName.name === 'ReadonlyArray' ||
node.typeName.name === 'Readonly') ||
(node.typeName.name === 'Readonly' &&
node.typeArguments?.params[0].type !== utils_1.AST_NODE_TYPES.TSArrayType)) {
return;
}
const isReadonlyWithGenericArrayType = node.typeName.name === 'Readonly' &&
node.typeArguments?.params[0].type === utils_1.AST_NODE_TYPES.TSArrayType;
const isReadonlyArrayType = node.typeName.name === 'ReadonlyArray' ||
isReadonlyWithGenericArrayType;
const currentOption = isReadonlyArrayType
? readonlyOption
: defaultOption;
if (currentOption === 'generic') {
return;
}
const readonlyPrefix = isReadonlyArrayType ? 'readonly ' : '';
const typeParams = node.typeArguments?.params;
const messageId = currentOption === 'array'
? isReadonlyWithGenericArrayType
? 'errorStringArrayReadonly'
: 'errorStringArray'
: isReadonlyArrayType && node.typeName.name !== 'ReadonlyArray'
? 'errorStringArraySimpleReadonly'
: 'errorStringArraySimple';
if (!typeParams) {
// Create an 'any' array
context.report({
node,
messageId,
data: {
type: 'any',
className: isReadonlyArrayType ? 'ReadonlyArray' : 'Array',
readonlyPrefix,
},
fix(fixer) {
return fixer.replaceText(node, `${readonlyPrefix}any[]`);
},
});
return;
}
if (typeParams.length !== 1 ||
(currentOption === 'array-simple' && !isSimpleType(typeParams[0]))) {
return;
}
const type = typeParams[0];
const typeParens = typeNeedsParentheses(type);
const parentParens = readonlyPrefix &&
node.parent.type === utils_1.AST_NODE_TYPES.TSArrayType &&
!(0, util_1.isParenthesized)(node.parent.elementType, context.sourceCode);
const start = `${parentParens ? '(' : ''}${readonlyPrefix}${typeParens ? '(' : ''}`;
const end = `${typeParens ? ')' : ''}${isReadonlyWithGenericArrayType ? '' : `[]`}${parentParens ? ')' : ''}`;
context.report({
node,
messageId,
data: {
type: getMessageType(type),
className: isReadonlyArrayType ? node.typeName.name : 'Array',
readonlyPrefix,
},
fix(fixer) {
return [
fixer.replaceTextRange([node.range[0], type.range[0]], start),
fixer.replaceTextRange([type.range[1], node.range[1]], end),
];
},
});
},
};
},
});

View File

@@ -0,0 +1,6 @@
import type { TSESLint } from '@typescript-eslint/utils';
export type MessageId = 'await' | 'awaitUsingOfNonAsyncDisposable' | 'convertToOrdinaryFor' | 'forAwaitOfNonAsyncIterable' | 'invalidPromiseAggregatorInput' | 'removeAwait';
declare const _default: TSESLint.RuleModule<MessageId, [], import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,228 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const util_1 = require("../util");
const getForStatementHeadLoc_1 = require("../util/getForStatementHeadLoc");
const isPromiseAggregatorMethod_1 = require("../util/isPromiseAggregatorMethod");
exports.default = (0, util_1.createRule)({
name: 'await-thenable',
meta: {
type: 'problem',
docs: {
description: 'Disallow awaiting a value that is not a Thenable',
recommended: 'recommended',
requiresTypeChecking: true,
},
hasSuggestions: true,
messages: {
await: 'Unexpected `await` of a non-Promise (non-"Thenable") value.',
awaitUsingOfNonAsyncDisposable: 'Unexpected `await using` of a value that is not async disposable.',
convertToOrdinaryFor: 'Convert to an ordinary `for...of` loop.',
forAwaitOfNonAsyncIterable: 'Unexpected `for await...of` of a value that is not async iterable.',
invalidPromiseAggregatorInput: 'Unexpected iterable of non-Promise (non-"Thenable") values passed to promise aggregator.',
removeAwait: 'Remove unnecessary `await`.',
},
schema: [],
},
defaultOptions: [],
create(context) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
return {
AwaitExpression(node) {
const awaitArgumentEsNode = node.argument;
const awaitArgumentType = services.getTypeAtLocation(awaitArgumentEsNode);
const awaitArgumentTsNode = services.esTreeNodeToTSNodeMap.get(awaitArgumentEsNode);
const certainty = (0, util_1.needsToBeAwaited)(checker, awaitArgumentTsNode, awaitArgumentType);
if (certainty === util_1.Awaitable.Never) {
context.report({
node,
messageId: 'await',
suggest: [
{
messageId: 'removeAwait',
fix(fixer) {
const awaitKeyword = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await expression'));
return fixer.remove(awaitKeyword);
},
},
],
});
}
},
CallExpression(node) {
if (!(0, isPromiseAggregatorMethod_1.isPromiseAggregatorMethod)(context, services, node)) {
return;
}
const argument = node.arguments.at(0);
if (argument == null) {
return;
}
if (argument.type === utils_1.TSESTree.AST_NODE_TYPES.ArrayExpression) {
for (const element of argument.elements) {
if (element == null) {
continue;
}
const type = (0, util_1.getConstrainedTypeAtLocation)(services, element);
const tsNode = services.esTreeNodeToTSNodeMap.get(element);
if (isAlwaysNonAwaitableType(type, tsNode, checker)) {
context.report({
node: element,
messageId: 'invalidPromiseAggregatorInput',
});
}
}
return;
}
const type = (0, util_1.getConstrainedTypeAtLocation)(services, argument);
if (isInvalidPromiseAggregatorInput(checker, services.esTreeNodeToTSNodeMap.get(argument), type)) {
context.report({
node: argument,
messageId: 'invalidPromiseAggregatorInput',
});
}
},
'ForOfStatement[await=true]'(node) {
const type = services.getTypeAtLocation(node.right);
if ((0, util_1.isTypeAnyType)(type)) {
return;
}
const hasAsyncIteratorSymbol = tsutils
.unionConstituents(type)
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncIterator', checker) != null);
if (!hasAsyncIteratorSymbol) {
context.report({
loc: (0, getForStatementHeadLoc_1.getForStatementHeadLoc)(context.sourceCode, node),
messageId: 'forAwaitOfNonAsyncIterable',
suggest: [
// Note that this suggestion causes broken code for sync iterables
// of promises, since the loop variable is not awaited.
{
messageId: 'convertToOrdinaryFor',
fix(fixer) {
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'for await loop'));
return fixer.remove(awaitToken);
},
},
],
});
}
},
'VariableDeclaration[kind="await using"]'(node) {
for (const declarator of node.declarations) {
const init = declarator.init;
if (init == null) {
continue;
}
const type = services.getTypeAtLocation(init);
if ((0, util_1.isTypeAnyType)(type)) {
continue;
}
const hasAsyncDisposeSymbol = tsutils
.unionConstituents(type)
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncDispose', checker) != null);
if (!hasAsyncDisposeSymbol) {
context.report({
node: init,
messageId: 'awaitUsingOfNonAsyncDisposable',
// let the user figure out what to do if there's
// await using a = b, c = d, e = f;
// it's rare and not worth the complexity to handle.
...(0, util_1.getFixOrSuggest)({
fixOrSuggest: node.declarations.length === 1 ? 'suggest' : 'none',
suggestion: {
messageId: 'removeAwait',
fix(fixer) {
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await using'));
return fixer.remove(awaitToken);
},
},
}),
});
}
}
},
};
},
});
function isInvalidPromiseAggregatorInput(checker, node, type) {
// non array/tuple/iterable types already show up as a type error
if (!isIterable(type, checker)) {
return false;
}
for (const part of tsutils.unionConstituents(type)) {
const valueTypes = getValueTypesOfArrayLike(part, checker);
if (valueTypes != null) {
for (const typeArgument of valueTypes) {
if (containsNonAwaitableType(typeArgument, node, checker)) {
return true;
}
}
}
}
return false;
}
function getValueTypesOfArrayLike(type, checker) {
if (checker.isTupleType(type)) {
return checker.getTypeArguments(type);
}
if (checker.isArrayLikeType(type)) {
return [
(0, util_1.nullThrows)(type.getNumberIndexType(), 'number index type should exist on an array-like'),
];
}
// `Iterable<...>`
if (tsutils.isTypeReference(type)) {
return checker.getTypeArguments(type).slice(0, 1);
}
return null;
}
function isAlwaysNonAwaitableType(type, node, checker) {
return tsutils
.unionConstituents(type)
.every(typeArgumentPart => (0, util_1.needsToBeAwaited)(checker, node, typeArgumentPart) === util_1.Awaitable.Never);
}
function containsNonAwaitableType(type, node, checker) {
return tsutils
.unionConstituents(type)
.some(typeArgumentPart => (0, util_1.needsToBeAwaited)(checker, node, typeArgumentPart) === util_1.Awaitable.Never);
}
function isIterable(type, checker) {
return tsutils
.unionConstituents(type)
.every(part => !!tsutils.getWellKnownSymbolPropertyOfType(part, 'iterator', checker));
}

View File

@@ -0,0 +1,17 @@
import type { TSESLint } from '@typescript-eslint/utils';
export type DirectiveConfig = boolean | 'allow-with-description' | {
descriptionFormat: string;
};
export interface OptionsShape {
minimumDescriptionLength?: number;
'ts-check'?: DirectiveConfig;
'ts-expect-error'?: DirectiveConfig;
'ts-ignore'?: DirectiveConfig;
'ts-nocheck'?: DirectiveConfig;
}
export type Options = [OptionsShape];
export type MessageIds = 'replaceTsIgnoreWithTsExpectError' | 'tsDirectiveComment' | 'tsDirectiveCommentDescriptionNotMatchPattern' | 'tsDirectiveCommentRequiresDescription' | 'tsIgnoreInsteadOfExpectError';
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,195 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
const defaultMinimumDescriptionLength = 3;
exports.default = (0, util_1.createRule)({
name: 'ban-ts-comment',
meta: {
type: 'problem',
docs: {
description: 'Disallow `@ts-<directive>` comments or require descriptions after directives',
recommended: {
recommended: true,
strict: [{ minimumDescriptionLength: 10 }],
},
},
hasSuggestions: true,
messages: {
replaceTsIgnoreWithTsExpectError: 'Replace "@ts-ignore" with "@ts-expect-error".',
tsDirectiveComment: 'Do not use "@ts-{{directive}}" because it alters compilation errors.',
tsDirectiveCommentDescriptionNotMatchPattern: 'The description for the "@ts-{{directive}}" directive must match the {{format}} format.',
tsDirectiveCommentRequiresDescription: 'Include a description after the "@ts-{{directive}}" directive to explain why the @ts-{{directive}} is necessary. The description must be {{minimumDescriptionLength}} characters or longer.',
tsIgnoreInsteadOfExpectError: 'Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.',
},
schema: [
{
type: 'object',
$defs: {
directiveConfigSchema: {
oneOf: [
{
type: 'boolean',
default: true,
},
{
type: 'string',
enum: ['allow-with-description'],
},
{
type: 'object',
additionalProperties: false,
properties: {
descriptionFormat: { type: 'string' },
},
},
],
},
},
additionalProperties: false,
properties: {
minimumDescriptionLength: {
type: 'number',
description: 'A minimum character length for descriptions when `allow-with-description` is enabled.',
},
'ts-check': {
$ref: '#/items/0/$defs/directiveConfigSchema',
description: 'Whether allow ts-check directives, and with which restrictions.',
},
'ts-expect-error': {
$ref: '#/items/0/$defs/directiveConfigSchema',
description: 'Whether and when expect-error directives, and with which restrictions.',
},
'ts-ignore': {
$ref: '#/items/0/$defs/directiveConfigSchema',
description: 'Whether allow ts-ignore directives, and with which restrictions.',
},
'ts-nocheck': {
$ref: '#/items/0/$defs/directiveConfigSchema',
description: 'Whether allow ts-nocheck directives, and with which restrictions.',
},
},
},
],
},
defaultOptions: [
{
minimumDescriptionLength: defaultMinimumDescriptionLength,
'ts-check': false,
'ts-expect-error': 'allow-with-description',
'ts-ignore': true,
'ts-nocheck': true,
},
],
create(context, [options]) {
// https://github.com/microsoft/TypeScript/blob/6f1ad5ad8bec5671f7e951a3524b62d82ec4be68/src/compiler/parser.ts#L10591
const singleLinePragmaRegEx = /^\/\/\/?\s*@ts-(?<directive>check|nocheck)(?<description>.*)$/;
/*
The regex used are taken from the ones used in the official TypeScript repo -
https://github.com/microsoft/TypeScript/blob/6f1ad5ad8bec5671f7e951a3524b62d82ec4be68/src/compiler/scanner.ts#L340-L348
*/
const commentDirectiveRegExSingleLine = /^\/*\s*@ts-(?<directive>expect-error|ignore)(?<description>.*)/;
const commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@ts-(?<directive>expect-error|ignore)(?<description>.*)/;
const descriptionFormats = new Map();
for (const directive of [
'ts-expect-error',
'ts-ignore',
'ts-nocheck',
'ts-check',
]) {
const option = options[directive];
if (typeof option === 'object' && option.descriptionFormat) {
descriptionFormats.set(directive, new RegExp(option.descriptionFormat));
}
}
function execDirectiveRegEx(regex, str) {
const match = regex.exec(str);
if (!match) {
return null;
}
const { description, directive } = (0, util_1.nullThrows)(match.groups, 'RegExp should contain groups');
return {
description: (0, util_1.nullThrows)(description, 'RegExp should contain "description" group'),
directive: (0, util_1.nullThrows)(directive, 'RegExp should contain "directive" group'),
};
}
function findDirectiveInComment(comment) {
if (comment.type === utils_1.AST_TOKEN_TYPES.Line) {
const matchedPragma = execDirectiveRegEx(singleLinePragmaRegEx, `//${comment.value}`);
if (matchedPragma) {
return matchedPragma;
}
return execDirectiveRegEx(commentDirectiveRegExSingleLine, comment.value);
}
const commentLines = comment.value.split('\n');
return execDirectiveRegEx(commentDirectiveRegExMultiLine, commentLines[commentLines.length - 1]);
}
return {
Program(node) {
const firstStatement = node.body.at(0);
const comments = context.sourceCode.getAllComments();
comments.forEach(comment => {
const match = findDirectiveInComment(comment);
if (!match) {
return;
}
const { description, directive } = match;
if (directive === 'nocheck' &&
firstStatement &&
firstStatement.loc.start.line <= comment.loc.start.line) {
return;
}
const fullDirective = `ts-${directive}`;
const option = options[fullDirective];
if (option === true) {
if (directive === 'ignore') {
// Special case to suggest @ts-expect-error instead of @ts-ignore
context.report({
node: comment,
messageId: 'tsIgnoreInsteadOfExpectError',
suggest: [
{
messageId: 'replaceTsIgnoreWithTsExpectError',
fix(fixer) {
const commentText = comment.value.replace(/@ts-ignore/, '@ts-expect-error');
return fixer.replaceText(comment, comment.type === utils_1.AST_TOKEN_TYPES.Line
? `//${commentText}`
: `/*${commentText}*/`);
},
},
],
});
}
else {
context.report({
node: comment,
messageId: 'tsDirectiveComment',
data: { directive },
});
}
}
if (option === 'allow-with-description' ||
(typeof option === 'object' && option.descriptionFormat)) {
const { minimumDescriptionLength } = options;
const format = descriptionFormats.get(fullDirective);
if ((0, util_1.getStringLength)(description.trim()) <
(0, util_1.nullThrows)(minimumDescriptionLength, 'Expected minimumDescriptionLength to be set')) {
context.report({
node: comment,
messageId: 'tsDirectiveCommentRequiresDescription',
data: { directive, minimumDescriptionLength },
});
}
else if (format && !format.test(description)) {
context.report({
node: comment,
messageId: 'tsDirectiveCommentDescriptionNotMatchPattern',
data: { directive, format: format.source },
});
}
}
});
},
};
},
});

View File

@@ -0,0 +1,4 @@
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"commentDetected", [], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
// tslint regex
// https://github.com/palantir/tslint/blob/95d9d958833fd9dc0002d18cbe34db20d0fbf437/src/enableDisableRules.ts#L32
const ENABLE_DISABLE_REGEX = /^\s*tslint:(enable|disable)(?:-(line|next-line))?(:|\s|$)/;
const toText = (text, type) => type === utils_1.AST_TOKEN_TYPES.Line
? ['//', text.trim()].join(' ')
: ['/*', text.trim(), '*/'].join(' ');
exports.default = (0, util_1.createRule)({
name: 'ban-tslint-comment',
meta: {
type: 'suggestion',
docs: {
description: 'Disallow `// tslint:<rule-flag>` comments',
recommended: 'stylistic',
},
fixable: 'code',
messages: {
commentDetected: 'tslint comment detected: "{{ text }}"',
},
schema: [],
},
defaultOptions: [],
create: context => {
return {
Program() {
const comments = context.sourceCode.getAllComments();
comments.forEach(c => {
if (ENABLE_DISABLE_REGEX.test(c.value)) {
context.report({
node: c,
messageId: 'commentDetected',
data: { text: toText(c.value, c.type) },
fix(fixer) {
const rangeStart = context.sourceCode.getIndexFromLoc({
column: c.loc.start.column > 0 ? c.loc.start.column - 1 : 0,
line: c.loc.start.line,
});
const rangeEnd = context.sourceCode.getIndexFromLoc({
column: c.loc.end.column,
line: c.loc.end.line,
});
return fixer.removeRange([rangeStart, rangeEnd + 1]);
},
});
}
});
},
};
},
});

View File

@@ -0,0 +1,7 @@
import type { TSESLint } from '@typescript-eslint/utils';
export type Options = ['fields' | 'getters'];
export type MessageIds = 'preferFieldStyle' | 'preferFieldStyleSuggestion' | 'preferGetterStyle' | 'preferGetterStyleSuggestion';
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,160 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
const printNodeModifiers = (node, final) => `${node.accessibility ?? ''}${node.static ? ' static' : ''} ${final} `.trimStart();
const isSupportedLiteral = (node) => {
switch (node.type) {
case utils_1.AST_NODE_TYPES.Literal:
return true;
case utils_1.AST_NODE_TYPES.TaggedTemplateExpression:
return node.quasi.quasis.length === 1;
case utils_1.AST_NODE_TYPES.TemplateLiteral:
return node.quasis.length === 1;
default:
return false;
}
};
exports.default = (0, util_1.createRule)({
name: 'class-literal-property-style',
meta: {
type: 'problem',
docs: {
description: 'Enforce that literals on classes are exposed in a consistent style',
recommended: 'stylistic',
},
hasSuggestions: true,
messages: {
preferFieldStyle: 'Literals should be exposed using readonly fields.',
preferFieldStyleSuggestion: 'Replace the literals with readonly fields.',
preferGetterStyle: 'Literals should be exposed using getters.',
preferGetterStyleSuggestion: 'Replace the literals with getters.',
},
schema: [
{
type: 'string',
description: 'Which literal class member syntax to prefer.',
enum: ['fields', 'getters'],
},
],
},
defaultOptions: ['fields'],
create(context, [style]) {
const propertiesInfoStack = [];
function enterClassBody() {
propertiesInfoStack.push({
excludeSet: new Set(),
properties: [],
});
}
function exitClassBody() {
const { excludeSet, properties } = (0, util_1.nullThrows)(propertiesInfoStack.pop(), 'Stack should exist on class exit');
properties.forEach(node => {
const { value } = node;
if (!value || !isSupportedLiteral(value)) {
return;
}
const name = (0, util_1.getStaticMemberAccessValue)(node, context);
if (name && excludeSet.has(name)) {
return;
}
context.report({
node: node.key,
messageId: 'preferGetterStyle',
suggest: [
{
messageId: 'preferGetterStyleSuggestion',
fix(fixer) {
const name = context.sourceCode.getText(node.key);
let text = '';
text += printNodeModifiers(node, 'get');
text += node.computed ? `[${name}]` : name;
text += `() { return ${context.sourceCode.getText(value)}; }`;
return fixer.replaceText(node, text);
},
},
],
});
});
}
function excludeAssignedProperty(node) {
if ((0, util_1.isAssignee)(node)) {
const { excludeSet } = propertiesInfoStack[propertiesInfoStack.length - 1];
const name = (0, util_1.getStaticMemberAccessValue)(node, context);
if (name) {
excludeSet.add(name);
}
}
}
return {
...(style === 'fields' && {
MethodDefinition(node) {
if (node.kind !== 'get' ||
node.override ||
!node.value.body ||
node.value.body.body.length === 0) {
return;
}
const [statement] = node.value.body.body;
if (statement.type !== utils_1.AST_NODE_TYPES.ReturnStatement) {
return;
}
const { argument } = statement;
if (!argument || !isSupportedLiteral(argument)) {
return;
}
const name = (0, util_1.getStaticMemberAccessValue)(node, context);
const hasDuplicateKeySetter = name &&
node.parent.body.some(element => {
return (element.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
element.kind === 'set' &&
(0, util_1.isStaticMemberAccessOfValue)(element, context, name));
});
if (hasDuplicateKeySetter) {
return;
}
context.report({
node: node.key,
messageId: 'preferFieldStyle',
suggest: [
{
messageId: 'preferFieldStyleSuggestion',
fix(fixer) {
const name = context.sourceCode.getText(node.key);
let text = '';
text += printNodeModifiers(node, 'readonly');
text += node.computed ? `[${name}]` : name;
text += ` = ${context.sourceCode.getText(argument)};`;
return fixer.replaceText(node, text);
},
},
],
});
},
}),
...(style === 'getters' && {
ClassBody: enterClassBody,
'ClassBody:exit': exitClassBody,
'MethodDefinition[kind="constructor"] ThisExpression'(node) {
if (node.parent.type === utils_1.AST_NODE_TYPES.MemberExpression) {
let parent = node.parent;
while (!(0, util_1.isFunction)(parent)) {
parent = parent.parent;
}
if (parent.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
parent.parent.kind === 'constructor') {
excludeAssignedProperty(node.parent);
}
}
},
PropertyDefinition(node) {
if (!node.readonly || node.declare || node.override) {
return;
}
const { properties } = propertiesInfoStack[propertiesInfoStack.length - 1];
properties.push(node);
},
}),
};
},
});

View File

@@ -0,0 +1,13 @@
export type Options = [
{
enforceForClassFields?: boolean;
exceptMethods?: string[];
ignoreClassesThatImplementAnInterface?: boolean | 'public-fields';
ignoreOverrideMethods?: boolean;
}
];
export type MessageIds = 'missingThis';
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingThis", Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,219 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'class-methods-use-this',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce that class methods utilize `this`',
extendsBaseRule: true,
requiresTypeChecking: false,
},
messages: {
missingThis: "Expected 'this' to be used by class {{name}}.",
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
enforceForClassFields: {
type: 'boolean',
description: 'Enforces that functions used as instance field initializers utilize `this`.',
},
exceptMethods: {
type: 'array',
description: 'Allows specified method names to be ignored with this rule.',
items: {
type: 'string',
},
},
ignoreClassesThatImplementAnInterface: {
description: 'Whether to ignore class members that are defined within a class that `implements` a type.',
oneOf: [
{
type: 'boolean',
description: 'Ignore all classes that implement an interface',
},
{
type: 'string',
description: 'Ignore only the public fields of classes that implement an interface',
enum: ['public-fields'],
},
],
},
ignoreOverrideMethods: {
type: 'boolean',
description: 'Whether to ignore members marked with the `override` modifier.',
},
},
},
],
},
defaultOptions: [
{
enforceForClassFields: true,
exceptMethods: [],
ignoreClassesThatImplementAnInterface: false,
ignoreOverrideMethods: false,
},
],
create(context, [{ enforceForClassFields, exceptMethods: exceptMethodsRaw, ignoreClassesThatImplementAnInterface, ignoreOverrideMethods, },]) {
const exceptMethods = new Set(exceptMethodsRaw);
let stack;
function pushContext(member) {
if (member?.parent.type === utils_1.AST_NODE_TYPES.ClassBody) {
stack = {
class: member.parent.parent,
member,
parent: stack,
usesThis: false,
};
}
else {
stack = {
class: null,
member: null,
parent: stack,
usesThis: false,
};
}
}
function enterFunction(node) {
if (node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
node.parent.type === utils_1.AST_NODE_TYPES.PropertyDefinition ||
node.parent.type === utils_1.AST_NODE_TYPES.AccessorProperty) {
pushContext(node.parent);
}
else {
pushContext();
}
}
/**
* Pop `this` used flag from the stack.
*/
function popContext() {
const oldStack = stack;
stack = stack?.parent;
return oldStack;
}
function isPublicField(accessibility) {
if (!accessibility || accessibility === 'public') {
return true;
}
return false;
}
/**
* Check if the node is an instance method not excluded by config
*/
function isIncludedInstanceMethod(node) {
if (node.static ||
(node.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
node.kind === 'constructor') ||
((node.type === utils_1.AST_NODE_TYPES.PropertyDefinition ||
node.type === utils_1.AST_NODE_TYPES.AccessorProperty) &&
!enforceForClassFields)) {
return false;
}
if (node.computed || exceptMethods.size === 0) {
return true;
}
const hashIfNeeded = node.key.type === utils_1.AST_NODE_TYPES.PrivateIdentifier ? '#' : '';
const name = (0, util_1.getStaticMemberAccessValue)(node, context);
return (typeof name !== 'string' || !exceptMethods.has(hashIfNeeded + name));
}
/**
* Checks if we are leaving a function that is a method, and reports if 'this' has not been used.
* Static methods and the constructor are exempt.
* Then pops the context off the stack.
*/
function exitFunction(node) {
const stackContext = popContext();
if (stackContext?.member == null ||
stackContext.usesThis ||
(ignoreOverrideMethods && stackContext.member.override) ||
(ignoreClassesThatImplementAnInterface === true &&
stackContext.class.implements.length > 0) ||
(ignoreClassesThatImplementAnInterface === 'public-fields' &&
stackContext.class.implements.length > 0 &&
isPublicField(stackContext.member.accessibility))) {
return;
}
if (isIncludedInstanceMethod(stackContext.member)) {
context.report({
loc: (0, util_1.getFunctionHeadLoc)(node, context.sourceCode),
node,
messageId: 'missingThis',
data: {
name: (0, util_1.getFunctionNameWithKind)(node),
},
});
}
}
return {
// function declarations have their own `this` context
FunctionDeclaration() {
pushContext();
},
'FunctionDeclaration:exit'() {
popContext();
},
FunctionExpression(node) {
enterFunction(node);
},
'FunctionExpression:exit'(node) {
exitFunction(node);
},
...(enforceForClassFields
? {
'AccessorProperty > ArrowFunctionExpression.value'(node) {
enterFunction(node);
},
'AccessorProperty > ArrowFunctionExpression.value:exit'(node) {
exitFunction(node);
},
'PropertyDefinition > ArrowFunctionExpression.value'(node) {
enterFunction(node);
},
'PropertyDefinition > ArrowFunctionExpression.value:exit'(node) {
exitFunction(node);
},
}
: {}),
/*
* Class field value are implicit functions.
*/
'AccessorProperty:exit'() {
popContext();
},
'AccessorProperty > *.key:exit'() {
pushContext();
},
'PropertyDefinition:exit'() {
popContext();
},
'PropertyDefinition > *.key:exit'() {
pushContext();
},
/*
* Class static blocks are implicit functions. They aren't required to use `this`,
* but we have to push context so that it captures any use of `this` in the static block
* separately from enclosing contexts, because static blocks have their own `this` and it
* shouldn't count as used `this` in enclosing contexts.
*/
StaticBlock() {
pushContext();
},
'StaticBlock:exit'() {
popContext();
},
'ThisExpression, Super'() {
if (stack) {
stack.usesThis = true;
}
},
};
},
});

View File

@@ -0,0 +1,6 @@
export type MessageIds = 'preferConstructor' | 'preferTypeAnnotation';
export type Options = ['constructor' | 'type-annotation'];
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,126 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
const builtInArrays = new Set([
'Float32Array',
'Float64Array',
'Int16Array',
'Int32Array',
'Int8Array',
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
]);
exports.default = (0, util_1.createRule)({
name: 'consistent-generic-constructors',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce specifying generic type arguments on type annotation or constructor name of a constructor call',
recommended: 'stylistic',
},
fixable: 'code',
messages: {
preferConstructor: 'The generic type arguments should be specified as part of the constructor type arguments.',
preferTypeAnnotation: 'The generic type arguments should be specified as part of the type annotation.',
},
schema: [
{
type: 'string',
description: 'Which constructor call syntax to prefer.',
enum: ['type-annotation', 'constructor'],
},
],
},
defaultOptions: ['constructor'],
create(context, [mode]) {
return {
'VariableDeclarator,PropertyDefinition,AccessorProperty,:matches(FunctionDeclaration,FunctionExpression) > AssignmentPattern'(node) {
function getLHSRHS() {
switch (node.type) {
case utils_1.AST_NODE_TYPES.VariableDeclarator:
return [node.id, node.init];
case utils_1.AST_NODE_TYPES.PropertyDefinition:
case utils_1.AST_NODE_TYPES.AccessorProperty:
return [node, node.value];
case utils_1.AST_NODE_TYPES.AssignmentPattern:
return [node.left, node.right];
default:
throw new Error(`Unhandled node type: ${node.type}`);
}
}
function isBuiltInArray(typeName) {
return (builtInArrays.has(typeName.name) &&
(0, util_1.isReferenceToGlobalFunction)(typeName.name, typeName, context.sourceCode));
}
const [lhsName, rhs] = getLHSRHS();
const lhs = lhsName.typeAnnotation?.typeAnnotation;
if (rhs?.type !== utils_1.AST_NODE_TYPES.NewExpression ||
rhs.callee.type !== utils_1.AST_NODE_TYPES.Identifier) {
return;
}
if (lhs &&
(lhs.type !== utils_1.AST_NODE_TYPES.TSTypeReference ||
lhs.typeName.type !== utils_1.AST_NODE_TYPES.Identifier ||
lhs.typeName.name !== rhs.callee.name ||
isBuiltInArray(lhs.typeName))) {
return;
}
if (mode === 'type-annotation') {
if (!lhs && rhs.typeArguments) {
const { callee, typeArguments } = rhs;
const typeAnnotation = context.sourceCode.getText(callee) +
context.sourceCode.getText(typeArguments);
context.report({
node,
messageId: 'preferTypeAnnotation',
fix(fixer) {
function getIDToAttachAnnotation() {
if (node.type !== utils_1.AST_NODE_TYPES.PropertyDefinition &&
node.type !== utils_1.AST_NODE_TYPES.AccessorProperty) {
return lhsName;
}
if (!node.computed) {
return node.key;
}
// If the property's computed, we have to attach the
// annotation after the square bracket, not the enclosed expression
return (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.key), util_1.NullThrowsReasons.MissingToken(']', 'key'));
}
return [
fixer.remove(typeArguments),
fixer.insertTextAfter(getIDToAttachAnnotation(), `: ${typeAnnotation}`),
];
},
});
}
return;
}
const isolatedDeclarations = context.parserOptions.isolatedDeclarations;
if (!isolatedDeclarations && lhs?.typeArguments && !rhs.typeArguments) {
const hasParens = context.sourceCode.getTokenAfter(rhs.callee)?.value === '(';
const extraComments = new Set(context.sourceCode.getCommentsInside(lhs.parent));
context.sourceCode
.getCommentsInside(lhs.typeArguments)
.forEach(c => extraComments.delete(c));
context.report({
node,
messageId: 'preferConstructor',
*fix(fixer) {
yield fixer.remove(lhs.parent);
for (const comment of extraComments) {
yield fixer.insertTextAfter(rhs.callee, context.sourceCode.getText(comment));
}
yield fixer.insertTextAfter(rhs.callee, context.sourceCode.getText(lhs.typeArguments));
if (!hasParens) {
yield fixer.insertTextAfter(rhs.callee, '()');
}
},
});
}
},
};
},
});

View File

@@ -0,0 +1,7 @@
import type { TSESLint } from '@typescript-eslint/utils';
export type MessageIds = 'preferIndexSignature' | 'preferIndexSignatureSuggestion' | 'preferRecord';
export type Options = ['index-signature' | 'record'];
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,256 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'consistent-indexed-object-style',
meta: {
type: 'suggestion',
docs: {
description: 'Require or disallow the `Record` type',
recommended: 'stylistic',
},
fixable: 'code',
// eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- suggestions are exposed through a helper.
hasSuggestions: true,
messages: {
preferIndexSignature: 'An index signature is preferred over a record.',
preferIndexSignatureSuggestion: 'Change into an index signature instead of a record.',
preferRecord: 'A record is preferred over an index signature.',
},
schema: [
{
type: 'string',
description: 'Which indexed object syntax to prefer.',
enum: ['record', 'index-signature'],
},
],
},
defaultOptions: ['record'],
create(context, [mode]) {
function checkMembers(members, node, parentId, prefix, postfix, safeFix = true) {
if (members.length !== 1) {
return;
}
const [member] = members;
if (member.type !== utils_1.AST_NODE_TYPES.TSIndexSignature) {
return;
}
const parameter = member.parameters.at(0);
if (parameter?.type !== utils_1.AST_NODE_TYPES.Identifier) {
return;
}
const keyType = parameter.typeAnnotation;
if (!keyType) {
return;
}
const valueType = member.typeAnnotation;
if (!valueType) {
return;
}
if (parentId) {
const scope = context.sourceCode.getScope(parentId);
const superVar = utils_1.ASTUtils.findVariable(scope, parentId.name);
if (superVar &&
isDeeplyReferencingType(node, superVar, new Set([parentId]))) {
return;
}
}
context.report({
node,
messageId: 'preferRecord',
fix: safeFix
? (fixer) => {
const key = context.sourceCode.getText(keyType.typeAnnotation);
const value = context.sourceCode.getText(valueType.typeAnnotation);
const record = member.readonly
? `Readonly<Record<${key}, ${value}>>`
: `Record<${key}, ${value}>`;
return fixer.replaceText(node, `${prefix}${record}${postfix}`);
}
: null,
});
}
return {
...(mode === 'index-signature' && {
TSTypeReference(node) {
const typeName = node.typeName;
if (typeName.type !== utils_1.AST_NODE_TYPES.Identifier) {
return;
}
if (typeName.name !== 'Record') {
return;
}
const params = node.typeArguments?.params;
if (params?.length !== 2) {
return;
}
const indexParam = params[0];
const shouldFix = indexParam.type === utils_1.AST_NODE_TYPES.TSStringKeyword ||
indexParam.type === utils_1.AST_NODE_TYPES.TSNumberKeyword ||
indexParam.type === utils_1.AST_NODE_TYPES.TSSymbolKeyword;
context.report({
node,
messageId: 'preferIndexSignature',
...(0, util_1.getFixOrSuggest)({
fixOrSuggest: shouldFix ? 'fix' : 'suggest',
suggestion: {
messageId: 'preferIndexSignatureSuggestion',
fix: fixer => {
const key = context.sourceCode.getText(params[0]);
const type = context.sourceCode.getText(params[1]);
return fixer.replaceText(node, `{ [key: ${key}]: ${type} }`);
},
},
}),
});
},
}),
...(mode === 'record' && {
TSInterfaceDeclaration(node) {
let genericTypes = '';
if (node.typeParameters?.params.length) {
genericTypes = `<${node.typeParameters.params
.map(p => context.sourceCode.getText(p))
.join(', ')}>`;
}
checkMembers(node.body.body, node, node.id, `type ${node.id.name}${genericTypes} = `, ';', !node.extends.length &&
node.parent.type !== utils_1.AST_NODE_TYPES.ExportDefaultDeclaration);
},
TSMappedType(node) {
const key = node.key;
const scope = context.sourceCode.getScope(key);
const scopeManagerKey = (0, util_1.nullThrows)(scope.variables.find(value => value.name === key.name && value.isTypeVariable), 'key type parameter must be a defined type variable in its scope');
// If the key is used to compute the value, we can't convert to a Record.
if (scopeManagerKey.references.some(reference => reference.isTypeReference)) {
return;
}
const constraint = node.constraint;
if (constraint.type === utils_1.AST_NODE_TYPES.TSTypeOperator &&
constraint.operator === 'keyof' &&
!(0, util_1.isParenthesized)(constraint, context.sourceCode)) {
// This is a weird special case, since modifiers are preserved by
// the mapped type, but not by the Record type. So this type is not,
// in general, equivalent to a Record type.
return;
}
// If the mapped type is circular, we can't convert it to a Record.
const parentId = findParentDeclaration(node)?.id;
if (parentId) {
const scope = context.sourceCode.getScope(key);
const superVar = utils_1.ASTUtils.findVariable(scope, parentId.name);
if (superVar) {
const isCircular = isDeeplyReferencingType(node.parent, superVar, new Set([parentId]));
if (isCircular) {
return;
}
}
}
// There's no builtin Mutable<T> type, so we can't autofix it really.
const canFix = node.readonly !== '-';
context.report({
node,
messageId: 'preferRecord',
...(canFix && {
fix: (fixer) => {
const keyType = context.sourceCode.getText(constraint);
const valueType = node.typeAnnotation
? context.sourceCode.getText(node.typeAnnotation)
: 'any';
let recordText = `Record<${keyType}, ${valueType}>`;
if (node.optional === '+' || node.optional === true) {
recordText = `Partial<${recordText}>`;
}
else if (node.optional === '-') {
recordText = `Required<${recordText}>`;
}
if (node.readonly === '+' || node.readonly === true) {
recordText = `Readonly<${recordText}>`;
}
return fixer.replaceText(node, recordText);
},
}),
});
},
TSTypeLiteral(node) {
const parent = findParentDeclaration(node);
checkMembers(node.members, node, parent?.id, '', '');
},
}),
};
},
});
function findParentDeclaration(node) {
if (node.parent && node.parent.type !== utils_1.AST_NODE_TYPES.TSTypeAnnotation) {
if (node.parent.type === utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration) {
return node.parent;
}
return findParentDeclaration(node.parent);
}
return undefined;
}
function isDeeplyReferencingType(node, superVar, visited) {
if (visited.has(node)) {
// something on the chain is circular but it's not the reference being checked
return false;
}
visited.add(node);
switch (node.type) {
case utils_1.AST_NODE_TYPES.TSTypeLiteral:
return node.members.some(member => isDeeplyReferencingType(member, superVar, visited));
case utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration:
return isDeeplyReferencingType(node.typeAnnotation, superVar, visited);
case utils_1.AST_NODE_TYPES.TSIndexedAccessType:
return [node.indexType, node.objectType].some(type => isDeeplyReferencingType(type, superVar, visited));
case utils_1.AST_NODE_TYPES.TSMappedType:
if (node.typeAnnotation) {
return isDeeplyReferencingType(node.typeAnnotation, superVar, visited);
}
break;
case utils_1.AST_NODE_TYPES.TSConditionalType:
return [
node.checkType,
node.extendsType,
node.falseType,
node.trueType,
].some(type => isDeeplyReferencingType(type, superVar, visited));
case utils_1.AST_NODE_TYPES.TSUnionType:
case utils_1.AST_NODE_TYPES.TSIntersectionType:
return node.types.some(type => isDeeplyReferencingType(type, superVar, visited));
case utils_1.AST_NODE_TYPES.TSInterfaceDeclaration:
return node.body.body.some(type => isDeeplyReferencingType(type, superVar, visited));
case utils_1.AST_NODE_TYPES.TSTypeAnnotation:
return isDeeplyReferencingType(node.typeAnnotation, superVar, visited);
case utils_1.AST_NODE_TYPES.TSIndexSignature: {
if (node.typeAnnotation) {
return isDeeplyReferencingType(node.typeAnnotation, superVar, visited);
}
break;
}
case utils_1.AST_NODE_TYPES.TSTypeParameterInstantiation: {
return node.params.some(param => isDeeplyReferencingType(param, superVar, visited));
}
case utils_1.AST_NODE_TYPES.TSTypeReference: {
if (isDeeplyReferencingType(node.typeName, superVar, visited)) {
return true;
}
if (node.typeArguments &&
isDeeplyReferencingType(node.typeArguments, superVar, visited)) {
return true;
}
break;
}
case utils_1.AST_NODE_TYPES.Identifier: {
// check if the identifier is a reference of the type being checked
if (superVar.references.some(ref => (0, util_1.isNodeEqual)(ref.identifier, node))) {
return true;
}
// otherwise, follow its definition(s)
const refVar = utils_1.ASTUtils.findVariable(superVar.scope, node.name);
if (refVar) {
return refVar.defs.some(def => isDeeplyReferencingType(def.node, superVar, visited));
}
}
}
return false;
}

View File

@@ -0,0 +1,18 @@
import type { TSESTree } from '@typescript-eslint/utils';
import type { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule } from '../util';
declare const baseRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingReturn" | "missingReturnValue" | "unexpectedReturnValue", [({
treatUndefinedAsUnspecified?: boolean;
} | undefined)?], unknown, {
'ArrowFunctionExpression:exit'(node: TSESTree.ArrowFunctionExpression): void;
'FunctionDeclaration:exit'(node: TSESTree.FunctionDeclaration): void;
'FunctionExpression:exit'(node: TSESTree.FunctionExpression): void;
ReturnStatement(node: TSESTree.ReturnStatement): void;
}>;
export type Options = InferOptionsTypeFromRule<typeof baseRule>;
export type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingReturn" | "missingReturnValue" | "unexpectedReturnValue", [({
treatUndefinedAsUnspecified?: boolean;
} | undefined)?], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,135 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
const getESLintCoreRule_1 = require("../util/getESLintCoreRule");
const baseRule = (0, getESLintCoreRule_1.getESLintCoreRule)('consistent-return');
const defaultOptions = [{ treatUndefinedAsUnspecified: false }];
exports.default = (0, util_1.createRule)({
name: 'consistent-return',
meta: {
type: 'suggestion',
defaultOptions,
docs: {
description: 'Require `return` statements to either always or never specify values',
extendsBaseRule: true,
requiresTypeChecking: true,
},
hasSuggestions: baseRule.meta.hasSuggestions,
messages: baseRule.meta.messages,
schema: baseRule.meta.schema,
},
defaultOptions,
create(context, [options]) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const rules = baseRule.create(context);
const functions = [];
const treatUndefinedAsUnspecified = options?.treatUndefinedAsUnspecified === true;
function enterFunction(node) {
functions.push(node);
}
function exitFunction() {
functions.pop();
}
function getCurrentFunction() {
return functions[functions.length - 1] ?? null;
}
function isPromiseVoid(node, type) {
if (tsutils.isThenableType(checker, node, type) &&
tsutils.isTypeReference(type)) {
const awaitedType = type.typeArguments?.[0];
if (awaitedType) {
if ((0, util_1.isTypeFlagSet)(awaitedType, ts.TypeFlags.Void)) {
return true;
}
return isPromiseVoid(node, awaitedType);
}
}
return false;
}
function isReturnVoidOrThenableVoid(node) {
const functionType = services.getTypeAtLocation(node);
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
const callSignatures = functionType.getCallSignatures();
return callSignatures.some(signature => {
const returnType = signature.getReturnType();
if (node.async) {
return isPromiseVoid(tsNode, returnType);
}
return (0, util_1.isTypeFlagSet)(returnType, ts.TypeFlags.Void);
});
}
return {
...rules,
ArrowFunctionExpression: enterFunction,
'ArrowFunctionExpression:exit'(node) {
exitFunction();
rules['ArrowFunctionExpression:exit'](node);
},
FunctionDeclaration: enterFunction,
'FunctionDeclaration:exit'(node) {
exitFunction();
rules['FunctionDeclaration:exit'](node);
},
FunctionExpression: enterFunction,
'FunctionExpression:exit'(node) {
exitFunction();
rules['FunctionExpression:exit'](node);
},
ReturnStatement(node) {
const functionNode = getCurrentFunction();
if (!node.argument &&
functionNode &&
isReturnVoidOrThenableVoid(functionNode)) {
return;
}
if (treatUndefinedAsUnspecified && node.argument) {
const returnValueType = services.getTypeAtLocation(node.argument);
if (returnValueType.flags === ts.TypeFlags.Undefined) {
rules.ReturnStatement({
...node,
argument: null,
});
return;
}
}
rules.ReturnStatement(node);
},
};
},
});

View File

@@ -0,0 +1,14 @@
import type { TSESLint } from '@typescript-eslint/utils';
export type MessageIds = 'angle-bracket' | 'as' | 'never' | 'replaceArrayTypeAssertionWithAnnotation' | 'replaceArrayTypeAssertionWithSatisfies' | 'replaceObjectTypeAssertionWithAnnotation' | 'replaceObjectTypeAssertionWithSatisfies' | 'unexpectedArrayTypeAssertion' | 'unexpectedObjectTypeAssertion';
type OptUnion = {
assertionStyle: 'angle-bracket' | 'as';
objectLiteralTypeAssertions?: 'allow' | 'allow-as-parameter' | 'never';
arrayLiteralTypeAssertions?: 'allow' | 'allow-as-parameter' | 'never';
} | {
assertionStyle: 'never';
};
export type Options = readonly [OptUnion];
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,256 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
const getWrappedCode_1 = require("../util/getWrappedCode");
exports.default = (0, util_1.createRule)({
name: 'consistent-type-assertions',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce consistent usage of type assertions',
recommended: 'stylistic',
},
fixable: 'code',
hasSuggestions: true,
messages: {
'angle-bracket': "Use '<{{cast}}>' instead of 'as {{cast}}'.",
as: "Use 'as {{cast}}' instead of '<{{cast}}>'.",
never: 'Do not use any type assertions.',
replaceArrayTypeAssertionWithAnnotation: 'Use const x: {{cast}} = [ ... ] instead.',
replaceArrayTypeAssertionWithSatisfies: 'Use const x = [ ... ] satisfies {{cast}} instead.',
replaceObjectTypeAssertionWithAnnotation: 'Use const x: {{cast}} = { ... } instead.',
replaceObjectTypeAssertionWithSatisfies: 'Use const x = { ... } satisfies {{cast}} instead.',
unexpectedArrayTypeAssertion: 'Always prefer const x: T[] = [ ... ].',
unexpectedObjectTypeAssertion: 'Always prefer const x: T = { ... }.',
},
schema: [
{
oneOf: [
{
type: 'object',
additionalProperties: false,
properties: {
assertionStyle: {
type: 'string',
description: 'The expected assertion style to enforce.',
enum: ['never'],
},
},
required: ['assertionStyle'],
},
{
type: 'object',
additionalProperties: false,
properties: {
arrayLiteralTypeAssertions: {
type: 'string',
description: 'Whether to always prefer type declarations for array literals used as variable initializers, rather than type assertions.',
enum: ['allow', 'allow-as-parameter', 'never'],
},
assertionStyle: {
type: 'string',
description: 'The expected assertion style to enforce.',
enum: ['as', 'angle-bracket'],
},
objectLiteralTypeAssertions: {
type: 'string',
description: 'Whether to always prefer type declarations for object literals used as variable initializers, rather than type assertions.',
enum: ['allow', 'allow-as-parameter', 'never'],
},
},
},
],
},
],
},
defaultOptions: [
{
arrayLiteralTypeAssertions: 'allow',
assertionStyle: 'as',
objectLiteralTypeAssertions: 'allow',
},
],
create(context, [options]) {
function isConst(node) {
if (node.type !== utils_1.AST_NODE_TYPES.TSTypeReference) {
return false;
}
return (node.typeName.type === utils_1.AST_NODE_TYPES.Identifier &&
node.typeName.name === 'const');
}
function reportIncorrectAssertionType(node) {
const messageId = options.assertionStyle;
// If this node is `as const`, then don't report an error.
if (isConst(node.typeAnnotation) && messageId === 'never') {
return;
}
context.report({
node,
messageId,
data: messageId !== 'never'
? { cast: context.sourceCode.getText(node.typeAnnotation) }
: {},
fix: messageId === 'as'
? (fixer) => {
// lazily access parserServices to avoid crashing on non TS files (#9860)
const tsNode = (0, util_1.getParserServices)(context, true).esTreeNodeToTSNodeMap.get(node);
const expressionCode = context.sourceCode.getText(node.expression);
const typeAnnotationCode = context.sourceCode.getText(node.typeAnnotation);
const asPrecedence = (0, util_1.getOperatorPrecedence)(ts.SyntaxKind.AsExpression, ts.SyntaxKind.Unknown);
const parentPrecedence = (0, util_1.getOperatorPrecedence)(tsNode.parent.kind, ts.isBinaryExpression(tsNode.parent)
? tsNode.parent.operatorToken.kind
: ts.SyntaxKind.Unknown, ts.isNewExpression(tsNode.parent)
? tsNode.parent.arguments != null &&
tsNode.parent.arguments.length > 0
: undefined);
const expressionPrecedence = (0, util_1.getOperatorPrecedenceForNode)(node.expression);
const expressionCodeWrapped = (0, getWrappedCode_1.getWrappedCode)(expressionCode, expressionPrecedence, asPrecedence);
const text = `${expressionCodeWrapped} as ${typeAnnotationCode}`;
return fixer.replaceText(node, (0, util_1.isParenthesized)(node, context.sourceCode)
? text
: (0, getWrappedCode_1.getWrappedCode)(text, asPrecedence, parentPrecedence));
}
: undefined,
});
}
function checkType(node) {
switch (node.type) {
case utils_1.AST_NODE_TYPES.TSAnyKeyword:
case utils_1.AST_NODE_TYPES.TSUnknownKeyword:
return false;
case utils_1.AST_NODE_TYPES.TSTypeReference:
return (
// Ignore `as const` and `<const>`
!isConst(node) ||
// Allow qualified names which have dots between identifiers, `Foo.Bar`
node.typeName.type === utils_1.AST_NODE_TYPES.TSQualifiedName);
default:
return true;
}
}
function getSuggestions(node, annotationMessageId, satisfiesMessageId) {
const suggestions = [];
if (node.parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator &&
!node.parent.id.typeAnnotation) {
const { parent } = node;
suggestions.push({
messageId: annotationMessageId,
data: { cast: context.sourceCode.getText(node.typeAnnotation) },
fix: fixer => [
fixer.insertTextAfter(parent.id, `: ${context.sourceCode.getText(node.typeAnnotation)}`),
fixer.replaceText(node, (0, util_1.getTextWithParentheses)(context.sourceCode, node.expression)),
],
});
}
suggestions.push({
messageId: satisfiesMessageId,
data: { cast: context.sourceCode.getText(node.typeAnnotation) },
fix: fixer => [
fixer.replaceText(node, (0, util_1.getTextWithParentheses)(context.sourceCode, node.expression)),
fixer.insertTextAfter(node, ` satisfies ${context.sourceCode.getText(node.typeAnnotation)}`),
],
});
return suggestions;
}
function isAsParameter(node) {
return (node.parent.type === utils_1.AST_NODE_TYPES.NewExpression ||
node.parent.type === utils_1.AST_NODE_TYPES.CallExpression ||
node.parent.type === utils_1.AST_NODE_TYPES.ThrowStatement ||
node.parent.type === utils_1.AST_NODE_TYPES.AssignmentPattern ||
node.parent.type === utils_1.AST_NODE_TYPES.JSXExpressionContainer ||
(node.parent.type === utils_1.AST_NODE_TYPES.TemplateLiteral &&
node.parent.parent.type === utils_1.AST_NODE_TYPES.TaggedTemplateExpression));
}
function checkExpressionForObjectAssertion(node) {
if (options.assertionStyle === 'never' ||
options.objectLiteralTypeAssertions === 'allow' ||
node.expression.type !== utils_1.AST_NODE_TYPES.ObjectExpression) {
return;
}
if (options.objectLiteralTypeAssertions === 'allow-as-parameter' &&
isAsParameter(node)) {
return;
}
if (checkType(node.typeAnnotation)) {
const suggest = getSuggestions(node, 'replaceObjectTypeAssertionWithAnnotation', 'replaceObjectTypeAssertionWithSatisfies');
context.report({
node,
messageId: 'unexpectedObjectTypeAssertion',
suggest,
});
}
}
function checkExpressionForArrayAssertion(node) {
if (options.assertionStyle === 'never' ||
options.arrayLiteralTypeAssertions === 'allow' ||
node.expression.type !== utils_1.AST_NODE_TYPES.ArrayExpression) {
return;
}
if (options.arrayLiteralTypeAssertions === 'allow-as-parameter' &&
isAsParameter(node)) {
return;
}
if (checkType(node.typeAnnotation)) {
const suggest = getSuggestions(node, 'replaceArrayTypeAssertionWithAnnotation', 'replaceArrayTypeAssertionWithSatisfies');
context.report({
node,
messageId: 'unexpectedArrayTypeAssertion',
suggest,
});
}
}
return {
TSAsExpression(node) {
if (options.assertionStyle !== 'as') {
reportIncorrectAssertionType(node);
return;
}
checkExpressionForObjectAssertion(node);
checkExpressionForArrayAssertion(node);
},
TSTypeAssertion(node) {
if (options.assertionStyle !== 'angle-bracket') {
reportIncorrectAssertionType(node);
return;
}
checkExpressionForObjectAssertion(node);
checkExpressionForArrayAssertion(node);
},
};
},
});

View File

@@ -0,0 +1,5 @@
import type { TSESLint } from '@typescript-eslint/utils';
declare const _default: TSESLint.RuleModule<"interfaceOverType" | "typeOverInterface", [string], import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,100 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'consistent-type-definitions',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce type definitions to consistently use either `interface` or `type`',
recommended: 'stylistic',
},
fixable: 'code',
messages: {
interfaceOverType: 'Use an `interface` instead of a `type`.',
typeOverInterface: 'Use a `type` instead of an `interface`.',
},
schema: [
{
type: 'string',
description: 'Which type definition syntax to prefer.',
enum: ['interface', 'type'],
},
],
},
defaultOptions: ['interface'],
create(context, [option]) {
/**
* Iterates from the highest parent to the currently traversed node
* to determine whether any node in tree is globally declared module declaration
*/
function isCurrentlyTraversedNodeWithinModuleDeclaration(node) {
return context.sourceCode
.getAncestors(node)
.some(node => node.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration &&
node.declare &&
node.kind === 'global');
}
return {
...(option === 'interface' && {
"TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(node) {
context.report({
node: node.id,
messageId: 'interfaceOverType',
fix(fixer) {
const typeToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(node.id, token => token.value === 'type'), util_1.NullThrowsReasons.MissingToken('type keyword', 'type alias'));
const equalsToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(node.typeAnnotation, token => token.value === '='), util_1.NullThrowsReasons.MissingToken('=', 'type alias'));
const beforeEqualsToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(equalsToken, {
includeComments: true,
}), util_1.NullThrowsReasons.MissingToken('before =', 'type alias'));
return [
// replace 'type' with 'interface'.
fixer.replaceText(typeToken, 'interface'),
// delete from the = to the { of the type, and put a space to be pretty.
fixer.replaceTextRange([beforeEqualsToken.range[1], node.typeAnnotation.range[0]], ' '),
// remove from the closing } through the end of the statement.
fixer.removeRange([
node.typeAnnotation.range[1],
node.range[1],
]),
];
},
});
},
}),
...(option === 'type' && {
TSInterfaceDeclaration(node) {
const fix = isCurrentlyTraversedNodeWithinModuleDeclaration(node)
? null
: (fixer) => {
const typeNode = node.typeParameters ?? node.id;
const fixes = [];
const firstToken = context.sourceCode.getTokenBefore(node.id);
if (firstToken) {
fixes.push(fixer.replaceText(firstToken, 'type'));
fixes.push(fixer.replaceTextRange([typeNode.range[1], node.body.range[0]], ' = '));
}
node.extends.forEach(heritage => {
const typeIdentifier = context.sourceCode.getText(heritage);
fixes.push(fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`));
});
if (node.parent.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
fixes.push(fixer.removeRange([node.parent.range[0], node.range[0]]), fixer.insertTextAfter(node.body, `\nexport default ${node.id.name}`));
}
return fixes;
};
context.report({
node: node.id,
messageId: 'typeOverInterface',
/**
* remove automatically fix when the interface is within a declare global
* @see {@link https://github.com/typescript-eslint/typescript-eslint/issues/2707}
*/
fix,
});
},
}),
};
},
});

View File

@@ -0,0 +1,11 @@
import type { TSESLint } from '@typescript-eslint/utils';
export type Options = [
{
fixMixedExportsWithInlineTypeSpecifier: boolean;
}
];
export type MessageIds = 'multipleExportsAreTypes' | 'singleExportIsType' | 'typeOverValue';
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,335 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'consistent-type-exports',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce consistent usage of type exports',
requiresTypeChecking: true,
},
fixable: 'code',
messages: {
multipleExportsAreTypes: 'Type exports {{exportNames}} are not values and should be exported using `export type`.',
singleExportIsType: 'Type export {{exportNames}} is not a value and should be exported using `export type`.',
typeOverValue: 'All exports in the declaration are only used as types. Use `export type`.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
fixMixedExportsWithInlineTypeSpecifier: {
type: 'boolean',
description: 'Whether the rule will autofix "mixed" export cases using TS inline type specifiers.',
},
},
},
],
},
defaultOptions: [
{
fixMixedExportsWithInlineTypeSpecifier: false,
},
],
create(context, [{ fixMixedExportsWithInlineTypeSpecifier }]) {
const sourceExportsMap = {};
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
/**
* Helper for identifying if a symbol resolves to a
* JavaScript value or a TypeScript type.
*
* @returns True/false if is a type or not, or undefined if the specifier
* can't be resolved.
*/
function isSymbolTypeBased(symbol) {
if (!symbol || checker.isUnknownSymbol(symbol)) {
return undefined;
}
if (symbol.getDeclarations()?.some(ts.isTypeOnlyImportOrExportDeclaration)) {
return true;
}
if (tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Value)) {
return false;
}
return tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)
? isSymbolTypeBased(checker.getImmediateAliasedSymbol(symbol))
: true;
}
return {
ExportAllDeclaration(node) {
if (node.exportKind === 'type') {
return;
}
const sourceModule = ts.resolveModuleName(node.source.value, context.filename, services.program.getCompilerOptions(), ts.sys);
if (sourceModule.resolvedModule == null) {
return;
}
const sourceFile = services.program.getSourceFile(sourceModule.resolvedModule.resolvedFileName);
if (sourceFile == null) {
return;
}
const sourceFileSymbol = checker.getSymbolAtLocation(sourceFile);
if (sourceFileSymbol == null) {
return;
}
const sourceFileType = checker.getTypeOfSymbol(sourceFileSymbol);
// Module can explicitly export types or values, and it's not difficult
// to distinguish one from the other, since we can get the flags of
// the exported symbols or check if symbol export declaration has
// the "type" keyword in it.
//
// Things get a lot more complicated when we're dealing with
// export * from './module-with-type-only-exports'
// export type * from './module-with-type-and-value-exports'
//
// TS checker has an internal function getExportsOfModuleWorker that
// recursively visits all module exports, including "export *". It then
// puts type-only-star-exported symbols into the typeOnlyExportStarMap
// property of sourceFile's SymbolLinks. Since symbol links aren't
// exposed outside the checker, we cannot access it directly.
//
// Therefore, to filter out value properties, we use the following hack:
// checker.getPropertiesOfType returns all exports that were originally
// values, but checker.getPropertyOfType returns undefined for
// properties that are mentioned in the typeOnlyExportStarMap.
const isThereAnyExportedValue = checker
.getPropertiesOfType(sourceFileType)
.some(propertyTypeSymbol => checker.getPropertyOfType(sourceFileType, propertyTypeSymbol.escapedName.toString()) != null);
if (isThereAnyExportedValue) {
return;
}
context.report({
node,
messageId: 'typeOverValue',
fix(fixer) {
const asteriskToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, token => token.type === utils_1.AST_TOKEN_TYPES.Punctuator &&
token.value === '*'), util_1.NullThrowsReasons.MissingToken('asterisk', 'export all declaration'));
return fixer.insertTextBefore(asteriskToken, 'type ');
},
});
},
ExportNamedDeclaration(node) {
// Coerce the source into a string for use as a lookup entry.
const source = getSourceFromExport(node) ?? 'undefined';
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const sourceExports = (sourceExportsMap[source] ||= {
reportValueExports: [],
source,
typeOnlyNamedExport: null,
valueOnlyNamedExport: null,
});
// Cache the first encountered exports for the package. We will need to come
// back to these later when fixing the problems.
if (node.exportKind === 'type') {
// The export is a type export
sourceExports.typeOnlyNamedExport ??= node;
}
else {
// The export is a value export
sourceExports.valueOnlyNamedExport ??= node;
}
// Next for the current export, we will separate type/value specifiers.
const typeBasedSpecifiers = [];
const inlineTypeSpecifiers = [];
const valueSpecifiers = [];
// Note: it is valid to export values as types. We will avoid reporting errors
// when this is encountered.
if (node.exportKind !== 'type') {
for (const specifier of node.specifiers) {
if (specifier.exportKind === 'type') {
inlineTypeSpecifiers.push(specifier);
continue;
}
const isTypeBased = isSymbolTypeBased(services.getSymbolAtLocation(specifier.exported));
if (isTypeBased === true) {
typeBasedSpecifiers.push(specifier);
}
else if (isTypeBased === false) {
// When isTypeBased is undefined, we should avoid reporting them.
valueSpecifiers.push(specifier);
}
}
}
if ((node.exportKind === 'value' && typeBasedSpecifiers.length) ||
(node.exportKind === 'type' && valueSpecifiers.length)) {
sourceExports.reportValueExports.push({
node,
inlineTypeSpecifiers,
typeBasedSpecifiers,
valueSpecifiers,
});
}
},
'Program:exit'() {
for (const sourceExports of Object.values(sourceExportsMap)) {
// If this export has no issues, move on.
if (sourceExports.reportValueExports.length === 0) {
continue;
}
for (const report of sourceExports.reportValueExports) {
if (report.valueSpecifiers.length === 0) {
// Export is all type-only with no type specifiers; convert the entire export to `export type`.
context.report({
node: report.node,
messageId: 'typeOverValue',
*fix(fixer) {
yield* fixExportInsertType(fixer, context.sourceCode, report.node);
},
});
continue;
}
// We have both type and value violations.
const allExportNames = report.typeBasedSpecifiers.map(specifier => specifier.local.type === utils_1.AST_NODE_TYPES.Identifier
? specifier.local.name
: specifier.local.value);
if (allExportNames.length === 1) {
const exportNames = allExportNames[0];
context.report({
node: report.node,
messageId: 'singleExportIsType',
data: { exportNames },
*fix(fixer) {
if (fixMixedExportsWithInlineTypeSpecifier) {
yield* fixAddTypeSpecifierToNamedExports(fixer, report);
}
else {
yield* fixSeparateNamedExports(fixer, context.sourceCode, report);
}
},
});
}
else {
const exportNames = (0, util_1.formatWordList)(allExportNames);
context.report({
node: report.node,
messageId: 'multipleExportsAreTypes',
data: { exportNames },
*fix(fixer) {
if (fixMixedExportsWithInlineTypeSpecifier) {
yield* fixAddTypeSpecifierToNamedExports(fixer, report);
}
else {
yield* fixSeparateNamedExports(fixer, context.sourceCode, report);
}
},
});
}
}
}
},
};
},
});
/**
* Inserts "type" into an export.
*
* Example:
*
* export type { Foo } from 'foo';
* ^^^^
*/
function* fixExportInsertType(fixer, sourceCode, node) {
const exportToken = (0, util_1.nullThrows)(sourceCode.getFirstToken(node), util_1.NullThrowsReasons.MissingToken('export', node.type));
yield fixer.insertTextAfter(exportToken, ' type');
for (const specifier of node.specifiers) {
if (specifier.exportKind === 'type') {
const kindToken = (0, util_1.nullThrows)(sourceCode.getFirstToken(specifier), util_1.NullThrowsReasons.MissingToken('export', specifier.type));
const firstTokenAfter = (0, util_1.nullThrows)(sourceCode.getTokenAfter(kindToken, {
includeComments: true,
}), 'Missing token following the export kind.');
yield fixer.removeRange([kindToken.range[0], firstTokenAfter.range[0]]);
}
}
}
/**
* Separates the exports which mismatch the kind of export the given
* node represents. For example, a type export's named specifiers which
* represent values will be inserted in a separate `export` statement.
*/
function* fixSeparateNamedExports(fixer, sourceCode, report) {
const { node, inlineTypeSpecifiers, typeBasedSpecifiers, valueSpecifiers } = report;
const typeSpecifiers = [...typeBasedSpecifiers, ...inlineTypeSpecifiers];
const source = getSourceFromExport(node);
const specifierNames = typeSpecifiers.map(getSpecifierText).join(', ');
const exportToken = (0, util_1.nullThrows)(sourceCode.getFirstToken(node), util_1.NullThrowsReasons.MissingToken('export', node.type));
// Filter the bad exports from the current line.
const filteredSpecifierNames = valueSpecifiers
.map(getSpecifierText)
.join(', ');
const openToken = (0, util_1.nullThrows)(sourceCode.getFirstToken(node, util_1.isOpeningBraceToken), util_1.NullThrowsReasons.MissingToken('{', node.type));
const closeToken = (0, util_1.nullThrows)(sourceCode.getLastToken(node, util_1.isClosingBraceToken), util_1.NullThrowsReasons.MissingToken('}', node.type));
// Remove exports from the current line which we're going to re-insert.
yield fixer.replaceTextRange([openToken.range[1], closeToken.range[0]], ` ${filteredSpecifierNames} `);
// Insert the bad exports into a new export line above.
yield fixer.insertTextBefore(exportToken, `export type { ${specifierNames} }${source ? ` from '${source}'` : ''};\n`);
}
function* fixAddTypeSpecifierToNamedExports(fixer, report) {
if (report.node.exportKind === 'type') {
return;
}
for (const specifier of report.typeBasedSpecifiers) {
yield fixer.insertTextBefore(specifier, 'type ');
}
}
/**
* Returns the source of the export, or undefined if the named export has no source.
*/
function getSourceFromExport(node) {
if (node.source?.type === utils_1.AST_NODE_TYPES.Literal &&
typeof node.source.value === 'string') {
return node.source.value;
}
return undefined;
}
/**
* Returns the specifier text for the export. If it is aliased, we take care to return
* the proper formatting.
*/
function getSpecifierText(specifier) {
const exportedName = specifier.exported.type === utils_1.AST_NODE_TYPES.Literal
? specifier.exported.raw
: specifier.exported.name;
const localName = specifier.local.type === utils_1.AST_NODE_TYPES.Literal
? specifier.local.raw
: specifier.local.name;
return `${localName}${exportedName !== localName ? ` as ${exportedName}` : ''}`;
}

View File

@@ -0,0 +1,15 @@
import type { TSESLint } from '@typescript-eslint/utils';
type Prefer = 'no-type-imports' | 'type-imports';
type FixStyle = 'inline-type-imports' | 'separate-type-imports';
export type Options = [
{
disallowTypeAnnotations?: boolean;
fixStyle?: FixStyle;
prefer?: Prefer;
}
];
export type MessageIds = 'avoidImportType' | 'noImportTypeAnnotations' | 'someImportsAreOnlyTypes' | 'typeOverValue';
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,608 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'consistent-type-imports',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce consistent usage of type imports',
},
fixable: 'code',
messages: {
avoidImportType: 'Use an `import` instead of an `import type`.',
noImportTypeAnnotations: '`import()` type annotations are forbidden.',
someImportsAreOnlyTypes: 'Imports {{typeImports}} are only used as type.',
typeOverValue: 'All imports in the declaration are only used as types. Use `import type`.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
disallowTypeAnnotations: {
type: 'boolean',
description: 'Whether to disallow type imports in type annotations (`import()`).',
},
fixStyle: {
type: 'string',
description: 'The expected type modifier to be added when an import is detected as used only in the type position.',
enum: ['separate-type-imports', 'inline-type-imports'],
},
prefer: {
type: 'string',
description: 'The expected import kind for type-only imports.',
enum: ['type-imports', 'no-type-imports'],
},
},
},
],
},
defaultOptions: [
{
disallowTypeAnnotations: true,
fixStyle: 'separate-type-imports',
prefer: 'type-imports',
},
],
create(context, [option]) {
const prefer = option.prefer ?? 'type-imports';
const disallowTypeAnnotations = option.disallowTypeAnnotations !== false;
const selectors = {};
if (disallowTypeAnnotations) {
selectors.TSImportType = (node) => {
context.report({
node,
messageId: 'noImportTypeAnnotations',
});
};
}
if (prefer === 'no-type-imports') {
return {
...selectors,
'ImportDeclaration[importKind = "type"]'(node) {
context.report({
node,
messageId: 'avoidImportType',
fix(fixer) {
return fixRemoveTypeSpecifierFromImportDeclaration(fixer, node);
},
});
},
'ImportSpecifier[importKind = "type"]'(node) {
context.report({
node,
messageId: 'avoidImportType',
fix(fixer) {
return fixRemoveTypeSpecifierFromImportSpecifier(fixer, node);
},
});
},
};
}
// prefer type imports
const fixStyle = option.fixStyle ?? 'separate-type-imports';
let hasDecoratorMetadata = false;
const sourceImportsMap = {};
const emitDecoratorMetadata = (0, util_1.getParserServices)(context, true).emitDecoratorMetadata ?? false;
const experimentalDecorators = (0, util_1.getParserServices)(context, true).experimentalDecorators ?? false;
if (experimentalDecorators && emitDecoratorMetadata) {
selectors.Decorator = () => {
hasDecoratorMetadata = true;
};
}
return {
...selectors,
ImportDeclaration(node) {
const source = node.source.value;
// sourceImports is the object containing all the specifics for a particular import source, type or value
sourceImportsMap[source] ??= {
reportValueImports: [], // if there is a mismatch where type importKind but value specifiers
source,
typeOnlyNamedImport: null, // if only type imports
valueImport: null, // if only value imports
valueOnlyNamedImport: null, // if only value imports with named specifiers
};
const sourceImports = sourceImportsMap[source];
if (node.importKind === 'type') {
if (!sourceImports.typeOnlyNamedImport &&
node.specifiers.every(specifier => specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier)) {
// definitely import type { TypeX }
sourceImports.typeOnlyNamedImport = node;
}
}
else if (!sourceImports.valueOnlyNamedImport &&
node.specifiers.length &&
node.specifiers.every(specifier => specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier)) {
sourceImports.valueOnlyNamedImport = node;
sourceImports.valueImport = node;
}
else if (!sourceImports.valueImport &&
node.specifiers.some(specifier => specifier.type === utils_1.AST_NODE_TYPES.ImportDefaultSpecifier)) {
sourceImports.valueImport = node;
}
const typeSpecifiers = [];
const inlineTypeSpecifiers = [];
const valueSpecifiers = [];
const unusedSpecifiers = [];
for (const specifier of node.specifiers) {
if (specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier &&
specifier.importKind === 'type') {
inlineTypeSpecifiers.push(specifier);
continue;
}
const [variable] = context.sourceCode.getDeclaredVariables(specifier);
if (variable.references.length === 0) {
unusedSpecifiers.push(specifier);
}
else {
const onlyHasTypeReferences = variable.references.every(ref => {
/**
* keep origin import kind when export
* export { Type }
* export default Type;
* export = Type;
*/
if ((ref.identifier.parent.type ===
utils_1.AST_NODE_TYPES.ExportSpecifier ||
ref.identifier.parent.type ===
utils_1.AST_NODE_TYPES.ExportDefaultDeclaration ||
ref.identifier.parent.type ===
utils_1.AST_NODE_TYPES.TSExportAssignment) &&
ref.isValueReference &&
ref.isTypeReference) {
return node.importKind === 'type';
}
if (ref.isValueReference) {
let parent = ref.identifier.parent;
let child = ref.identifier;
while (parent) {
switch (parent.type) {
// CASE 1:
// `type T = typeof foo` will create a value reference because "foo" must be a value type
// however this value reference is safe to use with type-only imports
case utils_1.AST_NODE_TYPES.TSTypeQuery:
return true;
case utils_1.AST_NODE_TYPES.TSQualifiedName:
// TSTypeQuery must have a TSESTree.EntityName as its child, so we can filter here and break early
if (parent.left !== child) {
return false;
}
child = parent;
parent = parent.parent;
continue;
// END CASE 1
//////////////
// CASE 2:
// `type T = { [foo]: string }` will create a value reference because "foo" must be a value type
// however this value reference is safe to use with type-only imports.
// Also this is represented as a non-type AST - hence it uses MemberExpression
case utils_1.AST_NODE_TYPES.TSPropertySignature:
return parent.key === child;
case utils_1.AST_NODE_TYPES.MemberExpression:
if (parent.object !== child) {
return false;
}
child = parent;
parent = parent.parent;
continue;
// END CASE 2
default:
return false;
}
}
}
return ref.isTypeReference;
});
if (onlyHasTypeReferences) {
typeSpecifiers.push(specifier);
}
else {
valueSpecifiers.push(specifier);
}
}
}
if (node.importKind === 'value' && typeSpecifiers.length) {
sourceImports.reportValueImports.push({
node,
inlineTypeSpecifiers,
typeSpecifiers,
unusedSpecifiers,
valueSpecifiers,
});
}
},
'Program:exit'() {
if (hasDecoratorMetadata) {
// Experimental decorator metadata is bowl of poop that cannot be
// supported based on pure syntactic analysis.
//
// So we can do one of two things:
// 1) add type-information to the rule in a breaking change and
// prevent users from using it so that we can fully support this
// case.
// 2) make the rule ignore all imports that are used in a file that
// might have decorator metadata.
//
// (1) is has huge impact and prevents the rule from being used by 99%
// of users Frankly - it's a straight-up bad option. So instead we
// choose with option (2) and just avoid reporting on any imports in a
// file with both emitDecoratorMetadata AND decorators
//
// For more context see the discussion in this issue and its linked
// issues:
// https://github.com/typescript-eslint/typescript-eslint/issues/5468
//
//
// NOTE - in TS 5.0 `experimentalDecorators` became the legacy option,
// replaced with un-flagged, stable decorators and thus the type-aware
// emitDecoratorMetadata implementation also became legacy. in TS 5.2
// support for the new, stable decorator metadata proposal was added -
// however this proposal does not include type information
//
//
// PHEW. So TL;DR what does all this mean?
// - if you use experimentalDecorators:true,
// emitDecoratorMetadata:true, and have a decorator in the file -
// the rule will do nothing in the file out of an abundance of
// caution.
// - else the rule will work as normal.
return;
}
for (const sourceImports of Object.values(sourceImportsMap)) {
if (sourceImports.reportValueImports.length === 0) {
// nothing to fix. value specifiers and type specifiers are correctly written
continue;
}
for (const report of sourceImports.reportValueImports) {
if (report.valueSpecifiers.length === 0 &&
report.unusedSpecifiers.length === 0 &&
report.node.importKind !== 'type') {
/**
* checks if import has type assertions
* @example
* ```ts
* import * as type from 'mod' assert \{ type: 'json' \};
* ```
* https://github.com/typescript-eslint/typescript-eslint/issues/7527
*/
if (report.node.attributes.length === 0) {
context.report({
node: report.node,
messageId: 'typeOverValue',
*fix(fixer) {
yield* fixToTypeImportDeclaration(fixer, report, sourceImports);
},
});
}
}
else {
// we have a mixed type/value import or just value imports, so we need to split them out into multiple imports if separate-type-imports is configured
const importNames = report.typeSpecifiers.map(specifier => `"${specifier.local.name}"`);
const message = (() => {
const typeImports = (0, util_1.formatWordList)(importNames);
if (importNames.length === 1) {
return {
messageId: 'someImportsAreOnlyTypes',
data: {
typeImports,
},
};
}
return {
messageId: 'someImportsAreOnlyTypes',
data: {
typeImports,
},
};
})();
context.report({
node: report.node,
...message,
*fix(fixer) {
// take all the typeSpecifiers and put them on a new line
yield* fixToTypeImportDeclaration(fixer, report, sourceImports);
},
});
}
}
}
},
};
function classifySpecifier(node) {
const defaultSpecifier = node.specifiers[0].type === utils_1.AST_NODE_TYPES.ImportDefaultSpecifier
? node.specifiers[0]
: null;
const namespaceSpecifier = node.specifiers.find((specifier) => specifier.type === utils_1.AST_NODE_TYPES.ImportNamespaceSpecifier) ?? null;
const namedSpecifiers = node.specifiers.filter((specifier) => specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier);
return {
defaultSpecifier,
namedSpecifiers,
namespaceSpecifier,
};
}
/**
* Returns information for fixing named specifiers, type or value
*/
function getFixesNamedSpecifiers(fixer, node, subsetNamedSpecifiers, allNamedSpecifiers) {
if (allNamedSpecifiers.length === 0) {
return {
removeTypeNamedSpecifiers: [],
typeNamedSpecifiersText: '',
};
}
const typeNamedSpecifiersTexts = [];
const removeTypeNamedSpecifiers = [];
if (subsetNamedSpecifiers.length === allNamedSpecifiers.length) {
// import Foo, {Type1, Type2} from 'foo'
// import DefType, {Type1, Type2} from 'foo'
const openingBraceToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(subsetNamedSpecifiers[0], util_1.isOpeningBraceToken), util_1.NullThrowsReasons.MissingToken('{', node.type));
const commaToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(openingBraceToken, util_1.isCommaToken), util_1.NullThrowsReasons.MissingToken(',', node.type));
const closingBraceToken = (0, util_1.nullThrows)(context.sourceCode.getFirstTokenBetween(openingBraceToken, node.source, util_1.isClosingBraceToken), util_1.NullThrowsReasons.MissingToken('}', node.type));
// import DefType, {...} from 'foo'
// ^^^^^^^ remove
removeTypeNamedSpecifiers.push(fixer.removeRange([commaToken.range[0], closingBraceToken.range[1]]));
typeNamedSpecifiersTexts.push(context.sourceCode.text.slice(openingBraceToken.range[1], closingBraceToken.range[0]));
}
else {
const namedSpecifierGroups = [];
let group = [];
for (const namedSpecifier of allNamedSpecifiers) {
if (subsetNamedSpecifiers.includes(namedSpecifier)) {
group.push(namedSpecifier);
}
else if (group.length) {
namedSpecifierGroups.push(group);
group = [];
}
}
if (group.length) {
namedSpecifierGroups.push(group);
}
for (const namedSpecifiers of namedSpecifierGroups) {
const { removeRange, textRange } = getNamedSpecifierRanges(namedSpecifiers, allNamedSpecifiers);
removeTypeNamedSpecifiers.push(fixer.removeRange(removeRange));
typeNamedSpecifiersTexts.push(context.sourceCode.text.slice(...textRange));
}
}
return {
removeTypeNamedSpecifiers,
typeNamedSpecifiersText: typeNamedSpecifiersTexts.join(','),
};
}
/**
* Returns ranges for fixing named specifier.
*/
function getNamedSpecifierRanges(namedSpecifierGroup, allNamedSpecifiers) {
const first = namedSpecifierGroup[0];
const last = namedSpecifierGroup[namedSpecifierGroup.length - 1];
const removeRange = [first.range[0], last.range[1]];
const textRange = [...removeRange];
const before = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(first), util_1.NullThrowsReasons.MissingToken('token', 'first specifier'));
textRange[0] = before.range[1];
if ((0, util_1.isCommaToken)(before)) {
removeRange[0] = before.range[0];
}
else {
removeRange[0] = before.range[1];
}
const isFirst = allNamedSpecifiers[0] === first;
const isLast = allNamedSpecifiers[allNamedSpecifiers.length - 1] === last;
const after = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(last), util_1.NullThrowsReasons.MissingToken('token', 'last specifier'));
textRange[1] = after.range[0];
if ((isFirst || isLast) && (0, util_1.isCommaToken)(after)) {
removeRange[1] = after.range[1];
}
return {
removeRange,
textRange,
};
}
/**
* insert specifiers to named import node.
* e.g.
* import type { Already, Type1, Type2 } from 'foo'
* ^^^^^^^^^^^^^ insert
*/
function fixInsertNamedSpecifiersInNamedSpecifierList(fixer, target, insertText) {
const closingBraceToken = (0, util_1.nullThrows)(context.sourceCode.getFirstTokenBetween((0, util_1.nullThrows)(context.sourceCode.getFirstToken(target), util_1.NullThrowsReasons.MissingToken('token before', 'import')), target.source, util_1.isClosingBraceToken), util_1.NullThrowsReasons.MissingToken('}', target.type));
const before = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(closingBraceToken), util_1.NullThrowsReasons.MissingToken('token before', 'closing brace'));
if (!(0, util_1.isCommaToken)(before) && !(0, util_1.isOpeningBraceToken)(before)) {
insertText = `,${insertText}`;
}
return fixer.insertTextBefore(closingBraceToken, insertText);
}
/**
* insert type keyword to named import node.
* e.g.
* import ADefault, { Already, type Type1, type Type2 } from 'foo'
* ^^^^ insert
*/
function* fixInsertTypeKeywordInNamedSpecifierList(fixer, typeSpecifiers) {
for (const spec of typeSpecifiers) {
const insertText = context.sourceCode.text.slice(...spec.range);
yield fixer.replaceTextRange(spec.range, `type ${insertText}`);
}
}
function* fixInlineTypeImportDeclaration(fixer, report, sourceImports) {
const { node } = report;
// For a value import, will only add an inline type to named specifiers
const { namedSpecifiers } = classifySpecifier(node);
const typeNamedSpecifiers = namedSpecifiers.filter(specifier => report.typeSpecifiers.includes(specifier));
if (sourceImports.valueImport) {
// add import named type specifiers to its value import
// import ValueA, { type A }
// ^^^^ insert
const { namedSpecifiers: valueImportNamedSpecifiers } = classifySpecifier(sourceImports.valueImport);
if (sourceImports.valueOnlyNamedImport ||
valueImportNamedSpecifiers.length) {
yield* fixInsertTypeKeywordInNamedSpecifierList(fixer, typeNamedSpecifiers);
}
}
}
function* fixToTypeImportDeclaration(fixer, report, sourceImports) {
const { node } = report;
const { defaultSpecifier, namedSpecifiers, namespaceSpecifier } = classifySpecifier(node);
if (namespaceSpecifier && !defaultSpecifier) {
// import * as types from 'foo'
// checks for presence of import assertions
if (node.attributes.length === 0) {
yield* fixInsertTypeSpecifierForImportDeclaration(fixer, node, false);
}
return;
}
if (defaultSpecifier) {
if (report.typeSpecifiers.includes(defaultSpecifier) &&
namedSpecifiers.length === 0 &&
!namespaceSpecifier) {
// import Type from 'foo'
yield* fixInsertTypeSpecifierForImportDeclaration(fixer, node, true);
return;
}
if (fixStyle === 'inline-type-imports' &&
!report.typeSpecifiers.includes(defaultSpecifier) &&
namedSpecifiers.length > 0 &&
!namespaceSpecifier) {
// if there is a default specifier but it isn't a type specifier, then just add the inline type modifier to the named specifiers
// import AValue, {BValue, Type1, Type2} from 'foo'
yield* fixInlineTypeImportDeclaration(fixer, report, sourceImports);
return;
}
}
else if (!namespaceSpecifier) {
if (fixStyle === 'inline-type-imports' &&
namedSpecifiers.some(specifier => report.typeSpecifiers.includes(specifier))) {
// import {AValue, Type1, Type2} from 'foo'
yield* fixInlineTypeImportDeclaration(fixer, report, sourceImports);
return;
}
if (namedSpecifiers.every(specifier => report.typeSpecifiers.includes(specifier))) {
// import {Type1, Type2} from 'foo'
yield* fixInsertTypeSpecifierForImportDeclaration(fixer, node, false);
return;
}
}
const typeNamedSpecifiers = namedSpecifiers.filter(specifier => report.typeSpecifiers.includes(specifier));
const fixesNamedSpecifiers = getFixesNamedSpecifiers(fixer, node, typeNamedSpecifiers, namedSpecifiers);
const afterFixes = [];
if (typeNamedSpecifiers.length) {
if (sourceImports.typeOnlyNamedImport) {
const insertTypeNamedSpecifiers = fixInsertNamedSpecifiersInNamedSpecifierList(fixer, sourceImports.typeOnlyNamedImport, fixesNamedSpecifiers.typeNamedSpecifiersText);
if (sourceImports.typeOnlyNamedImport.range[1] <= node.range[0]) {
yield insertTypeNamedSpecifiers;
}
else {
afterFixes.push(insertTypeNamedSpecifiers);
}
}
else {
// The import is both default and named. Insert named on new line because can't mix default type import and named type imports
// eslint-disable-next-line no-lonely-if
if (fixStyle === 'inline-type-imports') {
yield fixer.insertTextBefore(node, `import {${typeNamedSpecifiers
.map(spec => {
const insertText = context.sourceCode.text.slice(...spec.range);
return `type ${insertText}`;
})
.join(', ')}} from ${context.sourceCode.getText(node.source)};\n`);
}
else {
yield fixer.insertTextBefore(node, `import type {${fixesNamedSpecifiers.typeNamedSpecifiersText}} from ${context.sourceCode.getText(node.source)};\n`);
}
}
}
const fixesRemoveTypeNamespaceSpecifier = [];
if (namespaceSpecifier &&
report.typeSpecifiers.includes(namespaceSpecifier)) {
// import Foo, * as Type from 'foo'
// import DefType, * as Type from 'foo'
// import DefType, * as Type from 'foo'
const commaToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(namespaceSpecifier, util_1.isCommaToken), util_1.NullThrowsReasons.MissingToken(',', node.type));
// import Def, * as Ns from 'foo'
// ^^^^^^^^^ remove
fixesRemoveTypeNamespaceSpecifier.push(fixer.removeRange([commaToken.range[0], namespaceSpecifier.range[1]]));
// import type * as Ns from 'foo'
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ insert
yield fixer.insertTextBefore(node, `import type ${context.sourceCode.getText(namespaceSpecifier)} from ${context.sourceCode.getText(node.source)};\n`);
}
if (defaultSpecifier &&
report.typeSpecifiers.includes(defaultSpecifier)) {
if (report.typeSpecifiers.length === node.specifiers.length) {
const importToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isImportKeyword), util_1.NullThrowsReasons.MissingToken('import', node.type));
// import type Type from 'foo'
// ^^^^ insert
yield fixer.insertTextAfter(importToken, ' type');
}
else {
const commaToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(defaultSpecifier, util_1.isCommaToken), util_1.NullThrowsReasons.MissingToken(',', defaultSpecifier.type));
// import Type , {...} from 'foo'
// ^^^^^ pick
const defaultText = context.sourceCode.text
.slice(defaultSpecifier.range[0], commaToken.range[0])
.trim();
yield fixer.insertTextBefore(node, `import type ${defaultText} from ${context.sourceCode.getText(node.source)};\n`);
const afterToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(commaToken, {
includeComments: true,
}), util_1.NullThrowsReasons.MissingToken('any token', node.type));
// import Type , {...} from 'foo'
// ^^^^^^^ remove
yield fixer.removeRange([
defaultSpecifier.range[0],
afterToken.range[0],
]);
}
}
yield* fixesNamedSpecifiers.removeTypeNamedSpecifiers;
yield* fixesRemoveTypeNamespaceSpecifier;
yield* afterFixes;
}
function* fixInsertTypeSpecifierForImportDeclaration(fixer, node, isDefaultImport) {
// import type Foo from 'foo'
// ^^^^^ insert
const importToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isImportKeyword), util_1.NullThrowsReasons.MissingToken('import', node.type));
yield fixer.insertTextAfter(importToken, ' type');
if (isDefaultImport) {
// Has default import
const openingBraceToken = context.sourceCode.getFirstTokenBetween(importToken, node.source, util_1.isOpeningBraceToken);
if (openingBraceToken) {
// Only braces. e.g. import Foo, {} from 'foo'
const commaToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(openingBraceToken, util_1.isCommaToken), util_1.NullThrowsReasons.MissingToken(',', node.type));
const closingBraceToken = (0, util_1.nullThrows)(context.sourceCode.getFirstTokenBetween(openingBraceToken, node.source, util_1.isClosingBraceToken), util_1.NullThrowsReasons.MissingToken('}', node.type));
// import type Foo, {} from 'foo'
// ^^ remove
yield fixer.removeRange([
commaToken.range[0],
closingBraceToken.range[1],
]);
const specifiersText = context.sourceCode.text.slice(commaToken.range[1], closingBraceToken.range[1]);
if (node.specifiers.length > 1) {
yield fixer.insertTextAfter(node, `\nimport type${specifiersText} from ${context.sourceCode.getText(node.source)};`);
}
}
}
// make sure we don't do anything like `import type {type T} from 'foo';`
for (const specifier of node.specifiers) {
if (specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier &&
specifier.importKind === 'type') {
yield* fixRemoveTypeSpecifierFromImportSpecifier(fixer, specifier);
}
}
}
function* fixRemoveTypeSpecifierFromImportDeclaration(fixer, node) {
// import type Foo from 'foo'
// ^^^^ remove
const importToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isImportKeyword), util_1.NullThrowsReasons.MissingToken('import', node.type));
const typeToken = (0, util_1.nullThrows)(context.sourceCode.getFirstTokenBetween(importToken, node.specifiers[0]?.local ?? node.source, util_1.isTypeKeyword), util_1.NullThrowsReasons.MissingToken('type', node.type));
const afterToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(typeToken, { includeComments: true }), util_1.NullThrowsReasons.MissingToken('any token', node.type));
yield fixer.removeRange([typeToken.range[0], afterToken.range[0]]);
}
function* fixRemoveTypeSpecifierFromImportSpecifier(fixer, node) {
// import { type Foo } from 'foo'
// ^^^^ remove
const typeToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isTypeKeyword), util_1.NullThrowsReasons.MissingToken('type', node.type));
const afterToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(typeToken, { includeComments: true }), util_1.NullThrowsReasons.MissingToken('any token', node.type));
yield fixer.removeRange([typeToken.range[0], afterToken.range[0]]);
}
},
});

View File

@@ -0,0 +1,4 @@
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"shouldBeLast", [], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'default-param-last',
meta: {
type: 'suggestion',
docs: {
description: 'Enforce default parameters to be last',
extendsBaseRule: true,
frozen: true,
},
messages: {
shouldBeLast: 'Default parameters should be last.',
},
schema: [],
},
defaultOptions: [],
create(context) {
/**
* checks if node is optional parameter
* @param node the node to be evaluated
* @private
*/
function isOptionalParam(node) {
return ((node.type === utils_1.AST_NODE_TYPES.ArrayPattern ||
node.type === utils_1.AST_NODE_TYPES.AssignmentPattern ||
node.type === utils_1.AST_NODE_TYPES.Identifier ||
node.type === utils_1.AST_NODE_TYPES.ObjectPattern ||
node.type === utils_1.AST_NODE_TYPES.RestElement) &&
node.optional);
}
/**
* checks if node is plain parameter
* @param node the node to be evaluated
* @private
*/
function isPlainParam(node) {
return !(node.type === utils_1.AST_NODE_TYPES.AssignmentPattern ||
node.type === utils_1.AST_NODE_TYPES.RestElement ||
isOptionalParam(node));
}
function checkDefaultParamLast(node) {
let hasSeenPlainParam = false;
for (let i = node.params.length - 1; i >= 0; i--) {
const current = node.params[i];
const param = current.type === utils_1.AST_NODE_TYPES.TSParameterProperty
? current.parameter
: current;
if (isPlainParam(param)) {
hasSeenPlainParam = true;
continue;
}
if (hasSeenPlainParam &&
(isOptionalParam(param) ||
param.type === utils_1.AST_NODE_TYPES.AssignmentPattern)) {
context.report({ node: current, messageId: 'shouldBeLast' });
}
}
}
return {
ArrowFunctionExpression: checkDefaultParamLast,
FunctionDeclaration: checkDefaultParamLast,
FunctionExpression: checkDefaultParamLast,
};
},
});

View File

@@ -0,0 +1,23 @@
import type { TSESTree } from '@typescript-eslint/utils';
import type { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule } from '../util';
declare const baseRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"useBrackets" | "useDot", [{
allowIndexSignaturePropertyAccess?: boolean;
allowKeywords?: boolean;
allowPattern?: string;
allowPrivateClassPropertyAccess?: boolean;
allowProtectedClassPropertyAccess?: boolean;
}], unknown, {
MemberExpression(node: TSESTree.MemberExpression): void;
}>;
export type Options = InferOptionsTypeFromRule<typeof baseRule>;
export type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"useBrackets" | "useDot", [{
allowIndexSignaturePropertyAccess?: boolean;
allowKeywords?: boolean;
allowPattern?: string;
allowPrivateClassPropertyAccess?: boolean;
allowProtectedClassPropertyAccess?: boolean;
}], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,139 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
const getESLintCoreRule_1 = require("../util/getESLintCoreRule");
const baseRule = (0, getESLintCoreRule_1.getESLintCoreRule)('dot-notation');
const defaultOptions = [
{
allowIndexSignaturePropertyAccess: false,
allowKeywords: true,
allowPattern: '',
allowPrivateClassPropertyAccess: false,
allowProtectedClassPropertyAccess: false,
},
];
exports.default = (0, util_1.createRule)({
name: 'dot-notation',
meta: {
type: 'suggestion',
defaultOptions,
docs: {
description: 'Enforce dot notation whenever possible',
extendsBaseRule: true,
frozen: true,
recommended: 'stylistic',
requiresTypeChecking: true,
},
fixable: baseRule.meta.fixable,
hasSuggestions: baseRule.meta.hasSuggestions,
messages: baseRule.meta.messages,
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allowIndexSignaturePropertyAccess: {
type: 'boolean',
description: 'Whether to allow accessing properties matching an index signature with array notation.',
},
allowKeywords: {
type: 'boolean',
description: 'Whether to allow keywords such as ["class"]`.',
},
allowPattern: {
type: 'string',
description: 'Regular expression of names to allow.',
},
allowPrivateClassPropertyAccess: {
type: 'boolean',
description: 'Whether to allow accessing class members marked as `private` with array notation.',
},
allowProtectedClassPropertyAccess: {
type: 'boolean',
description: 'Whether to allow accessing class members marked as `protected` with array notation.',
},
},
},
],
},
defaultOptions,
create(context, [options]) {
const rules = baseRule.create(context);
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const allowPrivateClassPropertyAccess = options.allowPrivateClassPropertyAccess;
const allowProtectedClassPropertyAccess = options.allowProtectedClassPropertyAccess;
const allowIndexSignaturePropertyAccess = (options.allowIndexSignaturePropertyAccess ?? false) ||
tsutils.isCompilerOptionEnabled(services.program.getCompilerOptions(), 'noPropertyAccessFromIndexSignature');
return {
MemberExpression(node) {
if ((allowPrivateClassPropertyAccess ||
allowProtectedClassPropertyAccess ||
allowIndexSignaturePropertyAccess) &&
node.computed) {
// for perf reasons - only fetch symbols if we have to
const propertySymbol = services.getSymbolAtLocation(node.property) ??
services
.getTypeAtLocation(node.object)
.getNonNullableType()
.getProperties()
.find(propertySymbol => node.property.type === utils_1.AST_NODE_TYPES.Literal &&
propertySymbol.escapedName === node.property.value);
const modifierKind = (0, util_1.getModifiers)(propertySymbol?.getDeclarations()?.[0])?.[0].kind;
if ((allowPrivateClassPropertyAccess &&
modifierKind === ts.SyntaxKind.PrivateKeyword) ||
(allowProtectedClassPropertyAccess &&
modifierKind === ts.SyntaxKind.ProtectedKeyword)) {
return;
}
if (propertySymbol == null && allowIndexSignaturePropertyAccess) {
const objectType = services
.getTypeAtLocation(node.object)
.getNonNullableType();
const indexInfos = checker.getIndexInfosOfType(objectType);
if (indexInfos.some(info => tsutils.isTypeFlagSet(info.keyType, ts.TypeFlags.StringLike))) {
return;
}
}
}
rules.MemberExpression(node);
},
};
},
});

View File

@@ -0,0 +1,36 @@
import * as ts from 'typescript';
/**
* Retrieve only the Enum literals from a type. for example:
* - 123 --> []
* - {} --> []
* - Fruit.Apple --> [Fruit.Apple]
* - Fruit.Apple | Vegetable.Lettuce --> [Fruit.Apple, Vegetable.Lettuce]
* - Fruit.Apple | Vegetable.Lettuce | 123 --> [Fruit.Apple, Vegetable.Lettuce]
* - T extends Fruit --> [Fruit]
*/
export declare function getEnumLiterals(type: ts.Type): ts.LiteralType[];
/**
* A type can have 0 or more enum types. For example:
* - 123 --> []
* - {} --> []
* - Fruit.Apple --> [Fruit]
* - Fruit.Apple | Vegetable.Lettuce --> [Fruit, Vegetable]
* - Fruit.Apple | Vegetable.Lettuce | 123 --> [Fruit, Vegetable]
* - T extends Fruit --> [Fruit]
*/
export declare function getEnumTypes(typeChecker: ts.TypeChecker, type: ts.Type): ts.Type[];
/**
* Returns the enum key that matches the given literal node, or null if none
* match. For example:
* ```ts
* enum Fruit {
* Apple = 'apple',
* Banana = 'banana',
* }
*
* getEnumKeyForLiteral([Fruit.Apple, Fruit.Banana], 'apple') --> 'Fruit.Apple'
* getEnumKeyForLiteral([Fruit.Apple, Fruit.Banana], 'banana') --> 'Fruit.Banana'
* getEnumKeyForLiteral([Fruit.Apple, Fruit.Banana], 'cherry') --> null
* ```
*/
export declare function getEnumKeyForLiteral(enumLiterals: ts.LiteralType[], literal: unknown): string | null;

View File

@@ -0,0 +1,121 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEnumLiterals = getEnumLiterals;
exports.getEnumTypes = getEnumTypes;
exports.getEnumKeyForLiteral = getEnumKeyForLiteral;
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../../util");
/*
* If passed an enum member, returns the type of the parent. Otherwise,
* returns itself.
*
* For example:
* - `Fruit` --> `Fruit`
* - `Fruit.Apple` --> `Fruit`
*/
function getBaseEnumType(typeChecker, type) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const symbol = type.getSymbol();
if (!tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.EnumMember)) {
return type;
}
return typeChecker.getTypeAtLocation(symbol.valueDeclaration.parent);
}
/**
* Retrieve only the Enum literals from a type. for example:
* - 123 --> []
* - {} --> []
* - Fruit.Apple --> [Fruit.Apple]
* - Fruit.Apple | Vegetable.Lettuce --> [Fruit.Apple, Vegetable.Lettuce]
* - Fruit.Apple | Vegetable.Lettuce | 123 --> [Fruit.Apple, Vegetable.Lettuce]
* - T extends Fruit --> [Fruit]
*/
function getEnumLiterals(type) {
return tsutils
.unionConstituents(type)
.filter((subType) => (0, util_1.isTypeFlagSet)(subType, ts.TypeFlags.EnumLiteral));
}
/**
* A type can have 0 or more enum types. For example:
* - 123 --> []
* - {} --> []
* - Fruit.Apple --> [Fruit]
* - Fruit.Apple | Vegetable.Lettuce --> [Fruit, Vegetable]
* - Fruit.Apple | Vegetable.Lettuce | 123 --> [Fruit, Vegetable]
* - T extends Fruit --> [Fruit]
*/
function getEnumTypes(typeChecker, type) {
return getEnumLiterals(type).map(type => getBaseEnumType(typeChecker, type));
}
/**
* Returns the enum key that matches the given literal node, or null if none
* match. For example:
* ```ts
* enum Fruit {
* Apple = 'apple',
* Banana = 'banana',
* }
*
* getEnumKeyForLiteral([Fruit.Apple, Fruit.Banana], 'apple') --> 'Fruit.Apple'
* getEnumKeyForLiteral([Fruit.Apple, Fruit.Banana], 'banana') --> 'Fruit.Banana'
* getEnumKeyForLiteral([Fruit.Apple, Fruit.Banana], 'cherry') --> null
* ```
*/
function getEnumKeyForLiteral(enumLiterals, literal) {
for (const enumLiteral of enumLiterals) {
if (enumLiteral.value === literal) {
const { symbol } = enumLiteral;
const memberDeclaration = symbol.valueDeclaration;
const enumDeclaration = memberDeclaration.parent;
const memberNameIdentifier = memberDeclaration.name;
const enumName = enumDeclaration.name.text;
switch (memberNameIdentifier.kind) {
case ts.SyntaxKind.Identifier:
return `${enumName}.${memberNameIdentifier.text}`;
case ts.SyntaxKind.StringLiteral: {
const memberName = memberNameIdentifier.text.replaceAll("'", "\\'");
return `${enumName}['${memberName}']`;
}
case ts.SyntaxKind.ComputedPropertyName:
return `${enumName}[${memberNameIdentifier.expression.getText()}]`;
default:
break;
}
}
}
return null;
}

View File

@@ -0,0 +1,17 @@
export type Options = [
{
allowConciseArrowFunctionExpressionsStartingWithVoid?: boolean;
allowDirectConstAssertionInArrowFunctions?: boolean;
allowedNames?: string[];
allowExpressions?: boolean;
allowFunctionsWithoutTypeParameters?: boolean;
allowHigherOrderFunctions?: boolean;
allowIIFEs?: boolean;
allowTypedFunctionExpressions?: boolean;
}
];
export type MessageIds = 'missingReturnType';
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingReturnType", Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,179 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
const explicitReturnTypeUtils_1 = require("../util/explicitReturnTypeUtils");
exports.default = (0, util_1.createRule)({
name: 'explicit-function-return-type',
meta: {
type: 'problem',
docs: {
description: 'Require explicit return types on functions and class methods',
},
messages: {
missingReturnType: 'Missing return type on function.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allowConciseArrowFunctionExpressionsStartingWithVoid: {
type: 'boolean',
description: 'Whether to allow arrow functions that start with the `void` keyword.',
},
allowDirectConstAssertionInArrowFunctions: {
type: 'boolean',
description: 'Whether to ignore arrow functions immediately returning a `as const` value.',
},
allowedNames: {
type: 'array',
description: 'An array of function/method names that will not have their arguments or return values checked.',
items: {
type: 'string',
},
},
allowExpressions: {
type: 'boolean',
description: 'Whether to ignore function expressions (functions which are not part of a declaration).',
},
allowFunctionsWithoutTypeParameters: {
type: 'boolean',
description: "Whether to ignore functions that don't have generic type parameters.",
},
allowHigherOrderFunctions: {
type: 'boolean',
description: 'Whether to ignore functions immediately returning another function expression.',
},
allowIIFEs: {
type: 'boolean',
description: 'Whether to ignore immediately invoked function expressions (IIFEs).',
},
allowTypedFunctionExpressions: {
type: 'boolean',
description: 'Whether to ignore type annotations on the variable of function expressions.',
},
},
},
],
},
defaultOptions: [
{
allowConciseArrowFunctionExpressionsStartingWithVoid: false,
allowDirectConstAssertionInArrowFunctions: true,
allowedNames: [],
allowExpressions: false,
allowFunctionsWithoutTypeParameters: false,
allowHigherOrderFunctions: true,
allowIIFEs: false,
allowTypedFunctionExpressions: true,
},
],
create(context, [options]) {
const functionInfoStack = [];
function enterFunction(node) {
functionInfoStack.push({
node,
returns: [],
});
}
function popFunctionInfo(exitNodeType) {
return (0, util_1.nullThrows)(functionInfoStack.pop(), `Stack should exist on ${exitNodeType} exit`);
}
function isAllowedFunction(node) {
if (options.allowFunctionsWithoutTypeParameters && !node.typeParameters) {
return true;
}
if (options.allowIIFEs && isIIFE(node)) {
return true;
}
if (!options.allowedNames?.length) {
return false;
}
if (node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
node.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
const parent = node.parent;
let funcName;
if (node.id?.name) {
funcName = node.id.name;
}
else {
switch (parent.type) {
case utils_1.AST_NODE_TYPES.VariableDeclarator: {
if (parent.id.type === utils_1.AST_NODE_TYPES.Identifier) {
funcName = parent.id.name;
}
break;
}
case utils_1.AST_NODE_TYPES.MethodDefinition:
case utils_1.AST_NODE_TYPES.PropertyDefinition:
case utils_1.AST_NODE_TYPES.Property: {
if (parent.key.type === utils_1.AST_NODE_TYPES.Identifier &&
!parent.computed) {
funcName = parent.key.name;
}
break;
}
}
}
if (!!funcName && options.allowedNames.includes(funcName)) {
return true;
}
}
if (node.type === utils_1.AST_NODE_TYPES.FunctionDeclaration &&
node.id &&
options.allowedNames.includes(node.id.name)) {
return true;
}
return false;
}
function isIIFE(node) {
return node.parent.type === utils_1.AST_NODE_TYPES.CallExpression;
}
function exitFunctionExpression(node) {
const info = popFunctionInfo('function expression');
if (options.allowConciseArrowFunctionExpressionsStartingWithVoid &&
node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
node.expression &&
node.body.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
node.body.operator === 'void') {
return;
}
if (isAllowedFunction(node)) {
return;
}
if (options.allowTypedFunctionExpressions &&
((0, explicitReturnTypeUtils_1.isValidFunctionExpressionReturnType)(node, options) ||
(0, explicitReturnTypeUtils_1.ancestorHasReturnType)(node))) {
return;
}
(0, explicitReturnTypeUtils_1.checkFunctionReturnType)(info, options, context.sourceCode, loc => context.report({
loc,
node,
messageId: 'missingReturnType',
}));
}
return {
'ArrowFunctionExpression, FunctionExpression, FunctionDeclaration': enterFunction,
'ArrowFunctionExpression:exit': exitFunctionExpression,
'FunctionDeclaration:exit'(node) {
const info = popFunctionInfo('function declaration');
if (isAllowedFunction(node)) {
return;
}
if (options.allowTypedFunctionExpressions && node.returnType) {
return;
}
(0, explicitReturnTypeUtils_1.checkFunctionReturnType)(info, options, context.sourceCode, loc => context.report({
loc,
node,
messageId: 'missingReturnType',
}));
},
'FunctionExpression:exit': exitFunctionExpression,
ReturnStatement(node) {
functionInfoStack.at(-1)?.returns.push(node);
},
};
},
});

View File

@@ -0,0 +1,19 @@
import type { TSESLint } from '@typescript-eslint/utils';
type AccessibilityLevel = 'explicit' | 'no-public' | 'off';
export interface Config {
accessibility?: AccessibilityLevel;
ignoredMethodNames?: string[];
overrides?: {
accessors?: AccessibilityLevel;
constructors?: AccessibilityLevel;
methods?: AccessibilityLevel;
parameterProperties?: AccessibilityLevel;
properties?: AccessibilityLevel;
};
}
export type Options = [Config];
export type MessageIds = 'addExplicitAccessibility' | 'missingAccessibility' | 'unwantedPublicAccessibility';
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,299 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
const getMemberHeadLoc_1 = require("../util/getMemberHeadLoc");
const rangeToLoc_1 = require("../util/rangeToLoc");
exports.default = (0, util_1.createRule)({
name: 'explicit-member-accessibility',
meta: {
type: 'problem',
docs: {
description: 'Require explicit accessibility modifiers on class properties and methods',
// too opinionated to be recommended
},
fixable: 'code',
hasSuggestions: true,
messages: {
addExplicitAccessibility: "Add '{{ type }}' accessibility modifier",
missingAccessibility: 'Missing accessibility modifier on {{type}} {{name}}.',
unwantedPublicAccessibility: 'Public accessibility modifier on {{type}} {{name}}.',
},
schema: [
{
type: 'object',
$defs: {
accessibilityLevel: {
oneOf: [
{
type: 'string',
description: 'Always require an accessor.',
enum: ['explicit'],
},
{
type: 'string',
description: 'Require an accessor except when public.',
enum: ['no-public'],
},
{
type: 'string',
description: 'Never check whether there is an accessor.',
enum: ['off'],
},
],
},
},
additionalProperties: false,
properties: {
accessibility: {
$ref: '#/items/0/$defs/accessibilityLevel',
description: 'Which accessibility modifier is required to exist or not exist.',
},
ignoredMethodNames: {
type: 'array',
description: 'Specific method names that may be ignored.',
items: {
type: 'string',
},
},
overrides: {
type: 'object',
additionalProperties: false,
description: 'Changes to required accessibility modifiers for specific kinds of class members.',
properties: {
accessors: {
$ref: '#/items/0/$defs/accessibilityLevel',
description: 'Which member accessibility modifier requirements to apply for accessors.',
},
constructors: {
$ref: '#/items/0/$defs/accessibilityLevel',
description: 'Which member accessibility modifier requirements to apply for constructors.',
},
methods: {
$ref: '#/items/0/$defs/accessibilityLevel',
description: 'Which member accessibility modifier requirements to apply for methods.',
},
parameterProperties: {
$ref: '#/items/0/$defs/accessibilityLevel',
description: 'Which member accessibility modifier requirements to apply for parameterProperties.',
},
properties: {
$ref: '#/items/0/$defs/accessibilityLevel',
description: 'Which member accessibility modifier requirements to apply for properties.',
},
},
},
},
},
],
},
defaultOptions: [{ accessibility: 'explicit' }],
create(context, [option]) {
const baseCheck = option.accessibility ?? 'explicit';
const overrides = option.overrides ?? {};
const ctorCheck = overrides.constructors ?? baseCheck;
const accessorCheck = overrides.accessors ?? baseCheck;
const methodCheck = overrides.methods ?? baseCheck;
const propCheck = overrides.properties ?? baseCheck;
const paramPropCheck = overrides.parameterProperties ?? baseCheck;
const ignoredMethodNames = new Set(option.ignoredMethodNames ?? []);
/**
* Checks if a method declaration has an accessibility modifier.
* @param methodDefinition The node representing a MethodDefinition.
*/
function checkMethodAccessibilityModifier(methodDefinition) {
if (methodDefinition.key.type === utils_1.AST_NODE_TYPES.PrivateIdentifier) {
return;
}
let nodeType = 'method definition';
let check = baseCheck;
switch (methodDefinition.kind) {
case 'method':
check = methodCheck;
break;
case 'constructor':
check = ctorCheck;
break;
case 'get':
case 'set':
check = accessorCheck;
nodeType = `${methodDefinition.kind} property accessor`;
break;
}
const { name: methodName } = (0, util_1.getNameFromMember)(methodDefinition, context.sourceCode);
if (check === 'off' || ignoredMethodNames.has(methodName)) {
return;
}
if (check === 'no-public' &&
methodDefinition.accessibility === 'public') {
const publicKeyword = findPublicKeyword(methodDefinition);
context.report({
loc: (0, rangeToLoc_1.rangeToLoc)(context.sourceCode, publicKeyword.range),
messageId: 'unwantedPublicAccessibility',
data: {
name: methodName,
type: nodeType,
},
fix: fixer => fixer.removeRange(publicKeyword.rangeToRemove),
});
}
else if (check === 'explicit' && !methodDefinition.accessibility) {
context.report({
loc: (0, getMemberHeadLoc_1.getMemberHeadLoc)(context.sourceCode, methodDefinition),
messageId: 'missingAccessibility',
data: {
name: methodName,
type: nodeType,
},
suggest: getMissingAccessibilitySuggestions(methodDefinition),
});
}
}
/**
* Returns an object containing a range that corresponds to the "public"
* keyword for a node, and the range that would need to be removed to
* remove the "public" keyword (including associated whitespace).
*/
function findPublicKeyword(node) {
const tokens = context.sourceCode.getTokens(node);
let rangeToRemove;
let keywordRange;
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
if (token.type === utils_1.AST_TOKEN_TYPES.Keyword &&
token.value === 'public') {
keywordRange = structuredClone(token.range);
const commentsAfterPublicKeyword = context.sourceCode.getCommentsAfter(token);
if (commentsAfterPublicKeyword.length) {
// public /* Hi there! */ static foo()
// ^^^^^^^
rangeToRemove = [
token.range[0],
commentsAfterPublicKeyword[0].range[0],
];
break;
}
else {
// public static foo()
// ^^^^^^^
rangeToRemove = [token.range[0], tokens[i + 1].range[0]];
break;
}
}
}
return { range: keywordRange, rangeToRemove };
}
/**
* Creates a fixer that adds an accessibility modifier keyword
*/
function getMissingAccessibilitySuggestions(node) {
function fix(accessibility, fixer) {
if (node.decorators.length) {
const lastDecorator = node.decorators[node.decorators.length - 1];
const nextToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(lastDecorator), util_1.NullThrowsReasons.MissingToken('token', 'last decorator'));
return fixer.insertTextBefore(nextToken, `${accessibility} `);
}
return fixer.insertTextBefore(node, `${accessibility} `);
}
return [
{
messageId: 'addExplicitAccessibility',
data: { type: 'public' },
fix: fixer => fix('public', fixer),
},
{
messageId: 'addExplicitAccessibility',
data: { type: 'private' },
fix: fixer => fix('private', fixer),
},
{
messageId: 'addExplicitAccessibility',
data: { type: 'protected' },
fix: fixer => fix('protected', fixer),
},
];
}
/**
* Checks if property has an accessibility modifier.
* @param propertyDefinition The node representing a PropertyDefinition.
*/
function checkPropertyAccessibilityModifier(propertyDefinition) {
if (propertyDefinition.key.type === utils_1.AST_NODE_TYPES.PrivateIdentifier) {
return;
}
const nodeType = 'class property';
const { name: propertyName } = (0, util_1.getNameFromMember)(propertyDefinition, context.sourceCode);
if (propCheck === 'no-public' &&
propertyDefinition.accessibility === 'public') {
const publicKeywordRange = findPublicKeyword(propertyDefinition);
context.report({
loc: (0, rangeToLoc_1.rangeToLoc)(context.sourceCode, publicKeywordRange.range),
messageId: 'unwantedPublicAccessibility',
data: {
name: propertyName,
type: nodeType,
},
fix: fixer => fixer.removeRange(publicKeywordRange.rangeToRemove),
});
}
else if (propCheck === 'explicit' &&
!propertyDefinition.accessibility) {
context.report({
loc: (0, getMemberHeadLoc_1.getMemberHeadLoc)(context.sourceCode, propertyDefinition),
messageId: 'missingAccessibility',
data: {
name: propertyName,
type: nodeType,
},
suggest: getMissingAccessibilitySuggestions(propertyDefinition),
});
}
}
/**
* Checks that the parameter property has the desired accessibility modifiers set.
* @param node The node representing a Parameter Property
*/
function checkParameterPropertyAccessibilityModifier(node) {
const nodeType = 'parameter property';
const nodeName = node.parameter.type === utils_1.AST_NODE_TYPES.Identifier
? node.parameter.name
: node.parameter.left.name;
switch (paramPropCheck) {
case 'explicit': {
if (!node.accessibility) {
context.report({
loc: (0, getMemberHeadLoc_1.getParameterPropertyHeadLoc)(context.sourceCode, node, nodeName),
messageId: 'missingAccessibility',
data: {
name: nodeName,
type: nodeType,
},
suggest: getMissingAccessibilitySuggestions(node),
});
}
break;
}
case 'no-public': {
if (node.accessibility === 'public' && node.readonly) {
const publicKeyword = findPublicKeyword(node);
context.report({
loc: (0, rangeToLoc_1.rangeToLoc)(context.sourceCode, publicKeyword.range),
messageId: 'unwantedPublicAccessibility',
data: {
name: nodeName,
type: nodeType,
},
fix: fixer => fixer.removeRange(publicKeyword.rangeToRemove),
});
}
break;
}
}
}
return {
'MethodDefinition, TSAbstractMethodDefinition': checkMethodAccessibilityModifier,
'PropertyDefinition, TSAbstractPropertyDefinition, AccessorProperty, TSAbstractAccessorProperty': checkPropertyAccessibilityModifier,
TSParameterProperty: checkParameterPropertyAccessibilityModifier,
};
},
});

View File

@@ -0,0 +1,15 @@
export type Options = [
{
allowArgumentsExplicitlyTypedAsAny?: boolean;
allowDirectConstAssertionInArrowFunctions?: boolean;
allowedNames?: string[];
allowHigherOrderFunctions?: boolean;
allowTypedFunctionExpressions?: boolean;
allowOverloadFunctions?: boolean;
}
];
export type MessageIds = 'anyTypedArg' | 'anyTypedArgUnnamed' | 'missingArgType' | 'missingArgTypeUnnamed' | 'missingReturnType';
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,386 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const scope_manager_1 = require("@typescript-eslint/scope-manager");
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
const explicitReturnTypeUtils_1 = require("../util/explicitReturnTypeUtils");
exports.default = (0, util_1.createRule)({
name: 'explicit-module-boundary-types',
meta: {
type: 'problem',
docs: {
description: "Require explicit return and argument types on exported functions' and classes' public class methods",
},
messages: {
anyTypedArg: "Argument '{{name}}' should be typed with a non-any type.",
anyTypedArgUnnamed: '{{type}} argument should be typed with a non-any type.',
missingArgType: "Argument '{{name}}' should be typed.",
missingArgTypeUnnamed: '{{type}} argument should be typed.',
missingReturnType: 'Missing return type on function.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allowArgumentsExplicitlyTypedAsAny: {
type: 'boolean',
description: 'Whether to ignore arguments that are explicitly typed as `any`.',
},
allowDirectConstAssertionInArrowFunctions: {
type: 'boolean',
description: [
'Whether to ignore return type annotations on body-less arrow functions that return an `as const` type assertion.',
'You must still type the parameters of the function.',
].join('\n'),
},
allowedNames: {
type: 'array',
description: 'An array of function/method names that will not have their arguments or return values checked.',
items: {
type: 'string',
},
},
allowHigherOrderFunctions: {
type: 'boolean',
description: [
'Whether to ignore return type annotations on functions immediately returning another function expression.',
'You must still type the parameters of the function.',
].join('\n'),
},
allowOverloadFunctions: {
type: 'boolean',
description: 'Whether to ignore return type annotations on functions with overload signatures.',
},
allowTypedFunctionExpressions: {
type: 'boolean',
description: 'Whether to ignore type annotations on the variable of a function expression.',
},
},
},
],
},
defaultOptions: [
{
allowArgumentsExplicitlyTypedAsAny: false,
allowDirectConstAssertionInArrowFunctions: true,
allowedNames: [],
allowHigherOrderFunctions: true,
allowOverloadFunctions: false,
allowTypedFunctionExpressions: true,
},
],
create(context, [options]) {
// tracks all of the functions we've already checked
const checkedFunctions = new Set();
const functionStack = [];
const functionReturnsMap = new Map();
// all nodes visited, avoids infinite recursion for cyclic references
// (such as class member referring to itself)
const alreadyVisited = new Set();
function getReturnsInFunction(node) {
return functionReturnsMap.get(node) ?? [];
}
function enterFunction(node) {
functionStack.push(node);
functionReturnsMap.set(node, []);
}
function exitFunction() {
functionStack.pop();
}
/*
# How the rule works:
As the rule traverses the AST, it immediately checks every single function that it finds is exported.
"exported" means that it is either directly exported, or that its name is exported.
It also collects a list of every single function it finds on the way, but does not check them.
After it's finished traversing the AST, it then iterates through the list of found functions, and checks to see if
any of them are part of a higher-order function
*/
return {
'ArrowFunctionExpression, FunctionDeclaration, FunctionExpression': enterFunction,
'ArrowFunctionExpression:exit': exitFunction,
'ExportDefaultDeclaration:exit'(node) {
checkNode(node.declaration);
},
'ExportNamedDeclaration:not([source]):exit'(node) {
if (node.declaration) {
checkNode(node.declaration);
}
else {
for (const specifier of node.specifiers) {
followReference(specifier.local);
}
}
},
'FunctionDeclaration:exit': exitFunction,
'FunctionExpression:exit': exitFunction,
'Program:exit'() {
for (const [node, returns] of functionReturnsMap) {
if (isExportedHigherOrderFunction({ node, returns })) {
checkNode(node);
}
}
},
ReturnStatement(node) {
const current = functionStack[functionStack.length - 1];
functionReturnsMap.get(current)?.push(node);
},
'TSExportAssignment:exit'(node) {
checkNode(node.expression);
},
};
function checkParameters(node) {
function checkParameter(param) {
function report(namedMessageId, unnamedMessageId) {
if (param.type === utils_1.AST_NODE_TYPES.Identifier) {
context.report({
node: param,
messageId: namedMessageId,
data: { name: param.name },
});
}
else if (param.type === utils_1.AST_NODE_TYPES.ArrayPattern) {
context.report({
node: param,
messageId: unnamedMessageId,
data: { type: 'Array pattern' },
});
}
else if (param.type === utils_1.AST_NODE_TYPES.ObjectPattern) {
context.report({
node: param,
messageId: unnamedMessageId,
data: { type: 'Object pattern' },
});
}
else if (param.type === utils_1.AST_NODE_TYPES.RestElement) {
if (param.argument.type === utils_1.AST_NODE_TYPES.Identifier) {
context.report({
node: param,
messageId: namedMessageId,
data: { name: param.argument.name },
});
}
else {
context.report({
node: param,
messageId: unnamedMessageId,
data: { type: 'Rest' },
});
}
}
}
switch (param.type) {
case utils_1.AST_NODE_TYPES.ArrayPattern:
case utils_1.AST_NODE_TYPES.Identifier:
case utils_1.AST_NODE_TYPES.ObjectPattern:
case utils_1.AST_NODE_TYPES.RestElement:
if (!param.typeAnnotation) {
report('missingArgType', 'missingArgTypeUnnamed');
}
else if (options.allowArgumentsExplicitlyTypedAsAny !== true &&
param.typeAnnotation.typeAnnotation.type ===
utils_1.AST_NODE_TYPES.TSAnyKeyword) {
report('anyTypedArg', 'anyTypedArgUnnamed');
}
return;
case utils_1.AST_NODE_TYPES.TSParameterProperty:
return checkParameter(param.parameter);
case utils_1.AST_NODE_TYPES.AssignmentPattern: // ignored as it has a type via its assignment
return;
}
}
for (const arg of node.params) {
checkParameter(arg);
}
}
/**
* Checks if a function name is allowed and should not be checked.
*/
function isAllowedName(node) {
if (!node || !options.allowedNames || options.allowedNames.length === 0) {
return false;
}
if (node.type === utils_1.AST_NODE_TYPES.VariableDeclarator ||
node.type === utils_1.AST_NODE_TYPES.FunctionDeclaration) {
return (node.id?.type === utils_1.AST_NODE_TYPES.Identifier &&
options.allowedNames.includes(node.id.name));
}
if (node.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
node.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition ||
(node.type === utils_1.AST_NODE_TYPES.Property && node.method) ||
node.type === utils_1.AST_NODE_TYPES.PropertyDefinition ||
node.type === utils_1.AST_NODE_TYPES.AccessorProperty) {
return (0, util_1.isStaticMemberAccessOfValue)(node, context, ...options.allowedNames);
}
return false;
}
function isExportedHigherOrderFunction({ node, }) {
let current = node.parent;
while (current) {
if (current.type === utils_1.AST_NODE_TYPES.ReturnStatement) {
// the parent of a return will always be a block statement, so we can skip over it
current = current.parent.parent;
continue;
}
if (!(0, util_1.isFunction)(current)) {
return false;
}
const returns = getReturnsInFunction(current);
if (!(0, explicitReturnTypeUtils_1.doesImmediatelyReturnFunctionExpression)({ node: current, returns })) {
return false;
}
if (checkedFunctions.has(current)) {
return true;
}
current = current.parent;
}
return false;
}
function followReference(node) {
const scope = context.sourceCode.getScope(node);
const variable = scope.set.get(node.name);
/* istanbul ignore if */ if (!variable) {
return;
}
// check all of the definitions
for (const definition of variable.defs) {
// cases we don't care about in this rule
if ([
scope_manager_1.DefinitionType.CatchClause,
scope_manager_1.DefinitionType.ImplicitGlobalVariable,
scope_manager_1.DefinitionType.ImportBinding,
scope_manager_1.DefinitionType.Parameter,
].includes(definition.type)) {
continue;
}
checkNode(definition.node);
}
// follow references to find writes to the variable
for (const reference of variable.references) {
if (
// we don't want to check the initialization ref, as this is handled by the declaration check
!reference.init &&
reference.writeExpr) {
checkNode(reference.writeExpr);
}
}
}
function checkNode(node) {
if (node == null || alreadyVisited.has(node)) {
return;
}
alreadyVisited.add(node);
switch (node.type) {
case utils_1.AST_NODE_TYPES.ArrowFunctionExpression:
case utils_1.AST_NODE_TYPES.FunctionExpression: {
const returns = getReturnsInFunction(node);
return checkFunctionExpression({ node, returns });
}
case utils_1.AST_NODE_TYPES.ArrayExpression:
for (const element of node.elements) {
checkNode(element);
}
return;
case utils_1.AST_NODE_TYPES.PropertyDefinition:
case utils_1.AST_NODE_TYPES.AccessorProperty:
case utils_1.AST_NODE_TYPES.MethodDefinition:
case utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition:
if (node.accessibility === 'private' ||
node.key.type === utils_1.AST_NODE_TYPES.PrivateIdentifier) {
return;
}
return checkNode(node.value);
case utils_1.AST_NODE_TYPES.ClassDeclaration:
case utils_1.AST_NODE_TYPES.ClassExpression:
for (const element of node.body.body) {
checkNode(element);
}
return;
case utils_1.AST_NODE_TYPES.FunctionDeclaration: {
const returns = getReturnsInFunction(node);
return checkFunction({ node, returns });
}
case utils_1.AST_NODE_TYPES.Identifier:
return followReference(node);
case utils_1.AST_NODE_TYPES.ObjectExpression:
for (const property of node.properties) {
checkNode(property);
}
return;
case utils_1.AST_NODE_TYPES.Property:
return checkNode(node.value);
case utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression:
return checkEmptyBodyFunctionExpression(node);
case utils_1.AST_NODE_TYPES.VariableDeclaration:
for (const declaration of node.declarations) {
checkNode(declaration);
}
return;
case utils_1.AST_NODE_TYPES.VariableDeclarator:
return checkNode(node.init);
}
}
function checkEmptyBodyFunctionExpression(node) {
const isConstructor = node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
node.parent.kind === 'constructor';
const isSetAccessor = (node.parent.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition ||
node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition) &&
node.parent.kind === 'set';
if (!isConstructor && !isSetAccessor && !node.returnType) {
context.report({
node,
messageId: 'missingReturnType',
});
}
checkParameters(node);
}
function checkFunctionExpression({ node, returns, }) {
if (checkedFunctions.has(node)) {
return;
}
checkedFunctions.add(node);
if (isAllowedName(node.parent) ||
(0, explicitReturnTypeUtils_1.isTypedFunctionExpression)(node, options) ||
(0, explicitReturnTypeUtils_1.ancestorHasReturnType)(node)) {
return;
}
if (options.allowOverloadFunctions &&
node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
(0, util_1.hasOverloadSignatures)(node.parent, context)) {
return;
}
(0, explicitReturnTypeUtils_1.checkFunctionExpressionReturnType)({ node, returns }, options, context.sourceCode, loc => {
context.report({
loc,
node,
messageId: 'missingReturnType',
});
});
checkParameters(node);
}
function checkFunction({ node, returns, }) {
if (checkedFunctions.has(node)) {
return;
}
checkedFunctions.add(node);
if (isAllowedName(node) || (0, explicitReturnTypeUtils_1.ancestorHasReturnType)(node)) {
return;
}
if (options.allowOverloadFunctions &&
(0, util_1.hasOverloadSignatures)(node, context)) {
return;
}
(0, explicitReturnTypeUtils_1.checkFunctionReturnType)({ node, returns }, options, context.sourceCode, loc => {
context.report({
loc,
node,
messageId: 'missingReturnType',
});
});
checkParameters(node);
}
},
});

Some files were not shown because too many files have changed in this diff Show More