@foray1010/eslint-config 9.2.0 → 10.0.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/presets/base.cjs DELETED
@@ -1,364 +0,0 @@
1
- 'use strict'
2
-
3
- // @ts-expect-error
4
- const { hasDep, isESM } = require('@foray1010/common-presets-utils')
5
-
6
- const { testFileGlobs } = require('./utils/testUtil.cjs')
7
-
8
- /** @type {import('eslint').Linter.BaseConfig} */
9
- const cjsConfig = {
10
- parserOptions: {
11
- sourceType: 'script',
12
- },
13
- env: {
14
- commonjs: true,
15
- },
16
- rules: {
17
- // commonjs must use strict mode
18
- strict: ['error', 'global'],
19
- },
20
- }
21
-
22
- /** @type {import('eslint').Linter.BaseConfig} */
23
- const esmConfig = {
24
- parserOptions: {
25
- sourceType: 'module',
26
- },
27
- plugins: ['eslint-plugin-simple-import-sort'],
28
- rules: {
29
- // auto sort export statements
30
- 'simple-import-sort/exports': 'error',
31
- // auto sort import statements
32
- 'simple-import-sort/imports': 'error',
33
- },
34
- }
35
-
36
- /** @type {import('eslint').Linter.Config} */
37
- module.exports = {
38
- extends: [
39
- 'eslint:recommended',
40
- 'plugin:eslint-comments/recommended',
41
- 'plugin:import/recommended',
42
- 'plugin:jsdoc/recommended',
43
- // included eslint-config-prettier
44
- 'plugin:prettier/recommended',
45
- ],
46
- parserOptions: {
47
- ecmaVersion: 2020,
48
- },
49
- plugins: [
50
- 'eslint-plugin-eslint-comments',
51
- 'eslint-plugin-import',
52
- 'eslint-plugin-jsdoc',
53
- 'eslint-plugin-prettier',
54
- 'eslint-plugin-unicorn',
55
- ],
56
- env: {
57
- // should align with parserOptions.ecmaVersion
58
- es2020: true,
59
- /* Not using `node` to explicitly import node.js only built-in modules, e.g.
60
- * import { Buffer } from 'node:buffer'
61
- * import process from 'node:process'
62
- */
63
- 'shared-node-browser': true,
64
- },
65
- rules: {
66
- // allow disable eslint rules for whole file without re-enable it in the end of the file
67
- 'eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
68
- // make sure every eslint-disable comments are in use
69
- 'eslint-comments/no-unused-disable': 'error',
70
- // always use named function for easier to debug via stack trace
71
- 'func-names': ['error', 'as-needed'],
72
- // this rule doesn't support commonjs, some dependencies are using commonjs
73
- 'import/default': 'off',
74
- // enforce extensions for both cjs and esm
75
- 'import/extensions': [
76
- 'error',
77
- // https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_mandatory_file_extensions
78
- 'always',
79
- {
80
- pattern: {
81
- // eslint-plugin-import does not support checking es modules in typescript files
82
- cts: 'never',
83
- mts: 'never',
84
- ts: 'never',
85
- tsx: 'never',
86
- },
87
- },
88
- ],
89
- // make sure import statements above the others
90
- 'import/first': 'error',
91
- // separate import statements from the others
92
- 'import/newline-after-import': 'error',
93
- // avoid anonymous function or class for easier to debug via stack trace
94
- // for other types, enforcing named data can improve autocomplete when importing
95
- 'import/no-anonymous-default-export': [
96
- 'error',
97
- {
98
- allowArray: false,
99
- allowArrowFunction: false,
100
- allowAnonymousClass: false,
101
- allowAnonymousFunction: false,
102
- allowCallExpression: false,
103
- allowLiteral: false,
104
- allowObject: false,
105
- },
106
- ],
107
- // no circular dependency
108
- 'import/no-cycle': [
109
- 'error',
110
- {
111
- // speed up linting time
112
- ignoreExternal: true,
113
- },
114
- ],
115
- // do not allow import packages that are not listed in dependencies or peerDependencies
116
- 'import/no-extraneous-dependencies': [
117
- 'error',
118
- {
119
- devDependencies: [
120
- '!**/src/**', // allow files outside of src/
121
- '**/.*', // allow config rc files
122
- ...testFileGlobs,
123
- ],
124
- },
125
- ],
126
- // forbid a module from importing itself
127
- 'import/no-self-import': 'error',
128
- // use the shortest path in import statement, but allow /index because it will be standard to omit index as default file in directory
129
- 'import/no-useless-path-segments': [
130
- 'error',
131
- {
132
- commonjs: true,
133
- noUselessIndex: false,
134
- },
135
- ],
136
- // do not enforce JSDoc for internal methods
137
- 'jsdoc/require-jsdoc': 'off',
138
- // does not work well with TypeScript https://github.com/gajus/eslint-plugin-jsdoc/issues/145
139
- 'jsdoc/valid-types': 'off',
140
- // prefer explicitly convert type for readability
141
- 'no-implicit-coercion': 'error',
142
- // make sure private class members are in-use
143
- 'no-unused-private-class-members': 'error',
144
- // avoid assigning anonymous function to object key which is harder to trace when debug
145
- 'object-shorthand': ['error', 'always'],
146
- // prefer `const` when the variable won't be reassigned
147
- 'prefer-const': [
148
- 'error',
149
- {
150
- // if one of the variables will be reassigned, do not enforce `const`
151
- destructuring: 'all',
152
- },
153
- ],
154
- // use with `unicorn/throw-new-error`
155
- // disallow builtins to be created without `new` operator, to be consistent with es6 class syntax
156
- 'unicorn/new-for-builtins': 'error',
157
- // prefer `import from 'node:xxx'`
158
- 'unicorn/prefer-node-protocol': 'error',
159
- // prefer Number static properties over global ones
160
- 'unicorn/prefer-number-properties': 'error',
161
- // use with `unicorn/new-for-builtins`
162
- 'unicorn/throw-new-error': 'error',
163
- },
164
- overrides: [
165
- {
166
- files: ['*.js'],
167
- ...(isESM() ? esmConfig : cjsConfig),
168
- },
169
- {
170
- files: ['*.cjs'],
171
- ...cjsConfig,
172
- },
173
- {
174
- files: ['*.mjs'],
175
- ...esmConfig,
176
- },
177
- {
178
- files: testFileGlobs,
179
- extends: ['plugin:jest/recommended', 'plugin:jest/style'],
180
- plugins: ['eslint-plugin-jest'],
181
- rules: {
182
- // make sure lifecycle hooks on the top for readability
183
- 'jest/prefer-hooks-on-top': 'error',
184
- },
185
- },
186
- // typescript plugins are depended on `typescript` package
187
- ...(hasDep('typescript')
188
- ? [
189
- {
190
- files: ['*.{cts,mts,ts,tsx}'],
191
- ...esmConfig,
192
- },
193
- {
194
- files: ['*.{cts,mts,ts,tsx}'],
195
- extends: [
196
- 'plugin:@typescript-eslint/recommended',
197
- 'plugin:@typescript-eslint/recommended-requiring-type-checking',
198
- 'plugin:import/typescript',
199
- // included eslint-config-prettier
200
- 'plugin:prettier/recommended',
201
- ],
202
- parser: '@typescript-eslint/parser',
203
- parserOptions: {
204
- // faster linting on cli
205
- // https://github.com/typescript-eslint/typescript-eslint/issues/3528
206
- // turned off because @typescript-eslint/no-unsafe-* rules will output wrong errors
207
- // allowAutomaticSingleRunInference: true,
208
- project: ['./tsconfig*.json', './packages/*/tsconfig*.json'],
209
- },
210
- settings: {
211
- 'import/resolver': {
212
- typescript: true,
213
- },
214
- },
215
- plugins: [
216
- '@typescript-eslint/eslint-plugin',
217
- 'eslint-plugin-deprecation',
218
- 'eslint-plugin-functional',
219
- ],
220
- rules: {
221
- // extend existing rule
222
- '@typescript-eslint/ban-types': [
223
- 'error',
224
- {
225
- types: {
226
- // TypeScript team suggests to use `<T extends {}>` https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/#unconstrained-generics-no-longer-assignable-to
227
- '{}': false,
228
- },
229
- extendDefaults: true,
230
- },
231
- ],
232
- // separate type exports which allow certain optimizations within compilers
233
- '@typescript-eslint/consistent-type-exports': 'error',
234
- '@typescript-eslint/consistent-type-imports': [
235
- 'error',
236
- {
237
- // separate type imports which allow certain optimizations within compilers
238
- prefer: 'type-imports',
239
- },
240
- ],
241
- // disable the base rule as it can report incorrect errors, use @typescript-eslint/dot-notation instead
242
- 'dot-notation': 'off',
243
- // only allow indexed syntax (e.g. `obj['key']`) for accessing undefined fields
244
- '@typescript-eslint/dot-notation': [
245
- 'error',
246
- {
247
- allowIndexSignaturePropertyAccess: true,
248
- },
249
- ],
250
- // encourage to use private accessibility modifier
251
- '@typescript-eslint/explicit-member-accessibility': [
252
- 'error',
253
- {
254
- accessibility: 'explicit',
255
- },
256
- ],
257
- // sometimes auto detect can provide a better and narrower type
258
- '@typescript-eslint/explicit-module-boundary-types': 'off',
259
- // disallow duplicated value in enum as it is error-prone
260
- '@typescript-eslint/no-duplicate-enum-values': 'error',
261
- // need empty function for react context default value
262
- '@typescript-eslint/no-empty-function': 'off',
263
- // encourage to check error type before use in catch clauses
264
- '@typescript-eslint/no-implicit-any-catch': 'error',
265
- // 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
266
- '@typescript-eslint/no-import-type-side-effects': 'error',
267
- // enforce correct usage of `void` type
268
- '@typescript-eslint/no-invalid-void-type': 'error',
269
- // allow using async function as event handler in frontend
270
- '@typescript-eslint/no-misused-promises': [
271
- 'error',
272
- { checksVoidReturn: false },
273
- ],
274
- // declaration merging between classes and interfaces is unsafe
275
- '@typescript-eslint/no-unsafe-declaration-merging': 'error',
276
- // do not block functions referring to other functions
277
- '@typescript-eslint/no-use-before-define': [
278
- 'error',
279
- {
280
- /* options from eslint/no-use-before-define */
281
- // allow use function before defined as they could be hoisted
282
- functions: false,
283
- classes: true,
284
- variables: true,
285
-
286
- /* options from @typescript-eslint/no-use-before-define */
287
- enums: true,
288
- // confusing option, it will disable `typedefs`
289
- ignoreTypeReferences: false,
290
- // tsc allows types to be used before define
291
- typedefs: false,
292
- },
293
- ],
294
- // use with functional/prefer-readonly-type
295
- // mark class variables as readonly if it is not mutated
296
- '@typescript-eslint/prefer-readonly': 'error',
297
- // make sure functions which return a promise will just return a rejected promise instead of throwing an error
298
- '@typescript-eslint/promise-function-async': 'error',
299
- // allow primitive value in template string
300
- '@typescript-eslint/restrict-template-expressions': [
301
- 'error',
302
- {
303
- allowNumber: true,
304
- allowBoolean: true,
305
- allowAny: true, // mistakenly recognize string as any in 4.29.3
306
- allowNullish: true,
307
- allowRegExp: true,
308
- },
309
- ],
310
- // avoid missed switch-case by requiring switch-case statements to be exhaustive with union type
311
- '@typescript-eslint/switch-exhaustiveness-check': 'error',
312
- // ignore static function as those are not supposed to use `this`
313
- '@typescript-eslint/unbound-method': [
314
- 'error',
315
- { ignoreStatic: true },
316
- ],
317
- // do not allow usage of deprecated code
318
- 'deprecation/deprecation': 'error',
319
- // use with @typescript-eslint/prefer-readonly
320
- 'functional/prefer-readonly-type': [
321
- 'error',
322
- {
323
- // sometimes it is easier to mutate, it should be fine to mutate within local scope
324
- allowLocalMutation: true,
325
- // don't force library consumer to use readonly type
326
- allowMutableReturnType: true,
327
- // allow mutating class variables
328
- ignoreClass: 'fieldsOnly',
329
- },
330
- ],
331
- // forbid unnecessary callback wrapper
332
- 'functional/prefer-tacit': 'error',
333
- 'no-restricted-syntax': [
334
- 'error',
335
- {
336
- // 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
337
- selector:
338
- ':matches(PropertyDefinition, MethodDefinition, TSParameterProperty)[accessibility="private"]:not([kind="constructor"])',
339
- message:
340
- 'Use #private instead (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields)',
341
- },
342
- ],
343
- // @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
344
- // 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
345
- 'no-undef': 'error',
346
- },
347
- overrides: [
348
- {
349
- files: testFileGlobs,
350
- rules: {
351
- // doesn't work with jest.fn<void>()
352
- '@typescript-eslint/no-invalid-void-type': 'off',
353
- // replace by jest/unbound-method
354
- '@typescript-eslint/unbound-method': 'off',
355
- // allow passing an unbound method to `expect` calls
356
- 'jest/unbound-method': ['error', { ignoreStatic: true }],
357
- },
358
- },
359
- ],
360
- },
361
- ]
362
- : []),
363
- ],
364
- }
@@ -1,22 +0,0 @@
1
- 'use strict'
2
-
3
- const restrictedGlobals = require('confusing-browser-globals')
4
-
5
- /** @type {import('eslint').Linter.Config} */
6
- module.exports = {
7
- extends: ['plugin:compat/recommended'],
8
- plugins: ['eslint-plugin-compat'],
9
- env: {
10
- browser: true,
11
- webextensions: true,
12
- },
13
- globals: {
14
- // keep it until webpack has an official way to define env: https://github.com/webpack/webpack/issues/15833
15
- process: 'readonly',
16
- },
17
- rules: {
18
- 'no-restricted-globals': ['error', ...restrictedGlobals],
19
- // frontend environment doesn't support node.js modules
20
- 'import/no-nodejs-modules': 'error',
21
- },
22
- }
package/presets/node.cjs DELETED
@@ -1,61 +0,0 @@
1
- 'use strict'
2
-
3
- // @ts-expect-error
4
- const { isESM } = require('@foray1010/common-presets-utils')
5
-
6
- /** @type {import('eslint').Linter.BaseConfig} */
7
- const cjsConfig = {
8
- globals: {
9
- __dirname: 'readonly',
10
- __filename: 'readonly',
11
- },
12
- }
13
-
14
- /** @type {import('eslint').Linter.Config} */
15
- module.exports = {
16
- plugins: ['eslint-plugin-n'],
17
- globals: {
18
- // hack to mute no-undef error, and show n/prefer-global/buffer error instead
19
- Buffer: 'readonly',
20
- // hack to mute no-undef error, and show n/prefer-global/process error instead
21
- process: 'readonly',
22
- },
23
- rules: {
24
- // disallow deprecated node APIs
25
- 'n/no-deprecated-api': 'error',
26
- // disallow the assignment to `exports`
27
- 'n/no-exports-assign': 'error',
28
- // disallow `bin` files that npm ignores
29
- 'n/no-unpublished-bin': 'error',
30
- // disallow unsupported Node.js built-in APIs on the specified version
31
- 'n/no-unsupported-features/node-builtins': 'error',
32
- // prefer `import { Buffer } from 'node:buffer'` as it is not isomorphic
33
- 'n/prefer-global/buffer': ['error', 'never'],
34
- // prefer global `console` to be isomorphic
35
- 'n/prefer-global/console': ['error', 'always'],
36
- // prefer `import process from 'node:process'` as it is not isomorphic
37
- 'n/prefer-global/process': ['error', 'never'],
38
- // prefer global `TextDecoder` to be isomorphic
39
- 'n/prefer-global/text-decoder': ['error', 'always'],
40
- // prefer global `TextEncoder` to be isomorphic
41
- 'n/prefer-global/text-encoder': ['error', 'always'],
42
- // prefer global `URL` to be isomorphic
43
- 'n/prefer-global/url': ['error', 'always'],
44
- // prefer global `URLSearchParams` to be isomorphic
45
- 'n/prefer-global/url-search-params': ['error', 'always'],
46
- // make `process.exit()` expressions the same code path as `throw`
47
- 'n/process-exit-as-throw': 'error',
48
- // enforce shebang on the entry bin file
49
- 'n/shebang': 'error',
50
- },
51
- overrides: [
52
- {
53
- files: ['*.js'],
54
- ...(isESM() ? {} : cjsConfig),
55
- },
56
- {
57
- files: ['*.cjs', '*.cts'],
58
- ...cjsConfig,
59
- },
60
- ],
61
- }
package/presets/react.cjs DELETED
@@ -1,84 +0,0 @@
1
- 'use strict'
2
-
3
- const { testFileGlobs } = require('./utils/testUtil.cjs')
4
-
5
- /** @type {import('eslint').Linter.Config} */
6
- module.exports = {
7
- extends: [
8
- 'plugin:react/recommended',
9
- 'plugin:react/jsx-runtime',
10
- 'plugin:react-hooks/recommended',
11
- // included eslint-config-prettier
12
- 'plugin:prettier/recommended',
13
- ],
14
- parserOptions: {
15
- ecmaFeatures: {
16
- jsx: true,
17
- },
18
- },
19
- plugins: ['eslint-plugin-react', 'eslint-plugin-react-hooks'],
20
- settings: {
21
- react: {
22
- version: 'detect',
23
- },
24
- },
25
- rules: {
26
- // avoid unexpected form submits
27
- 'react/button-has-type': 'error',
28
- 'react/jsx-no-useless-fragment': [
29
- 'error',
30
- {
31
- // allow unnecessary fragment for single expression to bypass some typescript errors (e.g. do not allow string and only allow react element)
32
- allowExpressions: true,
33
- },
34
- ],
35
- 'react/jsx-sort-props': [
36
- 'error',
37
- {
38
- // any prop starts with `on`
39
- callbacksLast: true,
40
- ignoreCase: true,
41
- noSortAlphabetically: false,
42
- reservedFirst: true,
43
- shorthandFirst: false,
44
- shorthandLast: false,
45
- },
46
- ],
47
- // rely on typescript instead, and it does not work well with types that are imported from elsewhere
48
- 'react/prop-types': 'off',
49
- // avoid unnecessary closing tags
50
- 'react/self-closing-comp': 'error',
51
- 'react-hooks/exhaustive-deps': [
52
- 'error',
53
- {
54
- // support package `use-deep-compare`
55
- additionalHooks:
56
- '(useDeepCompareCallback|useDeepCompareEffect|useDeepCompareMemo)',
57
- },
58
- ],
59
- },
60
- overrides: [
61
- {
62
- files: testFileGlobs,
63
- extends: ['plugin:jest-dom/recommended', 'plugin:testing-library/react'],
64
- plugins: ['eslint-plugin-jest-dom', 'eslint-plugin-testing-library'],
65
- rules: {
66
- // avoid using unnecessary `await` as workaround for `not wrapped in act(...)` warnings
67
- 'testing-library/no-await-sync-events': [
68
- 'error',
69
- {
70
- eventModules: ['fire-event'],
71
- },
72
- ],
73
- // global flag /g holds state and might cause false-positives while querying for elements
74
- 'testing-library/no-global-regexp-flag-in-query': 'error',
75
- // explicitly assert the element to prevent reader missed the test cases
76
- 'testing-library/prefer-explicit-assert': 'error',
77
- // prefer @testing-library/user-event over fireEvent
78
- 'testing-library/prefer-user-event': 'error',
79
- // as `wait` is deprecated
80
- 'testing-library/prefer-wait-for': 'error',
81
- },
82
- },
83
- ],
84
- }
package/react.cjs DELETED
@@ -1,9 +0,0 @@
1
- 'use strict'
2
-
3
- module.exports = {
4
- extends: [
5
- './presets/base.cjs',
6
- './presets/browser.cjs',
7
- './presets/react.cjs',
8
- ],
9
- }