@foray1010/eslint-config 10.0.2 → 10.0.4

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/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [10.0.4](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@10.0.3...@foray1010/eslint-config@10.0.4) (2023-03-23)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **eslint-config:** disable n/prefer-global hacks as they do not work with flat config ([4ede17d](https://github.com/foray1010/common-presets/commit/4ede17d93e403892bb731d1ad1900e19d03a8179))
11
+ - **eslint-config:** still have errors when using in project without typescript ([a20ae50](https://github.com/foray1010/common-presets/commit/a20ae50a71af5970ee69565f153a94c520cc944b))
12
+
13
+ ## [10.0.3](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@10.0.2...@foray1010/eslint-config@10.0.3) (2023-03-23)
14
+
15
+ ### Bug Fixes
16
+
17
+ - **eslint-config:** errors when using in project without typescript ([d357595](https://github.com/foray1010/common-presets/commit/d3575954b9dac1290c77ff23ece9ce3e7c8fcc2f))
18
+
6
19
  ## [10.0.2](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@10.0.1...@foray1010/eslint-config@10.0.2) (2023-03-23)
7
20
 
8
21
  ### Bug Fixes
package/bases/base.mjs CHANGED
@@ -2,10 +2,6 @@ import js from '@eslint/js'
2
2
  import eslintPluginEslintComments from '@eslint-community/eslint-plugin-eslint-comments'
3
3
  // @ts-expect-error
4
4
  import { hasDep, isESM } from '@foray1010/common-presets-utils'
5
- import eslintPluginTypescriptEslint from '@typescript-eslint/eslint-plugin'
6
- import typescriptEslintParser from '@typescript-eslint/parser'
7
- import eslintPluginDeprecation from 'eslint-plugin-deprecation'
8
- import eslintPluginFunctional from 'eslint-plugin-functional'
9
5
  import eslintPluginImport from 'eslint-plugin-import'
10
6
  import eslintPluginJest from 'eslint-plugin-jest'
11
7
  import eslintPluginSimpleImportSort from 'eslint-plugin-simple-import-sort'
@@ -18,6 +14,201 @@ import {
18
14
  typeScriptTestFileGlobs,
19
15
  } from '../constants.mjs'
20
16
 
17
+ /** @returns {Promise<readonly import('eslint').Linter.FlatConfig[]>} */
18
+ async function generateTypeScriptConfig() {
19
+ // typescript plugins are depended on `typescript` package
20
+ if (!hasDep('typescript')) return []
21
+
22
+ const eslintPluginTypescriptEslint = (
23
+ await import('@typescript-eslint/eslint-plugin')
24
+ ).default
25
+ const typescriptEslintParser = (await import('@typescript-eslint/parser'))
26
+ .default
27
+ const eslintPluginDeprecation = (await import('eslint-plugin-deprecation'))
28
+ .default
29
+ const eslintPluginFunctional = (await import('eslint-plugin-functional'))
30
+ .default
31
+
32
+ return [
33
+ {
34
+ files: typeScriptFileGlobs,
35
+ languageOptions: {
36
+ /** @type {any} */
37
+ parser: typescriptEslintParser,
38
+ parserOptions: {
39
+ // faster linting on cli
40
+ // https://github.com/typescript-eslint/typescript-eslint/issues/3528
41
+ // turned off because @typescript-eslint/no-unsafe-* rules will output wrong errors
42
+ // allowAutomaticSingleRunInference: true,
43
+ project: ['./tsconfig*.json', './packages/*/tsconfig*.json'],
44
+ },
45
+ },
46
+ settings: {
47
+ 'import/resolver': {
48
+ typescript: true,
49
+ },
50
+ },
51
+ plugins: {
52
+ // @ts-expect-error
53
+ '@typescript-eslint': eslintPluginTypescriptEslint,
54
+ // @ts-expect-error
55
+ deprecation: eslintPluginDeprecation,
56
+ functional: eslintPluginFunctional,
57
+ },
58
+ rules: {
59
+ ...eslintPluginTypescriptEslint.configs['eslint-recommended']?.rules,
60
+ ...eslintPluginTypescriptEslint.configs['recommended']?.rules,
61
+ ...eslintPluginTypescriptEslint.configs[
62
+ 'recommended-requiring-type-checking'
63
+ ]?.rules,
64
+ ...eslintPluginImport.configs['typescript']?.rules,
65
+ // extend existing rule
66
+ '@typescript-eslint/ban-types': [
67
+ 'error',
68
+ {
69
+ types: {
70
+ // TypeScript team suggests to use `<T extends {}>` https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/#unconstrained-generics-no-longer-assignable-to
71
+ '{}': false,
72
+ },
73
+ extendDefaults: true,
74
+ },
75
+ ],
76
+ // separate type exports which allow certain optimizations within compilers
77
+ '@typescript-eslint/consistent-type-exports': 'error',
78
+ '@typescript-eslint/consistent-type-imports': [
79
+ 'error',
80
+ {
81
+ // separate type imports which allow certain optimizations within compilers
82
+ prefer: 'type-imports',
83
+ },
84
+ ],
85
+ // disable the base rule as it can report incorrect errors, use @typescript-eslint/dot-notation instead
86
+ 'dot-notation': 'off',
87
+ // only allow indexed syntax (e.g. `obj['key']`) for accessing undefined fields
88
+ '@typescript-eslint/dot-notation': [
89
+ 'error',
90
+ {
91
+ allowIndexSignaturePropertyAccess: true,
92
+ },
93
+ ],
94
+ // encourage to use private accessibility modifier
95
+ '@typescript-eslint/explicit-member-accessibility': [
96
+ 'error',
97
+ {
98
+ accessibility: 'explicit',
99
+ },
100
+ ],
101
+ // sometimes auto detect can provide a better and narrower type
102
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
103
+ // disallow duplicated value in enum as it is error-prone
104
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
105
+ // need empty function for react context default value
106
+ '@typescript-eslint/no-empty-function': 'off',
107
+ // encourage to check error type before use in catch clauses
108
+ '@typescript-eslint/no-implicit-any-catch': 'error',
109
+ // when using typescript 5.0 with verbatimModuleSyntax flag on, compiler will not remove import statements with only inline type imports which lead to side effects
110
+ '@typescript-eslint/no-import-type-side-effects': 'error',
111
+ // enforce correct usage of `void` type
112
+ '@typescript-eslint/no-invalid-void-type': 'error',
113
+ // allow using async function as event handler in frontend
114
+ '@typescript-eslint/no-misused-promises': [
115
+ 'error',
116
+ { checksVoidReturn: false },
117
+ ],
118
+ // declaration merging between classes and interfaces is unsafe
119
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
120
+ // do not block functions referring to other functions
121
+ '@typescript-eslint/no-use-before-define': [
122
+ 'error',
123
+ {
124
+ /* options from eslint/no-use-before-define */
125
+ // allow use function before defined as they could be hoisted
126
+ functions: false,
127
+ classes: true,
128
+ variables: true,
129
+
130
+ /* options from @typescript-eslint/no-use-before-define */
131
+ enums: true,
132
+ // confusing option, it will disable `typedefs`
133
+ ignoreTypeReferences: false,
134
+ // tsc allows types to be used before define
135
+ typedefs: false,
136
+ },
137
+ ],
138
+ // use with functional/prefer-readonly-type
139
+ // mark class variables as readonly if it is not mutated
140
+ '@typescript-eslint/prefer-readonly': 'error',
141
+ // make sure functions which return a promise will just return a rejected promise instead of throwing an error
142
+ '@typescript-eslint/promise-function-async': 'error',
143
+ // allow primitive value in template string
144
+ '@typescript-eslint/restrict-template-expressions': [
145
+ 'error',
146
+ {
147
+ allowNumber: true,
148
+ allowBoolean: true,
149
+ allowAny: true, // mistakenly recognize string as any in 4.29.3
150
+ allowNullish: true,
151
+ allowRegExp: true,
152
+ },
153
+ ],
154
+ // avoid missed switch-case by requiring switch-case statements to be exhaustive with union type
155
+ '@typescript-eslint/switch-exhaustiveness-check': 'error',
156
+ // ignore static function as those are not supposed to use `this`
157
+ '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }],
158
+ // do not allow usage of deprecated code
159
+ 'deprecation/deprecation': 'error',
160
+ // use with @typescript-eslint/prefer-readonly
161
+ 'functional/prefer-readonly-type': [
162
+ 'error',
163
+ {
164
+ // sometimes it is easier to mutate, it should be fine to mutate within local scope
165
+ allowLocalMutation: true,
166
+ // don't force library consumer to use readonly type
167
+ allowMutableReturnType: true,
168
+ // allow mutating class variables
169
+ ignoreClass: 'fieldsOnly',
170
+ },
171
+ ],
172
+ // forbid unnecessary callback wrapper
173
+ 'functional/prefer-tacit': 'error',
174
+ 'no-restricted-syntax': [
175
+ 'error',
176
+ {
177
+ // encourage to use JS standard #private over TS private accessibility modifier, but excluding constructor because it cannot be private in JS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields#description
178
+ selector:
179
+ ':matches(PropertyDefinition, MethodDefinition, TSParameterProperty)[accessibility="private"]:not([kind="constructor"])',
180
+ message:
181
+ 'Use #private instead (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields)',
182
+ },
183
+ ],
184
+ // @typescript-eslint/eslint-plugin suggests to disable it: https://github.com/typescript-eslint/typescript-eslint/blob/2588e9ea55f78352fdd6ae92a306135aabb49a1a/docs/linting/TROUBLESHOOTING.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
185
+ // It is disabled in recommended config but re-enabled here to enforce a subset of global variables that supported by both node.js and browsers
186
+ 'no-undef': 'error',
187
+ },
188
+ },
189
+ {
190
+ files: typeScriptTestFileGlobs,
191
+ plugins: {
192
+ // @ts-expect-error
193
+ '@typescript-eslint': eslintPluginTypescriptEslint,
194
+ jest: eslintPluginJest,
195
+ },
196
+ rules: {
197
+ // doesn't work with jest.fn<void>()
198
+ '@typescript-eslint/no-invalid-void-type': 'off',
199
+ // replace by jest/unbound-method
200
+ '@typescript-eslint/unbound-method': 'off',
201
+ // allow passing an unbound method to `expect` calls
202
+ 'jest/unbound-method': ['error', { ignoreStatic: true }],
203
+ },
204
+ },
205
+ {
206
+ files: typeScriptFileGlobs,
207
+ ...esmConfig,
208
+ },
209
+ ]
210
+ }
211
+
21
212
  /** @type {import('eslint').Linter.FlatConfig} */
22
213
  const cjsConfig = {
23
214
  languageOptions: {
@@ -51,7 +242,7 @@ const baseConfig = [
51
242
  js.configs.recommended,
52
243
  {
53
244
  languageOptions: {
54
- ecmaVersion: 2021,
245
+ ecmaVersion: 2022,
55
246
  globals: {
56
247
  // should align with languageOptions.ecmaVersion
57
248
  ...globals.es2021,
@@ -199,188 +390,6 @@ const baseConfig = [
199
390
  'jest/prefer-hooks-on-top': 'error',
200
391
  },
201
392
  },
202
- // typescript plugins are depended on `typescript` package
203
- // @ts-expect-error
204
- ...(hasDep('typescript')
205
- ? [
206
- {
207
- files: typeScriptFileGlobs,
208
- languageOptions: {
209
- /** @type {any} */
210
- parser: typescriptEslintParser,
211
- parserOptions: {
212
- // faster linting on cli
213
- // https://github.com/typescript-eslint/typescript-eslint/issues/3528
214
- // turned off because @typescript-eslint/no-unsafe-* rules will output wrong errors
215
- // allowAutomaticSingleRunInference: true,
216
- project: ['./tsconfig*.json', './packages/*/tsconfig*.json'],
217
- },
218
- },
219
- settings: {
220
- 'import/resolver': {
221
- typescript: true,
222
- },
223
- },
224
- plugins: {
225
- '@typescript-eslint': eslintPluginTypescriptEslint,
226
- deprecation: eslintPluginDeprecation,
227
- functional: eslintPluginFunctional,
228
- },
229
- rules: {
230
- ...eslintPluginTypescriptEslint.configs['eslint-recommended']
231
- ?.rules,
232
- ...eslintPluginTypescriptEslint.configs['recommended']?.rules,
233
- ...eslintPluginTypescriptEslint.configs[
234
- 'recommended-requiring-type-checking'
235
- ]?.rules,
236
- ...eslintPluginImport.configs['typescript']?.rules,
237
- // extend existing rule
238
- '@typescript-eslint/ban-types': [
239
- 'error',
240
- {
241
- types: {
242
- // TypeScript team suggests to use `<T extends {}>` https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/#unconstrained-generics-no-longer-assignable-to
243
- '{}': false,
244
- },
245
- extendDefaults: true,
246
- },
247
- ],
248
- // separate type exports which allow certain optimizations within compilers
249
- '@typescript-eslint/consistent-type-exports': 'error',
250
- '@typescript-eslint/consistent-type-imports': [
251
- 'error',
252
- {
253
- // separate type imports which allow certain optimizations within compilers
254
- prefer: 'type-imports',
255
- },
256
- ],
257
- // disable the base rule as it can report incorrect errors, use @typescript-eslint/dot-notation instead
258
- 'dot-notation': 'off',
259
- // only allow indexed syntax (e.g. `obj['key']`) for accessing undefined fields
260
- '@typescript-eslint/dot-notation': [
261
- 'error',
262
- {
263
- allowIndexSignaturePropertyAccess: true,
264
- },
265
- ],
266
- // encourage to use private accessibility modifier
267
- '@typescript-eslint/explicit-member-accessibility': [
268
- 'error',
269
- {
270
- accessibility: 'explicit',
271
- },
272
- ],
273
- // sometimes auto detect can provide a better and narrower type
274
- '@typescript-eslint/explicit-module-boundary-types': 'off',
275
- // disallow duplicated value in enum as it is error-prone
276
- '@typescript-eslint/no-duplicate-enum-values': 'error',
277
- // need empty function for react context default value
278
- '@typescript-eslint/no-empty-function': 'off',
279
- // encourage to check error type before use in catch clauses
280
- '@typescript-eslint/no-implicit-any-catch': 'error',
281
- // when using typescript 5.0 with verbatimModuleSyntax flag on, compiler will not remove import statements with only inline type imports which lead to side effects
282
- '@typescript-eslint/no-import-type-side-effects': 'error',
283
- // enforce correct usage of `void` type
284
- '@typescript-eslint/no-invalid-void-type': 'error',
285
- // allow using async function as event handler in frontend
286
- '@typescript-eslint/no-misused-promises': [
287
- 'error',
288
- { checksVoidReturn: false },
289
- ],
290
- // declaration merging between classes and interfaces is unsafe
291
- '@typescript-eslint/no-unsafe-declaration-merging': 'error',
292
- // do not block functions referring to other functions
293
- '@typescript-eslint/no-use-before-define': [
294
- 'error',
295
- {
296
- /* options from eslint/no-use-before-define */
297
- // allow use function before defined as they could be hoisted
298
- functions: false,
299
- classes: true,
300
- variables: true,
301
-
302
- /* options from @typescript-eslint/no-use-before-define */
303
- enums: true,
304
- // confusing option, it will disable `typedefs`
305
- ignoreTypeReferences: false,
306
- // tsc allows types to be used before define
307
- typedefs: false,
308
- },
309
- ],
310
- // use with functional/prefer-readonly-type
311
- // mark class variables as readonly if it is not mutated
312
- '@typescript-eslint/prefer-readonly': 'error',
313
- // make sure functions which return a promise will just return a rejected promise instead of throwing an error
314
- '@typescript-eslint/promise-function-async': 'error',
315
- // allow primitive value in template string
316
- '@typescript-eslint/restrict-template-expressions': [
317
- 'error',
318
- {
319
- allowNumber: true,
320
- allowBoolean: true,
321
- allowAny: true, // mistakenly recognize string as any in 4.29.3
322
- allowNullish: true,
323
- allowRegExp: true,
324
- },
325
- ],
326
- // avoid missed switch-case by requiring switch-case statements to be exhaustive with union type
327
- '@typescript-eslint/switch-exhaustiveness-check': 'error',
328
- // ignore static function as those are not supposed to use `this`
329
- '@typescript-eslint/unbound-method': [
330
- 'error',
331
- { ignoreStatic: true },
332
- ],
333
- // do not allow usage of deprecated code
334
- 'deprecation/deprecation': 'error',
335
- // use with @typescript-eslint/prefer-readonly
336
- 'functional/prefer-readonly-type': [
337
- 'error',
338
- {
339
- // sometimes it is easier to mutate, it should be fine to mutate within local scope
340
- allowLocalMutation: true,
341
- // don't force library consumer to use readonly type
342
- allowMutableReturnType: true,
343
- // allow mutating class variables
344
- ignoreClass: 'fieldsOnly',
345
- },
346
- ],
347
- // forbid unnecessary callback wrapper
348
- 'functional/prefer-tacit': 'error',
349
- 'no-restricted-syntax': [
350
- 'error',
351
- {
352
- // encourage to use JS standard #private over TS private accessibility modifier, but excluding constructor because it cannot be private in JS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields#description
353
- selector:
354
- ':matches(PropertyDefinition, MethodDefinition, TSParameterProperty)[accessibility="private"]:not([kind="constructor"])',
355
- message:
356
- 'Use #private instead (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields)',
357
- },
358
- ],
359
- // @typescript-eslint/eslint-plugin suggests to disable it: https://github.com/typescript-eslint/typescript-eslint/blob/2588e9ea55f78352fdd6ae92a306135aabb49a1a/docs/linting/TROUBLESHOOTING.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
360
- // It is disabled in recommended config but re-enabled here to enforce a subset of global variables that supported by both node.js and browsers
361
- 'no-undef': 'error',
362
- },
363
- },
364
- {
365
- files: typeScriptTestFileGlobs,
366
- plugins: {
367
- '@typescript-eslint': eslintPluginTypescriptEslint,
368
- jest: eslintPluginJest,
369
- },
370
- rules: {
371
- // doesn't work with jest.fn<void>()
372
- '@typescript-eslint/no-invalid-void-type': 'off',
373
- // replace by jest/unbound-method
374
- '@typescript-eslint/unbound-method': 'off',
375
- // allow passing an unbound method to `expect` calls
376
- 'jest/unbound-method': ['error', { ignoreStatic: true }],
377
- },
378
- },
379
- {
380
- files: typeScriptFileGlobs,
381
- ...esmConfig,
382
- },
383
- ]
384
- : []),
393
+ ...(await generateTypeScriptConfig()),
385
394
  ]
386
395
  export default baseConfig
package/bases/node.mjs CHANGED
@@ -20,16 +20,6 @@ const nodeConfig = [
20
20
  plugins: {
21
21
  n: eslintPluginN,
22
22
  },
23
- languageOptions: {
24
- globals: {
25
- // hack to mute no-undef error, and show n/prefer-global/buffer error instead
26
- // @ts-expect-error
27
- Buffer: 'writable',
28
- // hack to mute no-undef error, and show n/prefer-global/process error instead
29
- // @ts-expect-error
30
- process: 'writable',
31
- },
32
- },
33
23
  rules: {
34
24
  // disallow deprecated node APIs
35
25
  'n/no-deprecated-api': 'error',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@foray1010/eslint-config",
4
- "version": "10.0.2",
4
+ "version": "10.0.4",
5
5
  "homepage": "https://github.com/foray1010/common-presets/tree/master/packages/eslint-config#readme",
6
6
  "bugs": "https://github.com/foray1010/common-presets/issues",
7
7
  "repository": {
@@ -50,7 +50,13 @@
50
50
  },
51
51
  "peerDependencies": {
52
52
  "eslint": "^8.36.0",
53
- "prettier": "^2.0.0"
53
+ "prettier": "^2.0.0",
54
+ "typescript": "^5.0.2"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "typescript": {
58
+ "optional": true
59
+ }
54
60
  },
55
61
  "engines": {
56
62
  "node": "^16.14.0 || >=18.12.0"
@@ -58,5 +64,5 @@
58
64
  "publishConfig": {
59
65
  "access": "public"
60
66
  },
61
- "gitHead": "c532946a18c6a773dd05bb8be2c90e905181e165"
67
+ "gitHead": "2e022aa83c203045e5bbd0306888432f0b10dd41"
62
68
  }