@foray1010/eslint-config 10.0.2 → 10.0.3

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,12 @@
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.3](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@10.0.2...@foray1010/eslint-config@10.0.3) (2023-03-23)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **eslint-config:** errors when using in project without typescript ([d357595](https://github.com/foray1010/common-presets/commit/d3575954b9dac1290c77ff23ece9ce3e7c8fcc2f))
11
+
6
12
  ## [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
13
 
8
14
  ### Bug Fixes
package/bases/base.mjs CHANGED
@@ -2,8 +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
5
  import eslintPluginDeprecation from 'eslint-plugin-deprecation'
8
6
  import eslintPluginFunctional from 'eslint-plugin-functional'
9
7
  import eslintPluginImport from 'eslint-plugin-import'
@@ -18,6 +16,197 @@ import {
18
16
  typeScriptTestFileGlobs,
19
17
  } from '../constants.mjs'
20
18
 
19
+ /** @returns {Promise<readonly import('eslint').Linter.FlatConfig[]>} */
20
+ async function generateTypeScriptConfig() {
21
+ // typescript plugins are depended on `typescript` package
22
+ if (!hasDep('typescript')) return []
23
+
24
+ const eslintPluginTypescriptEslint = (
25
+ await import('@typescript-eslint/eslint-plugin')
26
+ ).default
27
+ const typescriptEslintParser = (await import('@typescript-eslint/parser'))
28
+ .default
29
+
30
+ return [
31
+ {
32
+ files: typeScriptFileGlobs,
33
+ languageOptions: {
34
+ /** @type {any} */
35
+ parser: typescriptEslintParser,
36
+ parserOptions: {
37
+ // faster linting on cli
38
+ // https://github.com/typescript-eslint/typescript-eslint/issues/3528
39
+ // turned off because @typescript-eslint/no-unsafe-* rules will output wrong errors
40
+ // allowAutomaticSingleRunInference: true,
41
+ project: ['./tsconfig*.json', './packages/*/tsconfig*.json'],
42
+ },
43
+ },
44
+ settings: {
45
+ 'import/resolver': {
46
+ typescript: true,
47
+ },
48
+ },
49
+ plugins: {
50
+ // @ts-expect-error
51
+ '@typescript-eslint': eslintPluginTypescriptEslint,
52
+ // @ts-expect-error
53
+ deprecation: eslintPluginDeprecation,
54
+ functional: eslintPluginFunctional,
55
+ },
56
+ rules: {
57
+ ...eslintPluginTypescriptEslint.configs['eslint-recommended']?.rules,
58
+ ...eslintPluginTypescriptEslint.configs['recommended']?.rules,
59
+ ...eslintPluginTypescriptEslint.configs[
60
+ 'recommended-requiring-type-checking'
61
+ ]?.rules,
62
+ ...eslintPluginImport.configs['typescript']?.rules,
63
+ // extend existing rule
64
+ '@typescript-eslint/ban-types': [
65
+ 'error',
66
+ {
67
+ types: {
68
+ // TypeScript team suggests to use `<T extends {}>` https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/#unconstrained-generics-no-longer-assignable-to
69
+ '{}': false,
70
+ },
71
+ extendDefaults: true,
72
+ },
73
+ ],
74
+ // separate type exports which allow certain optimizations within compilers
75
+ '@typescript-eslint/consistent-type-exports': 'error',
76
+ '@typescript-eslint/consistent-type-imports': [
77
+ 'error',
78
+ {
79
+ // separate type imports which allow certain optimizations within compilers
80
+ prefer: 'type-imports',
81
+ },
82
+ ],
83
+ // disable the base rule as it can report incorrect errors, use @typescript-eslint/dot-notation instead
84
+ 'dot-notation': 'off',
85
+ // only allow indexed syntax (e.g. `obj['key']`) for accessing undefined fields
86
+ '@typescript-eslint/dot-notation': [
87
+ 'error',
88
+ {
89
+ allowIndexSignaturePropertyAccess: true,
90
+ },
91
+ ],
92
+ // encourage to use private accessibility modifier
93
+ '@typescript-eslint/explicit-member-accessibility': [
94
+ 'error',
95
+ {
96
+ accessibility: 'explicit',
97
+ },
98
+ ],
99
+ // sometimes auto detect can provide a better and narrower type
100
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
101
+ // disallow duplicated value in enum as it is error-prone
102
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
103
+ // need empty function for react context default value
104
+ '@typescript-eslint/no-empty-function': 'off',
105
+ // encourage to check error type before use in catch clauses
106
+ '@typescript-eslint/no-implicit-any-catch': 'error',
107
+ // 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
108
+ '@typescript-eslint/no-import-type-side-effects': 'error',
109
+ // enforce correct usage of `void` type
110
+ '@typescript-eslint/no-invalid-void-type': 'error',
111
+ // allow using async function as event handler in frontend
112
+ '@typescript-eslint/no-misused-promises': [
113
+ 'error',
114
+ { checksVoidReturn: false },
115
+ ],
116
+ // declaration merging between classes and interfaces is unsafe
117
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
118
+ // do not block functions referring to other functions
119
+ '@typescript-eslint/no-use-before-define': [
120
+ 'error',
121
+ {
122
+ /* options from eslint/no-use-before-define */
123
+ // allow use function before defined as they could be hoisted
124
+ functions: false,
125
+ classes: true,
126
+ variables: true,
127
+
128
+ /* options from @typescript-eslint/no-use-before-define */
129
+ enums: true,
130
+ // confusing option, it will disable `typedefs`
131
+ ignoreTypeReferences: false,
132
+ // tsc allows types to be used before define
133
+ typedefs: false,
134
+ },
135
+ ],
136
+ // use with functional/prefer-readonly-type
137
+ // mark class variables as readonly if it is not mutated
138
+ '@typescript-eslint/prefer-readonly': 'error',
139
+ // make sure functions which return a promise will just return a rejected promise instead of throwing an error
140
+ '@typescript-eslint/promise-function-async': 'error',
141
+ // allow primitive value in template string
142
+ '@typescript-eslint/restrict-template-expressions': [
143
+ 'error',
144
+ {
145
+ allowNumber: true,
146
+ allowBoolean: true,
147
+ allowAny: true, // mistakenly recognize string as any in 4.29.3
148
+ allowNullish: true,
149
+ allowRegExp: true,
150
+ },
151
+ ],
152
+ // avoid missed switch-case by requiring switch-case statements to be exhaustive with union type
153
+ '@typescript-eslint/switch-exhaustiveness-check': 'error',
154
+ // ignore static function as those are not supposed to use `this`
155
+ '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }],
156
+ // do not allow usage of deprecated code
157
+ 'deprecation/deprecation': 'error',
158
+ // use with @typescript-eslint/prefer-readonly
159
+ 'functional/prefer-readonly-type': [
160
+ 'error',
161
+ {
162
+ // sometimes it is easier to mutate, it should be fine to mutate within local scope
163
+ allowLocalMutation: true,
164
+ // don't force library consumer to use readonly type
165
+ allowMutableReturnType: true,
166
+ // allow mutating class variables
167
+ ignoreClass: 'fieldsOnly',
168
+ },
169
+ ],
170
+ // forbid unnecessary callback wrapper
171
+ 'functional/prefer-tacit': 'error',
172
+ 'no-restricted-syntax': [
173
+ 'error',
174
+ {
175
+ // 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
176
+ selector:
177
+ ':matches(PropertyDefinition, MethodDefinition, TSParameterProperty)[accessibility="private"]:not([kind="constructor"])',
178
+ message:
179
+ 'Use #private instead (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields)',
180
+ },
181
+ ],
182
+ // @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
183
+ // 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
184
+ 'no-undef': 'error',
185
+ },
186
+ },
187
+ {
188
+ files: typeScriptTestFileGlobs,
189
+ plugins: {
190
+ // @ts-expect-error
191
+ '@typescript-eslint': eslintPluginTypescriptEslint,
192
+ jest: eslintPluginJest,
193
+ },
194
+ rules: {
195
+ // doesn't work with jest.fn<void>()
196
+ '@typescript-eslint/no-invalid-void-type': 'off',
197
+ // replace by jest/unbound-method
198
+ '@typescript-eslint/unbound-method': 'off',
199
+ // allow passing an unbound method to `expect` calls
200
+ 'jest/unbound-method': ['error', { ignoreStatic: true }],
201
+ },
202
+ },
203
+ {
204
+ files: typeScriptFileGlobs,
205
+ ...esmConfig,
206
+ },
207
+ ]
208
+ }
209
+
21
210
  /** @type {import('eslint').Linter.FlatConfig} */
22
211
  const cjsConfig = {
23
212
  languageOptions: {
@@ -51,7 +240,7 @@ const baseConfig = [
51
240
  js.configs.recommended,
52
241
  {
53
242
  languageOptions: {
54
- ecmaVersion: 2021,
243
+ ecmaVersion: 2022,
55
244
  globals: {
56
245
  // should align with languageOptions.ecmaVersion
57
246
  ...globals.es2021,
@@ -199,188 +388,6 @@ const baseConfig = [
199
388
  'jest/prefer-hooks-on-top': 'error',
200
389
  },
201
390
  },
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
- : []),
391
+ ...(await generateTypeScriptConfig()),
385
392
  ]
386
393
  export default baseConfig
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.3",
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": "11db51812a862318500928563f382138f8b5a9d6"
62
68
  }