@html-validate/eslint-config 9.6.3 → 9.7.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/index.mjs CHANGED
@@ -33,366 +33,378 @@ function filterRules(rules, predicate) {
33
33
  return Object.fromEntries(Object.entries(rules).filter(([key]) => predicate(key)));
34
34
  }
35
35
 
36
- export default [
37
- defineConfig({
38
- name: "@html-validate/eslint-config/global-ignore",
39
- ignores: [
40
- "**/.vscode-test/**", // @vscode/test-electron
41
- "**/coverage/**",
42
- "**/dist/**",
43
- "**/node_modules/**",
44
- "**/out/**", // vscode-html-validate
45
- "**/public/assets/**",
46
- "**/temp/**",
47
- "**/public/*.hot-update.js", // webpack
48
- ],
49
- }),
36
+ /**
37
+ * @param {{type: "module" | "commonjs" }} options
38
+ */
39
+ export default function defaultConfig(options) {
40
+ const moduleExtensions = options.type === "module" ? ["js", "mjs", "mts"] : ["mjs", "mts"];
41
+
42
+ const configs = [
43
+ defineConfig({
44
+ name: "@html-validate/eslint-config/global-ignore",
45
+ ignores: [
46
+ "**/.vscode-test/**", // @vscode/test-electron
47
+ "**/coverage/**",
48
+ "**/dist/**",
49
+ "**/node_modules/**",
50
+ "**/out/**", // vscode-html-validate
51
+ "**/public/assets/**",
52
+ "**/temp/**",
53
+ "**/public/*.hot-update.js", // webpack
54
+ ],
55
+ }),
50
56
 
51
- defineConfig({
52
- name: "@html-validate/eslint-config/language-options",
53
- languageOptions: {
54
- ecmaVersion: 2025,
55
- sourceType: "module",
56
- globals: {
57
- ...globals.es2025,
58
- ...globals.node,
57
+ defineConfig({
58
+ name: "@html-validate/eslint-config/language-options",
59
+ languageOptions: {
60
+ ecmaVersion: 2025,
61
+ sourceType: "module",
62
+ globals: {
63
+ ...globals.es2025,
64
+ ...globals.node,
65
+ },
59
66
  },
60
- },
61
- }),
67
+ }),
62
68
 
63
- defineConfig({
64
- name: "@html-validate/eslint-config/base",
65
- plugins: {
66
- "@eslint-community/eslint-comments": eslintPluginEslintComments,
67
- prettier: eslintPluginPrettier,
68
- "import-x": importX,
69
- n: eslintPluginN,
70
- "array-func": eslintPluginArrayFunc,
71
- regexp: eslintPluginRegexp,
72
- security: eslintPluginSecurity,
73
- sonarjs: eslintPluginSonarjs,
74
- unicorn: eslintPluginUnicorn,
75
- },
76
- settings: {
77
- "import-x/resolver-next": [createNodeResolver(), createTypeScriptImportResolver()],
78
- },
79
- rules: {
80
- ...js.configs.recommended.rules,
81
- ...eslintPluginEslintComments.configs.recommended.rules,
82
- ...filterRules(eslintConfigPrettier.rules, (rule) => {
83
- if (rule.startsWith("@stylistic/")) {
84
- return false;
85
- }
86
- if (rule.startsWith("@babel/") || rule.startsWith("babel/")) {
87
- return false;
88
- }
89
- if (rule.startsWith("flowtype/")) {
90
- return false;
91
- }
92
- if (rule.startsWith("react/")) {
93
- return false;
94
- }
95
- if (rule.startsWith("standard/")) {
96
- return false;
97
- }
98
- if (rule.startsWith("unicorn/")) {
99
- return false;
100
- }
101
- return true;
102
- }),
103
- ...eslintPluginPrettier.configs.recommended.rules,
104
- ...importX.flatConfigs.errors.rules,
105
- ...eslintPluginN.configs["recommended-module"].rules,
106
- ...eslintPluginArrayFunc.configs.recommended.rules,
107
- ...eslintPluginRegexp.configs.recommended.rules, // eslint-disable-line import-x/no-named-as-default-member -- to match other plugins here
108
- ...eslintPluginSecurity.configs.recommended.rules,
109
- ...eslintPluginSonarjs.configs.recommended.rules,
69
+ defineConfig({
70
+ name: "@html-validate/eslint-config/base",
71
+ plugins: {
72
+ "@eslint-community/eslint-comments": eslintPluginEslintComments,
73
+ prettier: eslintPluginPrettier,
74
+ "import-x": importX,
75
+ n: eslintPluginN,
76
+ "array-func": eslintPluginArrayFunc,
77
+ regexp: eslintPluginRegexp,
78
+ security: eslintPluginSecurity,
79
+ sonarjs: eslintPluginSonarjs,
80
+ unicorn: eslintPluginUnicorn,
81
+ },
82
+ settings: {
83
+ "import-x/resolver-next": [createNodeResolver(), createTypeScriptImportResolver()],
84
+ },
85
+ rules: {
86
+ ...js.configs.recommended.rules,
87
+ ...eslintPluginEslintComments.configs.recommended.rules,
88
+ ...filterRules(eslintConfigPrettier.rules, (rule) => {
89
+ if (rule.startsWith("@stylistic/")) {
90
+ return false;
91
+ }
92
+ if (rule.startsWith("@babel/") || rule.startsWith("babel/")) {
93
+ return false;
94
+ }
95
+ if (rule.startsWith("flowtype/")) {
96
+ return false;
97
+ }
98
+ if (rule.startsWith("react/")) {
99
+ return false;
100
+ }
101
+ if (rule.startsWith("standard/")) {
102
+ return false;
103
+ }
104
+ if (rule.startsWith("unicorn/")) {
105
+ return false;
106
+ }
107
+ return true;
108
+ }),
109
+ ...eslintPluginPrettier.configs.recommended.rules,
110
+ ...importX.flatConfigs.errors.rules,
111
+ ...eslintPluginN.configs["recommended-module"].rules,
112
+ ...eslintPluginArrayFunc.configs.recommended.rules,
113
+ ...eslintPluginRegexp.configs.recommended.rules, // eslint-disable-line import-x/no-named-as-default-member -- to match other plugins here
114
+ ...eslintPluginSecurity.configs.recommended.rules,
115
+ ...eslintPluginSonarjs.configs.recommended.rules,
110
116
 
111
- /* enable eslint-plugin-unicorn */
112
- ...eslintPluginUnicorn.configs.recommended.rules,
113
- "unicorn/catch-error-name": "off",
114
- "unicorn/comment-content": "error",
115
- "unicorn/consistent-assert": "off",
116
- "unicorn/consistent-boolean-name": "off", // while i would like this for variables I prefer not to force it on parameters, etc
117
- "unicorn/consistent-class-member-order": "off",
118
- "unicorn/consistent-compound-words": [
119
- "error",
120
- {
121
- allowList: {
122
- /* widely used in the html-validate projects */
123
- MetaData: true,
124
- MetaDataTable: true,
117
+ /* enable eslint-plugin-unicorn */
118
+ ...eslintPluginUnicorn.configs.recommended.rules,
119
+ "unicorn/catch-error-name": "off",
120
+ "unicorn/comment-content": "error",
121
+ "unicorn/consistent-assert": "off",
122
+ "unicorn/consistent-boolean-name": "off", // while i would like this for variables I prefer not to force it on parameters, etc
123
+ "unicorn/consistent-class-member-order": "off",
124
+ "unicorn/consistent-compound-words": [
125
+ "error",
126
+ {
127
+ allowList: {
128
+ /* widely used in the html-validate projects */
129
+ MetaData: true,
130
+ MetaDataTable: true,
131
+ },
125
132
  },
126
- },
127
- ],
128
- "unicorn/consistent-empty-array-spread": "off",
129
- "unicorn/custom-error-definition": "error",
130
- "unicorn/dom-node-dataset": "off",
131
- "unicorn/escape-case": "off", // typically not useful for this organisation
132
- "unicorn/expiring-todo-comments": "off", // could be useful later
133
- "unicorn/explicit-length-check": ["error", { "non-zero": "greater-than" }],
134
- "unicorn/filename-case": [
135
- /* enforce kebab-case in filenames */
136
- "error",
137
- {
138
- case: "kebabCase",
139
- ignore: ["^__(fixtures|mocks|snapshots|tests)__$", "^Gruntfile.js$"],
140
- },
141
- ],
142
- "unicorn/prefer-minimal-ternary": "off", // situational, i dont think `foo[expr ? "x": "y"].bar` is more readable than `expr ? foo.x.bar : foo.y.bar`.
143
- "unicorn/import-style": "off", // off for now
144
- "unicorn/no-abusive-eslint-disable": "off", // covered by eslint-plugin-eslint-comments
145
- "unicorn/no-array-callback-reference": "off", // opinionated, prefer to allow passing function references to array methods (and for most part TypeScript will handle this)
146
- "unicorn/no-array-reduce": "off", // allow usage of reduce()
147
- "unicorn/no-canvas-to-image": "off", // not really relevant for the html-validate projects
148
- "unicorn/no-document-cookie": "off", // typically not useful for this organisation
149
- "unicorn/no-empty-file": "off",
150
- "unicorn/no-immediate-mutation": "off",
151
- "unicorn/no-invalid-argument-count": "off", // does not respect optional parameters (e.g. jsdoc [param])
152
- "unicorn/no-invalid-fetch-options": "off", // let TypeScript and tests handle this
153
- "unicorn/no-named-default": "off", // named default is useful for Vue.js
154
- "unicorn/no-negated-condition": "off", // mostly agree with the rule but sometimes its useful to have the common case first even if negated
155
- "unicorn/no-negation-in-equality-check": "off",
156
- "unicorn/no-null": "off", // prefer using null over undefined
157
- "unicorn/no-process-exit": "off", // covered by n/no-process-exit (enabled by recommended-module preset)
158
- "unicorn/no-single-promise-in-promise-methods": "warn",
159
- "unicorn/no-static-only-class": "off",
160
- "unicorn/no-thenable": "off",
161
- "unicorn/no-this-outside-of-class": "off", // disagree somewhat with the rule, flags stateful objects
162
- "unicorn/no-unnecessary-polyfills": "off",
163
- "unicorn/no-unreadable-array-destructuring": "off",
164
- "unicorn/no-unreadable-iife": "off",
165
- "unicorn/no-useless-switch-case": "off",
166
- "unicorn/no-useless-undefined": "off", // opinionated, I prefer to explicitly pass undefined
167
- "unicorn/number-literal-case": ["error", { hexadecimalValue: "lowercase" }],
168
- "unicorn/numeric-separators-style": "off",
169
- "unicorn/prefer-bigint-literals": "off",
170
- "unicorn/prefer-classlist-toggle": "off",
171
- "unicorn/prefer-dom-node-append": "off",
172
- "unicorn/prefer-dom-node-remove": "off",
173
- "unicorn/prefer-dom-node-text-content": "off",
174
- "unicorn/prefer-event-target": "off",
175
- "unicorn/prefer-global-this": "off",
176
- "unicorn/prefer-import-meta-properties": "error",
177
- "unicorn/prefer-logical-operator-over-ternary": "off",
178
- "unicorn/prefer-modern-dom-apis": "off",
179
- "unicorn/prefer-module": "off",
180
- "unicorn/prefer-native-coercion-functions": "off",
181
- "unicorn/prefer-optional-catch-binding": "off", // covered by sonarjs/no-ignored-exceptions
182
- "unicorn/prefer-queue-microtask": [
183
- "error",
184
- { checkSetImmediate: true, checkSetTimeout: true },
185
- ],
186
- "unicorn/prefer-response-static-json": "off",
187
- "unicorn/prefer-scoped-selector": "off",
188
- "unicorn/prefer-short-arrow-method": "off",
189
- "unicorn/prefer-single-call": "off",
190
- "unicorn/prefer-spread": "off", // for now
191
- "unicorn/prefer-string-raw": "off", // for now
192
- "unicorn/prefer-ternary": "off",
193
- "unicorn/prevent-abbreviations": "off",
194
- "unicorn/relative-url-style": "warn",
195
- "unicorn/require-css-escape": "off", // would be useful but we dont have CSS.escape()
196
- "unicorn/require-module-attributes": "off",
197
- "unicorn/require-module-specifiers": "off",
198
- "unicorn/switch-case-braces": "off",
199
- "unicorn/text-encoding-identifier-case": "off",
200
- ...filterRules(eslintConfigPrettier.rules, (rule) => {
201
- return rule.startsWith("unicorn/");
202
- }),
133
+ ],
134
+ "unicorn/consistent-empty-array-spread": "off",
135
+ "unicorn/custom-error-definition": "error",
136
+ "unicorn/dom-node-dataset": "off",
137
+ "unicorn/escape-case": "off", // typically not useful for this organisation
138
+ "unicorn/expiring-todo-comments": "off", // could be useful later
139
+ "unicorn/explicit-length-check": ["error", { "non-zero": "greater-than" }],
140
+ "unicorn/filename-case": [
141
+ /* enforce kebab-case in filenames */
142
+ "error",
143
+ {
144
+ case: "kebabCase",
145
+ ignore: ["^__(fixtures|mocks|snapshots|tests)__$", "^Gruntfile.js$"],
146
+ },
147
+ ],
148
+ "unicorn/prefer-minimal-ternary": "off", // situational, i dont think `foo[expr ? "x": "y"].bar` is more readable than `expr ? foo.x.bar : foo.y.bar`.
149
+ "unicorn/import-style": "off", // off for now
150
+ "unicorn/no-abusive-eslint-disable": "off", // covered by eslint-plugin-eslint-comments
151
+ "unicorn/no-array-callback-reference": "off", // opinionated, prefer to allow passing function references to array methods (and for most part TypeScript will handle this)
152
+ "unicorn/no-array-reduce": "off", // allow usage of reduce()
153
+ "unicorn/no-canvas-to-image": "off", // not really relevant for the html-validate projects
154
+ "unicorn/no-document-cookie": "off", // typically not useful for this organisation
155
+ "unicorn/no-empty-file": "off",
156
+ "unicorn/no-immediate-mutation": "off",
157
+ "unicorn/no-invalid-argument-count": "off", // does not respect optional parameters (e.g. jsdoc [param])
158
+ "unicorn/no-invalid-fetch-options": "off", // let TypeScript and tests handle this
159
+ "unicorn/no-named-default": "off", // named default is useful for Vue.js
160
+ "unicorn/no-negated-condition": "off", // mostly agree with the rule but sometimes its useful to have the common case first even if negated
161
+ "unicorn/no-negation-in-equality-check": "off",
162
+ "unicorn/no-null": "off", // prefer using null over undefined
163
+ "unicorn/no-process-exit": "off", // covered by n/no-process-exit (enabled by recommended-module preset)
164
+ "unicorn/no-single-promise-in-promise-methods": "warn",
165
+ "unicorn/no-static-only-class": "off",
166
+ "unicorn/no-thenable": "off",
167
+ "unicorn/no-this-outside-of-class": "off", // disagree somewhat with the rule, flags stateful objects
168
+ "unicorn/no-unnecessary-polyfills": "off",
169
+ "unicorn/no-unreadable-array-destructuring": "off",
170
+ "unicorn/no-unreadable-iife": "off",
171
+ "unicorn/no-useless-switch-case": "off",
172
+ "unicorn/no-useless-undefined": "off", // opinionated, I prefer to explicitly pass undefined
173
+ "unicorn/number-literal-case": ["error", { hexadecimalValue: "lowercase" }],
174
+ "unicorn/numeric-separators-style": "off",
175
+ "unicorn/prefer-bigint-literals": "off",
176
+ "unicorn/prefer-classlist-toggle": "off",
177
+ "unicorn/prefer-dom-node-append": "off",
178
+ "unicorn/prefer-dom-node-remove": "off",
179
+ "unicorn/prefer-dom-node-text-content": "off",
180
+ "unicorn/prefer-event-target": "off",
181
+ "unicorn/prefer-global-this": "off",
182
+ "unicorn/prefer-import-meta-properties": "error",
183
+ "unicorn/prefer-logical-operator-over-ternary": "off",
184
+ "unicorn/prefer-modern-dom-apis": "off",
185
+ "unicorn/prefer-module": "off",
186
+ "unicorn/prefer-native-coercion-functions": "off",
187
+ "unicorn/prefer-optional-catch-binding": "off", // covered by sonarjs/no-ignored-exceptions
188
+ "unicorn/prefer-queue-microtask": [
189
+ "error",
190
+ { checkSetImmediate: true, checkSetTimeout: true },
191
+ ],
192
+ "unicorn/prefer-response-static-json": "off",
193
+ "unicorn/prefer-scoped-selector": "off",
194
+ "unicorn/prefer-short-arrow-method": "off",
195
+ "unicorn/prefer-single-call": "off",
196
+ "unicorn/prefer-spread": "off", // for now
197
+ "unicorn/prefer-string-raw": "off", // for now
198
+ "unicorn/prefer-ternary": "off",
199
+ "unicorn/prevent-abbreviations": "off",
200
+ "unicorn/relative-url-style": "warn",
201
+ "unicorn/require-css-escape": "off", // would be useful but we dont have CSS.escape()
202
+ "unicorn/require-module-attributes": "off",
203
+ "unicorn/require-module-specifiers": "off",
204
+ "unicorn/switch-case-braces": "off",
205
+ "unicorn/text-encoding-identifier-case": "off",
206
+ ...filterRules(eslintConfigPrettier.rules, (rule) => {
207
+ return rule.startsWith("unicorn/");
208
+ }),
203
209
 
204
- /* rule adjustments */
205
- "prefer-object-spread": "error",
206
- camelcase: "error",
207
- complexity: ["warn", 10],
208
- "consistent-return": "error",
209
- "consistent-this": "off",
210
- curly: "error",
211
- "dot-notation": "error",
212
- eqeqeq: ["error", "smart"],
213
- "max-depth": ["warn", 4],
214
- "max-params": ["error", { max: 5 }],
215
- "new-cap": "error",
216
- "no-console": "warn",
217
- "no-dupe-class-members": "off",
218
- "no-eval": "error",
219
- "no-extend-native": "error",
220
- "no-implied-eval": "error",
221
- "no-loop-func": "error",
222
- "no-new": "error",
223
- "no-new-func": "error",
224
- "no-undef": "off",
225
- "no-unneeded-ternary": "error",
226
- "no-unused-vars": ["error", { ignoreRestSiblings: true, argsIgnorePattern: "^_" }],
227
- "no-var": "error",
228
- "no-warning-comments": "warn",
229
- "object-shorthand": "error",
230
- "prefer-const": "error",
231
- "prefer-rest-params": "error",
232
- "prefer-spread": "error",
233
- "prefer-template": "error",
234
- "prettier/prettier": "warn",
235
- radix: "error",
236
- strict: "off",
237
- yoda: "error",
210
+ /* rule adjustments */
211
+ "prefer-object-spread": "error",
212
+ camelcase: "error",
213
+ complexity: ["warn", 10],
214
+ "consistent-return": "error",
215
+ "consistent-this": "off",
216
+ curly: "error",
217
+ "dot-notation": "error",
218
+ eqeqeq: ["error", "smart"],
219
+ "max-depth": ["warn", 4],
220
+ "max-params": ["error", { max: 5 }],
221
+ "new-cap": "error",
222
+ "no-console": "warn",
223
+ "no-dupe-class-members": "off",
224
+ "no-eval": "error",
225
+ "no-extend-native": "error",
226
+ "no-implied-eval": "error",
227
+ "no-loop-func": "error",
228
+ "no-new": "error",
229
+ "no-new-func": "error",
230
+ "no-undef": "off",
231
+ "no-unneeded-ternary": "error",
232
+ "no-unused-vars": ["error", { ignoreRestSiblings: true, argsIgnorePattern: "^_" }],
233
+ "no-var": "error",
234
+ "no-warning-comments": "warn",
235
+ "object-shorthand": "error",
236
+ "prefer-const": "error",
237
+ "prefer-rest-params": "error",
238
+ "prefer-spread": "error",
239
+ "prefer-template": "error",
240
+ "prettier/prettier": "warn",
241
+ radix: "error",
242
+ strict: "off",
243
+ yoda: "error",
238
244
 
239
- "@eslint-community/eslint-comments/disable-enable-pair": ["error", { allowWholeFile: true }],
240
- "@eslint-community/eslint-comments/require-description": [
241
- "error",
242
- { ignore: ["eslint-enable", "eslint-env", "exported", "global", "globals"] },
243
- ],
244
- "@eslint-community/eslint-comments/no-unused-disable": "error",
245
+ "@eslint-community/eslint-comments/disable-enable-pair": [
246
+ "error",
247
+ { allowWholeFile: true },
248
+ ],
249
+ "@eslint-community/eslint-comments/require-description": [
250
+ "error",
251
+ { ignore: ["eslint-enable", "eslint-env", "exported", "global", "globals"] },
252
+ ],
253
+ "@eslint-community/eslint-comments/no-unused-disable": "error",
245
254
 
246
- "import-x/default": "off",
247
- "import-x/extensions": ["error", "never", { json: "always" }],
248
- "import-x/newline-after-import": "error",
249
- "import-x/no-absolute-path": "error",
250
- "import-x/no-deprecated": "error",
251
- "import-x/no-dynamic-require": "error",
252
- "import-x/no-extraneous-dependencies": "error",
253
- "import-x/no-mutable-exports": "error",
254
- "import-x/no-named-default": "error",
255
- "import-x/no-useless-path-segments": "error",
256
- "import-x/order": [
257
- "warn",
258
- {
259
- alphabetize: {
260
- order: "asc",
261
- orderImportKind: "asc",
255
+ "import-x/default": "off",
256
+ "import-x/extensions": ["error", "never", { json: "always" }],
257
+ "import-x/newline-after-import": "error",
258
+ "import-x/no-absolute-path": "error",
259
+ "import-x/no-deprecated": "error",
260
+ "import-x/no-dynamic-require": "error",
261
+ "import-x/no-extraneous-dependencies": "error",
262
+ "import-x/no-mutable-exports": "error",
263
+ "import-x/no-named-default": "error",
264
+ "import-x/no-useless-path-segments": "error",
265
+ "import-x/order": [
266
+ "warn",
267
+ {
268
+ alphabetize: {
269
+ order: "asc",
270
+ orderImportKind: "asc",
271
+ },
272
+ named: {
273
+ enabled: true,
274
+ types: "types-first",
275
+ },
262
276
  },
263
- named: {
264
- enabled: true,
265
- types: "types-first",
266
- },
267
- },
268
- ],
269
- "import-x/no-named-as-default": "error",
270
- "import-x/no-named-as-default-member": "error",
271
- "import-x/no-duplicates": "error",
277
+ ],
278
+ "import-x/no-named-as-default": "error",
279
+ "import-x/no-named-as-default-member": "error",
280
+ "import-x/no-duplicates": "error",
272
281
 
273
- /* this is checked by compiler and without additional configuration does not
274
- * work with TypeScript */
275
- "n/no-missing-import": "off",
276
- "n/no-missing-require": "off",
282
+ /* this is checked by compiler and without additional configuration does not
283
+ * work with TypeScript */
284
+ "n/no-missing-import": "off",
285
+ "n/no-missing-require": "off",
277
286
 
278
- /* prefer "node:foo" over "foo" */
279
- "n/prefer-node-protocol": "error",
287
+ /* prefer "node:foo" over "foo" */
288
+ "n/prefer-node-protocol": "error",
280
289
 
281
- "security/detect-child-process": "off", // produces more noise than useful errors
282
- "security/detect-non-literal-fs-filename": "off", // html-validate reads files, don't want to acknowledge all occurrences
283
- "security/detect-non-literal-regexp": "error",
284
- "security/detect-non-literal-require": "error",
285
- "security/detect-object-injection": "off", // produces more noise than useful errors
286
- "security/detect-unsafe-regex": "error",
290
+ "security/detect-child-process": "off", // produces more noise than useful errors
291
+ "security/detect-non-literal-fs-filename": "off", // html-validate reads files, don't want to acknowledge all occurrences
292
+ "security/detect-non-literal-regexp": "error",
293
+ "security/detect-non-literal-require": "error",
294
+ "security/detect-object-injection": "off", // produces more noise than useful errors
295
+ "security/detect-unsafe-regex": "error",
287
296
 
288
- "sonarjs/argument-type": "off", // handled by TypeScript (and this rule is sometimes wrong)
289
- "sonarjs/arguments-order": "off", // another slow rule, would be nice to have enabled thought
290
- "sonarjs/assertions-in-tests": "off", // could be useful but yields lots of false positives (e.g. node:test isn't recognized)
291
- "sonarjs/cognitive-complexity": "off", // already covered by native complexity rule
292
- "sonarjs/concise-regex": "off", // already covered by unicorn/better-regex
293
- "sonarjs/deprecation": "off", // already covered by @typescript-eslint/no-deprecated
294
- "sonarjs/function-return-type": "off", // overly broad and opinionated, let TypeScript deal with this
295
- "sonarjs/no-alphabetical-sort": "off", // covered by unicorn/require-array-sort-compare
296
- "sonarjs/no-commented-code": "off", // neat rule but is very very slow (over 50% of the total linting time)
297
- "sonarjs/no-control-regex": "off", // already covered by no-control-regexp
298
- "sonarjs/no-empty-test-file": "off", // could be useful but it does not handle it.each or similar constructs thus yields more false positives than its worth */
299
- "sonarjs/no-redundant-optional": "off", // flags "foo?: string | undefined" as redundant even if `exactOptionalPropertyTypes` tsconfig is enabled */
300
- "sonarjs/no-skipped-tests": "off", // covered by jest/no-disabled-tests and mocha/no-pending-tests
301
- "sonarjs/no-small-switch": "off", // prefer to use small switches when the intention is to all more cases later
302
- "sonarjs/no-trivial-assertions": "off", // produces a bit too much noise
303
- "sonarjs/no-unused-vars": "off", // already coveredby @typescript-eslint/no-unused-vars
304
- "sonarjs/prefer-nullish-coalescing": "off", // requires TypeScript and strictNullChecks, which is sane, but we also use @typescript-eslint/prefer-nullish-coalescing so this becomes redundant
305
- "sonarjs/prefer-regexp-exec": "off", // prefer @typescript-eslint/prefer-regexp-exec
306
- "sonarjs/prefer-single-boolean-return": "off", // prefer to use multiple returns even for booleans (looks better and can yield performance increase
307
- "sonarjs/redundant-type-aliases": "off", // "redundant" type aliases helps with self-documenting code
308
- "sonarjs/super-linear-regex": "off", // covered by regexp/no-super-linear-backtracking
309
- "sonarjs/todo-tag": "off", // want to be able to leave todo tasks
310
- "sonarjs/unused-import": "off", // already covered by @typescript-eslint/no-unused-vars
311
- "sonarjs/unused-named-groups": "off", // named groups can help readability even if not used
312
- "sonarjs/use-type-alias": "off", // overly broad, lets leave this to the discretion of the author
313
- "sonarjs/void-use": "off", // used to silence warnings about unawaited promises
297
+ "sonarjs/argument-type": "off", // handled by TypeScript (and this rule is sometimes wrong)
298
+ "sonarjs/arguments-order": "off", // another slow rule, would be nice to have enabled thought
299
+ "sonarjs/assertions-in-tests": "off", // could be useful but yields lots of false positives (e.g. node:test isn't recognized)
300
+ "sonarjs/cognitive-complexity": "off", // already covered by native complexity rule
301
+ "sonarjs/concise-regex": "off", // already covered by unicorn/better-regex
302
+ "sonarjs/deprecation": "off", // already covered by @typescript-eslint/no-deprecated
303
+ "sonarjs/function-return-type": "off", // overly broad and opinionated, let TypeScript deal with this
304
+ "sonarjs/no-alphabetical-sort": "off", // covered by unicorn/require-array-sort-compare
305
+ "sonarjs/no-commented-code": "off", // neat rule but is very very slow (over 50% of the total linting time)
306
+ "sonarjs/no-control-regex": "off", // already covered by no-control-regexp
307
+ "sonarjs/no-empty-test-file": "off", // could be useful but it does not handle it.each or similar constructs thus yields more false positives than its worth */
308
+ "sonarjs/no-redundant-optional": "off", // flags "foo?: string | undefined" as redundant even if `exactOptionalPropertyTypes` tsconfig is enabled */
309
+ "sonarjs/no-skipped-tests": "off", // covered by jest/no-disabled-tests and mocha/no-pending-tests
310
+ "sonarjs/no-small-switch": "off", // prefer to use small switches when the intention is to all more cases later
311
+ "sonarjs/no-trivial-assertions": "off", // produces a bit too much noise
312
+ "sonarjs/no-unused-vars": "off", // already coveredby @typescript-eslint/no-unused-vars
313
+ "sonarjs/prefer-nullish-coalescing": "off", // requires TypeScript and strictNullChecks, which is sane, but we also use @typescript-eslint/prefer-nullish-coalescing so this becomes redundant
314
+ "sonarjs/prefer-regexp-exec": "off", // prefer @typescript-eslint/prefer-regexp-exec
315
+ "sonarjs/prefer-single-boolean-return": "off", // prefer to use multiple returns even for booleans (looks better and can yield performance increase
316
+ "sonarjs/redundant-type-aliases": "off", // "redundant" type aliases helps with self-documenting code
317
+ "sonarjs/super-linear-regex": "off", // covered by regexp/no-super-linear-backtracking
318
+ "sonarjs/todo-tag": "off", // want to be able to leave todo tasks
319
+ "sonarjs/unused-import": "off", // already covered by @typescript-eslint/no-unused-vars
320
+ "sonarjs/unused-named-groups": "off", // named groups can help readability even if not used
321
+ "sonarjs/use-type-alias": "off", // overly broad, lets leave this to the discretion of the author
322
+ "sonarjs/void-use": "off", // used to silence warnings about unawaited promises
314
323
 
315
- /* disable sonarjs AWS related rules as we dont use AWS */
316
- "sonarjs/aws-apigateway-public-api": "off",
317
- "sonarjs/aws-ec2-rds-dms-public": "off",
318
- "sonarjs/aws-ec2-unencrypted-ebs-volume": "off",
319
- "sonarjs/aws-efs-unencrypted": "off",
320
- "sonarjs/aws-iam-all-privileges": "off",
321
- "sonarjs/aws-iam-all-resources-accessible": "off",
322
- "sonarjs/aws-iam-privilege-escalation": "off",
323
- "sonarjs/aws-iam-public-access": "off",
324
- "sonarjs/aws-opensearchservice-domain": "off",
325
- "sonarjs/aws-rds-unencrypted-databases": "off",
326
- "sonarjs/aws-restricted-ip-admin-access": "off",
327
- "sonarjs/aws-s3-bucket-granted-access": "off",
328
- "sonarjs/aws-s3-bucket-insecure-http": "off",
329
- "sonarjs/aws-s3-bucket-public-access": "off",
330
- "sonarjs/aws-s3-bucket-server-encryption": "off",
331
- "sonarjs/aws-s3-bucket-versioning": "off",
332
- "sonarjs/aws-sagemaker-unencrypted-notebook": "off",
333
- "sonarjs/aws-sns-unencrypted-topics": "off",
334
- "sonarjs/aws-sqs-unencrypted-queue": "off",
335
- },
336
- }),
324
+ /* disable sonarjs AWS related rules as we dont use AWS */
325
+ "sonarjs/aws-apigateway-public-api": "off",
326
+ "sonarjs/aws-ec2-rds-dms-public": "off",
327
+ "sonarjs/aws-ec2-unencrypted-ebs-volume": "off",
328
+ "sonarjs/aws-efs-unencrypted": "off",
329
+ "sonarjs/aws-iam-all-privileges": "off",
330
+ "sonarjs/aws-iam-all-resources-accessible": "off",
331
+ "sonarjs/aws-iam-privilege-escalation": "off",
332
+ "sonarjs/aws-iam-public-access": "off",
333
+ "sonarjs/aws-opensearchservice-domain": "off",
334
+ "sonarjs/aws-rds-unencrypted-databases": "off",
335
+ "sonarjs/aws-restricted-ip-admin-access": "off",
336
+ "sonarjs/aws-s3-bucket-granted-access": "off",
337
+ "sonarjs/aws-s3-bucket-insecure-http": "off",
338
+ "sonarjs/aws-s3-bucket-public-access": "off",
339
+ "sonarjs/aws-s3-bucket-server-encryption": "off",
340
+ "sonarjs/aws-s3-bucket-versioning": "off",
341
+ "sonarjs/aws-sagemaker-unencrypted-notebook": "off",
342
+ "sonarjs/aws-sns-unencrypted-topics": "off",
343
+ "sonarjs/aws-sqs-unencrypted-queue": "off",
344
+ },
345
+ }),
337
346
 
338
- defineConfig({
339
- /* loosen rules for build scripts */
340
- name: "@html-validate/eslint-config/scripts",
341
- files: ["*.{js,mjs,cjs}", "*.{ts,mts,cts}"],
342
- rules: {
343
- "no-console": "off",
344
- },
345
- }),
347
+ defineConfig({
348
+ /* loosen rules for build scripts */
349
+ name: "@html-validate/eslint-config/scripts",
350
+ files: ["*.{js,mjs,cjs}", "*.{ts,mts,cts}"],
351
+ rules: {
352
+ "no-console": "off",
353
+ },
354
+ }),
346
355
 
347
- defineConfig({
348
- /* ensure all of these patterns are linted */
349
- name: "@html-validate/eslint-config/extensions",
350
- files: ["**/*.js", "**/*.cjs", "**/*.mjs"],
351
- }),
356
+ defineConfig({
357
+ /* ensure all of these patterns are linted */
358
+ name: "@html-validate/eslint-config/extensions",
359
+ files: ["**/*.js", "**/*.cjs", "**/*.mjs"],
360
+ }),
352
361
 
353
- defineConfig({
354
- /* disable rules requiring esm-only features */
355
- name: "@html-validate/eslint-config/cjs",
356
- files: ["**/*.cjs", "**/*.cts"],
357
- rules: {
358
- "unicorn/prefer-import-meta-properties": "off",
359
- "unicorn/prefer-top-level-await": "off",
360
- },
361
- }),
362
+ defineConfig({
363
+ /* disable rules requiring esm-only features */
364
+ name: "@html-validate/eslint-config/cjs",
365
+ files: ["**/*.cjs", "**/*.cts"],
366
+ rules: {
367
+ "unicorn/prefer-import-meta-properties": "off",
368
+ "unicorn/prefer-top-level-await": "off",
369
+ },
370
+ }),
362
371
 
363
- defineConfig({
364
- /* mjs requires file extension */
365
- name: "@html-validate/eslint-config/esm",
366
- files: ["**/*.mjs", "**/*.mts"],
367
- rules: {
368
- "import-x/extensions": [
369
- "error",
370
- "always",
371
- {
372
- ignorePackages: true,
373
- },
374
- ],
375
- },
376
- }),
372
+ defineConfig({
373
+ /* specific rules for modules */
374
+ name: "@html-validate/eslint-config/esm",
375
+ files: moduleExtensions.map((it) => `**/*.${it}`),
376
+ rules: {
377
+ "import-x/extensions": [
378
+ "error",
379
+ "always",
380
+ {
381
+ ignorePackages: true,
382
+ },
383
+ ],
384
+ },
385
+ }),
377
386
 
378
- defineConfig({
379
- /* files which should lint even if project isn't build yet */
380
- name: "@html-validate/eslint-config/dist",
381
- files: ["*.d.ts", ".htmlvalidate.{js,mjs,cjs}", "bin/*.{js,mjs,cjs}"],
382
- rules: {
383
- "import-x/export": "off",
384
- "import-x/extensions": "off",
385
- "import-x/no-unresolved": "off",
386
- },
387
- }),
387
+ defineConfig({
388
+ /* files which should lint even if project isn't build yet */
389
+ name: "@html-validate/eslint-config/dist",
390
+ files: ["*.d.ts", ".htmlvalidate.{js,mjs,cjs}", "bin/*.{js,mjs,cjs}"],
391
+ rules: {
392
+ "import-x/export": "off",
393
+ "import-x/extensions": "off",
394
+ "import-x/no-unresolved": "off",
395
+ },
396
+ }),
388
397
 
389
- defineConfig({
390
- /* semantic-release is only installed on demand during release, so the
391
- * imports in this file would be unresolved in a regular build */
392
- name: "@html-validate/eslint-config/semantic-release",
393
- files: ["release.config.{js,mjs}"],
394
- rules: {
395
- "import-x/no-unresolved": "off",
396
- },
397
- }),
398
- ];
398
+ defineConfig({
399
+ /* semantic-release is only installed on demand during release, so the
400
+ * imports in this file would be unresolved in a regular build */
401
+ name: "@html-validate/eslint-config/semantic-release",
402
+ files: ["release.config.{js,mjs}"],
403
+ rules: {
404
+ "import-x/no-unresolved": "off",
405
+ },
406
+ }),
407
+ ];
408
+
409
+ return configs;
410
+ }