@perfective/eslint-config 0.32.0 → 0.34.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.
- package/LICENSE +1 -1
- package/README.adoc +18 -3
- package/config/cypress/cypress-config.js +1 -1
- package/config/eslint/suggestions-rules.js +3 -0
- package/config/jest/index.d.ts +1 -0
- package/config/jest/index.js +2 -1
- package/config/jest/jest-config.d.ts +2 -0
- package/config/jest/jest-config.js +9 -12
- package/config/jest/jest-typescript-config.d.ts +10 -0
- package/config/jest/jest-typescript-config.js +24 -0
- package/config/jsdoc/jsdoc-config.js +60 -9
- package/config/rxjs/rxjs-config.js +2 -0
- package/config/stylistic/stylistic-config.js +5 -3
- package/config/testing-library/testing-library-config.js +5 -4
- package/config/typescript-eslint/extension-rules.js +2 -0
- package/config/typescript-eslint/index.d.ts +1 -0
- package/config/typescript-eslint/index.js +2 -1
- package/config/typescript-eslint/supported-rules.js +4 -1
- package/config/typescript-eslint/typescript-eslint-config.d.ts +15 -1
- package/config/typescript-eslint/typescript-eslint-config.js +13 -2
- package/config/unicorn/unicorn-config.js +7 -0
- package/linter/glob.d.ts +16 -0
- package/linter/glob.js +3 -1
- package/package.json +12 -12
- package/config/jest/typescript-eslint-jest-rules.d.ts +0 -2
- package/config/jest/typescript-eslint-jest-rules.js +0 -5
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2020-
|
|
3
|
+
Copyright (c) 2020-2026 Andrey Mikheychik (https://github.com/amikheychik)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.adoc
CHANGED
|
@@ -78,7 +78,7 @@ import { perfectiveEslintConfig } from '@perfective/eslint-config';
|
|
|
78
78
|
|
|
79
79
|
// Optional dependencies.
|
|
80
80
|
import { cypressConfig } from '@perfective/eslint-config/cypress';
|
|
81
|
-
import { jestConfig } from '@perfective/eslint-config/jest';
|
|
81
|
+
import { jestConfig, jestTypescriptConfig } from '@perfective/eslint-config/jest';
|
|
82
82
|
import { jestDomConfig } from '@perfective/eslint-config/jest-dom';
|
|
83
83
|
import { rxjsConfig } from '@perfective/eslint-config/rxjs';
|
|
84
84
|
import { testingLibraryConfig } from '@perfective/eslint-config/testing-library';
|
|
@@ -86,6 +86,7 @@ import { testingLibraryConfig } from '@perfective/eslint-config/testing-library'
|
|
|
86
86
|
const eslintConfig = perfectiveEslintConfig([
|
|
87
87
|
cypressConfig,
|
|
88
88
|
jestConfig,
|
|
89
|
+
jestTypescriptConfig,
|
|
89
90
|
jestDomConfig,
|
|
90
91
|
rxjsConfig,
|
|
91
92
|
testingLibraryConfig,
|
|
@@ -188,6 +189,12 @@ a nominal type for glob patterns.
|
|
|
188
189
|
** `jestFiles: Glob[]`
|
|
189
190
|
— the link:https://jestjs.io/docs/configuration#testmatch-arraystring[default] glob patterns
|
|
190
191
|
Jest uses to find test files.
|
|
192
|
+
** `jestJavascriptFiles: Glob[]`
|
|
193
|
+
— the link:https://jestjs.io/docs/configuration#testmatch-arraystring[default] glob patterns
|
|
194
|
+
Jest uses to find JavaScript test files.
|
|
195
|
+
** `jestTypescriptFiles: Glob[]`
|
|
196
|
+
— the link:https://jestjs.io/docs/configuration#testmatch-arraystring[default] glob patterns
|
|
197
|
+
Jest uses to find TypeScript test files.
|
|
191
198
|
** `cypressFiles: Glob`
|
|
192
199
|
— the link:https://docs.cypress.io/app/references/configuration#e2e[default] glob pattern
|
|
193
200
|
Cypress uses to load test files.
|
|
@@ -231,6 +238,11 @@ Overrides some rules for `perfectiveEslintConfig` for compatibility with Cypress
|
|
|
231
238
|
|
|
232
239
|
* `jestConfig(files: Glob[] = jestFiles): Linter.Config`
|
|
233
240
|
— creates a flat config for `eslint-plugin-jest` for a given list of files globs.
|
|
241
|
+
This config excludes the rules that require `@typescript-eslint` plugin.
|
|
242
|
+
+
|
|
243
|
+
* `jestTypescriptConfig(files: Glob[] = jestTypescriptFiles): Linter.Config`
|
|
244
|
+
— creates a flat config for `eslint-plugin-jest` for a given list of TypeScript file globs.
|
|
245
|
+
This config includes only the rules that require `@typescript-eslint` plugin.
|
|
234
246
|
|
|
235
247
|
=== `@perfective/eslint-config/jest-dom`
|
|
236
248
|
|
|
@@ -257,6 +269,9 @@ Allows to splice `internal` scope packages imports between the global and relati
|
|
|
257
269
|
|
|
258
270
|
=== `@perfective/eslint-config/typescript-eslint`
|
|
259
271
|
|
|
272
|
+
* `typescriptEslintDependentConfig(plugin: ESLint.Plugin, rules: Linter.RulesRecord, files: Glob[] = typescriptFiles): Linter.Config`
|
|
273
|
+
— a function to create a flat config for a given `plugin` that requires TypeScript ESLint plugin.
|
|
274
|
+
+
|
|
260
275
|
* `interface TypescriptEslintNamingConvention`
|
|
261
276
|
— configuration options for the
|
|
262
277
|
`link:https://typescript-eslint.io/rules/naming-convention/[@typescript-eslint/naming-convention]` rule.
|
|
@@ -270,7 +285,7 @@ Allows to splice `internal` scope packages imports between the global and relati
|
|
|
270
285
|
— values for the `@typescript-eslint/naming-convention` rule `format` option.
|
|
271
286
|
** `type TypescriptEslintNamingConventionUnderscore`
|
|
272
287
|
— values for the `@typescript-eslint/naming-convention` rule `leadingUnderscore` and `trailingUnderscore` options.
|
|
273
|
-
** `
|
|
288
|
+
** `typescriptEslintNamingConvention(extensions: TypescriptEslintNamingConvention[] = []): TypescriptEslintNamingConvention[]`
|
|
274
289
|
— creates configuration with the given extensions for the `@typescript-eslint/naming-convention` rule.
|
|
275
290
|
|
|
276
291
|
=== `@perfective/eslint-config/unicorn`
|
|
@@ -280,5 +295,5 @@ Allows to splice `internal` scope packages imports between the global and relati
|
|
|
280
295
|
`link:https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prevent-abbreviations.md[unicorn/prevent-abbreviation]` rule.
|
|
281
296
|
** `type UnicornPreventAbbreviationReplacements`
|
|
282
297
|
— nominal type for the `replacements` option of the `unicorn/prevent-abbreviation` rule.
|
|
283
|
-
** `
|
|
298
|
+
** `unicornPreventAbbreviations(replacements: UnicornPreventAbbreviationReplacements = {}, options: Partial<Pick<UnicornPreventAbbreviations, 'checkProperties'>> = {}): UnicornPreventAbbreviations`
|
|
284
299
|
— creates configuration for the `unicorn/prevent-abbreviation` rule with the given replacements and options.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import eslintPluginCypress from 'eslint-plugin-cypress
|
|
1
|
+
import eslintPluginCypress from 'eslint-plugin-cypress';
|
|
2
2
|
import { cypressFiles } from "../../linter/glob.js";
|
|
3
3
|
import { importNoExtraneousDependencies } from "../import/rules/no-extraneous-dependencies.js";
|
|
4
4
|
export function cypressConfig(files = [cypressFiles]) {
|
|
@@ -165,6 +165,9 @@ export const eslintSuggestionsRules = {
|
|
|
165
165
|
'prefer-rest-params': 'error',
|
|
166
166
|
'prefer-spread': 'error',
|
|
167
167
|
'prefer-template': 'warn',
|
|
168
|
+
'preserve-caught-error': ['off', {
|
|
169
|
+
requireCatchParameter: true
|
|
170
|
+
}],
|
|
168
171
|
'quote-props': 'off',
|
|
169
172
|
'radix': 'error',
|
|
170
173
|
'require-await': 'error',
|
package/config/jest/index.d.ts
CHANGED
package/config/jest/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { jestConfig } from "./jest-config.js";
|
|
1
|
+
export { jestConfig } from "./jest-config.js";
|
|
2
|
+
export { jestTypescriptConfig } from "./jest-typescript-config.js";
|
|
@@ -3,6 +3,8 @@ import { Glob } from '../../linter/glob';
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates a flat config for `eslint-plugin-jest` for a given list of files globs.
|
|
5
5
|
*
|
|
6
|
+
* This config excludes the rules that require `@typescript-eslint` plugin.
|
|
7
|
+
*
|
|
6
8
|
* @since v0.31.0
|
|
7
9
|
*/
|
|
8
10
|
export declare function jestConfig(files?: Glob[]): Linter.Config;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import eslintPluginJest from 'eslint-plugin-jest';
|
|
2
2
|
import { jestFiles } from "../../linter/glob.js";
|
|
3
|
-
import { importNoExtraneousDependencies } from "../import/
|
|
4
|
-
import { typescriptEslintJestRules } from "./typescript-eslint-jest-rules.js";
|
|
3
|
+
import { importNoExtraneousDependencies } from "../import/rules/no-extraneous-dependencies.js";
|
|
5
4
|
export function jestConfig(files = jestFiles) {
|
|
6
5
|
return {
|
|
7
6
|
files,
|
|
@@ -11,7 +10,7 @@ export function jestConfig(files = jestFiles) {
|
|
|
11
10
|
languageOptions: {
|
|
12
11
|
globals: eslintPluginJest.environments.globals.globals
|
|
13
12
|
},
|
|
14
|
-
rules: Object.assign(Object.assign(
|
|
13
|
+
rules: Object.assign(Object.assign({}, perfectiveRules()), {
|
|
15
14
|
'jest/consistent-test-it': ['warn', {
|
|
16
15
|
fn: 'test',
|
|
17
16
|
withinDescribe: 'it'
|
|
@@ -53,6 +52,7 @@ export function jestConfig(files = jestFiles) {
|
|
|
53
52
|
'jest/no-standalone-expect': 'error',
|
|
54
53
|
'jest/no-test-prefixes': 'warn',
|
|
55
54
|
'jest/no-test-return-statement': 'error',
|
|
55
|
+
'jest/no-unneeded-async-expect-function': 'warn',
|
|
56
56
|
'jest/no-untyped-mock-factory': 'warn',
|
|
57
57
|
'jest/padding-around-after-all-blocks': 'warn',
|
|
58
58
|
'jest/padding-around-after-each-blocks': 'warn',
|
|
@@ -76,14 +76,18 @@ export function jestConfig(files = jestFiles) {
|
|
|
76
76
|
'jest/prefer-lowercase-title': ['error', {
|
|
77
77
|
allowedPrefixes: [],
|
|
78
78
|
ignore: [],
|
|
79
|
+
ignoreTodos: false,
|
|
79
80
|
ignoreTopLevelDescribe: true
|
|
80
81
|
}],
|
|
81
82
|
'jest/prefer-mock-promise-shorthand': 'warn',
|
|
83
|
+
'jest/prefer-mock-return-shorthand': 'warn',
|
|
82
84
|
'jest/prefer-snapshot-hint': ['error', 'always'],
|
|
83
85
|
'jest/prefer-spy-on': 'warn',
|
|
84
86
|
'jest/prefer-strict-equal': 'warn',
|
|
85
87
|
'jest/prefer-to-be': 'warn',
|
|
86
88
|
'jest/prefer-to-contain': 'warn',
|
|
89
|
+
'jest/prefer-to-have-been-called': 'warn',
|
|
90
|
+
'jest/prefer-to-have-been-called-times': 'warn',
|
|
87
91
|
'jest/prefer-to-have-length': 'warn',
|
|
88
92
|
'jest/prefer-todo': 'warn',
|
|
89
93
|
'jest/require-hook': ['error', {
|
|
@@ -94,6 +98,7 @@ export function jestConfig(files = jestFiles) {
|
|
|
94
98
|
'jest/valid-describe-callback': 'error',
|
|
95
99
|
'jest/valid-expect-in-promise': 'error',
|
|
96
100
|
'jest/valid-expect': 'error',
|
|
101
|
+
'jest/valid-mock-module-path': 'error',
|
|
97
102
|
'jest/valid-title': ['warn', {
|
|
98
103
|
ignoreTypeOfDescribeName: true,
|
|
99
104
|
ignoreTypeOfTestName: false,
|
|
@@ -104,14 +109,6 @@ export function jestConfig(files = jestFiles) {
|
|
|
104
109
|
}
|
|
105
110
|
function perfectiveRules() {
|
|
106
111
|
return {
|
|
107
|
-
'@typescript-eslint/ban-ts-comment': ['error', {
|
|
108
|
-
'ts-expect-error': 'allow-with-description',
|
|
109
|
-
'ts-ignore': true,
|
|
110
|
-
'ts-nocheck': true,
|
|
111
|
-
'ts-check': false
|
|
112
|
-
}],
|
|
113
|
-
'@typescript-eslint/init-declarations': 'off',
|
|
114
|
-
'@typescript-eslint/unbound-method': 'off',
|
|
115
112
|
'import/no-extraneous-dependencies': ['error', importNoExtraneousDependencies({
|
|
116
113
|
devDependencies: jestFiles
|
|
117
114
|
})],
|
|
@@ -124,6 +121,6 @@ function perfectiveRules() {
|
|
|
124
121
|
}],
|
|
125
122
|
'prefer-arrow/prefer-arrow-functions': 'off',
|
|
126
123
|
'promise/always-return': 'off',
|
|
127
|
-
'
|
|
124
|
+
'rxjs-x/no-topromise': 'off'
|
|
128
125
|
};
|
|
129
126
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Linter } from 'eslint';
|
|
2
|
+
import { Glob } from '../../linter/glob';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a flat config for `eslint-plugin-jest` for a given list of TypeScript file globs.
|
|
5
|
+
*
|
|
6
|
+
* This config includes only the rules that require `@typescript-eslint` plugin.
|
|
7
|
+
*
|
|
8
|
+
* @since v0.34.0
|
|
9
|
+
*/
|
|
10
|
+
export declare function jestTypescriptConfig(files?: Glob[]): Linter.Config;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import eslintPluginJest from 'eslint-plugin-jest';
|
|
2
|
+
import { jestTypescriptFiles } from "../../linter/glob.js";
|
|
3
|
+
import { typescriptEslintDependentConfig } from "../typescript-eslint/typescript-eslint-config.js";
|
|
4
|
+
const jestTypescriptRules = {
|
|
5
|
+
'jest/no-error-equal': 'error',
|
|
6
|
+
'jest/no-unnecessary-assertion': 'error',
|
|
7
|
+
'jest/unbound-method': ['error', {
|
|
8
|
+
ignoreStatic: false
|
|
9
|
+
}],
|
|
10
|
+
'jest/valid-expect-with-promise': 'error'
|
|
11
|
+
};
|
|
12
|
+
const jestTypescriptEslintRulesOverrides = {
|
|
13
|
+
'@typescript-eslint/ban-ts-comment': ['error', {
|
|
14
|
+
'ts-expect-error': 'allow-with-description',
|
|
15
|
+
'ts-ignore': true,
|
|
16
|
+
'ts-nocheck': true,
|
|
17
|
+
'ts-check': false
|
|
18
|
+
}],
|
|
19
|
+
'@typescript-eslint/init-declarations': 'off',
|
|
20
|
+
'@typescript-eslint/unbound-method': 'off'
|
|
21
|
+
};
|
|
22
|
+
export function jestTypescriptConfig(files = jestTypescriptFiles) {
|
|
23
|
+
return typescriptEslintDependentConfig(eslintPluginJest, Object.assign(Object.assign({}, jestTypescriptRules), jestTypescriptEslintRulesOverrides), files);
|
|
24
|
+
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsdoc } from 'eslint-plugin-jsdoc';
|
|
2
2
|
import { javascriptFiles } from "../../linter/glob.js";
|
|
3
3
|
import { javascriptLanguageOptions } from "../../linter/language-options.js";
|
|
4
4
|
export function jsdocConfig() {
|
|
5
|
-
return {
|
|
6
|
-
|
|
7
|
-
jsdoc: {
|
|
8
|
-
rules: eslintPluginJsdoc.configs['flat/recommended'].plugins['jsdoc'].rules
|
|
9
|
-
}
|
|
10
|
-
},
|
|
5
|
+
return jsdoc({
|
|
6
|
+
config: 'flat/recommended',
|
|
11
7
|
settings: {
|
|
12
8
|
jsdoc: {
|
|
13
9
|
tagNamePreference: {
|
|
@@ -30,7 +26,9 @@ export function jsdocConfig() {
|
|
|
30
26
|
},
|
|
31
27
|
rules: {
|
|
32
28
|
'jsdoc/check-access': 'off',
|
|
33
|
-
'jsdoc/check-alignment': 'error',
|
|
29
|
+
'jsdoc/check-alignment': ['error', {
|
|
30
|
+
innerIndent: 1
|
|
31
|
+
}],
|
|
34
32
|
'jsdoc/check-examples': 'off',
|
|
35
33
|
'jsdoc/check-indentation': 'off',
|
|
36
34
|
'jsdoc/check-line-alignment': ['off', 'never'],
|
|
@@ -60,6 +58,11 @@ export function jsdocConfig() {
|
|
|
60
58
|
'jsdoc/empty-tags': ['error', {
|
|
61
59
|
tags: ['final', 'flags', 'sealed']
|
|
62
60
|
}],
|
|
61
|
+
'jsdoc/escape-inline-tags': ['error', {
|
|
62
|
+
allowedInlineTags: [],
|
|
63
|
+
enableFixer: false,
|
|
64
|
+
fixType: 'backticks'
|
|
65
|
+
}],
|
|
63
66
|
'jsdoc/implements-on-classes': 'error',
|
|
64
67
|
'jsdoc/imports-as-dependencies': 'error',
|
|
65
68
|
'jsdoc/lines-before-block': 'off',
|
|
@@ -90,6 +93,9 @@ export function jsdocConfig() {
|
|
|
90
93
|
'jsdoc/no-restricted-syntax': 'off',
|
|
91
94
|
'jsdoc/no-types': 'error',
|
|
92
95
|
'jsdoc/no-undefined-types': 'error',
|
|
96
|
+
'jsdoc/prefer-import-tag': 'warn',
|
|
97
|
+
'jsdoc/reject-any-type': 'error',
|
|
98
|
+
'jsdoc/reject-function-type': 'error',
|
|
93
99
|
'jsdoc/require-asterisk-prefix': ['error', 'always'],
|
|
94
100
|
'jsdoc/require-description': ['error', {
|
|
95
101
|
exemptedBy: ['inheritdoc', 'package', 'private', 'see', 'deprecated']
|
|
@@ -99,6 +105,8 @@ export function jsdocConfig() {
|
|
|
99
105
|
'jsdoc/require-file-overview': 'off',
|
|
100
106
|
'jsdoc/require-hyphen-before-param-description': ['warn', 'always'],
|
|
101
107
|
'jsdoc/require-jsdoc': 'off',
|
|
108
|
+
'jsdoc/require-next-description': 'error',
|
|
109
|
+
'jsdoc/require-next-type': 'error',
|
|
102
110
|
'jsdoc/require-param': 'off',
|
|
103
111
|
'jsdoc/require-param-description': 'error',
|
|
104
112
|
'jsdoc/require-param-name': 'error',
|
|
@@ -107,16 +115,24 @@ export function jsdocConfig() {
|
|
|
107
115
|
'jsdoc/require-property-description': 'error',
|
|
108
116
|
'jsdoc/require-property-name': 'error',
|
|
109
117
|
'jsdoc/require-property-type': 'error',
|
|
118
|
+
'jsdoc/require-rejects': 'error',
|
|
110
119
|
'jsdoc/require-returns': 'off',
|
|
111
120
|
'jsdoc/require-returns-check': 'error',
|
|
112
121
|
'jsdoc/require-returns-description': 'error',
|
|
113
122
|
'jsdoc/require-returns-type': 'off',
|
|
123
|
+
'jsdoc/require-tags': 'off',
|
|
114
124
|
'jsdoc/require-template': ['off', {
|
|
125
|
+
exemptedBy: [],
|
|
115
126
|
requireSeparateTemplates: false
|
|
116
127
|
}],
|
|
128
|
+
'jsdoc/require-template-description': 'off',
|
|
117
129
|
'jsdoc/require-throws': 'error',
|
|
130
|
+
'jsdoc/require-throws-description': 'error',
|
|
131
|
+
'jsdoc/require-throws-type': 'error',
|
|
118
132
|
'jsdoc/require-yields': 'error',
|
|
119
133
|
'jsdoc/require-yields-check': 'error',
|
|
134
|
+
'jsdoc/require-yields-description': 'error',
|
|
135
|
+
'jsdoc/require-yields-type': 'error',
|
|
120
136
|
'jsdoc/sort-tags': ['warn', {
|
|
121
137
|
tagSequence: [{
|
|
122
138
|
tags: ['summary', 'typeSummary']
|
|
@@ -157,11 +173,46 @@ export function jsdocConfig() {
|
|
|
157
173
|
startLines: 1,
|
|
158
174
|
endLines: 0,
|
|
159
175
|
applyToEndTag: false,
|
|
176
|
+
maxBlockLines: null,
|
|
160
177
|
tags: {}
|
|
161
178
|
}],
|
|
179
|
+
'jsdoc/ts-method-signature-style': 'warn',
|
|
180
|
+
'jsdoc/ts-no-empty-object-type': 'error',
|
|
181
|
+
'jsdoc/ts-no-unnecessary-template-expression': 'warn',
|
|
182
|
+
'jsdoc/ts-prefer-function-type': 'warn',
|
|
183
|
+
'jsdoc/type-formatting': ['warn', {
|
|
184
|
+
arrayBrackets: 'square',
|
|
185
|
+
arrowFunctionPostReturnMarkerSpacing: '',
|
|
186
|
+
arrowFunctionPreReturnMarkerSpacing: '',
|
|
187
|
+
enableFixer: true,
|
|
188
|
+
functionOrClassParameterSpacing: '',
|
|
189
|
+
functionOrClassPostGenericSpacing: '',
|
|
190
|
+
functionOrClassPostReturnMarkerSpacing: '',
|
|
191
|
+
functionOrClassPreReturnMarkerSpacing: '',
|
|
192
|
+
functionOrClassTypeParameterSpacing: '',
|
|
193
|
+
genericAndTupleElementSpacing: '',
|
|
194
|
+
genericDot: false,
|
|
195
|
+
keyValuePostColonSpacing: '',
|
|
196
|
+
keyValuePostKeySpacing: '',
|
|
197
|
+
keyValuePostOptionalSpacing: '',
|
|
198
|
+
keyValuePostVariadicSpacing: '',
|
|
199
|
+
methodQuotes: 'double',
|
|
200
|
+
objectFieldIndent: '',
|
|
201
|
+
objectFieldQuote: null,
|
|
202
|
+
objectFieldSeparator: 'comma',
|
|
203
|
+
objectFieldSeparatorOptionalLinebreak: true,
|
|
204
|
+
objectFieldSeparatorTrailingPunctuation: false,
|
|
205
|
+
parameterDefaultValueSpacing: ' ',
|
|
206
|
+
postMethodNameSpacing: '',
|
|
207
|
+
postNewSpacing: ' ',
|
|
208
|
+
separatorForSingleObjectField: false,
|
|
209
|
+
stringQuotes: 'double',
|
|
210
|
+
typeBracketSpacing: '',
|
|
211
|
+
unionSpacing: ' '
|
|
212
|
+
}],
|
|
162
213
|
'jsdoc/valid-types': 'error'
|
|
163
214
|
}
|
|
164
|
-
};
|
|
215
|
+
});
|
|
165
216
|
}
|
|
166
217
|
export function jsdocJavascriptConfig() {
|
|
167
218
|
return {
|
|
@@ -48,12 +48,14 @@ export function rxjsConfig(files = typescriptFiles) {
|
|
|
48
48
|
'rxjs-x/no-nested-subscribe': 'error',
|
|
49
49
|
'rxjs-x/no-redundant-notify': 'error',
|
|
50
50
|
'rxjs-x/no-sharereplay': 'off',
|
|
51
|
+
'rxjs-x/no-sharereplay-before-takeuntil': 'error',
|
|
51
52
|
'rxjs-x/no-subclass': 'error',
|
|
52
53
|
'rxjs-x/no-subject-unsubscribe': 'error',
|
|
53
54
|
'rxjs-x/no-subject-value': 'error',
|
|
54
55
|
'rxjs-x/no-subscribe-handlers': 'off',
|
|
55
56
|
'rxjs-x/no-topromise': 'error',
|
|
56
57
|
'rxjs-x/no-unbound-methods': 'error',
|
|
58
|
+
'rxjs-x/no-unnecessary-collection': 'error',
|
|
57
59
|
'rxjs-x/no-unsafe-catch': 'error',
|
|
58
60
|
'rxjs-x/no-unsafe-first': 'error',
|
|
59
61
|
'rxjs-x/no-unsafe-subject-next': 'error',
|
|
@@ -94,7 +94,7 @@ export function stylisticConfig() {
|
|
|
94
94
|
allowNamespace: false,
|
|
95
95
|
ignore: []
|
|
96
96
|
}],
|
|
97
|
-
'@stylistic/jsx-props-no-multi-spaces': '
|
|
97
|
+
'@stylistic/jsx-props-no-multi-spaces': 'off',
|
|
98
98
|
'@stylistic/jsx-quotes': ['warn', 'prefer-double'],
|
|
99
99
|
'@stylistic/jsx-self-closing-comp': ['warn', {
|
|
100
100
|
component: true,
|
|
@@ -161,6 +161,7 @@ export function stylisticConfig() {
|
|
|
161
161
|
exceptAfterSingleLine: true,
|
|
162
162
|
exceptAfterOverload: true
|
|
163
163
|
}],
|
|
164
|
+
'@stylistic/exp-list-style': 'off',
|
|
164
165
|
'@stylistic/max-len': ['error', {
|
|
165
166
|
code: 120,
|
|
166
167
|
tabWidth: 4,
|
|
@@ -197,8 +198,8 @@ export function stylisticConfig() {
|
|
|
197
198
|
ignoreJSX: 'all',
|
|
198
199
|
nestedBinaryExpressions: false,
|
|
199
200
|
nestedConditionalExpressions: false,
|
|
200
|
-
|
|
201
|
-
|
|
201
|
+
ternaryOperandBinaryExpressions: false,
|
|
202
|
+
ignoredNodes: ['ArrowFunctionExpression[body.type=ConditionalExpression]']
|
|
202
203
|
}],
|
|
203
204
|
'@stylistic/no-extra-semi': 'warn',
|
|
204
205
|
'@stylistic/no-floating-decimal': 'warn',
|
|
@@ -227,6 +228,7 @@ export function stylisticConfig() {
|
|
|
227
228
|
}],
|
|
228
229
|
'@stylistic/object-curly-spacing': ['warn', 'always', {
|
|
229
230
|
arraysInObjects: true,
|
|
231
|
+
emptyObjects: 'never',
|
|
230
232
|
objectsInObjects: true
|
|
231
233
|
}],
|
|
232
234
|
'@stylistic/object-property-newline': ['warn', {
|
|
@@ -8,14 +8,14 @@ export function testingLibraryConfig(files = jestFiles) {
|
|
|
8
8
|
},
|
|
9
9
|
rules: {
|
|
10
10
|
'testing-library/await-async-events': 'off',
|
|
11
|
-
'testing-library/await-async-queries': '
|
|
12
|
-
'testing-library/await-async-utils': '
|
|
11
|
+
'testing-library/await-async-queries': 'warn',
|
|
12
|
+
'testing-library/await-async-utils': 'warn',
|
|
13
13
|
'testing-library/consistent-data-testid': ['error', {
|
|
14
14
|
testIdPattern: '^[a-z0-9]+(-[a-z0-9]+)*$',
|
|
15
15
|
testIdAttribute: 'data-testId'
|
|
16
16
|
}],
|
|
17
17
|
'testing-library/no-await-sync-events': 'error',
|
|
18
|
-
'testing-library/no-await-sync-queries': '
|
|
18
|
+
'testing-library/no-await-sync-queries': 'warn',
|
|
19
19
|
'testing-library/no-container': 'error',
|
|
20
20
|
'testing-library/no-debugging-utils': 'error',
|
|
21
21
|
'testing-library/no-dom-import': 'warn',
|
|
@@ -26,7 +26,7 @@ export function testingLibraryConfig(files = jestFiles) {
|
|
|
26
26
|
'testing-library/no-render-in-lifecycle': 'error',
|
|
27
27
|
'testing-library/no-test-id-queries': 'error',
|
|
28
28
|
'testing-library/no-unnecessary-act': 'off',
|
|
29
|
-
'testing-library/no-wait-for-multiple-assertions': '
|
|
29
|
+
'testing-library/no-wait-for-multiple-assertions': 'warn',
|
|
30
30
|
'testing-library/no-wait-for-side-effects': 'error',
|
|
31
31
|
'testing-library/no-wait-for-snapshot': 'error',
|
|
32
32
|
'testing-library/prefer-explicit-assert': 'off',
|
|
@@ -40,6 +40,7 @@ export function testingLibraryConfig(files = jestFiles) {
|
|
|
40
40
|
'testing-library/prefer-query-matchers': 'off',
|
|
41
41
|
'testing-library/prefer-screen-queries': 'error',
|
|
42
42
|
'testing-library/prefer-user-event': 'error',
|
|
43
|
+
'testing-library/prefer-user-event-setup': 'error',
|
|
43
44
|
'testing-library/render-result-naming-convention': 'error'
|
|
44
45
|
}
|
|
45
46
|
};
|
|
@@ -68,6 +68,8 @@ export const extensionRules = {
|
|
|
68
68
|
}],
|
|
69
69
|
'no-unused-expressions': 'off',
|
|
70
70
|
'@typescript-eslint/no-unused-expressions': 'error',
|
|
71
|
+
'no-unused-private-class-members': 'off',
|
|
72
|
+
'@typescript-eslint/no-unused-private-class-members': 'error',
|
|
71
73
|
'no-unused-vars': 'off',
|
|
72
74
|
'@typescript-eslint/no-unused-vars': ['error', {
|
|
73
75
|
args: 'after-used',
|
|
@@ -1 +1,2 @@
|
|
|
1
1
|
export { TypescriptEslintNamingConvention, typescriptEslintNamingConvention, TypescriptEslintNamingConventionFormat, TypescriptEslintNamingConventionGroupSelector, TypescriptEslintNamingConventionIndividualSelector, TypescriptEslintNamingConventionSelector, TypescriptEslintNamingConventionUnderscore, } from './rules/typescript-eslint-naming-convention';
|
|
2
|
+
export { typescriptEslintDependentConfig } from './typescript-eslint-config';
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { typescriptEslintNamingConvention } from "./rules/typescript-eslint-naming-convention.js";
|
|
1
|
+
export { typescriptEslintNamingConvention } from "./rules/typescript-eslint-naming-convention.js";
|
|
2
|
+
export { typescriptEslintDependentConfig } from "./typescript-eslint-config.js";
|
|
@@ -144,10 +144,13 @@ export const supportedRules = {
|
|
|
144
144
|
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
|
|
145
145
|
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
|
|
146
146
|
'@typescript-eslint/no-unsafe-function-type': 'warn',
|
|
147
|
-
'@typescript-eslint/no-unsafe-member-access': 'error',
|
|
147
|
+
'@typescript-eslint/no-unsafe-member-access': ['error', {
|
|
148
|
+
allowOptionalChaining: false
|
|
149
|
+
}],
|
|
148
150
|
'@typescript-eslint/no-unsafe-return': 'error',
|
|
149
151
|
'@typescript-eslint/no-unsafe-type-assertion': 'off',
|
|
150
152
|
'@typescript-eslint/no-unsafe-unary-minus': 'error',
|
|
153
|
+
'@typescript-eslint/no-useless-default-assignment': 'error',
|
|
151
154
|
'@typescript-eslint/no-useless-empty-export': 'warn',
|
|
152
155
|
'@typescript-eslint/no-useless-template-literal': 'off',
|
|
153
156
|
'@typescript-eslint/no-var-requires': ['error', {
|
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
import { Linter } from 'eslint';
|
|
1
|
+
import { ESLint, Linter } from 'eslint';
|
|
2
|
+
import { Glob } from '../../linter/glob';
|
|
2
3
|
export declare function typescriptEslintConfig(): Linter.Config;
|
|
4
|
+
/**
|
|
5
|
+
* A function to create a flat config for a given `plugin` that requires TypeScript ESLint plugin.
|
|
6
|
+
*
|
|
7
|
+
* This function should be used by other plugin configurations to enable rules that require type information
|
|
8
|
+
* or to change the behavior of the `@typescript-eslint` plugin rules.
|
|
9
|
+
*
|
|
10
|
+
* @param plugin - An ESLint plugin with the rules.
|
|
11
|
+
* @param rules - Rules for the plugin or for the `@typescript-eslint` plugin.
|
|
12
|
+
* @param files - An optional list of globs to narrow down the applicable files.
|
|
13
|
+
*
|
|
14
|
+
* @since v0.34.0
|
|
15
|
+
*/
|
|
16
|
+
export declare function typescriptEslintDependentConfig(plugin: ESLint.Plugin, rules: Linter.RulesRecord, files?: Glob[]): Linter.Config;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { plugin } from 'typescript-eslint';
|
|
1
|
+
import { plugin as typescriptEslintPlugin } from 'typescript-eslint';
|
|
2
2
|
import { typescriptFiles } from "../../linter/glob.js";
|
|
3
3
|
import { typescriptLanguageOptions } from "../../linter/language-options.js";
|
|
4
4
|
import { extensionRules } from "./extension-rules.js";
|
|
@@ -8,8 +8,19 @@ export function typescriptEslintConfig() {
|
|
|
8
8
|
files: typescriptFiles,
|
|
9
9
|
languageOptions: typescriptLanguageOptions(),
|
|
10
10
|
plugins: {
|
|
11
|
-
'@typescript-eslint':
|
|
11
|
+
'@typescript-eslint': typescriptEslintPlugin
|
|
12
12
|
},
|
|
13
13
|
rules: Object.assign(Object.assign({}, supportedRules), extensionRules)
|
|
14
14
|
};
|
|
15
|
+
}
|
|
16
|
+
export function typescriptEslintDependentConfig(plugin, rules, files = typescriptFiles) {
|
|
17
|
+
return {
|
|
18
|
+
files,
|
|
19
|
+
languageOptions: typescriptLanguageOptions(),
|
|
20
|
+
plugins: {
|
|
21
|
+
'@typescript-eslint': typescriptEslintPlugin,
|
|
22
|
+
plugin
|
|
23
|
+
},
|
|
24
|
+
rules
|
|
25
|
+
};
|
|
15
26
|
}
|
|
@@ -36,6 +36,7 @@ export function unicornConfig() {
|
|
|
36
36
|
'unicorn/no-array-method-this-argument': 'warn',
|
|
37
37
|
'unicorn/no-array-reduce': 'off',
|
|
38
38
|
'unicorn/no-array-reverse': 'off',
|
|
39
|
+
'unicorn/no-array-sort': 'off',
|
|
39
40
|
'unicorn/no-await-expression-member': 'error',
|
|
40
41
|
'unicorn/no-await-in-promise-methods': 'error',
|
|
41
42
|
'unicorn/no-console-spaces': 'warn',
|
|
@@ -43,6 +44,7 @@ export function unicornConfig() {
|
|
|
43
44
|
'unicorn/no-empty-file': 'error',
|
|
44
45
|
'unicorn/no-for-loop': 'warn',
|
|
45
46
|
'unicorn/no-hex-escape': 'warn',
|
|
47
|
+
'unicorn/no-immediate-mutation': 'warn',
|
|
46
48
|
'unicorn/no-instanceof-array': 'off',
|
|
47
49
|
'unicorn/no-instanceof-builtins': 'warn',
|
|
48
50
|
'unicorn/no-invalid-fetch-options': 'error',
|
|
@@ -79,6 +81,7 @@ export function unicornConfig() {
|
|
|
79
81
|
'unicorn/no-unreadable-iife': 'error',
|
|
80
82
|
'unicorn/no-unsafe-regex': 'off',
|
|
81
83
|
'unicorn/no-unused-properties': 'off',
|
|
84
|
+
'unicorn/no-useless-collection-argument': 'warn',
|
|
82
85
|
'unicorn/no-useless-error-capture-stack-trace': 'warn',
|
|
83
86
|
'unicorn/no-useless-fallback-in-spread': 'warn',
|
|
84
87
|
'unicorn/no-useless-length-check': 'warn',
|
|
@@ -117,8 +120,10 @@ export function unicornConfig() {
|
|
|
117
120
|
'unicorn/prefer-array-index-of': 'warn',
|
|
118
121
|
'unicorn/prefer-array-some': 'error',
|
|
119
122
|
'unicorn/prefer-at': 'off',
|
|
123
|
+
'unicorn/prefer-bigint-literals': 'warn',
|
|
120
124
|
'unicorn/prefer-blob-reading-methods': 'error',
|
|
121
125
|
'unicorn/prefer-class-fields': 'warn',
|
|
126
|
+
'unicorn/prefer-classlist-toggle': 'warn',
|
|
122
127
|
'unicorn/prefer-code-point': 'error',
|
|
123
128
|
'unicorn/prefer-date-now': 'warn',
|
|
124
129
|
'unicorn/prefer-default-parameters': 'warn',
|
|
@@ -154,6 +159,7 @@ export function unicornConfig() {
|
|
|
154
159
|
'unicorn/prefer-query-selector': 'warn',
|
|
155
160
|
'unicorn/prefer-reflect-apply': 'warn',
|
|
156
161
|
'unicorn/prefer-regexp-test': 'off',
|
|
162
|
+
'unicorn/prefer-response-static-json': 'warn',
|
|
157
163
|
'unicorn/prefer-set-has': 'warn',
|
|
158
164
|
'unicorn/prefer-set-size': 'warn',
|
|
159
165
|
'unicorn/prefer-single-call': ['warn', {
|
|
@@ -176,6 +182,7 @@ export function unicornConfig() {
|
|
|
176
182
|
'unicorn/prevent-abbreviations': ['warn', unicornPreventAbbreviations()],
|
|
177
183
|
'unicorn/relative-url-style': ['warn', 'always'],
|
|
178
184
|
'unicorn/require-array-join-separator': 'warn',
|
|
185
|
+
'unicorn/require-module-attributes': 'warn',
|
|
179
186
|
'unicorn/require-module-specifiers': 'warn',
|
|
180
187
|
'unicorn/require-number-to-fixed-digits-argument': 'warn',
|
|
181
188
|
'unicorn/require-post-message-target-origin': 'error',
|
package/linter/glob.d.ts
CHANGED
|
@@ -40,6 +40,22 @@ export declare const typescriptDeclarationFiles: Glob;
|
|
|
40
40
|
* @since v0.31.0
|
|
41
41
|
*/
|
|
42
42
|
export declare const configurationFiles: string[];
|
|
43
|
+
/**
|
|
44
|
+
* The default glob patterns Jest uses to find JavaScript test files.
|
|
45
|
+
*
|
|
46
|
+
* @see https://jestjs.io/docs/configuration#testmatch-arraystring
|
|
47
|
+
*
|
|
48
|
+
* @since v0.34.0
|
|
49
|
+
*/
|
|
50
|
+
export declare const jestJavascriptFiles: Glob[];
|
|
51
|
+
/**
|
|
52
|
+
* The default glob patterns Jest uses to find TypeScript test files.
|
|
53
|
+
*
|
|
54
|
+
* @see https://jestjs.io/docs/configuration#testmatch-arraystring
|
|
55
|
+
*
|
|
56
|
+
* @since v0.34.0
|
|
57
|
+
*/
|
|
58
|
+
export declare const jestTypescriptFiles: Glob[];
|
|
43
59
|
/**
|
|
44
60
|
* The default glob patterns Jest uses to find test files.
|
|
45
61
|
*
|
package/linter/glob.js
CHANGED
|
@@ -4,5 +4,7 @@ export const tsxFiles = '**/*.tsx';
|
|
|
4
4
|
export const typescriptFiles = ['**/*.{ts,cts,mts}', tsxFiles];
|
|
5
5
|
export const typescriptDeclarationFiles = '**/*.d.{ts,cts,mts}';
|
|
6
6
|
export const configurationFiles = ['**/.*.js', '**/*.config.js', '**/gulpfile.js'];
|
|
7
|
-
export const
|
|
7
|
+
export const jestJavascriptFiles = ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec|test).js?(x)'];
|
|
8
|
+
export const jestTypescriptFiles = ['**/__tests__/**/*.ts?(x)', '**/?(*.)+(spec|test).ts?(x)'];
|
|
9
|
+
export const jestFiles = [...jestJavascriptFiles, ...jestTypescriptFiles];
|
|
8
10
|
export const cypressFiles = 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@perfective/eslint-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"description": "ESLint shareable rules configuration",
|
|
5
5
|
"keywords": ["code quality", "code standard", "code style", "eslint", "eslint config", "lint", "perfective", "tslint", "tslint config", "typescript"],
|
|
6
6
|
"author": "Andrey Mikheychik <a.mikheychik@gmail.com>",
|
|
@@ -13,24 +13,24 @@
|
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
|
|
16
|
-
"@stylistic/eslint-plugin": "^5.
|
|
17
|
-
"eslint": "^9.
|
|
16
|
+
"@stylistic/eslint-plugin": "^5.6.1",
|
|
17
|
+
"eslint": "^9.39.2",
|
|
18
18
|
"eslint-import-resolver-typescript": "^3.10.1",
|
|
19
|
-
"eslint-plugin-array-func": "^5.0
|
|
20
|
-
"eslint-plugin-cypress": "^5.
|
|
19
|
+
"eslint-plugin-array-func": "^5.1.0",
|
|
20
|
+
"eslint-plugin-cypress": "^5.2.1",
|
|
21
21
|
"eslint-plugin-import": "^2.32.0",
|
|
22
|
-
"eslint-plugin-jest": "^29.
|
|
22
|
+
"eslint-plugin-jest": "^29.12.1",
|
|
23
23
|
"eslint-plugin-jest-dom": "^5.5.0",
|
|
24
|
-
"eslint-plugin-jsdoc": "^
|
|
25
|
-
"eslint-plugin-n": "^17.
|
|
24
|
+
"eslint-plugin-jsdoc": "^61.7.1",
|
|
25
|
+
"eslint-plugin-n": "^17.23.1",
|
|
26
26
|
"eslint-plugin-prefer-arrow": "^1.2.3",
|
|
27
27
|
"eslint-plugin-promise": "^7.2.1",
|
|
28
|
-
"eslint-plugin-rxjs-x": "~0.
|
|
28
|
+
"eslint-plugin-rxjs-x": "~0.8.4",
|
|
29
29
|
"eslint-plugin-security": "^3.0.1",
|
|
30
30
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
31
|
-
"eslint-plugin-testing-library": "^7.
|
|
32
|
-
"eslint-plugin-unicorn": "^
|
|
33
|
-
"typescript-eslint": "^8.
|
|
31
|
+
"eslint-plugin-testing-library": "^7.15.4",
|
|
32
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
33
|
+
"typescript-eslint": "^8.52.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"eslint-plugin-cypress": {
|