eslint-config-beslogic 3.0.2 → 3.1.1

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
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.1
4
+
5
+ - Turned on `"objectLiteralTypeAssertions": "allow-as-parameter"` as error for `@typescript-eslint/consistent-type-assertions` in extra-strict config
6
+ - Enabled `@typescript-eslint/consistent-type-assertions` (but without the "as parameter" restriction) for Jest
7
+ - Added `boolean` and `nullish` to `@typescript-eslint/restrict-template-expressions` in `extra-strict` preset
8
+ If you really meant to write "true", "false", "null" or "undefined", then explicitly stringify it using `String()` (or `Intl.ListFormat` for `Array`s)
9
+ - Disabled `default-case` rule in TypeScript as it is redundant with `@typescript-eslint/switch-exhaustiveness-check` and conflicts with `unicorn/no-useless-switch-case`
10
+ - Bumped `eslint-plugin-sonarjs` to `2.0.4`
11
+ - Stopped attempting to support pre-commit.ci. Read the [`PR Autofixes`](https://github.com/BesLogic/shared-configs/blob/main/README.md#pr-autofixes) section of our Shared Configs for an explanation and alternatives.
12
+
3
13
  ## 3.0.2
4
14
 
5
15
  - Made `eslint-plugin-sonarjs` optional for pre-commit.ci contexts
package/README.md CHANGED
@@ -17,7 +17,7 @@ These are configuration files you'll have to update manually to best work with t
17
17
 
18
18
  ### `package.json`
19
19
 
20
- Read the [`package.json`](https://github.com/BesLogic/shared-configs#packagejson-for-dprint-and-eslint) section of our Shared Configs for one-liner shortcut scripts you can use.
20
+ Read the [`package.json`](https://github.com/BesLogic/shared-configs/blob/main/README.md#packagejson) section of our Shared Configs for one-liner shortcut scripts you can use.
21
21
 
22
22
  ### Base `tsconfig.json`
23
23
 
@@ -61,60 +61,10 @@ If you'd like to pin your config version, you can use a commit hash, like `https
61
61
 
62
62
  If also using [`beslogic/json-like` preset](#beslogicjson-like) extend from `https://raw.githubusercontent.com/BesLogic/shared-configs/main/dprint-json-like.json` instead.
63
63
 
64
- ### Usage with `pre-commit.ci` (`.pre-commit-config.yaml`)
64
+ ### PR Autofixes
65
65
 
66
- <!-- Use the following hook: <https://github.com/pre-commit/mirrors-eslint>
67
- Set `args: [--ignore-path, .gitignore, --fix, --quiet]`.\
68
- For mono-repos, specify your frontend project: `args: [frontend_project, --ignore-path, frontend_project/.gitignore, --fix, --quiet]`.
69
- -->
70
-
71
- ```yaml
72
- repos:
73
- - repo: local
74
- hooks:
75
- - id: eslint
76
- name: eslint
77
- language: node
78
- # To run at root
79
- entry: npm run eslint -- --fix --quiet
80
- # To run in specific project (for monorepos)
81
- entry: bash -c 'cd frontend_project && npm run eslint -- --fix --quiet'
82
- files: \.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx
83
- types: [file]
84
- pass_filenames: false
85
- additional_dependencies: [...]
86
- ```
87
-
88
- In the `additional_dependencies` field, you'll need to include _all_ the plugins we use (copy this project's `dependencies` in `package.json`), as well as the optional plugins you need for yor presets.
89
-
90
- As you'll easily bust the 250MiB limit on the free tier, omit the following dependencies as they're special-cased to always be ignored on `pre-commit.ci` anyway:
91
-
92
- - `dprint`
93
- - `@eslint-community/eslint-plugin-eslint-comments`
94
- - `esling-plugin-no-autofix`
95
- - `eslint-import-resolver-typescript`
96
- - `eslint-plugin-etc`
97
- - `eslint-plugin-jest-formatting`
98
- - `eslint-plugin-jest`
99
- - `eslint-plugin-sonarjs`
100
- - `eslint-plugin-testing-library`
101
-
102
- If using TypeScript and pre-commit.ci, in your ESLint config you'll _have to_ use the project service, or you'll run into OOM issues:
103
-
104
- ```js
105
- /** @type {import("eslint").Linter.Config} */
106
- module.exports = {
107
- parser: "@typescript-eslint/parser",
108
- parserOptions: {
109
- projectService: {
110
- allowDefaultProject: []
111
- },
112
- // Still needed for plugins that haven't updated to typescript-eslint@8 yet
113
- // Namely: eslint-plugin-sonarjs
114
- EXPERIMENTAL_useProjectService: true
115
- }
116
- }
117
- ```
66
+ We've stopped attempting to support pre-commit.ci.\
67
+ Read the [`PR Autofixes`](https://github.com/BesLogic/shared-configs/blob/main/README.md#pr-autofixes) section of our Shared Configs for an explanation and alternatives.
118
68
 
119
69
  ## Patched packages
120
70
 
@@ -50,7 +50,6 @@
50
50
  "sonarjs/media-has-caption": "error",
51
51
  "sonarjs/misplaced-loop-counter": "error",
52
52
  "sonarjs/mouse-events-a11y": "error",
53
- "sonarjs/new-cap": "error",
54
53
  "sonarjs/new-operator-misuse": "error",
55
54
  "sonarjs/no-accessor-field-mismatch": "error",
56
55
  "sonarjs/no-all-duplicated-branches": "error",
package/angular.js CHANGED
@@ -1,16 +1,10 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  // Copyright 2024 Beslogic Inc.
3
3
 
4
- const { getModuleVersion, jestNoRestrictedSyntax, jestFilePatterns, resolveModuleLocation } =
5
- require("./lib/utils")
4
+ const { getModuleVersion, jestNoRestrictedSyntax, jestFilePatterns } = require("./lib/utils")
6
5
 
7
6
  const angularEslintVersion = getModuleVersion("@angular-eslint/eslint-plugin", 16.2)
8
7
  const typescriptVersion = getModuleVersion("typescript", 4.7)
9
- const hasTestingLibrary = !!resolveModuleLocation("eslint-plugin-testing-library")
10
- // eslint-plugin-no-autofix is broken when run through pre-commit
11
- // https://github.com/aladdin-add/eslint-plugin/issues/98
12
- // Even if it gets fixed, `no-autofix` rules necessarily don't provide fixes anyway
13
- const hasNoAutofix = !!resolveModuleLocation("eslint-plugin-no-autofix")
14
8
 
15
9
  const javascriptConfig = require("./javascript")
16
10
  const typescriptConfig = require("./typescript")
@@ -81,9 +75,7 @@ module.exports = {
81
75
  "overrides": [
82
76
  {
83
77
  "files": ["*.html"],
84
- "plugins": hasNoAutofix
85
- ? ["no-autofix"]
86
- : [],
78
+ "plugins": ["no-autofix"],
87
79
  "extends": ["plugin:@angular-eslint/template/all"],
88
80
  "rules": {
89
81
  "@angular-eslint/template/click-events-have-key-events": "off",
@@ -331,9 +323,7 @@ module.exports = {
331
323
  },
332
324
  {
333
325
  "files": jestFilePatterns,
334
- "extends": hasTestingLibrary
335
- ? ["plugin:testing-library/angular"]
336
- : [],
326
+ "extends": ["plugin:testing-library/angular"],
337
327
  "rules": { "no-restricted-syntax": jestNoRestrictedSyntax(noRestrictedSyntax) }
338
328
  },
339
329
  {
package/extra-strict.js CHANGED
@@ -1,9 +1,18 @@
1
- const { isPreCommitCI, resolveModuleLocation } = require("./lib/utils")
1
+ const { resolveModuleLocation, jestFilePatterns } = require("./lib/utils")
2
2
 
3
- const hasEtc = !!resolveModuleLocation("eslint-plugin-etc")
4
- const hasNoAutofix = !!resolveModuleLocation("eslint-plugin-no-autofix")
3
+ // TODO: ADD no-unsafe-type-assertion ONCE IT'S PUBLISHED ! (and the message I used to include)
4
+ // (remove from non-strict, add back here, then re-disable for jest at the bottom of the file)
5
+ // https://github.com/typescript-eslint/typescript-eslint/pull/10051
6
+ // https://github.com/typescript-eslint/typescript-eslint/issues/7173
7
+
8
+ // These extra strict configs are not only for Angular. User may be using a different framework
5
9
  const hasAngularEslintTemplate = !!resolveModuleLocation("@angular-eslint/eslint-plugin-template")
6
10
 
11
+ const typeScriptConfig = require("./typescript")
12
+
13
+ const restrictTemplateExpressionsConfig = typeScriptConfig.overrides?.[0].rules
14
+ ?.["@typescript-eslint/restrict-template-expressions"]?.[1]
15
+
7
16
  /** @type {import("eslint").Linter.Config} */
8
17
  module.exports = {
9
18
  "overrides": [
@@ -16,13 +25,9 @@ module.exports = {
16
25
  /*
17
26
  * Cartant's etc rules
18
27
  */
19
- "etc/no-commented-out-code": hasEtc
20
- ? "error"
21
- : "off",
28
+ "etc/no-commented-out-code": "error",
22
29
  "sonarjs/no-commented-code": "off",
23
- "etc/no-enum": hasEtc
24
- ? "warn" // warn instead of error, not as problematic as of TS 5
25
- : "off",
30
+ "etc/no-enum": "warn", // warn instead of error, not as problematic as of TS 5
26
31
 
27
32
  // This is caught when noImplicitThis is enabled, which we assume in this config
28
33
  // https://typescript-eslint.io/rules/no-invalid-this/
@@ -36,7 +41,8 @@ module.exports = {
36
41
  * (copied from https://dev.azure.com/Beslogic/Beslogic%20Architecture%20Reference/_wiki/wikis/Beslogic-Architecture-Reference.wiki/656/Frontend-linting-and-formatting?anchor=total-functions/no-unsafe-type-assertion)
37
42
  * It can sometimes be hard to make sense of this rule, but let's be strict!
38
43
  * Tips:
39
- * - Prefer coercion over assertion: `String(value ?? '')` over `value as string | null`
44
+ * - Prefer coercion over assertion: e.g `String(value ?? '')` over `value as string | null`
45
+ * (this depends on your functional logic)
40
46
  * - Try to assign to an explicitly typed variable and TypeScript will tell you about the type difference!
41
47
  * ie: `const newValue: ExpectedType = unsafeValue`
42
48
  * - If using TypeScript 4.9+, consider using the `satisfies` Operator:
@@ -44,19 +50,30 @@ module.exports = {
44
50
  * `const newValue = {a: "A", b: 2} satisfies ExpectedType`
45
51
  * - If using TypeScript 4.9+, consider using the `in` Operator to narrow unlisted properties:
46
52
  * (https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#unlisted-property-narrowing-with-the-in-operator)
47
- * `if ("name" in unsafeValue&& typeof unsafeValue.name === "string") ...`
53
+ * `if ("name" in unsafeValue && typeof unsafeValue.name === "string") ...`
48
54
  * - Sometimes just casting as `Partial<>` is sufficient
49
55
  * - Double check that you are not accidentally removing `null | undefined` from the type when casting:
50
56
  * - `inputEvent.target as Partial<HTMLInputElement>` <-- Oops!
51
57
  * - `event.target as Partial<HTMLInputElement> | null` <-- Ok!
52
58
  */
53
- "no-autofix/@typescript-eslint/consistent-type-assertions": [
54
- hasNoAutofix
55
- ? "warn"
56
- : "off",
59
+ "@typescript-eslint/consistent-type-assertions": [
60
+ "error",
57
61
  { "assertionStyle": "as", "objectLiteralTypeAssertions": "allow-as-parameter" }
58
62
  ],
59
63
 
64
+ "@typescript-eslint/restrict-template-expressions": [
65
+ "error",
66
+ {
67
+ ...restrictTemplateExpressionsConfig,
68
+ // Writing "false", "null" or "undefined" may not be intended in a string
69
+ // for example: className={`form-control ${form?.errors && 'invalid'} `}
70
+ // If this is really intended, then stringify it using String()
71
+ // (or Intl.ListFormat for Arrays)
72
+ "allowBoolean": false,
73
+ "allowNullish": false
74
+ }
75
+ ],
76
+
60
77
  /*
61
78
  * @typescript-eslint rules that require strictNullChecks
62
79
  * These requires stricter tsconfig or fails.
@@ -65,9 +82,7 @@ module.exports = {
65
82
  // Setting allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing makes this rule useless on
66
83
  // null/undefined checks. So only set it in non-strict preset.
67
84
  "@typescript-eslint/no-unnecessary-condition": [
68
- isPreCommitCI
69
- ? "off" // Missing types lead to false-positives
70
- : "error",
85
+ "error",
71
86
  { "allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing": false }
72
87
  ],
73
88
  "@typescript-eslint/prefer-nullish-coalescing": "error",
@@ -88,7 +103,7 @@ module.exports = {
88
103
  "@angular-eslint/template/i18n": "off",
89
104
  "no-autofix/@angular-eslint/template/i18n": [
90
105
  // Too many TODO and needs per-project extensions to justify this as "error"
91
- hasNoAutofix && hasAngularEslintTemplate
106
+ hasAngularEslintTemplate
92
107
  ? "warn"
93
108
  : "off",
94
109
  {
@@ -133,6 +148,16 @@ module.exports = {
133
148
  }
134
149
  ]
135
150
  }
151
+ },
152
+ {
153
+ "files": jestFilePatterns,
154
+ "rules": {
155
+ // Allow fake types in tests, back to default config of allowing everywhere
156
+ "@typescript-eslint/consistent-type-assertions": [
157
+ "error",
158
+ { "assertionStyle": "as", "objectLiteralTypeAssertions": "allow" }
159
+ ]
160
+ }
136
161
  }
137
162
  ]
138
163
  }
package/javascript.js CHANGED
@@ -5,22 +5,9 @@ const restrictedGlobals = require("confusing-browser-globals")
5
5
  const {
6
6
  jestNoRestrictedSyntax,
7
7
  jestFilePatterns,
8
- resolveModuleLocation,
9
- idLenghtConfig,
10
- isPreCommitCI
8
+ idLenghtConfig
11
9
  } = require("./lib/utils")
12
10
 
13
- // eslint-plugin-no-autofix is broken when run through pre-commit
14
- // https://github.com/aladdin-add/eslint-plugin/issues/98
15
- // Even if it gets fixed, `no-autofix` rules necessarily don't provide fixes anyway
16
- const hasNoAutofix = !!resolveModuleLocation("eslint-plugin-no-autofix")
17
- // @eslint-community/eslint-comments' only autofix is removing unused suppression comments
18
- // Some rules get globally disabled for pre-commit.ci, so finding unused comments is expected
19
- const hasEslintComments = !!resolveModuleLocation("@eslint-community/eslint-plugin-eslint-comments")
20
- // eslint-plugin-sonarjs@2 pulls in a ton of extra dependnecies we don't need
21
- // https://community.sonarsource.com/t/warning-react-version-not-specified-in-eslint-plugin-react/125412/11?u=avasam
22
- const hasSonarJS = !!resolveModuleLocation("eslint-plugin-sonarjs")
23
-
24
11
  const noRestrictedSyntax = [
25
12
  "error",
26
13
  "WithStatement",
@@ -46,24 +33,18 @@ module.exports = {
46
33
  "plugins": [
47
34
  "@stylistic",
48
35
  "extra-rules",
49
- ...hasNoAutofix
50
- ? ["no-autofix"]
51
- : [],
36
+ "no-autofix",
52
37
  "no-relative-import-paths",
53
38
  "prefer-arrow",
54
39
  "simple-import-sort"
55
40
  ],
56
41
  "extends": [
57
42
  "eslint:recommended",
58
- ...hasSonarJS
59
- ? ["plugin:sonarjs/recommended-legacy"] // "legacy" is for ESLint v8 compatibility
60
- : [],
43
+ "plugin:sonarjs/recommended-legacy", // "legacy" is for ESLint v8 compatibility
61
44
  "plugin:unicorn/all",
62
45
  "plugin:regexp/all",
63
46
  "plugin:import/recommended",
64
- ...hasEslintComments
65
- ? ["plugin:@eslint-community/eslint-comments/recommended"]
66
- : []
47
+ "plugin:@eslint-community/eslint-comments/recommended"
67
48
  ],
68
49
  "env": {
69
50
  // https://eslint.org/docs/v8.x/use/configure/language-options#specifying-environments
@@ -245,9 +226,7 @@ module.exports = {
245
226
  ],
246
227
  // Using this to completely disallow all console calls except info, warn, error
247
228
  "no-autofix/no-console": [
248
- hasNoAutofix
249
- ? "error"
250
- : "off",
229
+ "error",
251
230
  {
252
231
  "allow": [
253
232
  "info",
@@ -261,14 +240,12 @@ module.exports = {
261
240
  * @eslint-community/eslint-comments/recommended overrides (https://eslint-community.github.io/eslint-plugin-eslint-comments/rules)
262
241
  */
263
242
  // TODO: Move back to "all files" once HTML parsing crash is fixed https://github.com/eslint-community/eslint-plugin-eslint-comments/issues/162
264
- "@eslint-community/eslint-comments/disable-enable-pair": hasEslintComments
265
- ? [
266
- "error",
267
- {
268
- "allowWholeFile": true
269
- }
270
- ]
271
- : "off"
243
+ "@eslint-community/eslint-comments/disable-enable-pair": [
244
+ "error",
245
+ {
246
+ "allowWholeFile": true
247
+ }
248
+ ]
272
249
  }
273
250
  },
274
251
  {
@@ -312,52 +289,41 @@ module.exports = {
312
289
  }
313
290
  ],
314
291
  "rules": {
315
- ...hasEslintComments
316
- ? {
317
- /*
318
- * @eslint-community/eslint-comments/recommended overrides (https://eslint-community.github.io/eslint-plugin-eslint-comments/rules)
319
- */
320
- "@eslint-community/eslint-comments/no-unused-disable": "error",
321
- "@eslint-community/eslint-comments/require-description": [
322
- "error",
323
- {
324
- "ignore": ["eslint-enable"]
325
- }
326
- ]
292
+ /*
293
+ * @eslint-community/eslint-comments/recommended overrides (https://eslint-community.github.io/eslint-plugin-eslint-comments/rules)
294
+ */
295
+ "@eslint-community/eslint-comments/no-unused-disable": "error",
296
+ "@eslint-community/eslint-comments/require-description": [
297
+ "error",
298
+ {
299
+ "ignore": ["eslint-enable"]
327
300
  }
328
- : {},
301
+ ],
329
302
 
330
- ...hasSonarJS
331
- ? {
332
- /*
333
- * sonarjs/recommended overrides (https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md#rules)
334
- */
335
- // Same as eslint (cyclomatic) complexity
336
- // This is also based on the fact that react-app service workers template hits this
337
- "sonarjs/cognitive-complexity": [
338
- "warn",
339
- 20
340
- ],
341
- // False-positives with top-level Promises (and maybe more, but that was enough for me ot disable)
342
- "sonarjs/constructor-for-side-effects": "off",
343
- "sonarjs/deprecation": "warn",
344
- "sonarjs/no-duplicate-string": "error",
345
- // Duplicates etc/no-commented-out-code. But is faster but also catches less.
346
- // Incidentally this is good for a non-strict config.
347
- "sonarjs/no-commented-code": "error",
348
- // Too annoying, let us use our lovely PATH :)
349
- "sonarjs/no-os-command-from-path": "off",
350
- // Too annoying, consider maybe for an extra-strict
351
- // but JS doesn't have kw params unlike Python
352
- "sonarjs/no-selector-parameter": "off",
353
- // Is default, but let's note that this option replaced `eslint-plugin-unused-imports` entirely,
354
- // so if there's an issue, we can always go back.
355
- "sonarjs/unused-import": "error",
356
- // TODO: Raise an issue. Also mention that online doc examples sees to be inverted
357
- // False-positives using Intl.DateTimeFormat()
358
- "sonarjs/new-cap": "off"
359
- }
360
- : {},
303
+ /*
304
+ * sonarjs/recommended overrides (https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md#rules)
305
+ */
306
+ // Same as eslint (cyclomatic) complexity
307
+ // This is also based on the fact that react-app service workers template hits this
308
+ "sonarjs/cognitive-complexity": [
309
+ "warn",
310
+ 20
311
+ ],
312
+ // False-positives with top-level Promises (and maybe more, but that was enough for me to disable)
313
+ "sonarjs/constructor-for-side-effects": "off",
314
+ "sonarjs/deprecation": "warn",
315
+ "sonarjs/no-duplicate-string": "error",
316
+ // Duplicates etc/no-commented-out-code. But is faster but also catches less.
317
+ // Incidentally this is good for a non-strict config.
318
+ "sonarjs/no-commented-code": "error",
319
+ // Too annoying, let us use our lovely PATH :)
320
+ "sonarjs/no-os-command-from-path": "off",
321
+ // Too annoying, consider maybe for an extra-strict
322
+ // but JS doesn't have keyword-only params, unlike Python
323
+ "sonarjs/no-selector-parameter": "off",
324
+ // Is default, but let's note that this option replaced `eslint-plugin-unused-imports` entirely,
325
+ // so if there's an issue, we can always go back.
326
+ "sonarjs/unused-import": "error",
361
327
 
362
328
  /*
363
329
  * eslint-plugin-sonarjs@2 added rules that duplicate base ESLint rules or specific plugins we prefer
@@ -372,6 +338,7 @@ module.exports = {
372
338
  // Base ESLint rules duplications (same names)
373
339
 
374
340
  "sonarjs/default-param-last": "off",
341
+ "sonarjs/new-cap": "off",
375
342
  "sonarjs/no-delete-var": "off",
376
343
  "sonarjs/no-empty-function": "off",
377
344
  "sonarjs/no-extend-native": "off",
@@ -482,9 +449,7 @@ module.exports = {
482
449
 
483
450
  // Extracted restricted import into its own rule so it's easier for projects to override/ignore
484
451
  "no-autofix/no-relative-import-paths/no-relative-import-paths": [
485
- hasNoAutofix
486
- ? "error"
487
- : "off",
452
+ "error",
488
453
  {
489
454
  "allowSameFolder": true
490
455
  }
@@ -530,9 +495,7 @@ module.exports = {
530
495
  "unicorn/no-null": "off",
531
496
  // This rule has been deprecated in favor of eslint-plugin-regexp
532
497
  "unicorn/no-unsafe-regex": "off",
533
- "unicorn/no-useless-undefined": isPreCommitCI
534
- ? "off" // Missing types lead to false-positives
535
- : "error",
498
+ "unicorn/no-useless-undefined": "error",
536
499
  "unicorn/numeric-separators-style": "error",
537
500
  "unicorn/prefer-add-event-listener": "error",
538
501
  "unicorn/prefer-array-find": [
@@ -624,9 +587,7 @@ module.exports = {
624
587
  // Autofixing is only applied when only checking for `singleReturnOnly: true`
625
588
  // but we still want to check for other cases
626
589
  "no-autofix/prefer-arrow/prefer-arrow-functions": [
627
- hasNoAutofix
628
- ? "error"
629
- : "off",
590
+ "error",
630
591
  {
631
592
  "classPropertiesAllowed": true,
632
593
  "disallowPrototype": true,
@@ -863,9 +824,7 @@ module.exports = {
863
824
  // HACK: Workaround for coordinates objects
864
825
  // TODO: Should be using rule composition instead
865
826
  "no-autofix/id-length": [
866
- hasNoAutofix
867
- ? "error"
868
- : "off",
827
+ "error",
869
828
  idLenghtConfig
870
829
  ],
871
830
  "no-empty-function": "error",
package/jest.js CHANGED
@@ -1,41 +1,22 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  // Copyright 2024 Beslogic Inc.
3
- const { getModuleVersion, resolveModuleLocation } = require("./lib/utils")
3
+ const { getModuleVersion } = require("./lib/utils")
4
4
 
5
5
  const jestGlobalsVersion = getModuleVersion("@jest/globals", 29)
6
- // These are big modules for pre-commit.
7
- // Outside of pre-commit, these should NOT be considered optional !
8
- const hasTestingLibrary = !!resolveModuleLocation("eslint-plugin-testing-library")
9
- const hasJestFormatting = !!resolveModuleLocation("eslint-plugin-jest-formatting")
10
- const hasJest = !!resolveModuleLocation("eslint-plugin-jest")
11
- // eslint-plugin-sonarjs@2 pulls in a ton of extra dependnecies we don't need
12
- // https://community.sonarsource.com/t/warning-react-version-not-specified-in-eslint-plugin-react/125412/11?u=avasam
13
- const hasSonarJS = !!resolveModuleLocation("eslint-plugin-sonarjs")
14
6
 
15
7
  /** @type {import("eslint").Linter.Config} */
16
8
  module.exports = {
17
9
  "extends": [
18
- ...hasJest
19
- ? ["plugin:jest/all"]
20
- : [],
21
- ...hasJestFormatting
22
- ? ["plugin:jest-formatting/strict"]
23
- : [],
10
+ "plugin:jest/all",
11
+ "plugin:jest-formatting/strict",
24
12
  // Note: The DOM preset includes some rules not in Marko or Vue (eg.: no-await-sync-events).
25
13
  // Those must be disabled in their preset if we ever support them.
26
- ...hasTestingLibrary
27
- ? ["plugin:testing-library/dom"]
28
- : []
14
+ "plugin:testing-library/dom"
29
15
  ],
30
16
  "env": {
31
17
  "browser": false,
32
18
  "jest": true,
33
- ...hasJest
34
- ? {
35
- // Setting to `false` is not enough: Environment key "jest/globals" is unknown
36
- "jest/globals": true
37
- }
38
- : {}
19
+ "jest/globals": true
39
20
  },
40
21
  "overrides": [
41
22
  {
@@ -62,8 +43,6 @@ module.exports = {
62
43
  ]
63
44
  }
64
45
  ],
65
- // Allow fake types in tests
66
- "no-autofix/@typescript-eslint/consistent-type-assertions": "off",
67
46
  // We can mock functions as empty
68
47
  "no-empty-function": "off",
69
48
  "@typescript-eslint/no-empty-function": "off",
@@ -76,66 +55,55 @@ module.exports = {
76
55
  "@typescript-eslint/no-unsafe-call": "off",
77
56
  // Allow printing "as-is" in tests
78
57
  "@typescript-eslint/restrict-template-expressions": "off",
79
- ...hasSonarJS
80
- ? {
81
- // Higher requirements for tests since we like being explicit
82
- // Arbitrary same as max-params (+1 because this is exclusive)
83
- "sonarjs/no-duplicate-string": [
84
- "error",
85
- { "threshold": 8 }
86
- ],
87
- // We could bump it higher than 4, but doc doesn't provide its config
88
- // So disabling since fluent tests are nested functions
89
- // (same comment in jsx)
90
- "sonarjs/no-nested-functions": "off"
91
- }
92
- : {},
58
+
59
+ // Higher requirements for tests since we like being explicit
60
+ // Arbitrary same as max-params (+1 because this is exclusive)
61
+ "sonarjs/no-duplicate-string": [
62
+ "error",
63
+ { "threshold": 8 }
64
+ ],
65
+ // We could bump it higher than 4, but doc doesn't provide its config
66
+ // So disabling since fluent tests are nested functions
67
+ // (same comment in jsx)
68
+ "sonarjs/no-nested-functions": "off",
93
69
 
94
70
  /*
95
71
  * jest/all overrides (https://github.com/jest-community/eslint-plugin-jest#rules)
96
72
  */
97
- ...hasJest
98
- ? {
99
- // Doesn't print well with testing-library's `findBy` and `waitFor`
100
- "jest/prefer-expect-resolves": "off",
101
- // May lead to accidentally missed expects
102
- "jest/prefer-expect-assertions": [
103
- "error",
104
- {
105
- "onlyFunctionsWithExpectInCallback": true,
106
- "onlyFunctionsWithExpectInLoop": true
107
- }
108
- ],
109
- // https://github.com/jestjs/jest/issues/15084
110
- // Since this will require a major jest version bump anyway,
111
- // I feel confortable not waiting for our own major version bump to add this
112
- ...jestGlobalsVersion < 30
113
- ? { "jest/prefer-importing-jest-globals": "off" }
114
- : {},
115
- // Top-level describe is often used for component name, which is capitalized
116
- "jest/prefer-lowercase-title": [
117
- "error",
118
- { "ignoreTopLevelDescribe": true }
119
- ],
120
- // Allow clearing mocks in beforeEach
121
- "jest/no-hooks": [
122
- "error",
123
- {
124
- "allow": ["beforeEach"]
125
- }
126
- ]
73
+ // Doesn't print well with testing-library's `findBy` and `waitFor`
74
+ "jest/prefer-expect-resolves": "off",
75
+ // May lead to accidentally missed expects
76
+ "jest/prefer-expect-assertions": [
77
+ "error",
78
+ {
79
+ "onlyFunctionsWithExpectInCallback": true,
80
+ "onlyFunctionsWithExpectInLoop": true
127
81
  }
82
+ ],
83
+ // https://github.com/jestjs/jest/issues/15084
84
+ // Since this will require a major jest version bump anyway,
85
+ // I feel confortable not waiting for our own major version bump to add this
86
+ ...jestGlobalsVersion < 30
87
+ ? { "jest/prefer-importing-jest-globals": "off" }
128
88
  : {},
89
+ // Top-level describe is often used for component name, which is capitalized
90
+ "jest/prefer-lowercase-title": [
91
+ "error",
92
+ { "ignoreTopLevelDescribe": true }
93
+ ],
94
+ // Allow clearing mocks in beforeEach
95
+ "jest/no-hooks": [
96
+ "error",
97
+ {
98
+ "allow": ["beforeEach"]
99
+ }
100
+ ],
129
101
 
130
102
  /*
131
103
  * testing-library overrides (https://github.com/testing-library/eslint-plugin-testing-library#supported-rules)
132
104
  */
133
- ...hasTestingLibrary
134
- ? {
135
- "testing-library/no-debugging-utils": "error",
136
- "testing-library/prefer-user-event": "warn",
137
- "testing-library/prefer-explicit-assert": "error"
138
- }
139
- : {}
105
+ "testing-library/no-debugging-utils": "error",
106
+ "testing-library/prefer-user-event": "warn",
107
+ "testing-library/prefer-explicit-assert": "error"
140
108
  }
141
109
  }
package/lib/utils.js CHANGED
@@ -1,5 +1,3 @@
1
- const isPreCommitCI = __dirname.startsWith("/pc/clone/")
2
-
3
1
  const getModuleVersion = (
4
2
  /** @type {string} */ nodeModule,
5
3
  /** @type {number} */ fallbackVersion
@@ -23,14 +21,7 @@ const getModuleVersion = (
23
21
 
24
22
  const resolveModuleLocation = (/** @type {string} */ nodeModule) => {
25
23
  try {
26
- const resolved = require.resolve(nodeModule)
27
- // equivalent to resolved.startsWith("/pc/clone/"))
28
- if (isPreCommitCI) {
29
- // Assume it's omitted from the pre-commit.ci run
30
- return false
31
- }
32
-
33
- return resolved
24
+ return require.resolve(nodeModule)
34
25
  } catch {
35
26
  return false
36
27
  }
@@ -86,7 +77,6 @@ module.exports = {
86
77
  getModuleVersion,
87
78
  idLenghtConfig,
88
79
  jestFilePatterns,
89
- isPreCommitCI,
90
80
  jestNoRestrictedSyntax,
91
81
  resolveModuleLocation
92
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-config-beslogic",
3
- "version": "3.0.2",
3
+ "version": "3.1.1",
4
4
  "description": "ESLint rules, plugins and configs used at Beslogic",
5
5
  "main": "index.js",
6
6
  "// dependencies": "Run for ourselves when we install dependencies w/o running npm i afterward",
@@ -35,8 +35,7 @@
35
35
  "material-ui",
36
36
  "angular",
37
37
  "dprint",
38
- "autofix",
39
- "pre-commit"
38
+ "autofix"
40
39
  ],
41
40
  "author": "Samuel Therrien <samuel.therrien@beslogic.com>",
42
41
  "license": "MIT",
@@ -63,7 +62,7 @@
63
62
  "eslint-plugin-prefer-arrow": "^1.2",
64
63
  "eslint-plugin-regexp": "^2.0",
65
64
  "eslint-plugin-simple-import-sort": ">=12.0",
66
- "eslint-plugin-sonarjs": "2.0.3",
65
+ "eslint-plugin-sonarjs": "2.0.4",
67
66
  "eslint-plugin-testing-library": "^6.0",
68
67
  "eslint-plugin-unicorn": ">=49.0"
69
68
  },
package/react.js CHANGED
@@ -3,9 +3,7 @@
3
3
 
4
4
  const javascriptConfig = require("./javascript")
5
5
  const typescriptConfig = require("./typescript")
6
- const { jestFilePatterns, resolveModuleLocation } = require("./lib/utils")
7
-
8
- const hasTestingLibrary = !!resolveModuleLocation("eslint-plugin-testing-library")
6
+ const { jestFilePatterns } = require("./lib/utils")
9
7
 
10
8
  const typeDefinitionOverride = typescriptConfig.overrides?.find(
11
9
  override => override.files === "*.d.ts"
@@ -100,9 +98,7 @@ module.exports = {
100
98
  },
101
99
  {
102
100
  "files": jestFilePatterns,
103
- "extends": hasTestingLibrary
104
- ? ["plugin:testing-library/react"]
105
- : []
101
+ "extends": "plugin:testing-library/react"
106
102
  },
107
103
  {
108
104
  "files": [
package/typescript.js CHANGED
@@ -2,17 +2,7 @@
2
2
  // Copyright 2024 Beslogic Inc.
3
3
 
4
4
  const javascriptConfig = require("./javascript")
5
- const { jestNoRestrictedSyntax, jestFilePatterns, resolveModuleLocation, isPreCommitCI } = require(
6
- "./lib/utils"
7
- )
8
-
9
- // The only autofix we use is `no-implicit-any-catch` and this is a big module for pre-commit
10
- // Outside of pre-commit, `eslint-plugin-etc` should NOT be considered optional !
11
- const hasEtc = !!resolveModuleLocation("eslint-plugin-etc")
12
- // Causes the following error in pre-commit.ci:
13
- // Resolve error: File 'eslint-config-beslogic/tsconfig.5.0.json' not found.
14
- // Outside of pre-commit, `eslint-import-resolver-typescript` should NOT be considered optional !
15
- const hasImportResolverTypescript = !!resolveModuleLocation("eslint-import-resolver-typescript")
5
+ const { jestNoRestrictedSyntax, jestFilePatterns } = require("./lib/utils")
16
6
 
17
7
  const noRestrictedSyntax = [
18
8
  ...javascriptConfig.rules?.["no-restricted-syntax"] ?? {},
@@ -41,6 +31,7 @@ const noUnusedVariablesConfig = autofixOverridesRules?.["autofix/no-unused-vars"
41
31
  /** @type {import("eslint").Linter.Config} */
42
32
  module.exports = {
43
33
  "overrides": [
34
+ // It's important to keep this override first, as other rules will extend from it
44
35
  {
45
36
  "files": [
46
37
  "*.ts",
@@ -48,35 +39,27 @@ module.exports = {
48
39
  ],
49
40
  "extends": [
50
41
  "plugin:@typescript-eslint/all",
51
- ...hasEtc
52
- ? ["plugin:etc/recommended"]
53
- : [],
54
- ...hasImportResolverTypescript
55
- ? ["plugin:import/typescript"]
56
- : []
42
+ "plugin:etc/recommended",
43
+ "plugin:import/typescript"
57
44
  ],
58
45
  "env": {
59
46
  // https://eslint.org/docs/v8.x/use/configure/language-options#specifying-environments
60
47
  "es2022": true // Same as tsconfig.json > compilerOptions.lib
61
48
  },
62
49
  "settings": {
63
- ...hasImportResolverTypescript
64
- ? {
65
- "import/resolver": {
66
- "typescript": {
67
- // Recommended by eslint-import-resolver-typescript
68
- // Always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
69
- "alwaysTryTypes": true,
70
- // Doesn't support `project: true` or `useProjectService`
71
- // https://github.com/import-js/eslint-import-resolver-typescript/issues/282
72
- "project": [
73
- "tsconfig?(.*).json",
74
- "projects/*/tsconfig?(.*).json"
75
- ]
76
- }
77
- }
50
+ "import/resolver": {
51
+ "typescript": {
52
+ // Recommended by eslint-import-resolver-typescript
53
+ // Always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
54
+ "alwaysTryTypes": true,
55
+ // Doesn't support `project: true` or `useProjectService`
56
+ // https://github.com/import-js/eslint-import-resolver-typescript/issues/282
57
+ "project": [
58
+ "tsconfig?(.*).json",
59
+ "projects/*/tsconfig?(.*).json"
60
+ ]
78
61
  }
79
- : {},
62
+ },
80
63
  "import/parsers": {
81
64
  "@typescript-eslint/parser": [
82
65
  ".ts",
@@ -118,21 +101,17 @@ module.exports = {
118
101
  /*
119
102
  * Cartant's etc rules
120
103
  */
121
- ...hasEtc
122
- ? {
123
- "etc/no-const-enum": "error",
124
- // This rule currently crashes :( Turn back to error if fixed
125
- // https://github.com/cartant/eslint-plugin-etc/issues/47
126
- "etc/throw-error": "off",
127
- "etc/underscore-internal": "error",
128
- // These two are extremely slow. More than should be expected
129
- // https://github.com/cartant/eslint-plugin-etc/issues/10#issuecomment-1618450905
130
- "etc/no-deprecated": "off",
131
- "etc/no-internal": "off",
132
- // See https://github.com/cartant/eslint-plugin-etc/issues/45#issuecomment-1137305254
133
- "etc/prefer-interface": "off"
134
- }
135
- : {},
104
+ "etc/no-const-enum": "error",
105
+ // This rule currently crashes :( Turn back to error if fixed
106
+ // https://github.com/cartant/eslint-plugin-etc/issues/47
107
+ "etc/throw-error": "off",
108
+ "etc/underscore-internal": "error",
109
+ // These two are extremely slow. More than should be expected
110
+ // https://github.com/cartant/eslint-plugin-etc/issues/10#issuecomment-1618450905
111
+ "etc/no-deprecated": "off",
112
+ "etc/no-internal": "off",
113
+ // See https://github.com/cartant/eslint-plugin-etc/issues/45#issuecomment-1137305254
114
+ "etc/prefer-interface": "off",
136
115
 
137
116
  /*
138
117
  * Overrides of base Javascript rules
@@ -144,6 +123,9 @@ module.exports = {
144
123
  // Obsoleted by @typescript-eslint/prefer-string-starts-ends-with
145
124
  "unicorn/prefer-string-starts-ends-with": "off",
146
125
 
126
+ // Redundant with @typescript-eslint/switch-exhaustiveness-check
127
+ // and conflicts with unicorn/no-useless-switch-case
128
+ "default-case": "off",
147
129
  // Using simple-import-sort instead
148
130
  "sort-imports": "off",
149
131
  // Not usable with typescript anyway
@@ -176,12 +158,6 @@ module.exports = {
176
158
  "ignoreClassesThatImplementAnInterface": true
177
159
  }
178
160
  ],
179
- // Is default, just expicitly setting it to contrast
180
- // no-autofix/@typescript-eslint/consistent-type-assertions in extra-strict
181
- "@typescript-eslint/consistent-type-assertions": [
182
- "error",
183
- { "assertionStyle": "as", "objectLiteralTypeAssertions": "allow" }
184
- ],
185
161
  // Prefer "noImplicitReturns": true in tsconfig.json
186
162
  "@typescript-eslint/consistent-return": "off",
187
163
  "@typescript-eslint/no-deprecated": "warn",
@@ -367,18 +343,6 @@ module.exports = {
367
343
  { "ignoreDifferentlyNamedParameters": true }
368
344
  ],
369
345
 
370
- ...isPreCommitCI // Missing types lead to false-positives
371
- // TODO: Under pre-commit.ci, consider extending
372
- // https://typescript-eslint.io/users/configs/#disable-type-checked
373
- ? {
374
- "@typescript-eslint/no-redundant-type-constituents": "off",
375
- "@typescript-eslint/no-unsafe-argument": "off",
376
- "@typescript-eslint/no-unsafe-member-access": "off",
377
- "@typescript-eslint/no-unsafe-return": "off",
378
- "@typescript-eslint/prefer-optional-chain": "off"
379
- }
380
- : {},
381
-
382
346
  /*
383
347
  * @typescript-eslint rules that require strictNullChecks
384
348
  * These requires stricter tsconfig or fails.
@@ -387,9 +351,7 @@ module.exports = {
387
351
  // Setting allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing makes this rule useless on
388
352
  // null/undefined checks. So only set it in non-strict preset.
389
353
  "@typescript-eslint/no-unnecessary-condition": [
390
- isPreCommitCI
391
- ? "off" // Missing types lead to false-positives
392
- : "error",
354
+ "error",
393
355
  { "allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing": true }
394
356
  ],
395
357
  // IDEM, but fully useless w/o strictNullChecks