@lidofinance/eslint-config 0.0.2 → 0.12.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/.eslintrc.js ADDED
@@ -0,0 +1,14 @@
1
+ const buildConfig = require("./lib/build-config");
2
+ const rulesets = require("./rulesets/hard");
3
+
4
+ const { plugins, rules, ...base } = buildConfig({}, rulesets);
5
+
6
+ module.exports = {
7
+ root: true,
8
+ ...base,
9
+ plugins: [...plugins, "prettier"],
10
+ rules: {
11
+ ...rules,
12
+ "prettier/prettier": "error",
13
+ },
14
+ };
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Lido ESint config
2
- *Automated, non-opinionated ESLint config foundation*
3
- > ❗ _Please note that this ESLint config is still 0.x and is subject to significant changes; it is mainly used by internal Lido teams._
2
+ Automated, non-opinionated ESLint config foundation
3
+ >
4
+ >❗ _Please note that this ESLint config is still 0.x and is subject to significant changes; it is mainly used by internal Lido teams._
4
5
 
5
6
 
6
7
  ### Installation
@@ -19,7 +20,7 @@ If using TypeScript, alter `tsconfig.json` line `includes` to include everything
19
20
  Style rules are intentionally not provided; bring your own code style, whatever it is - prettier, airbnb, xo or standard.
20
21
 
21
22
  ```json5
22
- // .eslintrc
23
+ // .eslintrc.js.js
23
24
  {
24
25
  "root": true,
25
26
 
package/all-hard.js CHANGED
@@ -1,12 +1,12 @@
1
- const buildConfig = require('./lib/build-config')
2
- const rulesets = require('./rulesets/hard')
1
+ const buildConfig = require("./lib/build-config");
2
+ const rulesets = require("./rulesets/hard");
3
3
 
4
4
  module.exports = buildConfig(
5
- {
6
- typescript: true,
7
- react: true,
8
- next: true,
9
- jest: true,
10
- },
11
- rulesets
12
- )
5
+ {
6
+ typescript: true,
7
+ react: true,
8
+ next: true,
9
+ jest: true,
10
+ },
11
+ rulesets
12
+ );
package/all.js CHANGED
@@ -1,12 +1,12 @@
1
- const buildConfig = require('./lib/build-config')
2
- const rulesets = require('./rulesets/easy')
1
+ const buildConfig = require("./lib/build-config");
2
+ const rulesets = require("./rulesets/easy");
3
3
 
4
4
  module.exports = buildConfig(
5
- {
6
- typescript: true,
7
- react: true,
8
- next: true,
9
- jest: true,
10
- },
11
- rulesets
12
- )
5
+ {
6
+ typescript: true,
7
+ react: true,
8
+ next: true,
9
+ jest: true,
10
+ },
11
+ rulesets
12
+ );
package/auto-hard.js CHANGED
@@ -1,5 +1,5 @@
1
- const buildConfig = require('./lib/build-config')
2
- const rulesets = require('./rulesets/hard')
3
- const env = require('./lib/env')
1
+ const buildConfig = require("./lib/build-config");
2
+ const rulesets = require("./rulesets/hard");
3
+ const env = require("./lib/env");
4
4
 
5
- module.exports = buildConfig(env, rulesets)
5
+ module.exports = buildConfig(env, rulesets);
package/auto.js CHANGED
@@ -1,5 +1,5 @@
1
- const buildConfig = require('./lib/build-config')
2
- const rulesets = require('./rulesets/easy')
3
- const env = require('./lib/env')
1
+ const buildConfig = require("./lib/build-config");
2
+ const rulesets = require("./rulesets/easy");
3
+ const env = require("./lib/env");
4
4
 
5
- module.exports = buildConfig(env, rulesets)
5
+ module.exports = buildConfig(env, rulesets);
@@ -1,214 +1,229 @@
1
- const ts = require('typescript')
1
+ const ts = require("typescript");
2
2
 
3
3
  const generalLoosenRules = {
4
- 'unicorn/consistent-function-scoping': 'off',
5
- 'unicorn/error-message': 'off',
6
- 'sonarjs/no-identical-conditions': 'off',
7
- 'sonarjs/no-identical-expressions': 'off',
8
- 'sonarjs/no-identical-functions': 'off',
9
- }
4
+ "unicorn/consistent-function-scoping": "off",
5
+ "unicorn/error-message": "off",
6
+ "sonarjs/no-identical-conditions": "off",
7
+ "sonarjs/no-identical-expressions": "off",
8
+ "sonarjs/no-identical-functions": "off",
9
+ };
10
+
10
11
  const loosenTsRules = {
11
- '@typescript-eslint/no-unsafe-argument': 'off',
12
- '@typescript-eslint/no-unsafe-assignment': 'off',
13
- '@typescript-eslint/no-unsafe-call': 'off',
14
- '@typescript-eslint/no-unsafe-member-access': 'off',
15
- '@typescript-eslint/no-unsafe-return': 'off',
16
- '@typescript-eslint/require-await': 'off',
17
- '@typescript-eslint/await-thenable': 'off',
18
- '@typescript-eslint/no-explicit-any': 'off',
19
- '@typescript-eslint/restrict-plus-operands': 'off',
20
- '@typescript-eslint/restrict-template-expressions': 'off',
21
- }
12
+ "@typescript-eslint/no-unsafe-argument": "off",
13
+ "@typescript-eslint/no-unsafe-assignment": "off",
14
+ "@typescript-eslint/no-unsafe-call": "off",
15
+ "@typescript-eslint/no-unsafe-member-access": "off",
16
+ "@typescript-eslint/no-unsafe-return": "off",
17
+ "@typescript-eslint/require-await": "off",
18
+ "@typescript-eslint/await-thenable": "off",
19
+ "@typescript-eslint/no-explicit-any": "off",
20
+ "@typescript-eslint/restrict-plus-operands": "off",
21
+ "@typescript-eslint/restrict-template-expressions": "off",
22
+ };
23
+
22
24
  const loosenReactRules = {
23
- // loosen some rules
24
- 'react/prop-types': 'off',
25
- 'react/react-in-jsx-scope': 'off',
26
- }
25
+ // loosen some rules
26
+ "react/prop-types": "off",
27
+ "react/react-in-jsx-scope": "off",
28
+ };
27
29
 
28
- module.exports = function buildConfig(env, { nextRules, tsRules, reactRules, defaultRules }) {
29
- const config = {
30
- extends: ['eslint:recommended'],
31
- env: {
32
- es2022: true,
33
- browser: env.react,
34
- node: true,
35
- },
36
- // future: add @brettz9, css-modules, eslint-comments plugins
37
- plugins: ['sonarjs', 'unicorn', 'import', 'promise'],
38
- settings: {
39
- 'import/resolver': {
40
- [require.resolve('eslint-import-resolver-node')]: {
41
- extensions: ['.js', '.jsx'],
42
- },
43
- },
30
+ module.exports = function buildConfig(
31
+ env,
32
+ { nextRules, tsRules, reactRules, defaultRules }
33
+ ) {
34
+ const config = {
35
+ extends: ["eslint:recommended"],
36
+ env: {
37
+ es2022: true,
38
+ browser: env.react,
39
+ node: true,
40
+ },
41
+ // future: add @brettz9, css-modules, eslint-comments plugins
42
+ plugins: ["sonarjs", "unicorn", "import", "promise"],
43
+ settings: {
44
+ "import/resolver": {
45
+ [require.resolve("eslint-import-resolver-node")]: {
46
+ extensions: [".js", ".jsx"],
44
47
  },
45
- rules: defaultRules,
46
- overrides: [],
47
- }
48
+ },
49
+ },
50
+ rules: defaultRules,
51
+ overrides: [],
52
+ };
48
53
 
49
- const loosenRules = {
50
- ...generalLoosenRules,
51
- ...(env.react ? loosenReactRules : {}),
52
- ...(env.typescript ? loosenTsRules : {}),
53
- }
54
+ const loosenRules = {
55
+ ...generalLoosenRules,
56
+ ...(env.react ? loosenReactRules : {}),
57
+ ...(env.typescript ? loosenTsRules : {}),
58
+ };
54
59
 
55
- if (env.react) {
56
- Object.assign(config, {
57
- plugins: [...config.plugins, 'react', 'react-hooks'],
58
- rules: {
59
- ...config.rules,
60
- ...reactRules,
61
- },
62
- settings: {
63
- ...config.settings,
64
- react: {
65
- version: 'detect',
66
- },
67
- },
68
- overrides: [
69
- ...config.overrides,
70
- {
71
- files: ['*.stories.*', '*.test.*'],
72
- rules: loosenRules,
73
- },
74
- ],
75
- })
76
- }
77
-
78
- if (env.next) {
79
- Object.assign(config, {
80
- plugins: [...config.plugins, '@next/next'],
81
- rules: {
82
- ...config.rules,
83
- ...nextRules,
84
- },
85
- })
86
- }
60
+ if (env.react) {
61
+ Object.assign(config, {
62
+ plugins: [...config.plugins, "react", "react-hooks"],
63
+ rules: {
64
+ ...config.rules,
65
+ ...reactRules,
66
+ },
67
+ settings: {
68
+ ...config.settings,
69
+ react: {
70
+ version: "detect",
71
+ },
72
+ },
73
+ overrides: [
74
+ ...config.overrides,
75
+ {
76
+ files: ["*.stories.*", "*.test.*"],
77
+ rules: loosenRules,
78
+ },
79
+ ],
80
+ });
81
+ }
87
82
 
88
- // order is important here
89
- if (env.jest) {
90
- Object.assign(config, {
91
- plugins: [...config.plugins, 'jest'],
92
- overrides: [
93
- ...config.overrides,
94
- {
95
- extends: ['plugin:jest/recommended'],
96
- files: ['__test__/**', 'test/**', '*.spec.*'],
97
- env: {
98
- 'jest/globals': true,
99
- },
100
- rules: {
101
- ...loosenRules,
102
- // sometimes there are problems with version detection causing this rule to crash ESLint
103
- 'jest/no-deprecated-functions': 'off',
104
- },
105
- },
106
- ],
107
- })
108
- }
83
+ if (env.next) {
84
+ Object.assign(config, {
85
+ plugins: [...config.plugins, "@next/next"],
86
+ rules: {
87
+ ...config.rules,
88
+ ...nextRules,
89
+ },
90
+ });
91
+ }
109
92
 
110
- if (env.typescript) {
111
- let tsconfigPath
93
+ // order is important here
94
+ if (env.jest) {
95
+ Object.assign(config, {
96
+ plugins: [...config.plugins, "jest"],
97
+ overrides: [
98
+ ...config.overrides,
99
+ {
100
+ extends: ["plugin:jest/recommended"],
101
+ files: ["__test__/**", "test/**", "*.spec.*", "*.test.js"],
102
+ env: {
103
+ "jest/globals": true,
104
+ },
105
+ rules: {
106
+ ...loosenRules,
107
+ // sometimes there are problems with version detection causing this rule to crash ESLint
108
+ "jest/no-deprecated-functions": "off",
109
+ },
110
+ },
111
+ ],
112
+ });
113
+ }
112
114
 
113
- try {
114
- // eslint-disable-next-line @typescript-eslint/unbound-method
115
- tsconfigPath = ts.findConfigFile(process.cwd(), ts.sys.fileExists, 'tsconfig.json')
116
- // eslint-disable-next-line @typescript-eslint/unbound-method
117
- const { config } = ts.readConfigFile(tsconfigPath, ts.sys.readFile)
118
- if (config) {
119
- // this are type-aware checks that require tsconfig presence
120
- Object.assign(tsRules, {
121
- '@typescript-eslint/await-thenable': 'warn',
122
- '@typescript-eslint/no-floating-promises': 'error',
123
- 'no-implied-eval': 'off',
124
- '@typescript-eslint/no-implied-eval': 'error',
125
- '@typescript-eslint/no-misused-promises': 'warn',
126
- '@typescript-eslint/no-unnecessary-type-assertion': 'warn',
127
- 'require-await': 'off',
128
- '@typescript-eslint/require-await': 'error',
129
- '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }],
130
- })
131
- }
132
- if (config?.compilerOptions?.strict) {
133
- Object.assign(tsRules, {
134
- '@typescript-eslint/restrict-plus-operands': 'warn',
135
- '@typescript-eslint/no-explicit-any': 'error',
136
- '@typescript-eslint/no-unsafe-argument': 'error',
137
- '@typescript-eslint/no-unsafe-assignment': 'error',
138
- '@typescript-eslint/no-unsafe-call': 'error',
139
- '@typescript-eslint/no-unsafe-member-access': 'error',
140
- '@typescript-eslint/no-unsafe-return': 'error',
141
- '@typescript-eslint/restrict-template-expressions': 'error',
142
- })
143
- }
144
- } catch {
145
- void 0
146
- }
115
+ if (env.typescript) {
116
+ let tsconfigPath;
147
117
 
148
- Object.assign(config, {
149
- plugins: [...config.plugins, '@typescript-eslint'],
150
- parser: '@typescript-eslint/parser',
151
- parserOptions: {
152
- sourceType: 'module',
153
- project: tsconfigPath,
154
- ecmaFeatures: {
155
- jsx: env.react,
156
- },
157
- warnOnUnsupportedTypeScriptVersion: true,
158
- },
159
- settings: {
160
- ...config.settings,
161
- 'import/resolver': {
162
- ...config.settings['import/resolver'],
163
- [require.resolve('eslint-import-resolver-typescript')]: {
164
- alwaysTryTypes: true,
165
- },
166
- },
167
- },
168
- rules: {
169
- ...config.rules,
170
- ...tsRules,
171
- },
172
- overrides: [
173
- ...config.overrides,
174
- // ESLint can only apply one override per file, and takes first one matched,
175
- // so multiple overrides should be combined.
176
- // order is important.
177
- {
178
- files: ['*.stories.ts', '*.stories.tsx', '*.stories.mts', '*.stories.cts'],
179
- rules: {
180
- ...loosenRules,
181
- },
182
- },
183
- {
184
- files: [
185
- '*.test.ts',
186
- '*.test.tsx',
187
- '*.test.mts',
188
- '*.test.cts',
189
- '__test__/**/*.ts',
190
- '__test__/**/*.tsx',
191
- '__test__/**/*.mts',
192
- '__test__/**/*.cts',
193
- ],
194
- extends: ['plugin:jest/recommended'],
195
- env: {
196
- 'jest/globals': true,
197
- },
198
- rules: {
199
- ...loosenRules,
200
- 'jest/no-deprecated-functions': 'off',
201
- },
202
- },
203
- {
204
- files: ['*.ts', '*.tsx', '*.mts', '*.cts'],
205
- rules: {
206
- ...tsRules,
207
- },
208
- },
209
- ],
210
- })
118
+ try {
119
+ tsconfigPath = ts.findConfigFile(
120
+ process.cwd(),
121
+ ts.sys.fileExists,
122
+ "tsconfig.json"
123
+ );
124
+ const tsConfigFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
125
+ if (tsConfigFile.config) {
126
+ // this are type-aware checks that require tsconfig presence
127
+ Object.assign(tsRules, {
128
+ "@typescript-eslint/await-thenable": "warn",
129
+ "@typescript-eslint/no-floating-promises": "error",
130
+ "no-implied-eval": "off",
131
+ "@typescript-eslint/no-implied-eval": "error",
132
+ "@typescript-eslint/no-misused-promises": "warn",
133
+ "@typescript-eslint/no-unnecessary-type-assertion": "warn",
134
+ "require-await": "off",
135
+ "@typescript-eslint/require-await": "error",
136
+ "@typescript-eslint/unbound-method": [
137
+ "error",
138
+ { ignoreStatic: true },
139
+ ],
140
+ });
141
+ }
142
+ if (config?.compilerOptions?.strict) {
143
+ Object.assign(tsRules, {
144
+ "@typescript-eslint/restrict-plus-operands": "warn",
145
+ "@typescript-eslint/no-explicit-any": "error",
146
+ "@typescript-eslint/no-unsafe-argument": "error",
147
+ "@typescript-eslint/no-unsafe-assignment": "error",
148
+ "@typescript-eslint/no-unsafe-call": "error",
149
+ "@typescript-eslint/no-unsafe-member-access": "error",
150
+ "@typescript-eslint/no-unsafe-return": "error",
151
+ "@typescript-eslint/restrict-template-expressions": "error",
152
+ });
153
+ }
154
+ } catch {
155
+ void 0;
211
156
  }
212
157
 
213
- return config
214
- }
158
+ Object.assign(config, {
159
+ plugins: [...config.plugins, "@typescript-eslint"],
160
+ parser: "@typescript-eslint/parser",
161
+ parserOptions: {
162
+ sourceType: "module",
163
+ project: tsconfigPath,
164
+ ecmaFeatures: {
165
+ jsx: env.react,
166
+ },
167
+ warnOnUnsupportedTypeScriptVersion: true,
168
+ },
169
+ settings: {
170
+ ...config.settings,
171
+ "import/resolver": {
172
+ ...config.settings["import/resolver"],
173
+ [require.resolve("eslint-import-resolver-typescript")]: {
174
+ alwaysTryTypes: true,
175
+ },
176
+ },
177
+ },
178
+ rules: {
179
+ ...config.rules,
180
+ ...tsRules,
181
+ },
182
+ overrides: [
183
+ ...config.overrides,
184
+ // ESLint can only apply one override per file, and takes first one matched,
185
+ // so multiple overrides should be combined.
186
+ // order is important.
187
+ {
188
+ files: [
189
+ "*.stories.ts",
190
+ "*.stories.tsx",
191
+ "*.stories.mts",
192
+ "*.stories.cts",
193
+ ],
194
+ rules: {
195
+ ...loosenRules,
196
+ },
197
+ },
198
+ {
199
+ files: [
200
+ "*.test.ts",
201
+ "*.test.tsx",
202
+ "*.test.mts",
203
+ "*.test.cts",
204
+ "__test__/**/*.ts",
205
+ "__test__/**/*.tsx",
206
+ "__test__/**/*.mts",
207
+ "__test__/**/*.cts",
208
+ ],
209
+ extends: ["plugin:jest/recommended"],
210
+ env: {
211
+ "jest/globals": true,
212
+ },
213
+ rules: {
214
+ ...loosenRules,
215
+ "jest/no-deprecated-functions": "off",
216
+ },
217
+ },
218
+ {
219
+ files: ["*.ts", "*.tsx", "*.mts", "*.cts"],
220
+ rules: {
221
+ ...tsRules,
222
+ },
223
+ },
224
+ ],
225
+ });
226
+ }
227
+
228
+ return config;
229
+ };
package/lib/env.js CHANGED
@@ -1,29 +1,60 @@
1
- const fs = require('fs')
2
- const path = require('path')
1
+ const fs = require("fs");
2
+ const path = require("path");
3
3
 
4
- let packageJsonPath = process.cwd()
4
+ let packageJsonPath = process.cwd();
5
5
 
6
- while (!fs.existsSync(path.join(packageJsonPath, 'package.json'))) {
7
- packageJsonPath = path.dirname(packageJsonPath)
8
- if (packageJsonPath === path.resolve('/')) {
9
- packageJsonPath = null
10
- break
11
- }
6
+ while (!fs.existsSync(path.join(packageJsonPath, "package.json"))) {
7
+ packageJsonPath = path.dirname(packageJsonPath);
8
+ if (packageJsonPath === path.resolve("/")) {
9
+ packageJsonPath = null;
10
+ break;
11
+ }
12
12
  }
13
13
 
14
- const packageJson = packageJsonPath === null ? null : require(path.join(packageJsonPath, 'package.json'))
14
+ let workspacePackageJsonPath = packageJsonPath
15
+ ? path.dirname(packageJsonPath)
16
+ : "/";
15
17
 
16
- const has = (...libs) =>
17
- libs.some((name) => {
18
- if (packageJsonPath === null) {
19
- return false
20
- }
21
- return !!packageJson.dependencies?.[name] || !!packageJson.devDependencies?.[name]
22
- })
18
+ while (!fs.existsSync(path.join(workspacePackageJsonPath, "package.json"))) {
19
+ workspacePackageJsonPath = path.dirname(workspacePackageJsonPath);
20
+ if (workspacePackageJsonPath === path.resolve("/")) {
21
+ workspacePackageJsonPath = null;
22
+ break;
23
+ }
24
+ }
23
25
 
24
- module.exports = {
25
- react: has('react'),
26
- next: has('next'),
27
- typescript: has('typescript'),
28
- jest: has('jest'),
26
+ const packageJson =
27
+ packageJsonPath === null
28
+ ? null
29
+ : require(path.join(packageJsonPath, "package.json"));
30
+
31
+ let workspaceJson =
32
+ workspacePackageJsonPath === null
33
+ ? null
34
+ : require(path.join(workspacePackageJsonPath, "package.json"));
35
+
36
+ if (!workspaceJson?.workspaces) {
37
+ workspaceJson = null;
29
38
  }
39
+
40
+ const dependencies = new Set([
41
+ ...(packageJson?.dependencies ? Object.keys(packageJson.dependencies) : []),
42
+ ...(packageJson?.devDependencies
43
+ ? Object.keys(packageJson.devDependencies)
44
+ : []),
45
+ ...(workspaceJson?.dependencies
46
+ ? Object.keys(workspaceJson?.dependencies)
47
+ : []),
48
+ ...(workspaceJson?.devDependencies
49
+ ? Object.keys(workspaceJson?.devDependencies)
50
+ : []),
51
+ ]);
52
+
53
+ const has = (...libs) => libs.some((name) => dependencies.has(name));
54
+
55
+ module.exports = {
56
+ react: has("react"),
57
+ next: has("next"),
58
+ typescript: has("typescript"),
59
+ jest: has("jest"),
60
+ };