@gitlab/eslint-plugin 21.5.0 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +299 -0
  2. package/README.md +16 -11
  3. package/docs/development.md +2 -1
  4. package/docs/usage.md +158 -47
  5. package/eslint9/index.js +6 -7
  6. package/lib/configs/base/best-practices.js +0 -4
  7. package/lib/configs/base/es6.js +1 -13
  8. package/lib/configs/base/imports.js +86 -106
  9. package/lib/configs/base/node.js +0 -4
  10. package/lib/confusing-browser-globals.js +68 -0
  11. package/lib/flat-configs/base.js +122 -0
  12. package/lib/flat-configs/default.js +13 -0
  13. package/lib/flat-configs/i18n.js +14 -0
  14. package/lib/flat-configs/jest.js +20 -0
  15. package/lib/flat-configs/tailwind.js +19 -0
  16. package/lib/flat-configs/typescript.js +136 -0
  17. package/lib/flat-configs/vue.js +16 -0
  18. package/lib/index.js +30 -39
  19. package/lib/plugin.js +32 -0
  20. package/lib/prettier-rules.js +10 -0
  21. package/lib/rules/no-runtime-template-compiler.js +6 -3
  22. package/lib/rules/require-i18n-strings.js +4 -4
  23. package/lib/rules/vtu-no-explicit-wrapper-destroy.js +1 -1
  24. package/lib/rules/vue-no-new-non-primitive-in-template.js +1 -1
  25. package/lib/rules/vue-no-undef-apollo-properties.js +1 -1
  26. package/lib/rules/vue-prefer-dollar-scopedslots.js +1 -1
  27. package/lib/rules/vue-require-required-key.js +1 -1
  28. package/lib/rules/vue-slot-name-casing.js +2 -3
  29. package/lib/utils/hardcoded-urls.js +1 -1
  30. package/lib/utils/string-utils.js +6 -8
  31. package/lib/vue-fragments.js +111 -0
  32. package/package.json +31 -12
  33. package/scripts/benchmarking/checkAllStrings.js +1 -1
  34. package/scripts/helpers/getConfigs.js +15 -6
  35. package/scripts/publish_npm_package.mjs +0 -2
  36. package/scripts/updateFiles.js +30 -6
  37. package/eslint9/configs/base.js +0 -140
  38. package/eslint9/configs/typescript.js +0 -134
  39. package/lib/configs/base.js +0 -115
  40. package/lib/configs/default.js +0 -17
  41. package/lib/configs/i18n.js +0 -10
  42. package/lib/configs/jest.js +0 -21
  43. package/lib/configs/tailwind.js +0 -10
  44. package/lib/configs/typescript.js +0 -95
  45. package/lib/configs/vue.js +0 -91
@@ -1,19 +1,28 @@
1
1
  const path = require('path');
2
2
  const glob = require('glob');
3
3
 
4
- const rulesDir = path.join(__dirname, '../../lib/configs');
4
+ const configsDir = path.join(__dirname, '../../lib/flat-configs');
5
5
 
6
- function getRule(fullPath) {
7
- const relative = path.relative(rulesDir, fullPath);
6
+ /*
7
+ lib/flat-configs/ is a closed set: this glob decides what `yarn update`
8
+ publishes as `plugin.configs[<basename>]`, so a shared helper dropped in that
9
+ directory becomes a bogus public config, which tests/lib/configs/exports.spec.js
10
+ fails on once `yarn update` has regenerated lib/index.js. That is why
11
+ lib/prettier-rules.js and lib/vue-fragments.js sit at the lib/ root instead;
12
+ put new shared code there.
13
+
14
+ No `.meta` spread, unlike getRules.js: a flat config exports an array.
15
+ */
16
+ function getConfig(fullPath) {
17
+ const relative = path.relative(configsDir, fullPath);
8
18
  const name = path.basename(relative, '.js');
9
19
  return {
10
- ...require(fullPath).meta,
11
20
  name,
12
21
  relative,
13
22
  fullPath,
14
23
  };
15
24
  }
16
25
 
17
- module.exports = function getRules() {
18
- return glob.sync(path.join(rulesDir, '**/*.js')).map(getRule);
26
+ module.exports = function getConfigs() {
27
+ return glob.sync(path.join(configsDir, '*.js')).map(getConfig);
19
28
  };
@@ -170,7 +170,6 @@ async function createReleases({ changesets, releases }) {
170
170
 
171
171
  if (type) {
172
172
  releaseDescriptionObject[type].push(
173
- // eslint-disable-next-line no-await-in-loop
174
173
  await defaultChangelogFunctions.getReleaseLine(changeset, type),
175
174
  );
176
175
  }
@@ -181,7 +180,6 @@ async function createReleases({ changesets, releases }) {
181
180
  .map(([type, lines]) => releaseSection(type, lines))
182
181
  .join('\n\n');
183
182
 
184
- // eslint-disable-next-line no-await-in-loop
185
183
  await createRelease({ tag: `v${release.newVersion}`, description });
186
184
  }
187
185
  }
@@ -9,21 +9,40 @@ const libPath = path.join(__dirname, '../lib');
9
9
  const rules = getRules();
10
10
  const configs = getConfigs();
11
11
 
12
- const createIndexJs = (ruleImports, configImports) => `/**
12
+ const createPluginJs = (ruleImports) => `/**
13
13
  * This file is GENERATED, please run \`yarn update\` after adding or renaming a rule
14
14
  */
15
+ const { name, version } = require('../package.json');
16
+
15
17
  module.exports = {
18
+ meta: { name, version },
16
19
  rules: {
17
20
  ${ruleImports.join('\n')}
18
21
  },
22
+ };
23
+ `;
24
+
25
+ const createIndexJs = (configImports) => `/**
26
+ * This file is GENERATED, please run \`yarn update\` after adding or renaming a rule
27
+ */
28
+ const plugin = require('./plugin.js');
29
+
30
+ /*
31
+ Getters, so requiring the plugin never loads a config the consumer is not
32
+ using: \`typescript\` pulls in optional peer dependencies, and eagerly
33
+ requiring it would throw for anyone without the TypeScript toolchain. Getters
34
+ in an object literal are enumerable, so \`Object.keys(configs)\` is unaffected.
35
+ */
36
+ module.exports = {
37
+ ...plugin,
19
38
  configs: {
20
39
  ${configImports.join('\n')}
21
- }
40
+ },
22
41
  };
23
42
  `;
24
43
 
25
44
  const writeIndexJs = () => {
26
- console.log('Updating lib/index.js...');
45
+ console.log('Updating lib/plugin.js and lib/index.js...');
27
46
 
28
47
  const ruleImports = rules.map((rule) => {
29
48
  const relPath = path.relative(libPath, rule.fullPath);
@@ -32,12 +51,17 @@ const writeIndexJs = () => {
32
51
 
33
52
  const configImports = configs.map((config) => {
34
53
  const relPath = path.relative(libPath, config.fullPath);
35
- return ` '${config.name}': require('./${relPath}'),`;
54
+ // Quoted so a hyphenated filename cannot emit a syntax error; prettier
55
+ // drops the quotes again where they are redundant.
56
+ return ` get '${config.name}'() {
57
+ return require('./${relPath}');
58
+ },`;
36
59
  });
37
60
 
38
- fs.writeFileSync(path.join(libPath, 'index.js'), createIndexJs(ruleImports, configImports));
61
+ fs.writeFileSync(path.join(libPath, 'plugin.js'), createPluginJs(ruleImports));
62
+ fs.writeFileSync(path.join(libPath, 'index.js'), createIndexJs(configImports));
39
63
 
40
- console.log('Successfully updated lib/index.js');
64
+ console.log('Successfully updated lib/plugin.js and lib/index.js');
41
65
  };
42
66
 
43
67
  const createDoc = (ruleDocs) => `<!--
@@ -1,140 +0,0 @@
1
- const confusingBrowserGlobals = require('confusing-browser-globals');
2
- const globals = require('globals');
3
- const unicornPlugin = require('eslint-plugin-unicorn');
4
- const promisePlugin = require('eslint-plugin-promise');
5
- const importPlugin = require('eslint-plugin-import');
6
-
7
- // Import all the base configurations
8
- const bestPracticesConfig = require('../../lib/configs/base/best-practices');
9
- const errorsConfig = require('../../lib/configs/base/errors');
10
- const nodeConfig = require('../../lib/configs/base/node');
11
- const styleConfig = require('../../lib/configs/base/style');
12
- const variablesConfig = require('../../lib/configs/base/variables');
13
- const es6Config = require('../../lib/configs/base/es6');
14
- const importsConfig = require('../../lib/configs/base/imports');
15
- const strictConfig = require('../../lib/configs/base/strict');
16
-
17
- /*
18
- This plugin contains rules related to GitLab JavaScript style guide
19
- Vue specific rules are in lib/configs/vue.js
20
- */
21
- module.exports = {
22
- languageOptions: {
23
- globals: {
24
- ...globals.browser,
25
- ...globals.es2020,
26
- ...globals.node,
27
- ...globals.es6,
28
- },
29
- ecmaVersion: 'latest',
30
- sourceType: 'module',
31
- parserOptions: {
32
- parser: 'espree',
33
- },
34
- },
35
- plugins: {
36
- unicorn: unicornPlugin,
37
- promise: promisePlugin,
38
- import: importPlugin,
39
- },
40
- settings: {
41
- // Merge import settings from imports config
42
- ...importsConfig.settings,
43
- },
44
- rules: {
45
- ...promisePlugin.configs['flat/recommended'].rules,
46
- // Merge all rules from the base configurations
47
- ...bestPracticesConfig.rules,
48
- ...errorsConfig.rules,
49
- ...nodeConfig.rules,
50
- ...styleConfig.rules,
51
- ...variablesConfig.rules,
52
- ...es6Config.rules,
53
- ...importsConfig.rules,
54
- ...strictConfig.rules,
55
- // Override specific rules from base configs
56
- // Promise rule customizations
57
- 'promise/catch-or-return': [
58
- 'error',
59
- {
60
- allowFinally: true,
61
- },
62
- ],
63
- camelcase: [
64
- 'error',
65
- {
66
- properties: 'never',
67
- ignoreDestructuring: true,
68
- },
69
- ],
70
- 'default-param-last': 'off',
71
- 'arrow-body-style': 'off',
72
- 'unicorn/filename-case': ['error', { case: 'snakeCase' }],
73
- 'unicorn/no-array-callback-reference': 'error',
74
- 'import/prefer-default-export': 'off',
75
- 'import/no-default-export': 'error',
76
- 'import/no-deprecated': 'error',
77
- 'import/no-dynamic-require': ['error', { esmodule: true }],
78
- 'no-implicit-coercion': [
79
- 'error',
80
- {
81
- boolean: true,
82
- number: true,
83
- string: true,
84
- },
85
- ],
86
- 'no-param-reassign': [
87
- 'error',
88
- {
89
- props: true,
90
- ignorePropertyModificationsFor: ['acc', 'accumulator', 'el', 'element', 'state'],
91
- },
92
- ],
93
- 'no-restricted-exports': [
94
- 'error',
95
- {
96
- restrictedNamedExports: [
97
- 'then', // avoid confusion when used with dynamic `import()` promise
98
- ],
99
- },
100
- ],
101
- 'no-restricted-syntax': 'off',
102
- 'no-sequences': [
103
- 'error',
104
- {
105
- allowInParentheses: false,
106
- },
107
- ],
108
- 'no-restricted-globals': [
109
- 'error',
110
- {
111
- name: 'isFinite',
112
- message:
113
- 'Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite',
114
- },
115
- {
116
- name: 'isNaN',
117
- message:
118
- 'Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan',
119
- },
120
- {
121
- name: 'escape',
122
- message:
123
- "The global `escape` function is unsafe. Did you mean to use `encodeURI`, `encodeURIComponent` or lodash's `escape` instead?",
124
- },
125
- {
126
- name: 'unescape',
127
- message:
128
- "The global `unescape` function is unsafe. Did you mean to use `decodeURI`, `decodeURIComponent` or lodash's `unescape` instead?",
129
- },
130
- ].concat(confusingBrowserGlobals),
131
- 'import/order': [
132
- 'error',
133
- {
134
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
135
- },
136
- ],
137
- // https://docs.gitlab.com/ee/development/fe_guide/style/javascript.html#limit-number-of-parameters
138
- 'max-params': ['error', { max: 3 }],
139
- },
140
- };
@@ -1,134 +0,0 @@
1
- const baseConfig = require('./base');
2
- const tsEslint = require('@typescript-eslint/eslint-plugin');
3
- const tsParser = require('@typescript-eslint/parser');
4
- const globals = require('globals');
5
-
6
- const tsConfig = [
7
- {
8
- languageOptions: {
9
- globals: {
10
- ...baseConfig.languageOptions.globals,
11
- ...globals.mocha,
12
- ...globals.jest,
13
- },
14
- ecmaVersion: baseConfig.languageOptions.ecmaVersion,
15
- sourceType: baseConfig.languageOptions.sourceType,
16
- parserOptions: baseConfig.languageOptions.parserOptions || {},
17
- },
18
- plugins: {
19
- ...baseConfig.plugins,
20
- },
21
- settings: {
22
- ...baseConfig.settings,
23
- },
24
- rules: {
25
- ...baseConfig.rules,
26
- },
27
- },
28
- // TypeScript-specific config
29
- {
30
- files: ['**/*.ts', '**/*.tsx'],
31
- languageOptions: {
32
- parser: tsParser,
33
- parserOptions: {
34
- project: ['./tsconfig.json'],
35
- tsconfigRootDir: process.cwd(),
36
- },
37
- },
38
- plugins: {
39
- '@typescript-eslint': tsEslint,
40
- },
41
- settings: {
42
- 'import/resolver': {
43
- node: {
44
- extensions: ['.mjs', '.js', '.json', '.node', '.ts', '.tsx'],
45
- },
46
- },
47
- },
48
- rules: {
49
- 'import/extensions': [
50
- 'error',
51
- 'ignorePackages',
52
- {
53
- js: 'never',
54
- jsx: 'never',
55
- ts: 'never',
56
- tsx: 'never',
57
- },
58
- ],
59
- semi: [2, 'always'],
60
- 'max-params': 'off',
61
- 'no-throw-literal': 'off',
62
- 'no-shadow': 'off',
63
- 'no-empty-function': 'off',
64
- 'no-plusplus': 'off',
65
- 'no-unused-vars': 'off',
66
- 'no-await-in-loop': 'error',
67
- 'unicorn/no-array-callback-reference': 'off',
68
- 'generator-star-spacing': 'off',
69
- 'max-len': 'off',
70
- 'no-console': 'warn',
71
- 'indent': 'off',
72
- 'quotes': 'off',
73
- 'implicit-arrow-linebreak': 'off',
74
- 'function-paren-newline': 'off',
75
- 'no-redeclare': 'off',
76
- 'brace-style': 'off',
77
- 'no-undef': 'off',
78
- 'no-tabs': 'off',
79
- 'operator-linebreak': 'off',
80
- 'no-confusing-arrow': 'off',
81
- 'object-curly-newline': 'off',
82
- '@typescript-eslint/only-throw-error': 'error',
83
- '@typescript-eslint/no-unused-vars': 'error',
84
- '@typescript-eslint/no-shadow': 'error',
85
- '@typescript-eslint/return-await': 'error',
86
- '@typescript-eslint/no-floating-promises': 'error',
87
- '@typescript-eslint/no-explicit-any': 'error',
88
- '@typescript-eslint/no-non-null-assertion': 'error',
89
- '@typescript-eslint/no-var-requires': 'error',
90
- '@typescript-eslint/explicit-member-accessibility': [
91
- 'error',
92
- {
93
- accessibility: 'no-public',
94
- },
95
- ],
96
- 'class-methods-use-this': 'off',
97
- 'import/no-cycle': 'error',
98
- 'promise/param-names': 'off',
99
- 'no-use-before-define': ['warn', 'nofunc'],
100
- 'no-restricted-syntax': [
101
- 'error',
102
- {
103
- selector: ':matches(PropertyDefinition, MethodDefinition)[accessibility="private"]',
104
- message: 'Use # prefix instead of `private` to indicate private class members.',
105
- },
106
- {
107
- selector: 'ForInStatement',
108
- message:
109
- 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
110
- },
111
- {
112
- selector: 'LabeledStatement',
113
- message:
114
- 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
115
- },
116
- {
117
- selector: 'WithStatement',
118
- message:
119
- '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
120
- },
121
- ],
122
- },
123
- },
124
- // Test files config
125
- {
126
- files: ['**/*.test.ts', '**/*.test.js'],
127
- rules: {
128
- 'max-classes-per-file': 'off',
129
- '@typescript-eslint/no-non-null-assertion': 'off',
130
- },
131
- },
132
- ];
133
-
134
- module.exports = tsConfig;
@@ -1,115 +0,0 @@
1
- const confusingBrowserGlobals = require('confusing-browser-globals');
2
-
3
- /*
4
- This plugin contains rules related to GitLab JavaScript style guide
5
- Vue specific rules are in lib/configs/vue.js
6
- */
7
- module.exports = {
8
- env: {
9
- browser: true,
10
- es2020: true,
11
- },
12
- extends: [
13
- ...[
14
- './base/best-practices.js',
15
- './base/errors',
16
- './base/node',
17
- './base/style',
18
- './base/variables',
19
- './base/es6',
20
- './base/imports',
21
- './base/strict',
22
- ].map((f) => require.resolve(f)),
23
- 'prettier',
24
- 'plugin:promise/recommended',
25
- ],
26
- parserOptions: {
27
- parser: 'espree',
28
- ecmaVersion: 'latest',
29
- },
30
- plugins: ['unicorn', 'promise', 'import', '@gitlab'],
31
- rules: {
32
- camelcase: [
33
- 'error',
34
- {
35
- properties: 'never',
36
- ignoreDestructuring: true,
37
- },
38
- ],
39
- 'default-param-last': 'off',
40
- 'arrow-body-style': 'off',
41
- 'unicorn/filename-case': ['error', { case: 'snakeCase' }],
42
- 'unicorn/no-array-callback-reference': 'error',
43
- 'import/prefer-default-export': 'off',
44
- 'import/no-default-export': 'error',
45
- 'import/no-deprecated': 'error',
46
- 'import/no-dynamic-require': ['error', { esmodule: true }],
47
- 'no-implicit-coercion': [
48
- 'error',
49
- {
50
- boolean: true,
51
- number: true,
52
- string: true,
53
- },
54
- ],
55
- 'no-param-reassign': [
56
- 'error',
57
- {
58
- props: true,
59
- ignorePropertyModificationsFor: ['acc', 'accumulator', 'el', 'element', 'state'],
60
- },
61
- ],
62
- 'no-restricted-exports': [
63
- 'error',
64
- {
65
- restrictedNamedExports: [
66
- 'then', // avoid confusion when used with dynamic `import()` promise
67
- ],
68
- },
69
- ],
70
- 'no-restricted-syntax': 'off',
71
- 'no-sequences': [
72
- 'error',
73
- {
74
- allowInParentheses: false,
75
- },
76
- ],
77
- 'promise/catch-or-return': [
78
- 'error',
79
- {
80
- allowFinally: true,
81
- },
82
- ],
83
- 'no-restricted-globals': [
84
- 'error',
85
- {
86
- name: 'isFinite',
87
- message:
88
- 'Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite',
89
- },
90
- {
91
- name: 'isNaN',
92
- message:
93
- 'Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan',
94
- },
95
- {
96
- name: 'escape',
97
- message:
98
- "The global `escape` function is unsafe. Did you mean to use `encodeURI`, `encodeURIComponent` or lodash's `escape` instead?",
99
- },
100
- {
101
- name: 'unescape',
102
- message:
103
- "The global `unescape` function is unsafe. Did you mean to use `decodeURI`, `decodeURIComponent` or lodash's `unescape` instead?",
104
- },
105
- ].concat(confusingBrowserGlobals),
106
- 'import/order': [
107
- 'error',
108
- {
109
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
110
- },
111
- ],
112
- // https://docs.gitlab.com/ee/development/fe_guide/style/javascript.html#limit-number-of-parameters
113
- 'max-params': ['error', { max: 3 }],
114
- },
115
- };
@@ -1,17 +0,0 @@
1
- const baseConfig = require('./base');
2
- const vueConfig = require('./vue');
3
-
4
- module.exports = {
5
- ...baseConfig,
6
- extends: [
7
- ...baseConfig.extends,
8
- 'prettier',
9
- 'plugin:promise/recommended',
10
- 'plugin:vue/recommended',
11
- ],
12
- rules: {
13
- ...baseConfig.rules,
14
- ...vueConfig.rules,
15
- },
16
- overrides: vueConfig.overrides,
17
- };
@@ -1,10 +0,0 @@
1
- module.exports = {
2
- plugins: ['@gitlab'],
3
- rules: {
4
- '@gitlab/require-i18n-strings': 'error',
5
- '@gitlab/vue-require-i18n-attribute-strings': 'error',
6
- '@gitlab/vue-require-i18n-strings': 'error',
7
- '@gitlab/require-valid-i18n-helpers': 'error',
8
- '@gitlab/vue-require-valid-i18n-helpers': 'error',
9
- },
10
- };
@@ -1,21 +0,0 @@
1
- module.exports = {
2
- extends: ['plugin:jest/recommended'],
3
- rules: {
4
- 'jest/consistent-test-it': ['error', { fn: 'it', withinDescribe: 'it' }],
5
- 'jest/no-conditional-expect': 'off',
6
- 'jest/valid-title': [
7
- 'error',
8
- {
9
- ignoreTypeOfDescribeName: true,
10
- },
11
- ],
12
- 'jest/no-restricted-matchers': [
13
- 'error',
14
- {
15
- toBeFalsy: 'Prefer a stronger matcher like `toBe(false)`',
16
- toBeTruthy: 'Prefer a stronger matcher like `toBe(true)`',
17
- },
18
- ],
19
- 'jest/prefer-to-have-length': 'error',
20
- },
21
- };
@@ -1,10 +0,0 @@
1
- module.exports = {
2
- plugins: ['@gitlab', 'tailwindcss'],
3
- rules: {
4
- '@gitlab/tailwind-no-interpolation': 'error',
5
- '@gitlab/vue-tailwind-no-interpolation': 'error',
6
- '@gitlab/tailwind-no-max-width-media-queries': 'error',
7
- '@gitlab/vue-tailwind-no-max-width-media-queries': 'error',
8
- 'tailwindcss/no-arbitrary-value': 'error',
9
- },
10
- };
@@ -1,95 +0,0 @@
1
- const baseConfig = require('./base');
2
-
3
- const tsConfig = {
4
- env: {
5
- mocha: true,
6
- jest: true,
7
- },
8
- parserOptions: baseConfig.parserOptions,
9
- extends: [...baseConfig.extends],
10
- plugins: [...baseConfig.plugins],
11
- rules: {
12
- ...baseConfig.rules,
13
- 'import/extensions': [
14
- 'error',
15
- 'ignorePackages',
16
- {
17
- js: 'never',
18
- jsx: 'never',
19
- ts: 'never',
20
- tsx: 'never',
21
- },
22
- ],
23
- },
24
- overrides: [
25
- {
26
- files: ['**/*.ts'],
27
- parserOptions: {
28
- parser: '@typescript-eslint/parser',
29
- project: ['./tsconfig.json'],
30
- },
31
- plugins: ['@typescript-eslint', 'import'],
32
- extends: [
33
- 'eslint:recommended',
34
- 'plugin:@typescript-eslint/strict',
35
- 'plugin:import/typescript',
36
- ],
37
- reportUnusedDisableDirectives: true,
38
- rules: {
39
- semi: [2, 'always'],
40
- 'max-params': 'off',
41
- 'no-throw-literal': 'off',
42
- 'no-shadow': 'off',
43
- 'no-empty-function': 'off',
44
- 'no-plusplus': 'off',
45
- 'unicorn/no-array-callback-reference': 'off',
46
- '@typescript-eslint/no-throw-literal': 'error',
47
- '@typescript-eslint/no-unused-vars': 'error',
48
- '@typescript-eslint/no-shadow': 'error',
49
- '@typescript-eslint/return-await': 'error',
50
- '@typescript-eslint/no-floating-promises': 'error',
51
- '@typescript-eslint/explicit-member-accessibility': [
52
- 'error',
53
- {
54
- accessibility: 'no-public',
55
- },
56
- ],
57
- 'class-methods-use-this': 'off',
58
- 'import/no-cycle': 'error',
59
- 'promise/param-names': 'off',
60
- 'no-use-before-define': ['warn', 'nofunc'],
61
- 'no-restricted-syntax': [
62
- 'error',
63
- {
64
- selector: ':matches(PropertyDefinition, MethodDefinition)[accessibility="private"]',
65
- message: 'Use # prefix instead of `private` to indicate private class members.',
66
- },
67
- {
68
- selector: 'ForInStatement',
69
- message:
70
- 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
71
- },
72
- {
73
- selector: 'LabeledStatement',
74
- message:
75
- 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
76
- },
77
- {
78
- selector: 'WithStatement',
79
- message:
80
- '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
81
- },
82
- ],
83
- },
84
- },
85
- {
86
- files: ['*.test.ts', '*.test.js'],
87
- rules: {
88
- 'max-classes-per-file': 'off',
89
- '@typescript-eslint/no-non-null-assertion': 'off',
90
- },
91
- },
92
- ],
93
- };
94
-
95
- module.exports = tsConfig;