@shelf/eslint-config 6.2.0 → 6.3.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/README.md +34 -3
- package/base-no-prettier.js +68 -0
- package/common/overrides.js +6 -0
- package/frontend-typescript-no-prettier.js +124 -0
- package/frontend-typescript.js +1 -0
- package/package.json +10 -2
- package/typescript-no-prettier.js +146 -0
- package/typescript.js +1 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @shelf/eslint-config
|
|
1
|
+
# @shelf/eslint-config
|
|
2
2
|
|
|
3
3
|
## Style Guide
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ $ pnpm add --save-dev --save-exact @shelf/eslint-config
|
|
|
15
15
|
### Backend
|
|
16
16
|
|
|
17
17
|
```js
|
|
18
|
-
import tsConfig from '@shelf/eslint-config/typescript';
|
|
18
|
+
import tsConfig from '@shelf/eslint-config/typescript.js';
|
|
19
19
|
|
|
20
20
|
export default [...tsConfig];
|
|
21
21
|
```
|
|
@@ -23,7 +23,7 @@ export default [...tsConfig];
|
|
|
23
23
|
### Frontend
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
|
-
import feTsConfig from '@shelf/eslint-config/frontend-typescript';
|
|
26
|
+
import feTsConfig from '@shelf/eslint-config/frontend-typescript.js';
|
|
27
27
|
|
|
28
28
|
export default [
|
|
29
29
|
...feTsConfig,
|
|
@@ -37,6 +37,37 @@ export default [
|
|
|
37
37
|
];
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
## Oxfmt Migrations
|
|
41
|
+
|
|
42
|
+
Repos that move formatting out of ESLint and into Oxfmt should use the additive no-Prettier entrypoints:
|
|
43
|
+
|
|
44
|
+
### Backend, no Prettier plugin
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
import tsConfig from '@shelf/eslint-config/typescript-no-prettier.js';
|
|
48
|
+
|
|
49
|
+
export default [...tsConfig];
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Frontend, no Prettier plugin
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
import feTsConfig from '@shelf/eslint-config/frontend-typescript-no-prettier.js';
|
|
56
|
+
|
|
57
|
+
export default [
|
|
58
|
+
...feTsConfig,
|
|
59
|
+
{
|
|
60
|
+
settings: {
|
|
61
|
+
react: {
|
|
62
|
+
version: 'detect',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The legacy `typescript.js` and `frontend-typescript.js` entrypoints stay supported for repos that still format through Prettier.
|
|
70
|
+
|
|
40
71
|
## Publish
|
|
41
72
|
|
|
42
73
|
```sh
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import jestFormatting from 'eslint-plugin-jest-formatting';
|
|
2
|
+
import jestPlugin from 'eslint-plugin-jest';
|
|
3
|
+
import stylistic from '@stylistic/eslint-plugin';
|
|
4
|
+
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
5
|
+
import {fixupPluginRules} from '@eslint/compat';
|
|
6
|
+
import env from './common/env.js';
|
|
7
|
+
import paddingLineRules from './rules/padding-line-between-statements.js';
|
|
8
|
+
import jestRules from './rules/jest.js';
|
|
9
|
+
import preferEs6 from './rules/prefer-es6.js';
|
|
10
|
+
import importOrder from './rules/import-order.js';
|
|
11
|
+
import sortImports from './rules/sort-imports.js';
|
|
12
|
+
import comments from './rules/comments.js';
|
|
13
|
+
import defaultBarrelExports, {
|
|
14
|
+
barrelPagesOverride,
|
|
15
|
+
barrelPlugin,
|
|
16
|
+
} from './rules/default-barrel-exports.js';
|
|
17
|
+
|
|
18
|
+
const jestFormattingCompat = fixupPluginRules(jestFormatting);
|
|
19
|
+
|
|
20
|
+
export default [
|
|
21
|
+
{
|
|
22
|
+
files: jestFormattingCompat.configs.strict.overrides[0].files,
|
|
23
|
+
rules: jestFormattingCompat.configs.strict.overrides[0].rules,
|
|
24
|
+
plugins: {
|
|
25
|
+
'jest-formatting': jestFormattingCompat,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
jestPlugin.configs['flat/recommended'],
|
|
29
|
+
jestPlugin.configs['flat/style'],
|
|
30
|
+
{
|
|
31
|
+
plugins: {
|
|
32
|
+
'@stylistic': stylistic,
|
|
33
|
+
...barrelPlugin,
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
languageOptions: {
|
|
37
|
+
globals: {
|
|
38
|
+
...env,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
rules: {
|
|
43
|
+
...paddingLineRules,
|
|
44
|
+
...jestRules,
|
|
45
|
+
...preferEs6,
|
|
46
|
+
'no-empty': [
|
|
47
|
+
'error',
|
|
48
|
+
{
|
|
49
|
+
allowEmptyCatch: true,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
...importOrder,
|
|
53
|
+
...sortImports,
|
|
54
|
+
...comments,
|
|
55
|
+
...defaultBarrelExports,
|
|
56
|
+
'comma-dangle': 'off',
|
|
57
|
+
camelcase: 'error',
|
|
58
|
+
eqeqeq: ['error', 'smart'],
|
|
59
|
+
'new-cap': 'error',
|
|
60
|
+
'no-extend-native': 'error',
|
|
61
|
+
'no-use-before-define': ['error', 'nofunc'],
|
|
62
|
+
'@stylistic/multiline-comment-style': ['error', 'separate-lines'],
|
|
63
|
+
'require-await': 'error',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
barrelPagesOverride,
|
|
67
|
+
eslintConfigPrettier,
|
|
68
|
+
];
|
package/common/overrides.js
CHANGED
|
@@ -9,6 +9,12 @@ export default {
|
|
|
9
9
|
'@typescript-eslint/no-explicit-any': 'off',
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
|
+
noUnusedVarsInTypes: {
|
|
13
|
+
files: ['**/types.ts', '**/types/**/*.ts'],
|
|
14
|
+
rules: {
|
|
15
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
12
18
|
allowRequireInConfigs: {
|
|
13
19
|
files: [
|
|
14
20
|
'*wallaby.config.js',
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import node from 'eslint-plugin-n';
|
|
4
|
+
import testingLibrary from 'eslint-plugin-testing-library';
|
|
5
|
+
import {fixupConfigRules, fixupPluginRules} from '@eslint/compat';
|
|
6
|
+
import tsParser from '@typescript-eslint/parser';
|
|
7
|
+
import js from '@eslint/js';
|
|
8
|
+
import {FlatCompat} from '@eslint/eslintrc';
|
|
9
|
+
import tsEslint from 'typescript-eslint';
|
|
10
|
+
import sonarjs from 'eslint-plugin-sonarjs';
|
|
11
|
+
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
12
|
+
import react from 'eslint-plugin-react';
|
|
13
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
14
|
+
import _import from 'eslint-plugin-import';
|
|
15
|
+
import globals from 'globals';
|
|
16
|
+
import overrides from './common/overrides.js';
|
|
17
|
+
import youDontNeedLodash from './rules/you-dont-need-lodash.js';
|
|
18
|
+
import typescriptRules from './rules/typescript.js';
|
|
19
|
+
import consistentTypeImports from './rules/consistent-type-imports.js';
|
|
20
|
+
import baseNoPrettierConfig from './base-no-prettier.js';
|
|
21
|
+
import env from './common/env.js';
|
|
22
|
+
import restrictedPackages from './rules/restricted-packages-import.js';
|
|
23
|
+
|
|
24
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
25
|
+
const __dirname = path.dirname(__filename);
|
|
26
|
+
const compat = new FlatCompat({
|
|
27
|
+
baseDirectory: __dirname,
|
|
28
|
+
recommendedConfig: js.configs.recommended,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const testingLibraryReact = {
|
|
32
|
+
rules: compat.extends('plugin:testing-library/react')[0].rules,
|
|
33
|
+
files: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default [
|
|
37
|
+
...compat.extends('plugin:you-dont-need-lodash-underscore/compatible'),
|
|
38
|
+
...tsEslint.configs.recommended,
|
|
39
|
+
...fixupConfigRules(compat.extends('plugin:react/recommended', 'plugin:react-hooks/recommended')),
|
|
40
|
+
sonarjs.configs.recommended,
|
|
41
|
+
...baseNoPrettierConfig,
|
|
42
|
+
{
|
|
43
|
+
rules: {
|
|
44
|
+
...restrictedPackages,
|
|
45
|
+
'no-console': 'error',
|
|
46
|
+
'react-hooks/exhaustive-deps': 'error',
|
|
47
|
+
'sonarjs/cognitive-complexity': ['error', 18],
|
|
48
|
+
'@stylistic/multiline-comment-style': 'off',
|
|
49
|
+
'no-unreachable': 'error',
|
|
50
|
+
'react/react-in-jsx-scope': 'off',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
testingLibraryReact,
|
|
54
|
+
{
|
|
55
|
+
plugins: {
|
|
56
|
+
react: fixupPluginRules(react),
|
|
57
|
+
'react-hooks': fixupPluginRules(reactHooks),
|
|
58
|
+
import: fixupPluginRules(_import),
|
|
59
|
+
'@typescript-eslint': tsEslint.plugin,
|
|
60
|
+
node,
|
|
61
|
+
'testing-library': fixupPluginRules(testingLibrary),
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
languageOptions: {
|
|
65
|
+
globals: {
|
|
66
|
+
...env,
|
|
67
|
+
...globals.browser,
|
|
68
|
+
},
|
|
69
|
+
parser: tsParser,
|
|
70
|
+
parserOptions: {
|
|
71
|
+
ecmaFeatures: {
|
|
72
|
+
jsx: true,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
rules: {
|
|
78
|
+
// Often test name starts with component name which are always capitalized
|
|
79
|
+
'jest/lowercase-name': 'off',
|
|
80
|
+
'react/prop-types': 'off',
|
|
81
|
+
'react/display-name': 'warn',
|
|
82
|
+
'testing-library/await-async-queries': 'error',
|
|
83
|
+
'testing-library/no-await-sync-queries': 'error',
|
|
84
|
+
// 'testing-library/no-wait-for-empty-callback': 'error',
|
|
85
|
+
// It's enabled in overrides
|
|
86
|
+
'testing-library/no-debugging-utils': 'off',
|
|
87
|
+
'testing-library/consistent-data-testid': [
|
|
88
|
+
2,
|
|
89
|
+
{
|
|
90
|
+
testIdPattern: '^(([a-z])+(-)*)+$',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
...consistentTypeImports,
|
|
94
|
+
// it fail to compile TS on react static class properties (displayName | defaultProps | etc..)
|
|
95
|
+
'@typescript-eslint/explicit-member-accessibility': 0,
|
|
96
|
+
'@typescript-eslint/consistent-type-assertions': 'warn',
|
|
97
|
+
// Don`t need for typescript files
|
|
98
|
+
'@typescript-eslint/no-empty-function': 'off',
|
|
99
|
+
...typescriptRules,
|
|
100
|
+
'@typescript-eslint/no-unused-vars': ['error', {ignoreRestSiblings: true}],
|
|
101
|
+
...youDontNeedLodash,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
overrides.allowRequireInConfigs,
|
|
105
|
+
overrides.noExplicitsInTests,
|
|
106
|
+
overrides.noUnusedVarsInTypes,
|
|
107
|
+
overrides.noCastWithJestMock,
|
|
108
|
+
overrides.noTSRulesWithJSON,
|
|
109
|
+
{
|
|
110
|
+
files: ['**/*.test.{ts,tsx,js}', '**/mocks.ts', '**/mock.js'],
|
|
111
|
+
rules: {
|
|
112
|
+
camelcase: 'off',
|
|
113
|
+
'sonarjs/no-duplicate-string': 'off',
|
|
114
|
+
'testing-library/no-debugging-utils': 'error',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
files: ['**/*.styled.{ts,tsx}'],
|
|
119
|
+
rules: {
|
|
120
|
+
'sonarjs/no-nested-template-literals': 'off',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
eslintConfigPrettier,
|
|
124
|
+
];
|
package/frontend-typescript.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shelf/eslint-config",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"description": "ESLint Config for Shelf Projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "shelfio/eslint-config",
|
|
@@ -16,8 +16,11 @@
|
|
|
16
16
|
"common",
|
|
17
17
|
"rules",
|
|
18
18
|
"base.js",
|
|
19
|
+
"base-no-prettier.js",
|
|
19
20
|
"frontend-typescript.js",
|
|
20
|
-
"typescript.js"
|
|
21
|
+
"frontend-typescript-no-prettier.js",
|
|
22
|
+
"typescript.js",
|
|
23
|
+
"typescript-no-prettier.js"
|
|
21
24
|
],
|
|
22
25
|
"main": "base.js",
|
|
23
26
|
"keywords": [
|
|
@@ -61,6 +64,11 @@
|
|
|
61
64
|
"eslint": "10.x",
|
|
62
65
|
"prettier": "3.x"
|
|
63
66
|
},
|
|
67
|
+
"peerDependenciesMeta": {
|
|
68
|
+
"prettier": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
71
|
+
},
|
|
64
72
|
"publishConfig": {
|
|
65
73
|
"access": "public"
|
|
66
74
|
},
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import jestFormatting from 'eslint-plugin-jest-formatting';
|
|
4
|
+
import _import from 'eslint-plugin-import';
|
|
5
|
+
import node from 'eslint-plugin-n';
|
|
6
|
+
import {fixupPluginRules} from '@eslint/compat';
|
|
7
|
+
import tsParser from '@typescript-eslint/parser';
|
|
8
|
+
import js from '@eslint/js';
|
|
9
|
+
import {FlatCompat} from '@eslint/eslintrc';
|
|
10
|
+
import tsEslint from 'typescript-eslint';
|
|
11
|
+
import jestPlugin from 'eslint-plugin-jest';
|
|
12
|
+
import shelfNoLodash from 'eslint-plugin-shelf-no-need-lodash-methods';
|
|
13
|
+
import stylistic from '@stylistic/eslint-plugin';
|
|
14
|
+
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
15
|
+
import env from './common/env.js';
|
|
16
|
+
import jestRules from './rules/jest.js';
|
|
17
|
+
import paddingLineRules from './rules/padding-line-between-statements.js';
|
|
18
|
+
import preferEs6 from './rules/prefer-es6.js';
|
|
19
|
+
import importOrder from './rules/import-order.js';
|
|
20
|
+
import sortImports from './rules/sort-imports.js';
|
|
21
|
+
import typeAssertionRules from './rules/consistent-type-assertions.js';
|
|
22
|
+
import consistentTypeImports from './rules/consistent-type-imports.js';
|
|
23
|
+
import youDontNeedLodash from './rules/you-dont-need-lodash.js';
|
|
24
|
+
import typescriptRules from './rules/typescript.js';
|
|
25
|
+
import restrictedPackages from './rules/restricted-packages-import.js';
|
|
26
|
+
import overrides from './common/overrides.js';
|
|
27
|
+
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = path.dirname(__filename);
|
|
30
|
+
const compat = new FlatCompat({
|
|
31
|
+
baseDirectory: __dirname,
|
|
32
|
+
recommendedConfig: js.configs.recommended,
|
|
33
|
+
});
|
|
34
|
+
const jestFormattingCompat = fixupPluginRules(jestFormatting);
|
|
35
|
+
|
|
36
|
+
export default [
|
|
37
|
+
...compat.extends('plugin:you-dont-need-lodash-underscore/compatible'),
|
|
38
|
+
...tsEslint.configs.recommended,
|
|
39
|
+
{
|
|
40
|
+
files: jestFormattingCompat.configs.strict.overrides[0].files,
|
|
41
|
+
rules: jestFormattingCompat.configs.strict.overrides[0].rules,
|
|
42
|
+
plugins: {
|
|
43
|
+
'jest-formatting': jestFormattingCompat,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
jestPlugin.configs['flat/recommended'],
|
|
47
|
+
jestPlugin.configs['flat/style'],
|
|
48
|
+
shelfNoLodash.configs.all,
|
|
49
|
+
{
|
|
50
|
+
plugins: {
|
|
51
|
+
'jest-formatting': jestFormattingCompat,
|
|
52
|
+
import: fixupPluginRules(_import),
|
|
53
|
+
node,
|
|
54
|
+
'@stylistic': stylistic,
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
languageOptions: {
|
|
58
|
+
globals: {
|
|
59
|
+
...env,
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
parser: tsParser,
|
|
63
|
+
|
|
64
|
+
parserOptions: {
|
|
65
|
+
ecmaFeatures: {
|
|
66
|
+
jsx: true,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
settings: {
|
|
72
|
+
'import/internal-regex': '^@shelf/',
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
rules: {
|
|
76
|
+
complexity: [
|
|
77
|
+
'warn',
|
|
78
|
+
{
|
|
79
|
+
max: 5,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
|
|
83
|
+
'multiline-ternary': ['error', 'never'],
|
|
84
|
+
curly: 'error',
|
|
85
|
+
'no-nested-ternary': 'error',
|
|
86
|
+
|
|
87
|
+
...paddingLineRules,
|
|
88
|
+
...jestRules,
|
|
89
|
+
...preferEs6,
|
|
90
|
+
...importOrder,
|
|
91
|
+
...sortImports,
|
|
92
|
+
'comma-dangle': 'off',
|
|
93
|
+
...typeAssertionRules,
|
|
94
|
+
camelcase: [
|
|
95
|
+
'error',
|
|
96
|
+
{
|
|
97
|
+
properties: 'never',
|
|
98
|
+
ignoreGlobals: true,
|
|
99
|
+
allow: ['hash_key', 'range_key'],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
eqeqeq: ['error', 'smart'],
|
|
103
|
+
'new-cap': 'error',
|
|
104
|
+
'no-extend-native': 'error',
|
|
105
|
+
'no-use-before-define': 'off',
|
|
106
|
+
...consistentTypeImports,
|
|
107
|
+
'@stylistic/multiline-comment-style': ['error', 'separate-lines'],
|
|
108
|
+
'arrow-body-style': [
|
|
109
|
+
'error',
|
|
110
|
+
'as-needed',
|
|
111
|
+
{
|
|
112
|
+
requireReturnForObjectLiteral: true,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
'id-length': [
|
|
116
|
+
'warn',
|
|
117
|
+
{
|
|
118
|
+
min: 1,
|
|
119
|
+
max: 22,
|
|
120
|
+
properties: 'never',
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
'no-unreachable': 'error',
|
|
124
|
+
'require-await': 'error',
|
|
125
|
+
...youDontNeedLodash,
|
|
126
|
+
'@typescript-eslint/ban-ts-comment': 'warn',
|
|
127
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
128
|
+
...typescriptRules,
|
|
129
|
+
...restrictedPackages,
|
|
130
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
131
|
+
'no-restricted-syntax': [
|
|
132
|
+
'error',
|
|
133
|
+
{
|
|
134
|
+
selector: "ObjectExpression > Property[key.name='accountId'] ~ SpreadElement",
|
|
135
|
+
message: "Danger, this can overwrite 'accountId'. Rearrange the order.",
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
eslintConfigPrettier,
|
|
141
|
+
overrides.allowRequireInConfigs,
|
|
142
|
+
overrides.noExplicitsInTests,
|
|
143
|
+
overrides.noUnusedVarsInTypes,
|
|
144
|
+
overrides.noCastWithJestMock,
|
|
145
|
+
overrides.noTSRulesWithJSON,
|
|
146
|
+
];
|