linter-bundle 7.12.1 → 8.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/CHANGELOG.md CHANGED
@@ -6,7 +6,84 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v7.12.1...HEAD)
9
+ [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v8.0.0...HEAD)
10
+
11
+ ## [8.0.0] - 2026-07-16
12
+
13
+ ### Breaking changes
14
+
15
+ - [general] Drop support for Node.js 20 (end-of-life since April 2026), as some of the dependencies are not supporting it anymore. Node.js `^22.13.0 || >=24.0.0` is required now.
16
+ - [eslint] Replaced the abandoned `eslint-plugin-eslint-comments` with its maintained community fork [`@eslint-community/eslint-plugin-eslint-comments`](https://github.com/eslint-community/eslint-plugin-eslint-comments). The rule names (`eslint-comments/*`) and the rule set remain unchanged.
17
+ - [eslint] Renamed the disabled `unicorn/prefer-dom-node-dataset` rule to [`unicorn/dom-node-dataset`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/dom-node-dataset.md) and enabled it with the new `preferAttributes` option, as `setAttribute()` is faster than `dataset`
18
+ - [eslint] Renamed the disabled `unicorn/prefer-json-parse-buffer` rule to [`unicorn/consistent-json-file-read`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-json-file-read.md) and enabled it with the `string` option, as TypeScript requires strings here
19
+ - [eslint] Removed the `unicorn/better-regex` rule, as it has been removed in `eslint-plugin-unicorn` v65
20
+
21
+ ### Changed
22
+
23
+ - [eslint] Updated `@stylistic/eslint-plugin` from `5.9.0` to `5.10.0`
24
+ - [eslint] Updated `eslint` from `9.39.3` to `9.39.5`
25
+ - [eslint] Updated `eslint-import-resolver-typescript` from `4.4.4` to `4.4.5`
26
+ - [eslint] Updated `eslint-import-resolver-webpack` from `0.13.10` to `0.13.11`
27
+ - [eslint] Updated `eslint-plugin-functional` from `9.0.2` to `10.0.0`
28
+ - [eslint] Updated `eslint-plugin-jest` from `29.15.0` to `29.15.4`
29
+ - [eslint] Updated `eslint-plugin-jsdoc` from `62.7.0` to `63.0.13`
30
+ - [eslint] Updated `eslint-plugin-n` from `17.24.0` to `18.1.0`
31
+ - [eslint] Updated `eslint-plugin-promise` from `7.2.1` to `7.3.0`
32
+ - [eslint] Updated `eslint-plugin-react-hooks` from `7.0.1` to `7.1.1`
33
+ - [eslint] Updated `eslint-plugin-unicorn` from `63.0.0` to `65.0.1`
34
+ - [eslint] Updated `globals` from `17.3.0` to `17.6.0`
35
+ - [eslint] Updated `typescript-eslint` from `8.56.0` to `8.61.1`
36
+ - [stylelint] Updated `stylelint` from `17.3.0` to `17.13.0`
37
+ - [stylelint] Updated `stylelint-order` from `7.0.1` to `8.1.1`
38
+ - [stylelint] Updated `stylelint-scss` from `7.0.0` to `7.2.0`
39
+ - [markdown] Updated `markdownlint-cli` from `0.47.0` to `0.48.0`
40
+ - [eslint] Make use of new [`unicorn/better-dom-traversing`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/better-dom-traversing.md) rule
41
+ - [eslint] Make use of new [`unicorn/consistent-compound-words`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-compound-words.md) rule
42
+ - [eslint] Make use of new [`unicorn/consistent-template-literal-escape`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-template-literal-escape.md) rule
43
+ - [eslint] Make use of new [`unicorn/no-array-fill-with-reference-type`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-fill-with-reference-type.md) rule
44
+ - [eslint] Make use of new [`unicorn/no-array-from-fill`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-from-fill.md) rule
45
+ - [eslint] Make use of new [`unicorn/no-blob-to-file`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-blob-to-file.md) rule
46
+ - [eslint] Make use of new [`unicorn/no-canvas-to-image`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-canvas-to-image.md) rule
47
+ - [eslint] Make use of new [`unicorn/no-confusing-array-splice`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-confusing-array-splice.md) rule
48
+ - [eslint] Make use of new [`unicorn/no-duplicate-set-values`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-duplicate-set-values.md) rule
49
+ - [eslint] Make use of new [`unicorn/no-exports-in-scripts`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-exports-in-scripts.md) rule
50
+ - [eslint] Make use of new [`unicorn/no-incorrect-query-selector`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-incorrect-query-selector.md) rule
51
+ - [eslint] Make use of new [`unicorn/no-invalid-file-input-accept`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-invalid-file-input-accept.md) rule
52
+ - [eslint] Make use of new [`unicorn/no-late-current-target-access`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-late-current-target-access.md) rule
53
+ - [eslint] Make use of new [`unicorn/no-this-outside-of-class`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-this-outside-of-class.md) rule
54
+ - [eslint] Make use of new [`unicorn/no-unused-array-method-return`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unused-array-method-return.md) rule
55
+ - [eslint] Make use of new [`unicorn/no-useless-iterator-to-array`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-iterator-to-array.md) rule
56
+ - [eslint] Make use of new [`unicorn/prefer-array-last-methods`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-last-methods.md) rule
57
+ - [eslint] Make use of new [`unicorn/prefer-https`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-https.md) rule
58
+ - [eslint] Make use of new [`unicorn/prefer-includes-over-repeated-comparisons`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-includes-over-repeated-comparisons.md) rule
59
+ - [eslint] Make use of new [`unicorn/prefer-iterator-to-array-at-end`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-iterator-to-array-at-end.md) rule
60
+ - [eslint] Make use of new [`unicorn/prefer-math-abs`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-math-abs.md) rule
61
+ - [eslint] Make use of new [`unicorn/prefer-queue-microtask`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-queue-microtask.md) rule
62
+ - [eslint] Make use of new [`unicorn/prefer-simple-condition-first`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-simple-condition-first.md) rule
63
+ - [eslint] Make use of new [`unicorn/prefer-split-limit`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-split-limit.md) rule
64
+ - [eslint] Make use of new [`unicorn/prefer-string-match-all`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-match-all.md) rule
65
+ - [eslint] Make use of new [`unicorn/prefer-string-pad-start-end`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-pad-start-end.md) rule
66
+ - [eslint] Make use of new [`unicorn/prefer-string-repeat`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-repeat.md) rule
67
+ - [eslint] Make use of new [`unicorn/require-css-escape`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/require-css-escape.md) rule
68
+ - [eslint] Make use of new [`unicorn/require-passive-events`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/require-passive-events.md) rule
69
+ - [eslint] Make use of new [`unicorn/switch-case-break-position`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/switch-case-break-position.md) rule
70
+ - [stylelint] Make use of new [`selector-no-deprecated`](https://stylelint.io/user-guide/rules/selector-no-deprecated/) rule
71
+ - [eslint] Added but disabled [`unicorn/no-manually-wrapped-comments`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-manually-wrapped-comments.md) rule, as manual line-breaks in comments are often intentional
72
+ - [eslint] Added but disabled [`unicorn/no-unnecessary-nested-ternary`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unnecessary-nested-ternary.md) rule, as it is covered by the ESLint `no-nested-ternary` rule
73
+ - [eslint] Added but disabled [`unicorn/prefer-get-or-insert-computed`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-get-or-insert-computed.md) rule, as `Map#getOrInsertComputed()` is not supported by current browsers and Node.js versions
74
+ - [eslint] Added but disabled [`unicorn/prefer-iterator-concat`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-iterator-concat.md) rule, as `Iterator.concat()` is not supported by current browsers and requires Node.js 26
75
+ - [eslint] Added but disabled [`unicorn/try-complexity`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/try-complexity.md) rule, as arbitrary complexity limits are too opinionated
76
+ - [stylelint] Added but disabled [`property-layout-mappings`](https://stylelint.io/user-guide/rules/property-layout-mappings/) rule, as it is covered by `csstools/use-logical`
77
+ - [stylelint] Added but disabled [`relative-selector-nesting-notation`](https://stylelint.io/user-guide/rules/relative-selector-nesting-notation/) rule, as both notations are fine, depending on the use-case
78
+ - [stylelint] Added but disabled [`selector-no-invalid`](https://stylelint.io/user-guide/rules/selector-no-invalid/) rule, as it is not suitable for SCSS syntax
79
+ - [stylelint] Added but disabled [`unit-layout-mappings`](https://stylelint.io/user-guide/rules/unit-layout-mappings/) rule, as physical viewport units are still allowed, in line with the `csstools/use-logical` exceptions
80
+ - [stylelint] Added but disabled [`value-keyword-layout-mappings`](https://stylelint.io/user-guide/rules/value-keyword-layout-mappings/) rule, as it is covered by `csstools/use-logical`
81
+ - [stylelint] Added but disabled [`order/custom-properties-alphabetical-order`](https://github.com/hudochenkov/stylelint-order/blob/master/rules/custom-properties-alphabetical-order/README.md) rule
82
+ - [eslint] Adapted the `unicorn/prefer-export-from` configuration to the renamed `checkUsedVariables` option (previously `ignoreUsedVariables`; same behavior)
83
+ - [general] `check-outdated` now ignores `eslint@10.5.0` and `eslint-plugin-unicorn@67.0.0`: ESLint 10 is still blocked by `eslint-plugin-import`, `eslint-plugin-react` and `eslint-plugin-jsx-a11y`, and `eslint-plugin-unicorn` v66+ requires ESLint 10.4
84
+ - [general] Updated the internal TypeScript from `5.9.3` to `6.0.3` and removed the deprecated `baseUrl` option from the `tsconfig.json`
85
+
86
+ [Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v7.12.1...v8.0.0)
10
87
 
11
88
  ## [7.12.1] - 2026-02-21
12
89
 
package/eslint/index.mjs CHANGED
@@ -6,8 +6,6 @@ import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
 
8
8
  import stylisticPlugin from '@stylistic/eslint-plugin';
9
- // @ts-expect-error -- There are no type definitions for this plugin
10
- import eslintCommentsPlugin from 'eslint-plugin-eslint-comments';
11
9
  import functionalPlugin from 'eslint-plugin-functional';
12
10
  import importPlugin from 'eslint-plugin-import';
13
11
  // @ts-expect-error -- There are no type definitions for this plugin
@@ -18,6 +16,8 @@ import unicornPlugin from 'eslint-plugin-unicorn';
18
16
  import globals from 'globals';
19
17
  import * as typescriptEslint from 'typescript-eslint';
20
18
 
19
+ import { rules as eslintCommentsRules } from '@eslint-community/eslint-plugin-eslint-comments';
20
+
21
21
  import * as ensureType from '../helper/ensure-type.mjs';
22
22
  import { linterBundleConfig } from '../helper/linter-bundle-config.js';
23
23
 
@@ -40,7 +40,7 @@ export default [
40
40
  'node_modules/'
41
41
  ],
42
42
  plugins: {
43
- 'eslint-comments': eslintCommentsPlugin,
43
+ 'eslint-comments': { rules: eslintCommentsRules },
44
44
  'functional': functionalPlugin,
45
45
  'import': importPlugin,
46
46
  'jsx-a11y': jsxA11YPlugin,
@@ -961,9 +961,9 @@ export default [
961
961
  'import/unambiguous': 'off',
962
962
 
963
963
  /**
964
- * eslint-plugin-eslint-comments
964
+ * @eslint-community/eslint-plugin-eslint-comments
965
965
  *
966
- * @see https://mysticatea.github.io/eslint-plugin-eslint-comments/
966
+ * @see https://eslint-community.github.io/eslint-plugin-eslint-comments/
967
967
  */
968
968
  'eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
969
969
  'eslint-comments/no-aggregating-enable': 'error',
@@ -1001,15 +1001,19 @@ export default [
1001
1001
  * eslint-plugin-unicorn
1002
1002
  * @see https://github.com/sindresorhus/eslint-plugin-unicorn
1003
1003
  */
1004
- 'unicorn/better-regex': 'error',
1004
+ 'unicorn/better-dom-traversing': 'error',
1005
1005
  'unicorn/catch-error-name': 'error',
1006
1006
  'unicorn/consistent-assert': 'error',
1007
+ 'unicorn/consistent-compound-words': 'error',
1007
1008
  'unicorn/consistent-date-clone': 'error',
1008
1009
  'unicorn/consistent-destructuring': 'off', // Depending on the usage, it makes sense to destructure e.g. `props` only partial.
1009
1010
  'unicorn/consistent-empty-array-spread': 'error',
1010
1011
  'unicorn/consistent-existence-index-check': 'error',
1011
1012
  'unicorn/consistent-function-scoping': 'error',
1013
+ 'unicorn/consistent-json-file-read': ['error', 'string'], // TypeScript states that string needs to be used as of the ES specification. @see https://github.com/microsoft/TypeScript/issues/11842
1014
+ 'unicorn/consistent-template-literal-escape': 'error',
1012
1015
  'unicorn/custom-error-definition': 'off',
1016
+ 'unicorn/dom-node-dataset': ['error', { preferAttributes: true }], // `setAttribute` is faster than `dataset`. See https://www.measurethat.net/Benchmarks/Show/7740/0/classname-vs-setattribute-vs-classlist-vs-dataset
1013
1017
  'unicorn/empty-brace-spaces': 'error',
1014
1018
  'unicorn/error-message': 'error',
1015
1019
  'unicorn/escape-case': 'error',
@@ -1057,24 +1061,35 @@ export default [
1057
1061
  'unicorn/no-abusive-eslint-disable': 'error',
1058
1062
  'unicorn/no-accessor-recursion': 'error',
1059
1063
  'unicorn/no-array-callback-reference': 'off', // If I use functions, they are the best option for this use-case
1064
+ 'unicorn/no-array-fill-with-reference-type': 'error',
1060
1065
  'unicorn/no-array-for-each': 'error',
1066
+ 'unicorn/no-array-from-fill': 'error',
1061
1067
  'unicorn/no-array-method-this-argument': 'error',
1062
1068
  'unicorn/no-array-reduce': ['error', { allowSimpleOperations: true }],
1063
1069
  'unicorn/no-array-reverse': 'error',
1064
1070
  'unicorn/no-array-sort': 'error',
1065
1071
  'unicorn/no-await-expression-member': 'error',
1072
+ 'unicorn/no-blob-to-file': 'error',
1073
+ 'unicorn/no-canvas-to-image': 'error',
1074
+ 'unicorn/no-confusing-array-splice': 'error',
1066
1075
  'unicorn/no-console-spaces': 'error',
1067
1076
  'unicorn/no-document-cookie': 'error',
1077
+ 'unicorn/no-duplicate-set-values': 'error',
1068
1078
  'unicorn/no-empty-file': 'error',
1079
+ 'unicorn/no-exports-in-scripts': 'error',
1069
1080
  'unicorn/no-for-loop': 'off', // @typescript-eslint/prefer-for-of
1070
1081
  'unicorn/no-hex-escape': 'error',
1071
1082
  'unicorn/no-immediate-mutation': 'error',
1083
+ 'unicorn/no-incorrect-query-selector': 'error',
1072
1084
  'unicorn/no-instanceof-builtins': 'error',
1073
1085
  'unicorn/no-invalid-fetch-options': 'error',
1086
+ 'unicorn/no-invalid-file-input-accept': 'error',
1074
1087
  'unicorn/no-invalid-remove-event-listener': 'error',
1075
1088
  'unicorn/no-keyword-prefix': 'off',
1089
+ 'unicorn/no-late-current-target-access': 'error',
1076
1090
  'unicorn/no-lonely-if': 'off', // Sometimes the code is clearer if-conditions are not combined
1077
1091
  'unicorn/no-magic-array-flat-depth': 'error',
1092
+ 'unicorn/no-manually-wrapped-comments': 'off', // Manual line-breaks in comments are often intentional, and there is no reliable way to distinguish them from automatic wrapping
1078
1093
  'unicorn/no-named-default': 'error',
1079
1094
  'unicorn/no-negated-condition': 'off',
1080
1095
  'unicorn/no-negation-in-equality-check': 'error',
@@ -1087,18 +1102,22 @@ export default [
1087
1102
  'unicorn/no-static-only-class': 'error',
1088
1103
  'unicorn/no-thenable': 'error',
1089
1104
  'unicorn/no-this-assignment': 'error',
1105
+ 'unicorn/no-this-outside-of-class': 'error',
1090
1106
  'unicorn/no-typeof-undefined': 'error',
1091
1107
  'unicorn/no-unnecessary-array-flat-depth': 'error',
1092
1108
  'unicorn/no-unnecessary-array-splice-count': 'error',
1093
1109
  'unicorn/no-unnecessary-await': 'error',
1110
+ 'unicorn/no-unnecessary-nested-ternary': 'off', // Covered by the ESLint `no-nested-ternary` rule, which disallows nested ternaries in general
1094
1111
  'unicorn/no-unnecessary-polyfills': 'error',
1095
1112
  'unicorn/no-unnecessary-slice-end': 'error',
1096
1113
  'unicorn/no-unreadable-array-destructuring': 'error',
1097
1114
  'unicorn/no-unreadable-iife': 'error',
1115
+ 'unicorn/no-unused-array-method-return': 'error',
1098
1116
  'unicorn/no-unused-properties': 'error',
1099
1117
  'unicorn/no-useless-collection-argument': 'error',
1100
1118
  'unicorn/no-useless-error-capture-stack-trace': 'error',
1101
1119
  'unicorn/no-useless-fallback-in-spread': 'error',
1120
+ 'unicorn/no-useless-iterator-to-array': 'error',
1102
1121
  'unicorn/no-useless-promise-resolve-reject': 'error',
1103
1122
  'unicorn/no-useless-length-check': 'error',
1104
1123
  'unicorn/no-useless-spread': 'error',
@@ -1112,6 +1131,7 @@ export default [
1112
1131
  'unicorn/prefer-array-flat': 'error',
1113
1132
  'unicorn/prefer-array-flat-map': 'error',
1114
1133
  'unicorn/prefer-array-index-of': 'error',
1134
+ 'unicorn/prefer-array-last-methods': 'error',
1115
1135
  'unicorn/prefer-array-some': 'error',
1116
1136
  'unicorn/prefer-at': 'off', // @todo Disabled for now, since `at` is not supported by TypeScript type definitions yet.
1117
1137
  'unicorn/prefer-blob-reading-methods': 'off', // @todo Disabled for now, since it's only supported in Safari 14+. Activate in 2025
@@ -1126,13 +1146,18 @@ export default [
1126
1146
  'unicorn/prefer-dom-node-remove': 'error',
1127
1147
  'unicorn/prefer-dom-node-text-content': 'error',
1128
1148
  'unicorn/prefer-event-target': 'error',
1129
- 'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }],
1149
+ 'unicorn/prefer-export-from': ['error', { checkUsedVariables: false }],
1150
+ 'unicorn/prefer-get-or-insert-computed': 'off', // @todo Disabled for now, since `Map#getOrInsertComputed()` is not supported by current browsers and Node.js versions. Check back in 2027
1130
1151
  'unicorn/prefer-global-this': 'off', // This makes only sense if the same code may run on the server-side. Often the auto-fixing of this rule doesn't make sense
1152
+ 'unicorn/prefer-https': 'error',
1131
1153
  'unicorn/prefer-import-meta-properties': 'off', // @todo Regarding `n/no-unsupported-features/node-builtins` it's still an experimental feature, so check back in 2026
1132
1154
  'unicorn/prefer-includes': 'error',
1133
- 'unicorn/prefer-json-parse-buffer': 'off', // TypeScript states that string needs to be used as of the ES specification. @see https://github.com/microsoft/TypeScript/issues/11842
1155
+ 'unicorn/prefer-includes-over-repeated-comparisons': 'error',
1156
+ 'unicorn/prefer-iterator-concat': 'off', // @todo Disabled for now, since `Iterator.concat()` is not supported by current browsers and requires Node.js 26. Check back in 2027
1157
+ 'unicorn/prefer-iterator-to-array-at-end': 'error',
1134
1158
  'unicorn/prefer-keyboard-event-key': 'error',
1135
1159
  'unicorn/prefer-logical-operator-over-ternary': 'error',
1160
+ 'unicorn/prefer-math-abs': 'error',
1136
1161
  'unicorn/prefer-math-min-max': 'error',
1137
1162
  'unicorn/prefer-math-trunc': 'error',
1138
1163
  'unicorn/prefer-modern-dom-apis': 'error',
@@ -1145,13 +1170,19 @@ export default [
1145
1170
  'unicorn/prefer-optional-catch-binding': 'error',
1146
1171
  'unicorn/prefer-prototype-methods': 'error',
1147
1172
  'unicorn/prefer-query-selector': 'off', // document.getElementById() is much faster
1173
+ 'unicorn/prefer-queue-microtask': 'error',
1148
1174
  'unicorn/prefer-reflect-apply': 'error',
1149
1175
  'unicorn/prefer-response-static-json': 'error',
1150
1176
  'unicorn/prefer-set-has': 'error',
1151
1177
  'unicorn/prefer-set-size': 'error',
1178
+ 'unicorn/prefer-simple-condition-first': 'error',
1152
1179
  'unicorn/prefer-single-call': 'error',
1180
+ 'unicorn/prefer-split-limit': 'error',
1153
1181
  'unicorn/prefer-spread': 'off', // @todo Disabled till there a solution for the warning, that `slice()` on Typed-Arrays should be replaced (which is not possible). @see https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1064
1182
+ 'unicorn/prefer-string-match-all': 'error',
1183
+ 'unicorn/prefer-string-pad-start-end': 'error',
1154
1184
  'unicorn/prefer-string-raw': 'off', // The overhead of writing String.raw`...` is not worth the inconsistency in writing strings
1185
+ 'unicorn/prefer-string-repeat': 'error',
1155
1186
  'unicorn/prefer-string-replace-all': 'off', // @todo Available since 2020 in browsers. Should this be preferred?
1156
1187
  'unicorn/prefer-string-slice': 'off', // @todo As of today (2020.08.24) and since the last 9 years, substr() is three times faster than slice() in Firefox.
1157
1188
  'unicorn/prefer-string-starts-ends-with': 'error',
@@ -1165,15 +1196,19 @@ export default [
1165
1196
  'unicorn/prevent-abbreviations': ['error', { ignore: ['args', 'i', 'j', 'i18n', /[Rr]ef/u, /[Pp]arams/u, /[Pp]rops/u] }],
1166
1197
  'unicorn/relative-url-style': 'error',
1167
1198
  'unicorn/require-array-join-separator': 'error',
1199
+ 'unicorn/require-css-escape': 'error',
1168
1200
  'unicorn/require-module-attributes': 'error',
1169
1201
  'unicorn/require-module-specifiers': 'error',
1170
1202
  'unicorn/require-number-to-fixed-digits-argument': 'error',
1203
+ 'unicorn/require-passive-events': 'error',
1171
1204
  'unicorn/require-post-message-target-origin': 'off', // False-positive with Workers which don't support a `targetOrigin`
1172
1205
  'unicorn/string-content': 'off', // Breaks code (e.g. imports with `...` in Next.js or GraphQL template strings),
1173
1206
  'unicorn/switch-case-braces': ['error', 'avoid'],
1207
+ 'unicorn/switch-case-break-position': 'error',
1174
1208
  'unicorn/template-indent': 'error',
1175
1209
  'unicorn/text-encoding-identifier-case': 'off',
1176
- 'unicorn/throw-new-error': 'error'
1210
+ 'unicorn/throw-new-error': 'error',
1211
+ 'unicorn/try-complexity': 'off' // Arbitrary complexity limits are too opinionated
1177
1212
  }
1178
1213
  },
1179
1214
  {
package/eslint/jest.mjs CHANGED
@@ -172,7 +172,7 @@ async function getJestVersion () {
172
172
 
173
173
  const jestModule = await import(fileUrl.toString());
174
174
  const jest = ('default' in jestModule ? jestModule.default : jestModule);
175
- const version = jest.getVersion().split('.')[0];
175
+ const version = jest.getVersion().split('.', 1)[0];
176
176
 
177
177
  if (isMainThread) {
178
178
  process.stdout.write(`Detected Jest version: ${version}\n\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linter-bundle",
3
- "version": "7.12.1",
3
+ "version": "8.0.0",
4
4
  "type": "module",
5
5
  "description": "Ready-to use bundle of linting tools, containing configurations for ESLint, stylelint and markdownlint.",
6
6
  "keywords": [
@@ -24,7 +24,7 @@
24
24
  "lint": "lint.js"
25
25
  },
26
26
  "engines": {
27
- "node": "^20.19.0 || ^22.13.0 || >=24.0.0"
27
+ "node": "^22.13.0 || >=24.0.0"
28
28
  },
29
29
  "repository": {
30
30
  "type": "git",
@@ -37,38 +37,38 @@
37
37
  "lint": "npm run _test-stylelint && npm run _stylelint-find-rules && node ./lint files tsc ts md audit --min-severity=critical",
38
38
  "preversion": "npm whoami && npm run check-outdated && npm run lint",
39
39
  "postversion": "git push && git push --tags && npm publish",
40
- "check-outdated": "npx --yes -- check-outdated --ignore-pre-releases --min-age 30 --min-age-patch 1",
40
+ "check-outdated": "npx --yes -- check-outdated --ignore-pre-releases --min-age 30 --min-age-patch 1 --ignore-packages eslint@10.5.0,eslint-plugin-unicorn@67.0.0",
41
41
  "_stylelint-find-rules": "stylelint-find-new-rules ./stylelint/index.mjs",
42
42
  "_test-stylelint": "node ./test-stylelint.js"
43
43
  },
44
44
  "dependencies": {
45
- "@stylistic/eslint-plugin": "5.9.0",
46
- "eslint": "9.39.3",
45
+ "@eslint-community/eslint-plugin-eslint-comments": "4.7.2",
46
+ "@stylistic/eslint-plugin": "5.10.0",
47
+ "eslint": "9.39.5",
47
48
  "eslint-formatter-unix": "9.0.1",
48
- "eslint-import-resolver-typescript": "4.4.4",
49
- "eslint-import-resolver-webpack": "0.13.10",
50
- "eslint-plugin-eslint-comments": "3.2.0",
51
- "eslint-plugin-functional": "9.0.2",
49
+ "eslint-import-resolver-typescript": "4.4.5",
50
+ "eslint-import-resolver-webpack": "0.13.11",
51
+ "eslint-plugin-functional": "10.0.0",
52
52
  "eslint-plugin-import": "2.32.0",
53
- "eslint-plugin-jest": "29.15.0",
54
- "eslint-plugin-jsdoc": "62.7.0",
53
+ "eslint-plugin-jest": "29.15.4",
54
+ "eslint-plugin-jsdoc": "63.0.13",
55
55
  "eslint-plugin-jsx-a11y": "6.10.2",
56
- "eslint-plugin-n": "17.24.0",
57
- "eslint-plugin-promise": "7.2.1",
56
+ "eslint-plugin-n": "18.1.0",
57
+ "eslint-plugin-promise": "7.3.0",
58
58
  "eslint-plugin-react": "7.37.5",
59
- "eslint-plugin-react-hooks": "7.0.1",
60
- "eslint-plugin-unicorn": "63.0.0",
61
- "globals": "17.3.0",
62
- "markdownlint-cli": "0.47.0",
59
+ "eslint-plugin-react-hooks": "7.1.1",
60
+ "eslint-plugin-unicorn": "65.0.1",
61
+ "globals": "17.6.0",
62
+ "markdownlint-cli": "0.48.0",
63
63
  "micromatch": "4.0.8",
64
64
  "postcss-scss": "4.0.9",
65
- "stylelint": "17.3.0",
65
+ "stylelint": "17.13.0",
66
66
  "stylelint-declaration-block-no-ignored-properties": "3.0.0",
67
67
  "stylelint-high-performance-animation": "2.0.0",
68
- "stylelint-order": "7.0.1",
69
- "stylelint-scss": "7.0.0",
68
+ "stylelint-order": "8.1.1",
69
+ "stylelint-scss": "7.2.0",
70
70
  "stylelint-use-logical": "2.1.3",
71
- "typescript-eslint": "8.56.0"
71
+ "typescript-eslint": "8.61.1"
72
72
  },
73
73
  "peerDependencies": {
74
74
  "@typescript-eslint/utils": "*",
@@ -78,8 +78,8 @@
78
78
  "devDependencies": {
79
79
  "@types/eslint": "9.6.1",
80
80
  "@types/micromatch": "4.0.10",
81
- "@types/node": "25.3.0",
81
+ "@types/node": "25.9.5",
82
82
  "stylelint-find-new-rules": "6.0.0",
83
- "typescript": "5.9.3"
83
+ "typescript": "6.0.3"
84
84
  }
85
85
  }
@@ -384,8 +384,10 @@ export default {
384
384
  'font', // Shorthand property is to complex
385
385
  'grid-gap' // @deprecated Use gap.
386
386
  ],
387
+ 'property-layout-mappings': null, // Covered by `csstools/use-logical`
387
388
  'property-no-unknown': null, // Covered by scss/property-no-unknown
388
389
  'property-no-vendor-prefix': true,
390
+ 'relative-selector-nesting-notation': null, // Both notations are fine, depending on the use-case
389
391
  'rule-selector-property-disallowed-list': null,
390
392
  'rule-empty-line-before': [
391
393
  'always-multi-line',
@@ -420,6 +422,8 @@ export default {
420
422
  'selector-max-type': 6,
421
423
  'selector-max-universal': [1, { ignoreAfterCombinators: ['>', '+'] }],
422
424
  'selector-nested-pattern': null,
425
+ 'selector-no-deprecated': true,
426
+ 'selector-no-invalid': null, // Not suitable for SCSS syntax, which is the main use-case of this configuration. @see https://stylelint.io/user-guide/rules/selector-no-invalid
423
427
  'selector-no-qualifying-type': [true, { ignore: ['attribute', 'class'] }],
424
428
  'selector-no-vendor-prefix': true,
425
429
  'selector-not-notation': 'complex',
@@ -438,6 +442,7 @@ export default {
438
442
  'time-min-milliseconds': 40, // @todo For the delay of transitions 40ms should be the minimum, for the duration 150ms should be the minimum (change it, as soon as https://github.com/stylelint/stylelint/issues/4552 got implemented)
439
443
  'unit-allowed-list': null,
440
444
  'unit-disallowed-list': null,
445
+ 'unit-layout-mappings': null, // In line with the `csstools/use-logical` exceptions, physical viewport units are still allowed
441
446
  'unit-no-unknown': true,
442
447
  'value-keyword-case': [
443
448
  'lower',
@@ -446,6 +451,7 @@ export default {
446
451
  ignoreProperties: ['composes']
447
452
  }
448
453
  ],
454
+ 'value-keyword-layout-mappings': null, // Covered by `csstools/use-logical`
449
455
  'value-no-vendor-prefix': true,
450
456
 
451
457
  /**
@@ -551,6 +557,7 @@ export default {
551
557
  *
552
558
  * @see https://www.npmjs.com/package/stylelint-order
553
559
  */
560
+ 'order/custom-properties-alphabetical-order': null,
554
561
  'order/order': [
555
562
  'dollar-variables',
556
563
  'at-variables',
@@ -5,6 +5,7 @@ import ruleMessages from 'stylelint/lib/utils/ruleMessages.mjs';
5
5
  import validateOptions from 'stylelint/lib/utils/validateOptions.mjs';
6
6
 
7
7
  import whitespaceChecker from '../../utils/whitespaceChecker.mjs';
8
+ // eslint-disable-next-line unicorn/consistent-compound-words -- "NameSpace" refers to the space after the at-rule name here, not to a "namespace"
8
9
  import atRuleNameSpaceChecker from '../atRuleNameSpaceChecker.mjs';
9
10
 
10
11
  const ruleName = 'plugin/at-rule-name-space-after';
@@ -12,6 +12,7 @@ import report from 'stylelint/lib/utils/report.mjs';
12
12
  * fix?: ((atRule: import('postcss').AtRule) => void) | null,
13
13
  * }} options
14
14
  */
15
+ // eslint-disable-next-line unicorn/consistent-compound-words -- "NameSpace" refers to the space after the at-rule name here, not to a "namespace"
15
16
  export default function atRuleNameSpaceChecker (options) {
16
17
  options.root.walkAtRules((atRule) => {
17
18
  if (!isStandardSyntaxAtRule(atRule)) {
@@ -79,12 +79,12 @@ const rule = (primary, secondaryOptions, context) => {
79
79
  if (!startNode?.next) { return; }
80
80
 
81
81
  if (startNode.type === 'comment') {
82
- const reNewLine = /\r?\n/u;
83
- const newLineMatch = reNewLine.test(startNode.raws.before || '');
82
+ const reNewline = /\r?\n/u;
83
+ const newlineMatch = reNewline.test(startNode.raws.before || '');
84
84
 
85
85
  const next = startNode.next();
86
86
 
87
- if (next && newLineMatch && !reNewLine.test(next.raws.before || '')) {
87
+ if (next && newlineMatch && !reNewline.test(next.raws.before || '')) {
88
88
  backupCommentNextBefores.set(next, next.raws.before);
89
89
  next.raws.before = startNode.raws.before;
90
90
  }
@@ -141,7 +141,7 @@ const rule = (primary, secondaryOptions, context) => {
141
141
  backupCommentNextBefores.clear();
142
142
 
143
143
  // Fix
144
- const reNewLine = /\r?\n/u;
144
+ const reNewline = /\r?\n/u;
145
145
  let fixTarget = statement.first;
146
146
 
147
147
  while (fixTarget) {
@@ -149,7 +149,7 @@ const rule = (primary, secondaryOptions, context) => {
149
149
 
150
150
  if (typeof fixTargetRaws.before !== 'string') { continue; }
151
151
 
152
- if (reNewLine.test(fixTargetRaws.before || '')) {
152
+ if (reNewline.test(fixTargetRaws.before || '')) {
153
153
  fixTargetRaws.before = fixTargetRaws.before.replace(/\r?\n/gu, '');
154
154
  }
155
155
 
@@ -56,19 +56,19 @@ const rule = (primary, secondaryOptions) => (root, result) => {
56
56
  const rootString = root.toString();
57
57
  // Array of skipped sub strings, i.e `url(...)`, `@import "..."`
58
58
  /** @type {Array<[number, number]>} */
59
- let skippedSubStrings = [];
60
- let skippedSubStringsIndex = 0;
59
+ let skippedSubstrings = [];
60
+ let skippedSubstringsIndex = 0;
61
61
 
62
62
  for (const pattern of EXCLUDED_PATTERNS) {
63
63
  for (const match of rootString.matchAll(pattern)) {
64
64
  const subMatch = match[1] || '';
65
- const startOfSubString = (match.index || 0) + (match[0] || '').indexOf(subMatch);
65
+ const startOfSubstring = (match.index || 0) + (match[0] || '').indexOf(subMatch);
66
66
 
67
- skippedSubStrings.push([startOfSubString, startOfSubString + subMatch.length]);
67
+ skippedSubstrings.push([startOfSubstring, startOfSubstring + subMatch.length]);
68
68
  }
69
69
  }
70
70
 
71
- skippedSubStrings = skippedSubStrings.toSorted((a, b) => a[0] - b[0]);
71
+ skippedSubstrings = skippedSubstrings.toSorted((a, b) => a[0] - b[0]);
72
72
 
73
73
  // Check first line
74
74
  checkNewline({ endIndex: 0 });
@@ -93,23 +93,23 @@ const rule = (primary, secondaryOptions) => (root, result) => {
93
93
  * @param {number} start
94
94
  * @param {number} end
95
95
  */
96
- function tryToPopSubString (start, end) {
97
- const skippedSubString = skippedSubStrings[skippedSubStringsIndex];
96
+ function tryToPopSubstring (start, end) {
97
+ const skippedSubstring = skippedSubstrings[skippedSubstringsIndex];
98
98
 
99
- assert(skippedSubString);
100
- const [startSubString, endSubString] = skippedSubString;
99
+ assert(skippedSubstring);
100
+ const [startSubstring, endSubstring] = skippedSubstring;
101
101
 
102
- // Excluded substring does not presented in current line
103
- if (end < startSubString) {
102
+ // Excluded Substring does not presented in current line
103
+ if (end < startSubstring) {
104
104
  return 0;
105
105
  }
106
106
 
107
- // Compute excluded substring size regarding to current line indexes
108
- const excluded = Math.min(end, endSubString) - Math.max(start, startSubString);
107
+ // Compute excluded Substring size regarding to current line indexes
108
+ const excluded = Math.min(end, endSubstring) - Math.max(start, startSubstring);
109
109
 
110
- // Current substring is out of range for next lines
111
- if (endSubString <= end) {
112
- skippedSubStringsIndex++;
110
+ // Current Substring is out of range for next lines
111
+ if (endSubstring <= end) {
112
+ skippedSubstringsIndex++;
113
113
  }
114
114
 
115
115
  return excluded;
@@ -131,8 +131,8 @@ const rule = (primary, secondaryOptions) => (root, result) => {
131
131
  }
132
132
 
133
133
  const rawLineLength = nextNewlineIndex - match.endIndex;
134
- const excludedLength = skippedSubStrings[skippedSubStringsIndex] ?
135
- tryToPopSubString(match.endIndex, nextNewlineIndex)
134
+ const excludedLength = skippedSubstrings[skippedSubstringsIndex] ?
135
+ tryToPopSubstring(match.endIndex, nextNewlineIndex)
136
136
  : 0;
137
137
  const lineText = rootString.slice(match.endIndex, nextNewlineIndex);
138
138
 
@@ -77,11 +77,15 @@ const rule = (primary, _secondaryOptions) => (root, result) => {
77
77
  }
78
78
 
79
79
  if (value.includes('*')) {
80
- value.split('*').some((value_) => processValue({
81
- ...valueNode,
82
- sourceIndex: value.indexOf(value_) + value_.length + 1,
83
- value: value_
84
- }));
80
+ for (const value_ of value.split('*')) {
81
+ if (processValue({
82
+ ...valueNode,
83
+ sourceIndex: value.indexOf(value_) + value_.length + 1,
84
+ value: value_
85
+ })) {
86
+ break;
87
+ }
88
+ }
85
89
  }
86
90
 
87
91
  needFix = processValue(valueNode);