eslint 9.22.0 → 9.23.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.
Files changed (415) hide show
  1. package/README.md +47 -45
  2. package/bin/eslint.js +92 -90
  3. package/conf/default-cli-options.js +22 -22
  4. package/conf/ecma-version.js +1 -1
  5. package/conf/globals.js +97 -98
  6. package/conf/replacements.json +24 -20
  7. package/conf/rule-type-list.json +88 -92
  8. package/lib/api.js +12 -12
  9. package/lib/cli-engine/cli-engine.js +828 -808
  10. package/lib/cli-engine/file-enumerator.js +381 -387
  11. package/lib/cli-engine/formatters/formatters-meta.json +16 -16
  12. package/lib/cli-engine/formatters/html.js +107 -99
  13. package/lib/cli-engine/formatters/json-with-metadata.js +5 -5
  14. package/lib/cli-engine/formatters/json.js +2 -2
  15. package/lib/cli-engine/formatters/stylish.js +96 -75
  16. package/lib/cli-engine/hash.js +1 -1
  17. package/lib/cli-engine/index.js +1 -1
  18. package/lib/cli-engine/lint-result-cache.js +144 -145
  19. package/lib/cli-engine/load-rules.js +16 -16
  20. package/lib/cli.js +541 -457
  21. package/lib/config/config-loader.js +648 -618
  22. package/lib/config/config.js +247 -221
  23. package/lib/config/default-config.js +54 -45
  24. package/lib/config/flat-config-array.js +167 -172
  25. package/lib/config/flat-config-helpers.js +65 -68
  26. package/lib/config/flat-config-schema.js +375 -368
  27. package/lib/config/rule-validator.js +139 -144
  28. package/lib/config-api.js +2 -2
  29. package/lib/eslint/eslint-helpers.js +709 -679
  30. package/lib/eslint/eslint.js +944 -886
  31. package/lib/eslint/index.js +2 -2
  32. package/lib/eslint/legacy-eslint.js +576 -532
  33. package/lib/languages/js/index.js +263 -264
  34. package/lib/languages/js/source-code/index.js +1 -1
  35. package/lib/languages/js/source-code/source-code.js +1128 -1057
  36. package/lib/languages/js/source-code/token-store/backward-token-comment-cursor.js +39 -35
  37. package/lib/languages/js/source-code/token-store/backward-token-cursor.js +35 -36
  38. package/lib/languages/js/source-code/token-store/cursor.js +36 -36
  39. package/lib/languages/js/source-code/token-store/cursors.js +80 -52
  40. package/lib/languages/js/source-code/token-store/decorative-cursor.js +17 -18
  41. package/lib/languages/js/source-code/token-store/filter-cursor.js +19 -20
  42. package/lib/languages/js/source-code/token-store/forward-token-comment-cursor.js +40 -32
  43. package/lib/languages/js/source-code/token-store/forward-token-cursor.js +40 -41
  44. package/lib/languages/js/source-code/token-store/index.js +592 -498
  45. package/lib/languages/js/source-code/token-store/limit-cursor.js +17 -18
  46. package/lib/languages/js/source-code/token-store/padded-token-cursor.js +23 -16
  47. package/lib/languages/js/source-code/token-store/skip-cursor.js +19 -20
  48. package/lib/languages/js/source-code/token-store/utils.js +63 -60
  49. package/lib/languages/js/validate-language-options.js +104 -89
  50. package/lib/linter/apply-disable-directives.js +467 -383
  51. package/lib/linter/code-path-analysis/code-path-analyzer.js +650 -672
  52. package/lib/linter/code-path-analysis/code-path-segment.js +215 -216
  53. package/lib/linter/code-path-analysis/code-path-state.js +2118 -2096
  54. package/lib/linter/code-path-analysis/code-path.js +307 -319
  55. package/lib/linter/code-path-analysis/debug-helpers.js +183 -163
  56. package/lib/linter/code-path-analysis/fork-context.js +296 -271
  57. package/lib/linter/code-path-analysis/id-generator.js +22 -23
  58. package/lib/linter/file-context.js +119 -120
  59. package/lib/linter/index.js +3 -3
  60. package/lib/linter/interpolate.js +16 -16
  61. package/lib/linter/linter.js +2402 -2044
  62. package/lib/linter/node-event-generator.js +284 -225
  63. package/lib/linter/report-translator.js +256 -219
  64. package/lib/linter/rule-fixer.js +122 -124
  65. package/lib/linter/rules.js +35 -35
  66. package/lib/linter/safe-emitter.js +18 -18
  67. package/lib/linter/source-code-fixer.js +94 -92
  68. package/lib/linter/timing.js +104 -101
  69. package/lib/linter/vfile.js +70 -73
  70. package/lib/options.js +375 -361
  71. package/lib/rule-tester/index.js +1 -1
  72. package/lib/rule-tester/rule-tester.js +1307 -1045
  73. package/lib/rules/accessor-pairs.js +297 -262
  74. package/lib/rules/array-bracket-newline.js +249 -237
  75. package/lib/rules/array-bracket-spacing.js +262 -223
  76. package/lib/rules/array-callback-return.js +401 -355
  77. package/lib/rules/array-element-newline.js +357 -312
  78. package/lib/rules/arrow-body-style.js +399 -280
  79. package/lib/rules/arrow-parens.js +205 -172
  80. package/lib/rules/arrow-spacing.js +168 -162
  81. package/lib/rules/block-scoped-var.js +124 -122
  82. package/lib/rules/block-spacing.js +185 -175
  83. package/lib/rules/brace-style.js +261 -198
  84. package/lib/rules/callback-return.js +202 -189
  85. package/lib/rules/camelcase.js +402 -391
  86. package/lib/rules/capitalized-comments.js +252 -231
  87. package/lib/rules/class-methods-use-this.js +179 -171
  88. package/lib/rules/comma-dangle.js +378 -345
  89. package/lib/rules/comma-spacing.js +192 -194
  90. package/lib/rules/comma-style.js +374 -315
  91. package/lib/rules/complexity.js +172 -168
  92. package/lib/rules/computed-property-spacing.js +235 -210
  93. package/lib/rules/consistent-return.js +180 -169
  94. package/lib/rules/consistent-this.js +166 -146
  95. package/lib/rules/constructor-super.js +411 -403
  96. package/lib/rules/curly.js +406 -331
  97. package/lib/rules/default-case-last.js +37 -30
  98. package/lib/rules/default-case.js +88 -84
  99. package/lib/rules/default-param-last.js +68 -53
  100. package/lib/rules/dot-location.js +121 -109
  101. package/lib/rules/dot-notation.js +191 -155
  102. package/lib/rules/eol-last.js +121 -119
  103. package/lib/rules/eqeqeq.js +167 -154
  104. package/lib/rules/for-direction.js +145 -120
  105. package/lib/rules/func-call-spacing.js +260 -230
  106. package/lib/rules/func-name-matching.js +292 -208
  107. package/lib/rules/func-names.js +164 -163
  108. package/lib/rules/func-style.js +158 -126
  109. package/lib/rules/function-call-argument-newline.js +151 -128
  110. package/lib/rules/function-paren-newline.js +348 -290
  111. package/lib/rules/generator-star-spacing.js +228 -209
  112. package/lib/rules/getter-return.js +207 -171
  113. package/lib/rules/global-require.js +84 -73
  114. package/lib/rules/grouped-accessor-pairs.js +169 -149
  115. package/lib/rules/guard-for-in.js +71 -62
  116. package/lib/rules/handle-callback-err.js +107 -102
  117. package/lib/rules/id-blacklist.js +181 -198
  118. package/lib/rules/id-denylist.js +167 -186
  119. package/lib/rules/id-length.js +196 -170
  120. package/lib/rules/id-match.js +343 -288
  121. package/lib/rules/implicit-arrow-linebreak.js +101 -78
  122. package/lib/rules/indent-legacy.js +1343 -1117
  123. package/lib/rules/indent.js +2271 -1758
  124. package/lib/rules/index.js +317 -292
  125. package/lib/rules/init-declarations.js +115 -106
  126. package/lib/rules/jsx-quotes.js +93 -81
  127. package/lib/rules/key-spacing.js +749 -632
  128. package/lib/rules/keyword-spacing.js +647 -604
  129. package/lib/rules/line-comment-position.js +141 -127
  130. package/lib/rules/linebreak-style.js +106 -105
  131. package/lib/rules/lines-around-comment.js +539 -447
  132. package/lib/rules/lines-around-directive.js +232 -202
  133. package/lib/rules/lines-between-class-members.js +304 -233
  134. package/lib/rules/logical-assignment-operators.js +581 -398
  135. package/lib/rules/max-classes-per-file.js +68 -67
  136. package/lib/rules/max-depth.js +145 -142
  137. package/lib/rules/max-len.js +472 -433
  138. package/lib/rules/max-lines-per-function.js +200 -175
  139. package/lib/rules/max-lines.js +157 -161
  140. package/lib/rules/max-nested-callbacks.js +101 -103
  141. package/lib/rules/max-params.js +77 -75
  142. package/lib/rules/max-statements-per-line.js +204 -197
  143. package/lib/rules/max-statements.js +167 -163
  144. package/lib/rules/multiline-comment-style.js +636 -478
  145. package/lib/rules/multiline-ternary.js +240 -175
  146. package/lib/rules/new-cap.js +232 -212
  147. package/lib/rules/new-parens.js +87 -78
  148. package/lib/rules/newline-after-var.js +286 -249
  149. package/lib/rules/newline-before-return.js +228 -221
  150. package/lib/rules/newline-per-chained-call.js +141 -126
  151. package/lib/rules/no-alert.js +89 -78
  152. package/lib/rules/no-array-constructor.js +121 -112
  153. package/lib/rules/no-async-promise-executor.js +29 -23
  154. package/lib/rules/no-await-in-loop.js +68 -70
  155. package/lib/rules/no-bitwise.js +123 -99
  156. package/lib/rules/no-buffer-constructor.js +54 -46
  157. package/lib/rules/no-caller.js +38 -32
  158. package/lib/rules/no-case-declarations.js +60 -56
  159. package/lib/rules/no-catch-shadow.js +75 -72
  160. package/lib/rules/no-class-assign.js +50 -47
  161. package/lib/rules/no-compare-neg-zero.js +61 -47
  162. package/lib/rules/no-cond-assign.js +147 -131
  163. package/lib/rules/no-confusing-arrow.js +97 -80
  164. package/lib/rules/no-console.js +201 -198
  165. package/lib/rules/no-const-assign.js +46 -40
  166. package/lib/rules/no-constant-binary-expression.js +499 -404
  167. package/lib/rules/no-constant-condition.js +157 -142
  168. package/lib/rules/no-constructor-return.js +48 -48
  169. package/lib/rules/no-continue.js +24 -26
  170. package/lib/rules/no-control-regex.js +124 -120
  171. package/lib/rules/no-debugger.js +27 -29
  172. package/lib/rules/no-delete-var.js +28 -28
  173. package/lib/rules/no-div-regex.js +46 -40
  174. package/lib/rules/no-dupe-args.js +67 -68
  175. package/lib/rules/no-dupe-class-members.js +92 -88
  176. package/lib/rules/no-dupe-else-if.js +99 -76
  177. package/lib/rules/no-dupe-keys.js +132 -109
  178. package/lib/rules/no-duplicate-case.js +49 -42
  179. package/lib/rules/no-duplicate-imports.js +178 -175
  180. package/lib/rules/no-else-return.js +429 -384
  181. package/lib/rules/no-empty-character-class.js +56 -49
  182. package/lib/rules/no-empty-function.js +126 -127
  183. package/lib/rules/no-empty-pattern.js +62 -57
  184. package/lib/rules/no-empty-static-block.js +36 -34
  185. package/lib/rules/no-empty.js +97 -85
  186. package/lib/rules/no-eq-null.js +36 -31
  187. package/lib/rules/no-eval.js +255 -249
  188. package/lib/rules/no-ex-assign.js +41 -38
  189. package/lib/rules/no-extend-native.js +160 -158
  190. package/lib/rules/no-extra-bind.js +200 -189
  191. package/lib/rules/no-extra-boolean-cast.js +397 -347
  192. package/lib/rules/no-extra-label.js +149 -130
  193. package/lib/rules/no-extra-parens.js +1653 -1324
  194. package/lib/rules/no-extra-semi.js +145 -143
  195. package/lib/rules/no-fallthrough.js +198 -156
  196. package/lib/rules/no-floating-decimal.js +73 -65
  197. package/lib/rules/no-func-assign.js +53 -54
  198. package/lib/rules/no-global-assign.js +77 -72
  199. package/lib/rules/no-implicit-coercion.js +348 -292
  200. package/lib/rules/no-implicit-globals.js +157 -134
  201. package/lib/rules/no-implied-eval.js +139 -111
  202. package/lib/rules/no-import-assign.js +144 -158
  203. package/lib/rules/no-inline-comments.js +100 -94
  204. package/lib/rules/no-inner-declarations.js +114 -100
  205. package/lib/rules/no-invalid-regexp.js +221 -189
  206. package/lib/rules/no-invalid-this.js +122 -116
  207. package/lib/rules/no-irregular-whitespace.js +265 -251
  208. package/lib/rules/no-iterator.js +28 -32
  209. package/lib/rules/no-label-var.js +58 -61
  210. package/lib/rules/no-labels.js +137 -132
  211. package/lib/rules/no-lone-blocks.js +126 -122
  212. package/lib/rules/no-lonely-if.js +107 -76
  213. package/lib/rules/no-loop-func.js +233 -212
  214. package/lib/rules/no-loss-of-precision.js +215 -200
  215. package/lib/rules/no-magic-numbers.js +245 -217
  216. package/lib/rules/no-misleading-character-class.js +498 -445
  217. package/lib/rules/no-mixed-operators.js +187 -181
  218. package/lib/rules/no-mixed-requires.js +252 -239
  219. package/lib/rules/no-mixed-spaces-and-tabs.js +133 -120
  220. package/lib/rules/no-multi-assign.js +45 -43
  221. package/lib/rules/no-multi-spaces.js +162 -142
  222. package/lib/rules/no-multi-str.js +41 -40
  223. package/lib/rules/no-multiple-empty-lines.js +195 -157
  224. package/lib/rules/no-native-reassign.js +89 -84
  225. package/lib/rules/no-negated-condition.js +78 -74
  226. package/lib/rules/no-negated-in-lhs.js +44 -42
  227. package/lib/rules/no-nested-ternary.js +32 -31
  228. package/lib/rules/no-new-func.js +70 -61
  229. package/lib/rules/no-new-native-nonconstructor.js +42 -38
  230. package/lib/rules/no-new-object.js +47 -47
  231. package/lib/rules/no-new-require.js +47 -46
  232. package/lib/rules/no-new-symbol.js +51 -49
  233. package/lib/rules/no-new-wrappers.js +42 -40
  234. package/lib/rules/no-new.js +27 -28
  235. package/lib/rules/no-nonoctal-decimal-escape.js +140 -120
  236. package/lib/rules/no-obj-calls.js +65 -52
  237. package/lib/rules/no-object-constructor.js +103 -96
  238. package/lib/rules/no-octal-escape.js +39 -42
  239. package/lib/rules/no-octal.js +31 -31
  240. package/lib/rules/no-param-reassign.js +234 -216
  241. package/lib/rules/no-path-concat.js +65 -66
  242. package/lib/rules/no-plusplus.js +59 -60
  243. package/lib/rules/no-process-env.js +48 -47
  244. package/lib/rules/no-process-exit.js +53 -49
  245. package/lib/rules/no-promise-executor-return.js +213 -181
  246. package/lib/rules/no-proto.js +25 -28
  247. package/lib/rules/no-prototype-builtins.js +145 -123
  248. package/lib/rules/no-redeclare.js +153 -151
  249. package/lib/rules/no-regex-spaces.js +182 -160
  250. package/lib/rules/no-restricted-exports.js +207 -184
  251. package/lib/rules/no-restricted-globals.js +110 -111
  252. package/lib/rules/no-restricted-imports.js +656 -536
  253. package/lib/rules/no-restricted-modules.js +221 -201
  254. package/lib/rules/no-restricted-properties.js +180 -152
  255. package/lib/rules/no-restricted-syntax.js +55 -51
  256. package/lib/rules/no-return-assign.js +54 -49
  257. package/lib/rules/no-return-await.js +147 -123
  258. package/lib/rules/no-script-url.js +51 -44
  259. package/lib/rules/no-self-assign.js +147 -145
  260. package/lib/rules/no-self-compare.js +62 -45
  261. package/lib/rules/no-sequences.js +134 -115
  262. package/lib/rules/no-setter-return.js +184 -151
  263. package/lib/rules/no-shadow-restricted-names.js +60 -45
  264. package/lib/rules/no-shadow.js +341 -315
  265. package/lib/rules/no-spaced-func.js +81 -76
  266. package/lib/rules/no-sparse-arrays.js +53 -58
  267. package/lib/rules/no-sync.js +60 -59
  268. package/lib/rules/no-tabs.js +82 -71
  269. package/lib/rules/no-template-curly-in-string.js +32 -31
  270. package/lib/rules/no-ternary.js +24 -28
  271. package/lib/rules/no-this-before-super.js +320 -318
  272. package/lib/rules/no-throw-literal.js +30 -35
  273. package/lib/rules/no-trailing-spaces.js +198 -190
  274. package/lib/rules/no-undef-init.js +75 -60
  275. package/lib/rules/no-undef.js +50 -47
  276. package/lib/rules/no-undefined.js +72 -74
  277. package/lib/rules/no-underscore-dangle.js +369 -326
  278. package/lib/rules/no-unexpected-multiline.js +111 -101
  279. package/lib/rules/no-unmodified-loop-condition.js +253 -253
  280. package/lib/rules/no-unneeded-ternary.js +211 -146
  281. package/lib/rules/no-unreachable-loop.js +144 -141
  282. package/lib/rules/no-unreachable.js +254 -247
  283. package/lib/rules/no-unsafe-finally.js +92 -84
  284. package/lib/rules/no-unsafe-negation.js +104 -82
  285. package/lib/rules/no-unsafe-optional-chaining.js +191 -177
  286. package/lib/rules/no-unused-expressions.js +177 -161
  287. package/lib/rules/no-unused-labels.js +138 -123
  288. package/lib/rules/no-unused-private-class-members.js +205 -181
  289. package/lib/rules/no-unused-vars.js +1668 -1448
  290. package/lib/rules/no-use-before-define.js +228 -230
  291. package/lib/rules/no-useless-assignment.js +589 -510
  292. package/lib/rules/no-useless-backreference.js +211 -192
  293. package/lib/rules/no-useless-call.js +57 -52
  294. package/lib/rules/no-useless-catch.js +39 -39
  295. package/lib/rules/no-useless-computed-key.js +143 -114
  296. package/lib/rules/no-useless-concat.js +64 -59
  297. package/lib/rules/no-useless-constructor.js +157 -110
  298. package/lib/rules/no-useless-escape.js +341 -290
  299. package/lib/rules/no-useless-rename.js +182 -155
  300. package/lib/rules/no-useless-return.js +343 -311
  301. package/lib/rules/no-var.js +232 -211
  302. package/lib/rules/no-void.js +49 -47
  303. package/lib/rules/no-warning-comments.js +190 -185
  304. package/lib/rules/no-whitespace-before-property.js +130 -114
  305. package/lib/rules/no-with.js +23 -25
  306. package/lib/rules/nonblock-statement-body-position.js +148 -129
  307. package/lib/rules/object-curly-newline.js +305 -264
  308. package/lib/rules/object-curly-spacing.js +359 -313
  309. package/lib/rules/object-property-newline.js +136 -105
  310. package/lib/rules/object-shorthand.js +606 -501
  311. package/lib/rules/one-var-declaration-per-line.js +103 -99
  312. package/lib/rules/one-var.js +652 -536
  313. package/lib/rules/operator-assignment.js +218 -160
  314. package/lib/rules/operator-linebreak.js +294 -250
  315. package/lib/rules/padded-blocks.js +345 -307
  316. package/lib/rules/padding-line-between-statements.js +442 -438
  317. package/lib/rules/prefer-arrow-callback.js +361 -312
  318. package/lib/rules/prefer-const.js +417 -376
  319. package/lib/rules/prefer-destructuring.js +300 -278
  320. package/lib/rules/prefer-exponentiation-operator.js +175 -132
  321. package/lib/rules/prefer-named-capture-group.js +152 -139
  322. package/lib/rules/prefer-numeric-literals.js +120 -112
  323. package/lib/rules/prefer-object-has-own.js +115 -81
  324. package/lib/rules/prefer-object-spread.js +212 -192
  325. package/lib/rules/prefer-promise-reject-errors.js +139 -121
  326. package/lib/rules/prefer-reflect.js +126 -106
  327. package/lib/rules/prefer-regex-literals.js +577 -465
  328. package/lib/rules/prefer-rest-params.js +78 -79
  329. package/lib/rules/prefer-spread.js +46 -43
  330. package/lib/rules/prefer-template.js +265 -194
  331. package/lib/rules/quote-props.js +372 -306
  332. package/lib/rules/quotes.js +373 -325
  333. package/lib/rules/radix.js +151 -135
  334. package/lib/rules/require-atomic-updates.js +315 -284
  335. package/lib/rules/require-await.js +143 -115
  336. package/lib/rules/require-unicode-regexp.js +281 -176
  337. package/lib/rules/require-yield.js +52 -53
  338. package/lib/rules/rest-spread-spacing.js +127 -115
  339. package/lib/rules/semi-spacing.js +280 -249
  340. package/lib/rules/semi-style.js +175 -133
  341. package/lib/rules/semi.js +455 -435
  342. package/lib/rules/sort-imports.js +305 -232
  343. package/lib/rules/sort-keys.js +218 -187
  344. package/lib/rules/sort-vars.js +126 -92
  345. package/lib/rules/space-before-blocks.js +198 -188
  346. package/lib/rules/space-before-function-paren.js +185 -165
  347. package/lib/rules/space-in-parens.js +358 -287
  348. package/lib/rules/space-infix-ops.js +236 -200
  349. package/lib/rules/space-unary-ops.js +355 -297
  350. package/lib/rules/spaced-comment.js +362 -318
  351. package/lib/rules/strict.js +264 -229
  352. package/lib/rules/switch-colon-spacing.js +129 -121
  353. package/lib/rules/symbol-description.js +44 -47
  354. package/lib/rules/template-curly-spacing.js +147 -141
  355. package/lib/rules/template-tag-spacing.js +97 -87
  356. package/lib/rules/unicode-bom.js +53 -55
  357. package/lib/rules/use-isnan.js +236 -205
  358. package/lib/rules/utils/ast-utils.js +2039 -1860
  359. package/lib/rules/utils/char-source.js +162 -155
  360. package/lib/rules/utils/fix-tracker.js +83 -80
  361. package/lib/rules/utils/keywords.js +59 -59
  362. package/lib/rules/utils/lazy-loading-rule-map.js +79 -76
  363. package/lib/rules/utils/regular-expressions.js +32 -24
  364. package/lib/rules/utils/unicode/index.js +4 -4
  365. package/lib/rules/utils/unicode/is-combining-character.js +1 -1
  366. package/lib/rules/utils/unicode/is-emoji-modifier.js +1 -1
  367. package/lib/rules/utils/unicode/is-regional-indicator-symbol.js +1 -1
  368. package/lib/rules/utils/unicode/is-surrogate-pair.js +1 -1
  369. package/lib/rules/valid-typeof.js +152 -110
  370. package/lib/rules/vars-on-top.js +151 -144
  371. package/lib/rules/wrap-iife.js +203 -190
  372. package/lib/rules/wrap-regex.js +69 -57
  373. package/lib/rules/yield-star-spacing.js +144 -133
  374. package/lib/rules/yoda.js +282 -271
  375. package/lib/services/parser-service.js +35 -35
  376. package/lib/services/processor-service.js +66 -73
  377. package/lib/shared/ajv.js +14 -14
  378. package/lib/shared/assert.js +3 -4
  379. package/lib/shared/ast-utils.js +7 -6
  380. package/lib/shared/deep-merge-arrays.js +24 -22
  381. package/lib/shared/directives.js +3 -2
  382. package/lib/shared/flags.js +46 -17
  383. package/lib/shared/logging.js +24 -25
  384. package/lib/shared/option-utils.js +43 -36
  385. package/lib/shared/runtime-info.js +136 -127
  386. package/lib/shared/serialization.js +27 -27
  387. package/lib/shared/severity.js +22 -22
  388. package/lib/shared/stats.js +5 -5
  389. package/lib/shared/string-utils.js +16 -16
  390. package/lib/shared/text-table.js +28 -27
  391. package/lib/shared/traverser.js +153 -146
  392. package/lib/types/index.d.ts +2010 -1559
  393. package/lib/types/rules.d.ts +5253 -5140
  394. package/lib/types/use-at-your-own-risk.d.ts +32 -30
  395. package/lib/unsupported-api.js +5 -5
  396. package/messages/all-files-ignored.js +3 -3
  397. package/messages/all-matched-files-ignored.js +3 -3
  398. package/messages/config-file-missing.js +2 -2
  399. package/messages/config-plugin-missing.js +3 -3
  400. package/messages/config-serialize-function.js +9 -7
  401. package/messages/eslintrc-incompat.js +13 -15
  402. package/messages/eslintrc-plugins.js +3 -4
  403. package/messages/extend-config-missing.js +3 -3
  404. package/messages/failed-to-read-json.js +3 -3
  405. package/messages/file-not-found.js +3 -3
  406. package/messages/invalid-rule-options.js +2 -2
  407. package/messages/invalid-rule-severity.js +2 -2
  408. package/messages/no-config-found.js +3 -3
  409. package/messages/plugin-conflict.js +8 -8
  410. package/messages/plugin-invalid.js +3 -3
  411. package/messages/plugin-missing.js +3 -3
  412. package/messages/print-config-with-directory-path.js +2 -2
  413. package/messages/shared.js +6 -1
  414. package/messages/whitespace-found.js +3 -3
  415. package/package.json +11 -17
@@ -43,58 +43,58 @@ const MINIMATCH_OPTIONS = { dot: true };
43
43
  * The error type when no files match a glob.
44
44
  */
45
45
  class NoFilesFoundError extends Error {
46
-
47
- /**
48
- * @param {string} pattern The glob pattern which was not found.
49
- * @param {boolean} globEnabled If `false` then the pattern was a glob pattern, but glob was disabled.
50
- */
51
- constructor(pattern, globEnabled) {
52
- super(`No files matching '${pattern}' were found${!globEnabled ? " (glob was disabled)" : ""}.`);
53
- this.messageTemplate = "file-not-found";
54
- this.messageData = { pattern, globDisabled: !globEnabled };
55
- }
46
+ /**
47
+ * @param {string} pattern The glob pattern which was not found.
48
+ * @param {boolean} globEnabled If `false` then the pattern was a glob pattern, but glob was disabled.
49
+ */
50
+ constructor(pattern, globEnabled) {
51
+ super(
52
+ `No files matching '${pattern}' were found${!globEnabled ? " (glob was disabled)" : ""}.`,
53
+ );
54
+ this.messageTemplate = "file-not-found";
55
+ this.messageData = { pattern, globDisabled: !globEnabled };
56
+ }
56
57
  }
57
58
 
58
59
  /**
59
60
  * The error type when a search fails to match multiple patterns.
60
61
  */
61
62
  class UnmatchedSearchPatternsError extends Error {
62
-
63
- /**
64
- * @param {Object} options The options for the error.
65
- * @param {string} options.basePath The directory that was searched.
66
- * @param {Array<string>} options.unmatchedPatterns The glob patterns
67
- * which were not found.
68
- * @param {Array<string>} options.patterns The glob patterns that were
69
- * searched.
70
- * @param {Array<string>} options.rawPatterns The raw glob patterns that
71
- * were searched.
72
- */
73
- constructor({ basePath, unmatchedPatterns, patterns, rawPatterns }) {
74
- super(`No files matching '${rawPatterns}' in '${basePath}' were found.`);
75
- this.basePath = basePath;
76
- this.unmatchedPatterns = unmatchedPatterns;
77
- this.patterns = patterns;
78
- this.rawPatterns = rawPatterns;
79
- }
63
+ /**
64
+ * @param {Object} options The options for the error.
65
+ * @param {string} options.basePath The directory that was searched.
66
+ * @param {Array<string>} options.unmatchedPatterns The glob patterns
67
+ * which were not found.
68
+ * @param {Array<string>} options.patterns The glob patterns that were
69
+ * searched.
70
+ * @param {Array<string>} options.rawPatterns The raw glob patterns that
71
+ * were searched.
72
+ */
73
+ constructor({ basePath, unmatchedPatterns, patterns, rawPatterns }) {
74
+ super(
75
+ `No files matching '${rawPatterns}' in '${basePath}' were found.`,
76
+ );
77
+ this.basePath = basePath;
78
+ this.unmatchedPatterns = unmatchedPatterns;
79
+ this.patterns = patterns;
80
+ this.rawPatterns = rawPatterns;
81
+ }
80
82
  }
81
83
 
82
84
  /**
83
85
  * The error type when there are files matched by a glob, but all of them have been ignored.
84
86
  */
85
87
  class AllFilesIgnoredError extends Error {
86
-
87
- /**
88
- * @param {string} pattern The glob pattern which was not found.
89
- */
90
- constructor(pattern) {
91
- super(`All files matched by '${pattern}' are ignored.`);
92
- this.messageTemplate = "all-matched-files-ignored";
93
- this.messageData = { pattern };
94
- }
88
+ /**
89
+ * @param {string} pattern The glob pattern which was not found.
90
+ */
91
+ constructor(pattern) {
92
+ super(`All files matched by '${pattern}' are ignored.`);
93
+ this.messageTemplate = "all-matched-files-ignored";
94
+ this.messageData = { pattern };
95
+ }
95
96
  }
96
97
 
97
-
98
98
  //-----------------------------------------------------------------------------
99
99
  // General Helpers
100
100
  //-----------------------------------------------------------------------------
@@ -105,7 +105,7 @@ class AllFilesIgnoredError extends Error {
105
105
  * @returns {boolean} `true` if `value` is a non-empty string.
106
106
  */
107
107
  function isNonEmptyString(value) {
108
- return typeof value === "string" && value.trim() !== "";
108
+ return typeof value === "string" && value.trim() !== "";
109
109
  }
110
110
 
111
111
  /**
@@ -114,7 +114,9 @@ function isNonEmptyString(value) {
114
114
  * @returns {boolean} `true` if `value` is an array of non-empty strings.
115
115
  */
116
116
  function isArrayOfNonEmptyString(value) {
117
- return Array.isArray(value) && value.length && value.every(isNonEmptyString);
117
+ return (
118
+ Array.isArray(value) && value.length && value.every(isNonEmptyString)
119
+ );
118
120
  }
119
121
 
120
122
  /**
@@ -124,7 +126,7 @@ function isArrayOfNonEmptyString(value) {
124
126
  * strings.
125
127
  */
126
128
  function isEmptyArrayOrArrayOfNonEmptyString(value) {
127
- return Array.isArray(value) && value.every(isNonEmptyString);
129
+ return Array.isArray(value) && value.every(isNonEmptyString);
128
130
  }
129
131
 
130
132
  //-----------------------------------------------------------------------------
@@ -137,7 +139,7 @@ function isEmptyArrayOrArrayOfNonEmptyString(value) {
137
139
  * @returns {string} The pattern with slashes normalized.
138
140
  */
139
141
  function normalizeToPosix(pattern) {
140
- return pattern.replace(/\\/gu, "/");
142
+ return pattern.replace(/\\/gu, "/");
141
143
  }
142
144
 
143
145
  /**
@@ -146,10 +148,9 @@ function normalizeToPosix(pattern) {
146
148
  * @returns {boolean} `true` if the string is a glob pattern.
147
149
  */
148
150
  function isGlobPattern(pattern) {
149
- return isGlob(path.sep === "\\" ? normalizeToPosix(pattern) : pattern);
151
+ return isGlob(path.sep === "\\" ? normalizeToPosix(pattern) : pattern);
150
152
  }
151
153
 
152
-
153
154
  /**
154
155
  * Determines if a given glob pattern will return any results.
155
156
  * Used primarily to help with useful error messages.
@@ -159,38 +160,39 @@ function isGlobPattern(pattern) {
159
160
  * @returns {Promise<boolean>} True if there is a glob match, false if not.
160
161
  */
161
162
  async function globMatch({ basePath, pattern }) {
162
-
163
- let found = false;
164
- const { hfs } = await import("@humanfs/node");
165
- const patternToUse = normalizeToPosix(path.relative(basePath, pattern));
166
-
167
- const matcher = new Minimatch(patternToUse, MINIMATCH_OPTIONS);
168
-
169
- const walkSettings = {
170
-
171
- directoryFilter(entry) {
172
- return !found && matcher.match(entry.path, true);
173
- },
174
-
175
- entryFilter(entry) {
176
- if (found || entry.isDirectory) {
177
- return false;
178
- }
179
-
180
- if (matcher.match(entry.path)) {
181
- found = true;
182
- return true;
183
- }
184
-
185
- return false;
186
- }
187
- };
188
-
189
- if (await hfs.isDirectory(basePath)) {
190
- return hfs.walk(basePath, walkSettings).next().then(() => found);
191
- }
192
-
193
- return found;
163
+ let found = false;
164
+ const { hfs } = await import("@humanfs/node");
165
+ const patternToUse = normalizeToPosix(path.relative(basePath, pattern));
166
+
167
+ const matcher = new Minimatch(patternToUse, MINIMATCH_OPTIONS);
168
+
169
+ const walkSettings = {
170
+ directoryFilter(entry) {
171
+ return !found && matcher.match(entry.path, true);
172
+ },
173
+
174
+ entryFilter(entry) {
175
+ if (found || entry.isDirectory) {
176
+ return false;
177
+ }
178
+
179
+ if (matcher.match(entry.path)) {
180
+ found = true;
181
+ return true;
182
+ }
183
+
184
+ return false;
185
+ },
186
+ };
187
+
188
+ if (await hfs.isDirectory(basePath)) {
189
+ return hfs
190
+ .walk(basePath, walkSettings)
191
+ .next()
192
+ .then(() => found);
193
+ }
194
+
195
+ return found;
194
196
  }
195
197
 
196
198
  /**
@@ -214,130 +216,128 @@ async function globMatch({ basePath, pattern }) {
214
216
  * match any files.
215
217
  */
216
218
  async function globSearch({
217
- basePath,
218
- patterns,
219
- rawPatterns,
220
- configLoader,
221
- errorOnUnmatchedPattern
219
+ basePath,
220
+ patterns,
221
+ rawPatterns,
222
+ configLoader,
223
+ errorOnUnmatchedPattern,
222
224
  }) {
223
-
224
- if (patterns.length === 0) {
225
- return [];
226
- }
227
-
228
- /*
229
- * In this section we are converting the patterns into Minimatch
230
- * instances for performance reasons. Because we are doing the same
231
- * matches repeatedly, it's best to compile those patterns once and
232
- * reuse them multiple times.
233
- *
234
- * To do that, we convert any patterns with an absolute path into a
235
- * relative path and normalize it to Posix-style slashes. We also keep
236
- * track of the relative patterns to map them back to the original
237
- * patterns, which we need in order to throw an error if there are any
238
- * unmatched patterns.
239
- */
240
- const relativeToPatterns = new Map();
241
- const matchers = patterns.map((pattern, i) => {
242
- const patternToUse = normalizeToPosix(path.relative(basePath, pattern));
243
-
244
- relativeToPatterns.set(patternToUse, patterns[i]);
245
-
246
- return new Minimatch(patternToUse, MINIMATCH_OPTIONS);
247
- });
248
-
249
- /*
250
- * We track unmatched patterns because we may want to throw an error when
251
- * they occur. To start, this set is initialized with all of the patterns.
252
- * Every time a match occurs, the pattern is removed from the set, making
253
- * it easy to tell if we have any unmatched patterns left at the end of
254
- * search.
255
- */
256
- const unmatchedPatterns = new Set([...relativeToPatterns.keys()]);
257
- const { hfs } = await import("@humanfs/node");
258
-
259
- const walk = hfs.walk(
260
- basePath,
261
- {
262
- async directoryFilter(entry) {
263
-
264
- if (!matchers.some(matcher => matcher.match(entry.path, true))) {
265
- return false;
266
- }
267
-
268
- const absolutePath = path.resolve(basePath, entry.path);
269
- const configs = await configLoader.loadConfigArrayForDirectory(absolutePath);
270
-
271
- return !configs.isDirectoryIgnored(absolutePath);
272
- },
273
- async entryFilter(entry) {
274
- const absolutePath = path.resolve(basePath, entry.path);
275
-
276
- // entries may be directories or files so filter out directories
277
- if (entry.isDirectory) {
278
- return false;
279
- }
280
-
281
- const configs = await configLoader.loadConfigArrayForFile(absolutePath);
282
- const config = configs.getConfig(absolutePath);
283
-
284
- /*
285
- * Optimization: We need to track when patterns are left unmatched
286
- * and so we use `unmatchedPatterns` to do that. There is a bit of
287
- * complexity here because the same file can be matched by more than
288
- * one pattern. So, when we start, we actually need to test every
289
- * pattern against every file. Once we know there are no remaining
290
- * unmatched patterns, then we can switch to just looking for the
291
- * first matching pattern for improved speed.
292
- */
293
- const matchesPattern = unmatchedPatterns.size > 0
294
- ? matchers.reduce((previousValue, matcher) => {
295
- const pathMatches = matcher.match(entry.path);
296
-
297
- /*
298
- * We updated the unmatched patterns set only if the path
299
- * matches and the file has a config. If the file has no
300
- * config, that means there wasn't a match for the
301
- * pattern so it should not be removed.
302
- *
303
- * Performance note: `getConfig()` aggressively caches
304
- * results so there is no performance penalty for calling
305
- * it multiple times with the same argument.
306
- */
307
- if (pathMatches && config) {
308
- unmatchedPatterns.delete(matcher.pattern);
309
- }
310
-
311
- return pathMatches || previousValue;
312
- }, false)
313
- : matchers.some(matcher => matcher.match(entry.path));
314
-
315
- return matchesPattern && config !== void 0;
316
- }
317
- }
318
- );
319
-
320
- const filePaths = [];
321
-
322
- if (await hfs.isDirectory(basePath)) {
323
- for await (const entry of walk) {
324
- filePaths.push(path.resolve(basePath, entry.path));
325
- }
326
- }
327
-
328
- // now check to see if we have any unmatched patterns
329
- if (errorOnUnmatchedPattern && unmatchedPatterns.size > 0) {
330
- throw new UnmatchedSearchPatternsError({
331
- basePath,
332
- unmatchedPatterns: [...unmatchedPatterns].map(
333
- pattern => relativeToPatterns.get(pattern)
334
- ),
335
- patterns,
336
- rawPatterns
337
- });
338
- }
339
-
340
- return filePaths;
225
+ if (patterns.length === 0) {
226
+ return [];
227
+ }
228
+
229
+ /*
230
+ * In this section we are converting the patterns into Minimatch
231
+ * instances for performance reasons. Because we are doing the same
232
+ * matches repeatedly, it's best to compile those patterns once and
233
+ * reuse them multiple times.
234
+ *
235
+ * To do that, we convert any patterns with an absolute path into a
236
+ * relative path and normalize it to Posix-style slashes. We also keep
237
+ * track of the relative patterns to map them back to the original
238
+ * patterns, which we need in order to throw an error if there are any
239
+ * unmatched patterns.
240
+ */
241
+ const relativeToPatterns = new Map();
242
+ const matchers = patterns.map((pattern, i) => {
243
+ const patternToUse = normalizeToPosix(path.relative(basePath, pattern));
244
+
245
+ relativeToPatterns.set(patternToUse, patterns[i]);
246
+
247
+ return new Minimatch(patternToUse, MINIMATCH_OPTIONS);
248
+ });
249
+
250
+ /*
251
+ * We track unmatched patterns because we may want to throw an error when
252
+ * they occur. To start, this set is initialized with all of the patterns.
253
+ * Every time a match occurs, the pattern is removed from the set, making
254
+ * it easy to tell if we have any unmatched patterns left at the end of
255
+ * search.
256
+ */
257
+ const unmatchedPatterns = new Set([...relativeToPatterns.keys()]);
258
+ const { hfs } = await import("@humanfs/node");
259
+
260
+ const walk = hfs.walk(basePath, {
261
+ async directoryFilter(entry) {
262
+ if (!matchers.some(matcher => matcher.match(entry.path, true))) {
263
+ return false;
264
+ }
265
+
266
+ const absolutePath = path.resolve(basePath, entry.path);
267
+ const configs =
268
+ await configLoader.loadConfigArrayForDirectory(absolutePath);
269
+
270
+ return !configs.isDirectoryIgnored(absolutePath);
271
+ },
272
+ async entryFilter(entry) {
273
+ const absolutePath = path.resolve(basePath, entry.path);
274
+
275
+ // entries may be directories or files so filter out directories
276
+ if (entry.isDirectory) {
277
+ return false;
278
+ }
279
+
280
+ const configs =
281
+ await configLoader.loadConfigArrayForFile(absolutePath);
282
+ const config = configs.getConfig(absolutePath);
283
+
284
+ /*
285
+ * Optimization: We need to track when patterns are left unmatched
286
+ * and so we use `unmatchedPatterns` to do that. There is a bit of
287
+ * complexity here because the same file can be matched by more than
288
+ * one pattern. So, when we start, we actually need to test every
289
+ * pattern against every file. Once we know there are no remaining
290
+ * unmatched patterns, then we can switch to just looking for the
291
+ * first matching pattern for improved speed.
292
+ */
293
+ const matchesPattern =
294
+ unmatchedPatterns.size > 0
295
+ ? matchers.reduce((previousValue, matcher) => {
296
+ const pathMatches = matcher.match(entry.path);
297
+
298
+ /*
299
+ * We updated the unmatched patterns set only if the path
300
+ * matches and the file has a config. If the file has no
301
+ * config, that means there wasn't a match for the
302
+ * pattern so it should not be removed.
303
+ *
304
+ * Performance note: `getConfig()` aggressively caches
305
+ * results so there is no performance penalty for calling
306
+ * it multiple times with the same argument.
307
+ */
308
+ if (pathMatches && config) {
309
+ unmatchedPatterns.delete(matcher.pattern);
310
+ }
311
+
312
+ return pathMatches || previousValue;
313
+ }, false)
314
+ : matchers.some(matcher => matcher.match(entry.path));
315
+
316
+ return matchesPattern && config !== void 0;
317
+ },
318
+ });
319
+
320
+ const filePaths = [];
321
+
322
+ if (await hfs.isDirectory(basePath)) {
323
+ for await (const entry of walk) {
324
+ filePaths.push(path.resolve(basePath, entry.path));
325
+ }
326
+ }
327
+
328
+ // now check to see if we have any unmatched patterns
329
+ if (errorOnUnmatchedPattern && unmatchedPatterns.size > 0) {
330
+ throw new UnmatchedSearchPatternsError({
331
+ basePath,
332
+ unmatchedPatterns: [...unmatchedPatterns].map(pattern =>
333
+ relativeToPatterns.get(pattern),
334
+ ),
335
+ patterns,
336
+ rawPatterns,
337
+ });
338
+ }
339
+
340
+ return filePaths;
341
341
  }
342
342
 
343
343
  /**
@@ -358,26 +358,25 @@ async function globSearch({
358
358
  * matches some files when there are no ignores.
359
359
  */
360
360
  async function throwErrorForUnmatchedPatterns({
361
- basePath,
362
- patterns,
363
- rawPatterns,
364
- unmatchedPatterns
361
+ basePath,
362
+ patterns,
363
+ rawPatterns,
364
+ unmatchedPatterns,
365
365
  }) {
366
+ const pattern = unmatchedPatterns[0];
367
+ const rawPattern = rawPatterns[patterns.indexOf(pattern)];
366
368
 
367
- const pattern = unmatchedPatterns[0];
368
- const rawPattern = rawPatterns[patterns.indexOf(pattern)];
369
+ const patternHasMatch = await globMatch({
370
+ basePath,
371
+ pattern,
372
+ });
369
373
 
370
- const patternHasMatch = await globMatch({
371
- basePath,
372
- pattern
373
- });
374
+ if (patternHasMatch) {
375
+ throw new AllFilesIgnoredError(rawPattern);
376
+ }
374
377
 
375
- if (patternHasMatch) {
376
- throw new AllFilesIgnoredError(rawPattern);
377
- }
378
-
379
- // if we get here there are truly no matches
380
- throw new NoFilesFoundError(rawPattern, true);
378
+ // if we get here there are truly no matches
379
+ throw new NoFilesFoundError(rawPattern, true);
381
380
  }
382
381
 
383
382
  /**
@@ -392,69 +391,71 @@ async function throwErrorForUnmatchedPatterns({
392
391
  * @returns {Promise<Array<string>>} An array of matching file paths
393
392
  * or an empty array if there are no matches.
394
393
  */
395
- async function globMultiSearch({ searches, configLoader, errorOnUnmatchedPattern }) {
396
-
397
- /*
398
- * For convenience, we normalized the search map into an array of objects.
399
- * Next, we filter out all searches that have no patterns. This happens
400
- * primarily for the cwd, which is prepopulated in the searches map as an
401
- * optimization. However, if it has no patterns, it means all patterns
402
- * occur outside of the cwd and we can safely filter out that search.
403
- */
404
- const normalizedSearches = [...searches].map(
405
- ([basePath, { patterns, rawPatterns }]) => ({ basePath, patterns, rawPatterns })
406
- ).filter(({ patterns }) => patterns.length > 0);
407
-
408
- const results = await Promise.allSettled(
409
- normalizedSearches.map(
410
- ({ basePath, patterns, rawPatterns }) => globSearch({
411
- basePath,
412
- patterns,
413
- rawPatterns,
414
- configLoader,
415
- errorOnUnmatchedPattern
416
- })
417
- )
418
- );
419
-
420
- /*
421
- * The first loop handles errors from the glob searches. Since we can't
422
- * use `await` inside `flatMap`, we process errors separately in this loop.
423
- * This results in two iterations over `results`, but since the length is
424
- * less than or equal to the number of globs and directories passed on the
425
- * command line, the performance impact should be minimal.
426
- */
427
- for (let i = 0; i < results.length; i++) {
428
-
429
- const result = results[i];
430
- const currentSearch = normalizedSearches[i];
431
-
432
- if (result.status === "fulfilled") {
433
- continue;
434
- }
435
-
436
- // if we make it here then there was an error
437
- const error = result.reason;
438
-
439
- // unexpected errors should be re-thrown
440
- if (!error.basePath) {
441
- throw error;
442
- }
443
-
444
- if (errorOnUnmatchedPattern) {
445
-
446
- await throwErrorForUnmatchedPatterns({
447
- ...currentSearch,
448
- unmatchedPatterns: error.unmatchedPatterns
449
- });
450
-
451
- }
452
-
453
- }
454
-
455
- // second loop for `fulfulled` results
456
- return results.flatMap(result => result.value);
457
-
394
+ async function globMultiSearch({
395
+ searches,
396
+ configLoader,
397
+ errorOnUnmatchedPattern,
398
+ }) {
399
+ /*
400
+ * For convenience, we normalized the search map into an array of objects.
401
+ * Next, we filter out all searches that have no patterns. This happens
402
+ * primarily for the cwd, which is prepopulated in the searches map as an
403
+ * optimization. However, if it has no patterns, it means all patterns
404
+ * occur outside of the cwd and we can safely filter out that search.
405
+ */
406
+ const normalizedSearches = [...searches]
407
+ .map(([basePath, { patterns, rawPatterns }]) => ({
408
+ basePath,
409
+ patterns,
410
+ rawPatterns,
411
+ }))
412
+ .filter(({ patterns }) => patterns.length > 0);
413
+
414
+ const results = await Promise.allSettled(
415
+ normalizedSearches.map(({ basePath, patterns, rawPatterns }) =>
416
+ globSearch({
417
+ basePath,
418
+ patterns,
419
+ rawPatterns,
420
+ configLoader,
421
+ errorOnUnmatchedPattern,
422
+ }),
423
+ ),
424
+ );
425
+
426
+ /*
427
+ * The first loop handles errors from the glob searches. Since we can't
428
+ * use `await` inside `flatMap`, we process errors separately in this loop.
429
+ * This results in two iterations over `results`, but since the length is
430
+ * less than or equal to the number of globs and directories passed on the
431
+ * command line, the performance impact should be minimal.
432
+ */
433
+ for (let i = 0; i < results.length; i++) {
434
+ const result = results[i];
435
+ const currentSearch = normalizedSearches[i];
436
+
437
+ if (result.status === "fulfilled") {
438
+ continue;
439
+ }
440
+
441
+ // if we make it here then there was an error
442
+ const error = result.reason;
443
+
444
+ // unexpected errors should be re-thrown
445
+ if (!error.basePath) {
446
+ throw error;
447
+ }
448
+
449
+ if (errorOnUnmatchedPattern) {
450
+ await throwErrorForUnmatchedPatterns({
451
+ ...currentSearch,
452
+ unmatchedPatterns: error.unmatchedPatterns,
453
+ });
454
+ }
455
+ }
456
+
457
+ // second loop for `fulfulled` results
458
+ return results.flatMap(result => result.value);
458
459
  }
459
460
 
460
461
  /**
@@ -472,130 +473,122 @@ async function globMultiSearch({ searches, configLoader, errorOnUnmatchedPattern
472
473
  * @throws {NoFilesFoundError} If no files matched the given patterns.
473
474
  */
474
475
  async function findFiles({
475
- patterns,
476
- globInputPaths,
477
- cwd,
478
- configLoader,
479
- errorOnUnmatchedPattern
476
+ patterns,
477
+ globInputPaths,
478
+ cwd,
479
+ configLoader,
480
+ errorOnUnmatchedPattern,
480
481
  }) {
481
-
482
- const results = [];
483
- const missingPatterns = [];
484
- let globbyPatterns = [];
485
- let rawPatterns = [];
486
- const searches = new Map([[cwd, { patterns: globbyPatterns, rawPatterns: [] }]]);
487
-
488
- /*
489
- * This part is a bit involved because we need to account for
490
- * the different ways that the patterns can match directories.
491
- * For each different way, we need to decide if we should look
492
- * for a config file or just use the default config. (Directories
493
- * without a config file always use the default config.)
494
- *
495
- * Here are the cases:
496
- *
497
- * 1. A directory is passed directly (e.g., "subdir"). In this case, we
498
- * can assume that the user intends to lint this directory and we should
499
- * not look for a config file in the parent directory, because the only
500
- * reason to do that would be to ignore this directory (which we already
501
- * know we don't want to do). Instead, we use the default config until we
502
- * get to the directory that was passed, at which point we start looking
503
- * for config files again.
504
- *
505
- * 2. A dot (".") or star ("*"). In this case, we want to read
506
- * the config file in the current directory because the user is
507
- * explicitly asking to lint the current directory. Note that "."
508
- * will traverse into subdirectories while "*" will not.
509
- *
510
- * 3. A directory is passed in the form of "subdir/subsubdir".
511
- * In this case, we don't want to look for a config file in the
512
- * parent directory ("subdir"). We can skip looking for a config
513
- * file until `entry.depth` is greater than 1 because there's no
514
- * way that the pattern can match `entry.path` yet.
515
- *
516
- * 4. A directory glob pattern is passed (e.g., "subd*"). We want
517
- * this case to act like case 2 because it's unclear whether or not
518
- * any particular directory is meant to be traversed.
519
- *
520
- * 5. A recursive glob pattern is passed (e.g., "**"). We want this
521
- * case to act like case 2.
522
- */
523
-
524
- // check to see if we have explicit files and directories
525
- const filePaths = patterns.map(filePath => path.resolve(cwd, filePath));
526
- const stats = await Promise.all(
527
- filePaths.map(
528
- filePath => fsp.stat(filePath).catch(() => { })
529
- )
530
- );
531
-
532
- stats.forEach((stat, index) => {
533
-
534
- const filePath = filePaths[index];
535
- const pattern = normalizeToPosix(patterns[index]);
536
-
537
- if (stat) {
538
-
539
- // files are added directly to the list
540
- if (stat.isFile()) {
541
- results.push(filePath);
542
- }
543
-
544
- // directories need extensions attached
545
- if (stat.isDirectory()) {
546
-
547
- if (!searches.has(filePath)) {
548
- searches.set(filePath, { patterns: [], rawPatterns: [] });
549
- }
550
- ({ patterns: globbyPatterns, rawPatterns } = searches.get(filePath));
551
-
552
- globbyPatterns.push(`${normalizeToPosix(filePath)}/**`);
553
- rawPatterns.push(pattern);
554
- }
555
-
556
- return;
557
- }
558
-
559
- // save patterns for later use based on whether globs are enabled
560
- if (globInputPaths && isGlobPattern(pattern)) {
561
-
562
- /*
563
- * We are grouping patterns by their glob parent. This is done to
564
- * make it easier to determine when a config file should be loaded.
565
- */
566
-
567
- const basePath = path.resolve(cwd, globParent(pattern));
568
-
569
- if (!searches.has(basePath)) {
570
- searches.set(basePath, { patterns: [], rawPatterns: [] });
571
- }
572
- ({ patterns: globbyPatterns, rawPatterns } = searches.get(basePath));
573
-
574
- globbyPatterns.push(filePath);
575
- rawPatterns.push(pattern);
576
- } else {
577
- missingPatterns.push(pattern);
578
- }
579
- });
580
-
581
- // there were patterns that didn't match anything, tell the user
582
- if (errorOnUnmatchedPattern && missingPatterns.length) {
583
- throw new NoFilesFoundError(missingPatterns[0], globInputPaths);
584
- }
585
-
586
- // now we are safe to do the search
587
- const globbyResults = await globMultiSearch({
588
- searches,
589
- configLoader,
590
- errorOnUnmatchedPattern
591
- });
592
-
593
- return [
594
- ...new Set([
595
- ...results,
596
- ...globbyResults
597
- ])
598
- ];
482
+ const results = [];
483
+ const missingPatterns = [];
484
+ let globbyPatterns = [];
485
+ let rawPatterns = [];
486
+ const searches = new Map([
487
+ [cwd, { patterns: globbyPatterns, rawPatterns: [] }],
488
+ ]);
489
+
490
+ /*
491
+ * This part is a bit involved because we need to account for
492
+ * the different ways that the patterns can match directories.
493
+ * For each different way, we need to decide if we should look
494
+ * for a config file or just use the default config. (Directories
495
+ * without a config file always use the default config.)
496
+ *
497
+ * Here are the cases:
498
+ *
499
+ * 1. A directory is passed directly (e.g., "subdir"). In this case, we
500
+ * can assume that the user intends to lint this directory and we should
501
+ * not look for a config file in the parent directory, because the only
502
+ * reason to do that would be to ignore this directory (which we already
503
+ * know we don't want to do). Instead, we use the default config until we
504
+ * get to the directory that was passed, at which point we start looking
505
+ * for config files again.
506
+ *
507
+ * 2. A dot (".") or star ("*"). In this case, we want to read
508
+ * the config file in the current directory because the user is
509
+ * explicitly asking to lint the current directory. Note that "."
510
+ * will traverse into subdirectories while "*" will not.
511
+ *
512
+ * 3. A directory is passed in the form of "subdir/subsubdir".
513
+ * In this case, we don't want to look for a config file in the
514
+ * parent directory ("subdir"). We can skip looking for a config
515
+ * file until `entry.depth` is greater than 1 because there's no
516
+ * way that the pattern can match `entry.path` yet.
517
+ *
518
+ * 4. A directory glob pattern is passed (e.g., "subd*"). We want
519
+ * this case to act like case 2 because it's unclear whether or not
520
+ * any particular directory is meant to be traversed.
521
+ *
522
+ * 5. A recursive glob pattern is passed (e.g., "**"). We want this
523
+ * case to act like case 2.
524
+ */
525
+
526
+ // check to see if we have explicit files and directories
527
+ const filePaths = patterns.map(filePath => path.resolve(cwd, filePath));
528
+ const stats = await Promise.all(
529
+ filePaths.map(filePath => fsp.stat(filePath).catch(() => {})),
530
+ );
531
+
532
+ stats.forEach((stat, index) => {
533
+ const filePath = filePaths[index];
534
+ const pattern = normalizeToPosix(patterns[index]);
535
+
536
+ if (stat) {
537
+ // files are added directly to the list
538
+ if (stat.isFile()) {
539
+ results.push(filePath);
540
+ }
541
+
542
+ // directories need extensions attached
543
+ if (stat.isDirectory()) {
544
+ if (!searches.has(filePath)) {
545
+ searches.set(filePath, { patterns: [], rawPatterns: [] });
546
+ }
547
+ ({ patterns: globbyPatterns, rawPatterns } =
548
+ searches.get(filePath));
549
+
550
+ globbyPatterns.push(`${normalizeToPosix(filePath)}/**`);
551
+ rawPatterns.push(pattern);
552
+ }
553
+
554
+ return;
555
+ }
556
+
557
+ // save patterns for later use based on whether globs are enabled
558
+ if (globInputPaths && isGlobPattern(pattern)) {
559
+ /*
560
+ * We are grouping patterns by their glob parent. This is done to
561
+ * make it easier to determine when a config file should be loaded.
562
+ */
563
+
564
+ const basePath = path.resolve(cwd, globParent(pattern));
565
+
566
+ if (!searches.has(basePath)) {
567
+ searches.set(basePath, { patterns: [], rawPatterns: [] });
568
+ }
569
+ ({ patterns: globbyPatterns, rawPatterns } =
570
+ searches.get(basePath));
571
+
572
+ globbyPatterns.push(filePath);
573
+ rawPatterns.push(pattern);
574
+ } else {
575
+ missingPatterns.push(pattern);
576
+ }
577
+ });
578
+
579
+ // there were patterns that didn't match anything, tell the user
580
+ if (errorOnUnmatchedPattern && missingPatterns.length) {
581
+ throw new NoFilesFoundError(missingPatterns[0], globInputPaths);
582
+ }
583
+
584
+ // now we are safe to do the search
585
+ const globbyResults = await globMultiSearch({
586
+ searches,
587
+ configLoader,
588
+ errorOnUnmatchedPattern,
589
+ });
590
+
591
+ return [...new Set([...results, ...globbyResults])];
599
592
  }
600
593
 
601
594
  //-----------------------------------------------------------------------------
@@ -609,7 +602,7 @@ async function findFiles({
609
602
  * @private
610
603
  */
611
604
  function isErrorMessage(message) {
612
- return message.severity === 2;
605
+ return message.severity === 2;
613
606
  }
614
607
 
615
608
  /**
@@ -621,60 +614,72 @@ function isErrorMessage(message) {
621
614
  * @private
622
615
  */
623
616
  function createIgnoreResult(filePath, baseDir, configStatus) {
624
- let message;
625
-
626
- switch (configStatus) {
627
- case "external":
628
- message = "File ignored because outside of base path.";
629
- break;
630
- case "unconfigured":
631
- message = "File ignored because no matching configuration was supplied.";
632
- break;
633
- default:
634
- {
635
- const isInNodeModules = baseDir && path.dirname(path.relative(baseDir, filePath)).split(path.sep).includes("node_modules");
636
-
637
- if (isInNodeModules) {
638
- message = "File ignored by default because it is located under the node_modules directory. Use ignore pattern \"!**/node_modules/\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
639
- } else {
640
- message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
641
- }
642
- }
643
- break;
644
- }
645
-
646
- return {
647
- filePath,
648
- messages: [
649
- {
650
- ruleId: null,
651
- fatal: false,
652
- severity: 1,
653
- message,
654
- nodeType: null
655
- }
656
- ],
657
- suppressedMessages: [],
658
- errorCount: 0,
659
- warningCount: 1,
660
- fatalErrorCount: 0,
661
- fixableErrorCount: 0,
662
- fixableWarningCount: 0
663
- };
617
+ let message;
618
+
619
+ switch (configStatus) {
620
+ case "external":
621
+ message = "File ignored because outside of base path.";
622
+ break;
623
+ case "unconfigured":
624
+ message =
625
+ "File ignored because no matching configuration was supplied.";
626
+ break;
627
+ default:
628
+ {
629
+ const isInNodeModules =
630
+ baseDir &&
631
+ path
632
+ .dirname(path.relative(baseDir, filePath))
633
+ .split(path.sep)
634
+ .includes("node_modules");
635
+
636
+ if (isInNodeModules) {
637
+ message =
638
+ 'File ignored by default because it is located under the node_modules directory. Use ignore pattern "!**/node_modules/" to disable file ignore settings or use "--no-warn-ignored" to suppress this warning.';
639
+ } else {
640
+ message =
641
+ 'File ignored because of a matching ignore pattern. Use "--no-ignore" to disable file ignore settings or use "--no-warn-ignored" to suppress this warning.';
642
+ }
643
+ }
644
+ break;
645
+ }
646
+
647
+ return {
648
+ filePath,
649
+ messages: [
650
+ {
651
+ ruleId: null,
652
+ fatal: false,
653
+ severity: 1,
654
+ message,
655
+ nodeType: null,
656
+ },
657
+ ],
658
+ suppressedMessages: [],
659
+ errorCount: 0,
660
+ warningCount: 1,
661
+ fatalErrorCount: 0,
662
+ fixableErrorCount: 0,
663
+ fixableWarningCount: 0,
664
+ };
664
665
  }
665
666
 
666
667
  //-----------------------------------------------------------------------------
667
668
  // Options-related Helpers
668
669
  //-----------------------------------------------------------------------------
669
670
 
670
-
671
671
  /**
672
672
  * Check if a given value is a valid fix type or not.
673
673
  * @param {any} x The value to check.
674
674
  * @returns {boolean} `true` if `x` is valid fix type.
675
675
  */
676
676
  function isFixType(x) {
677
- return x === "directive" || x === "problem" || x === "suggestion" || x === "layout";
677
+ return (
678
+ x === "directive" ||
679
+ x === "problem" ||
680
+ x === "suggestion" ||
681
+ x === "layout"
682
+ );
678
683
  }
679
684
 
680
685
  /**
@@ -683,18 +688,18 @@ function isFixType(x) {
683
688
  * @returns {boolean} `true` if `x` is an array of fix types.
684
689
  */
685
690
  function isFixTypeArray(x) {
686
- return Array.isArray(x) && x.every(isFixType);
691
+ return Array.isArray(x) && x.every(isFixType);
687
692
  }
688
693
 
689
694
  /**
690
695
  * The error for invalid options.
691
696
  */
692
697
  class ESLintInvalidOptionsError extends Error {
693
- constructor(messages) {
694
- super(`Invalid Options:\n- ${messages.join("\n- ")}`);
695
- this.code = "ESLINT_INVALID_OPTIONS";
696
- Error.captureStackTrace(this, ESLintInvalidOptionsError);
697
- }
698
+ constructor(messages) {
699
+ super(`Invalid Options:\n- ${messages.join("\n- ")}`);
700
+ this.code = "ESLINT_INVALID_OPTIONS";
701
+ Error.captureStackTrace(this, ESLintInvalidOptionsError);
702
+ }
698
703
  }
699
704
 
700
705
  /**
@@ -704,171 +709,200 @@ class ESLintInvalidOptionsError extends Error {
704
709
  * @returns {ESLintOptions} The normalized options.
705
710
  */
706
711
  function processOptions({
707
- allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored.
708
- baseConfig = null,
709
- cache = false,
710
- cacheLocation = ".eslintcache",
711
- cacheStrategy = "metadata",
712
- cwd = process.cwd(),
713
- errorOnUnmatchedPattern = true,
714
- fix = false,
715
- fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
716
- flags = [],
717
- globInputPaths = true,
718
- ignore = true,
719
- ignorePatterns = null,
720
- overrideConfig = null,
721
- overrideConfigFile = null,
722
- plugins = {},
723
- stats = false,
724
- warnIgnored = true,
725
- passOnNoPatterns = false,
726
- ruleFilter = () => true,
727
- ...unknownOptions
712
+ allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored.
713
+ baseConfig = null,
714
+ cache = false,
715
+ cacheLocation = ".eslintcache",
716
+ cacheStrategy = "metadata",
717
+ cwd = process.cwd(),
718
+ errorOnUnmatchedPattern = true,
719
+ fix = false,
720
+ fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
721
+ flags = [],
722
+ globInputPaths = true,
723
+ ignore = true,
724
+ ignorePatterns = null,
725
+ overrideConfig = null,
726
+ overrideConfigFile = null,
727
+ plugins = {},
728
+ stats = false,
729
+ warnIgnored = true,
730
+ passOnNoPatterns = false,
731
+ ruleFilter = () => true,
732
+ ...unknownOptions
728
733
  }) {
729
- const errors = [];
730
- const unknownOptionKeys = Object.keys(unknownOptions);
731
-
732
- if (unknownOptionKeys.length >= 1) {
733
- errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`);
734
- if (unknownOptionKeys.includes("cacheFile")) {
735
- errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead.");
736
- }
737
- if (unknownOptionKeys.includes("configFile")) {
738
- errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead.");
739
- }
740
- if (unknownOptionKeys.includes("envs")) {
741
- errors.push("'envs' has been removed.");
742
- }
743
- if (unknownOptionKeys.includes("extensions")) {
744
- errors.push("'extensions' has been removed.");
745
- }
746
- if (unknownOptionKeys.includes("resolvePluginsRelativeTo")) {
747
- errors.push("'resolvePluginsRelativeTo' has been removed.");
748
- }
749
- if (unknownOptionKeys.includes("globals")) {
750
- errors.push("'globals' has been removed. Please use the 'overrideConfig.languageOptions.globals' option instead.");
751
- }
752
- if (unknownOptionKeys.includes("ignorePath")) {
753
- errors.push("'ignorePath' has been removed.");
754
- }
755
- if (unknownOptionKeys.includes("ignorePattern")) {
756
- errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.");
757
- }
758
- if (unknownOptionKeys.includes("parser")) {
759
- errors.push("'parser' has been removed. Please use the 'overrideConfig.languageOptions.parser' option instead.");
760
- }
761
- if (unknownOptionKeys.includes("parserOptions")) {
762
- errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.languageOptions.parserOptions' option instead.");
763
- }
764
- if (unknownOptionKeys.includes("rules")) {
765
- errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead.");
766
- }
767
- if (unknownOptionKeys.includes("rulePaths")) {
768
- errors.push("'rulePaths' has been removed. Please define your rules using plugins.");
769
- }
770
- if (unknownOptionKeys.includes("reportUnusedDisableDirectives")) {
771
- errors.push("'reportUnusedDisableDirectives' has been removed. Please use the 'overrideConfig.linterOptions.reportUnusedDisableDirectives' option instead.");
772
- }
773
- }
774
- if (typeof allowInlineConfig !== "boolean") {
775
- errors.push("'allowInlineConfig' must be a boolean.");
776
- }
777
- if (typeof baseConfig !== "object") {
778
- errors.push("'baseConfig' must be an object or null.");
779
- }
780
- if (typeof cache !== "boolean") {
781
- errors.push("'cache' must be a boolean.");
782
- }
783
- if (!isNonEmptyString(cacheLocation)) {
784
- errors.push("'cacheLocation' must be a non-empty string.");
785
- }
786
- if (
787
- cacheStrategy !== "metadata" &&
788
- cacheStrategy !== "content"
789
- ) {
790
- errors.push("'cacheStrategy' must be any of \"metadata\", \"content\".");
791
- }
792
- if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) {
793
- errors.push("'cwd' must be an absolute path.");
794
- }
795
- if (typeof errorOnUnmatchedPattern !== "boolean") {
796
- errors.push("'errorOnUnmatchedPattern' must be a boolean.");
797
- }
798
- if (typeof fix !== "boolean" && typeof fix !== "function") {
799
- errors.push("'fix' must be a boolean or a function.");
800
- }
801
- if (fixTypes !== null && !isFixTypeArray(fixTypes)) {
802
- errors.push("'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\".");
803
- }
804
- if (!isEmptyArrayOrArrayOfNonEmptyString(flags)) {
805
- errors.push("'flags' must be an array of non-empty strings.");
806
- }
807
- if (typeof globInputPaths !== "boolean") {
808
- errors.push("'globInputPaths' must be a boolean.");
809
- }
810
- if (typeof ignore !== "boolean") {
811
- errors.push("'ignore' must be a boolean.");
812
- }
813
- if (!isEmptyArrayOrArrayOfNonEmptyString(ignorePatterns) && ignorePatterns !== null) {
814
- errors.push("'ignorePatterns' must be an array of non-empty strings or null.");
815
- }
816
- if (typeof overrideConfig !== "object") {
817
- errors.push("'overrideConfig' must be an object or null.");
818
- }
819
- if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null && overrideConfigFile !== true) {
820
- errors.push("'overrideConfigFile' must be a non-empty string, null, or true.");
821
- }
822
- if (typeof passOnNoPatterns !== "boolean") {
823
- errors.push("'passOnNoPatterns' must be a boolean.");
824
- }
825
- if (typeof plugins !== "object") {
826
- errors.push("'plugins' must be an object or null.");
827
- } else if (plugins !== null && Object.keys(plugins).includes("")) {
828
- errors.push("'plugins' must not include an empty string.");
829
- }
830
- if (Array.isArray(plugins)) {
831
- errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.");
832
- }
833
- if (typeof stats !== "boolean") {
834
- errors.push("'stats' must be a boolean.");
835
- }
836
- if (typeof warnIgnored !== "boolean") {
837
- errors.push("'warnIgnored' must be a boolean.");
838
- }
839
- if (typeof ruleFilter !== "function") {
840
- errors.push("'ruleFilter' must be a function.");
841
- }
842
- if (errors.length > 0) {
843
- throw new ESLintInvalidOptionsError(errors);
844
- }
845
-
846
- return {
847
- allowInlineConfig,
848
- baseConfig,
849
- cache,
850
- cacheLocation,
851
- cacheStrategy,
852
-
853
- // when overrideConfigFile is true that means don't do config file lookup
854
- configFile: overrideConfigFile === true ? false : overrideConfigFile,
855
- overrideConfig,
856
- cwd: path.normalize(cwd),
857
- errorOnUnmatchedPattern,
858
- fix,
859
- fixTypes,
860
- flags: [...flags],
861
- globInputPaths,
862
- ignore,
863
- ignorePatterns,
864
- stats,
865
- passOnNoPatterns,
866
- warnIgnored,
867
- ruleFilter
868
- };
734
+ const errors = [];
735
+ const unknownOptionKeys = Object.keys(unknownOptions);
736
+
737
+ if (unknownOptionKeys.length >= 1) {
738
+ errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`);
739
+ if (unknownOptionKeys.includes("cacheFile")) {
740
+ errors.push(
741
+ "'cacheFile' has been removed. Please use the 'cacheLocation' option instead.",
742
+ );
743
+ }
744
+ if (unknownOptionKeys.includes("configFile")) {
745
+ errors.push(
746
+ "'configFile' has been removed. Please use the 'overrideConfigFile' option instead.",
747
+ );
748
+ }
749
+ if (unknownOptionKeys.includes("envs")) {
750
+ errors.push("'envs' has been removed.");
751
+ }
752
+ if (unknownOptionKeys.includes("extensions")) {
753
+ errors.push("'extensions' has been removed.");
754
+ }
755
+ if (unknownOptionKeys.includes("resolvePluginsRelativeTo")) {
756
+ errors.push("'resolvePluginsRelativeTo' has been removed.");
757
+ }
758
+ if (unknownOptionKeys.includes("globals")) {
759
+ errors.push(
760
+ "'globals' has been removed. Please use the 'overrideConfig.languageOptions.globals' option instead.",
761
+ );
762
+ }
763
+ if (unknownOptionKeys.includes("ignorePath")) {
764
+ errors.push("'ignorePath' has been removed.");
765
+ }
766
+ if (unknownOptionKeys.includes("ignorePattern")) {
767
+ errors.push(
768
+ "'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.",
769
+ );
770
+ }
771
+ if (unknownOptionKeys.includes("parser")) {
772
+ errors.push(
773
+ "'parser' has been removed. Please use the 'overrideConfig.languageOptions.parser' option instead.",
774
+ );
775
+ }
776
+ if (unknownOptionKeys.includes("parserOptions")) {
777
+ errors.push(
778
+ "'parserOptions' has been removed. Please use the 'overrideConfig.languageOptions.parserOptions' option instead.",
779
+ );
780
+ }
781
+ if (unknownOptionKeys.includes("rules")) {
782
+ errors.push(
783
+ "'rules' has been removed. Please use the 'overrideConfig.rules' option instead.",
784
+ );
785
+ }
786
+ if (unknownOptionKeys.includes("rulePaths")) {
787
+ errors.push(
788
+ "'rulePaths' has been removed. Please define your rules using plugins.",
789
+ );
790
+ }
791
+ if (unknownOptionKeys.includes("reportUnusedDisableDirectives")) {
792
+ errors.push(
793
+ "'reportUnusedDisableDirectives' has been removed. Please use the 'overrideConfig.linterOptions.reportUnusedDisableDirectives' option instead.",
794
+ );
795
+ }
796
+ }
797
+ if (typeof allowInlineConfig !== "boolean") {
798
+ errors.push("'allowInlineConfig' must be a boolean.");
799
+ }
800
+ if (typeof baseConfig !== "object") {
801
+ errors.push("'baseConfig' must be an object or null.");
802
+ }
803
+ if (typeof cache !== "boolean") {
804
+ errors.push("'cache' must be a boolean.");
805
+ }
806
+ if (!isNonEmptyString(cacheLocation)) {
807
+ errors.push("'cacheLocation' must be a non-empty string.");
808
+ }
809
+ if (cacheStrategy !== "metadata" && cacheStrategy !== "content") {
810
+ errors.push('\'cacheStrategy\' must be any of "metadata", "content".');
811
+ }
812
+ if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) {
813
+ errors.push("'cwd' must be an absolute path.");
814
+ }
815
+ if (typeof errorOnUnmatchedPattern !== "boolean") {
816
+ errors.push("'errorOnUnmatchedPattern' must be a boolean.");
817
+ }
818
+ if (typeof fix !== "boolean" && typeof fix !== "function") {
819
+ errors.push("'fix' must be a boolean or a function.");
820
+ }
821
+ if (fixTypes !== null && !isFixTypeArray(fixTypes)) {
822
+ errors.push(
823
+ '\'fixTypes\' must be an array of any of "directive", "problem", "suggestion", and "layout".',
824
+ );
825
+ }
826
+ if (!isEmptyArrayOrArrayOfNonEmptyString(flags)) {
827
+ errors.push("'flags' must be an array of non-empty strings.");
828
+ }
829
+ if (typeof globInputPaths !== "boolean") {
830
+ errors.push("'globInputPaths' must be a boolean.");
831
+ }
832
+ if (typeof ignore !== "boolean") {
833
+ errors.push("'ignore' must be a boolean.");
834
+ }
835
+ if (
836
+ !isEmptyArrayOrArrayOfNonEmptyString(ignorePatterns) &&
837
+ ignorePatterns !== null
838
+ ) {
839
+ errors.push(
840
+ "'ignorePatterns' must be an array of non-empty strings or null.",
841
+ );
842
+ }
843
+ if (typeof overrideConfig !== "object") {
844
+ errors.push("'overrideConfig' must be an object or null.");
845
+ }
846
+ if (
847
+ !isNonEmptyString(overrideConfigFile) &&
848
+ overrideConfigFile !== null &&
849
+ overrideConfigFile !== true
850
+ ) {
851
+ errors.push(
852
+ "'overrideConfigFile' must be a non-empty string, null, or true.",
853
+ );
854
+ }
855
+ if (typeof passOnNoPatterns !== "boolean") {
856
+ errors.push("'passOnNoPatterns' must be a boolean.");
857
+ }
858
+ if (typeof plugins !== "object") {
859
+ errors.push("'plugins' must be an object or null.");
860
+ } else if (plugins !== null && Object.keys(plugins).includes("")) {
861
+ errors.push("'plugins' must not include an empty string.");
862
+ }
863
+ if (Array.isArray(plugins)) {
864
+ errors.push(
865
+ "'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.",
866
+ );
867
+ }
868
+ if (typeof stats !== "boolean") {
869
+ errors.push("'stats' must be a boolean.");
870
+ }
871
+ if (typeof warnIgnored !== "boolean") {
872
+ errors.push("'warnIgnored' must be a boolean.");
873
+ }
874
+ if (typeof ruleFilter !== "function") {
875
+ errors.push("'ruleFilter' must be a function.");
876
+ }
877
+ if (errors.length > 0) {
878
+ throw new ESLintInvalidOptionsError(errors);
879
+ }
880
+
881
+ return {
882
+ allowInlineConfig,
883
+ baseConfig,
884
+ cache,
885
+ cacheLocation,
886
+ cacheStrategy,
887
+
888
+ // when overrideConfigFile is true that means don't do config file lookup
889
+ configFile: overrideConfigFile === true ? false : overrideConfigFile,
890
+ overrideConfig,
891
+ cwd: path.normalize(cwd),
892
+ errorOnUnmatchedPattern,
893
+ fix,
894
+ fixTypes,
895
+ flags: [...flags],
896
+ globInputPaths,
897
+ ignore,
898
+ ignorePatterns,
899
+ stats,
900
+ passOnNoPatterns,
901
+ warnIgnored,
902
+ ruleFilter,
903
+ };
869
904
  }
870
905
 
871
-
872
906
  //-----------------------------------------------------------------------------
873
907
  // Cache-related helpers
874
908
  //-----------------------------------------------------------------------------
@@ -884,82 +918,78 @@ function processOptions({
884
918
  * @returns {string} the resolved path to the cache file
885
919
  */
886
920
  function getCacheFile(cacheFile, cwd) {
887
-
888
- /*
889
- * make sure the path separators are normalized for the environment/os
890
- * keeping the trailing path separator if present
891
- */
892
- const normalizedCacheFile = path.normalize(cacheFile);
893
-
894
- const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile);
895
- const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep;
896
-
897
- /**
898
- * return the name for the cache file in case the provided parameter is a directory
899
- * @returns {string} the resolved path to the cacheFile
900
- */
901
- function getCacheFileForDirectory() {
902
- return path.join(resolvedCacheFile, `.cache_${hash(cwd)}`);
903
- }
904
-
905
- let fileStats;
906
-
907
- try {
908
- fileStats = fs.lstatSync(resolvedCacheFile);
909
- } catch {
910
- fileStats = null;
911
- }
912
-
913
-
914
- /*
915
- * in case the file exists we need to verify if the provided path
916
- * is a directory or a file. If it is a directory we want to create a file
917
- * inside that directory
918
- */
919
- if (fileStats) {
920
-
921
- /*
922
- * is a directory or is a file, but the original file the user provided
923
- * looks like a directory but `path.resolve` removed the `last path.sep`
924
- * so we need to still treat this like a directory
925
- */
926
- if (fileStats.isDirectory() || looksLikeADirectory) {
927
- return getCacheFileForDirectory();
928
- }
929
-
930
- // is file so just use that file
931
- return resolvedCacheFile;
932
- }
933
-
934
- /*
935
- * here we known the file or directory doesn't exist,
936
- * so we will try to infer if its a directory if it looks like a directory
937
- * for the current operating system.
938
- */
939
-
940
- // if the last character passed is a path separator we assume is a directory
941
- if (looksLikeADirectory) {
942
- return getCacheFileForDirectory();
943
- }
944
-
945
- return resolvedCacheFile;
921
+ /*
922
+ * make sure the path separators are normalized for the environment/os
923
+ * keeping the trailing path separator if present
924
+ */
925
+ const normalizedCacheFile = path.normalize(cacheFile);
926
+
927
+ const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile);
928
+ const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep;
929
+
930
+ /**
931
+ * return the name for the cache file in case the provided parameter is a directory
932
+ * @returns {string} the resolved path to the cacheFile
933
+ */
934
+ function getCacheFileForDirectory() {
935
+ return path.join(resolvedCacheFile, `.cache_${hash(cwd)}`);
936
+ }
937
+
938
+ let fileStats;
939
+
940
+ try {
941
+ fileStats = fs.lstatSync(resolvedCacheFile);
942
+ } catch {
943
+ fileStats = null;
944
+ }
945
+
946
+ /*
947
+ * in case the file exists we need to verify if the provided path
948
+ * is a directory or a file. If it is a directory we want to create a file
949
+ * inside that directory
950
+ */
951
+ if (fileStats) {
952
+ /*
953
+ * is a directory or is a file, but the original file the user provided
954
+ * looks like a directory but `path.resolve` removed the `last path.sep`
955
+ * so we need to still treat this like a directory
956
+ */
957
+ if (fileStats.isDirectory() || looksLikeADirectory) {
958
+ return getCacheFileForDirectory();
959
+ }
960
+
961
+ // is file so just use that file
962
+ return resolvedCacheFile;
963
+ }
964
+
965
+ /*
966
+ * here we known the file or directory doesn't exist,
967
+ * so we will try to infer if its a directory if it looks like a directory
968
+ * for the current operating system.
969
+ */
970
+
971
+ // if the last character passed is a path separator we assume is a directory
972
+ if (looksLikeADirectory) {
973
+ return getCacheFileForDirectory();
974
+ }
975
+
976
+ return resolvedCacheFile;
946
977
  }
947
978
 
948
-
949
979
  //-----------------------------------------------------------------------------
950
980
  // Exports
951
981
  //-----------------------------------------------------------------------------
952
982
 
953
983
  module.exports = {
954
- findFiles,
984
+ findFiles,
955
985
 
956
- isNonEmptyString,
957
- isArrayOfNonEmptyString,
986
+ isNonEmptyString,
987
+ isArrayOfNonEmptyString,
958
988
 
959
- createIgnoreResult,
960
- isErrorMessage,
989
+ createIgnoreResult,
990
+ isErrorMessage,
961
991
 
962
- processOptions,
992
+ processOptions,
963
993
 
964
- getCacheFile
994
+ getCacheFile,
965
995
  };