eslint-plugin-unicorn 56.0.1 → 58.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/configs/flat-config-base.js +4 -3
  2. package/index.d.ts +7 -3
  3. package/index.js +32 -37
  4. package/package.json +57 -115
  5. package/readme.md +15 -138
  6. package/rules/ast/call-or-new-expression.js +3 -11
  7. package/rules/ast/function-types.js +6 -4
  8. package/rules/ast/index.js +18 -32
  9. package/rules/ast/is-arrow-function-body.js +1 -5
  10. package/rules/ast/is-directive.js +2 -5
  11. package/rules/ast/is-empty-node.js +1 -4
  12. package/rules/ast/is-expression-statement.js +1 -5
  13. package/rules/ast/is-function.js +2 -5
  14. package/rules/ast/is-member-expression.js +1 -5
  15. package/rules/ast/is-method-call.js +3 -6
  16. package/rules/ast/is-negative-one.js +2 -6
  17. package/rules/ast/is-reference-identifier.js +1 -5
  18. package/rules/ast/is-static-require.js +8 -12
  19. package/rules/ast/is-tagged-template-literal.js +2 -6
  20. package/rules/ast/is-undefined.js +1 -5
  21. package/rules/ast/literal.js +11 -17
  22. package/rules/better-regex.js +9 -8
  23. package/rules/catch-error-name.js +11 -8
  24. package/rules/consistent-assert.js +98 -0
  25. package/rules/consistent-date-clone.js +54 -0
  26. package/rules/consistent-destructuring.js +6 -6
  27. package/rules/consistent-empty-array-spread.js +4 -3
  28. package/rules/consistent-existence-index-check.js +9 -5
  29. package/rules/consistent-function-scoping.js +7 -11
  30. package/rules/custom-error-definition.js +14 -12
  31. package/rules/empty-brace-spaces.js +8 -7
  32. package/rules/error-message.js +7 -18
  33. package/rules/escape-case.js +29 -17
  34. package/rules/expiring-todo-comments.js +20 -20
  35. package/rules/explicit-length-check.js +9 -8
  36. package/rules/filename-case.js +15 -6
  37. package/rules/fix/add-parenthesizes-to-return-or-throw-expression.js +2 -6
  38. package/rules/fix/append-argument.js +2 -5
  39. package/rules/fix/extend-fix-range.js +1 -5
  40. package/rules/fix/fix-space-around-keywords.js +4 -7
  41. package/rules/fix/index.js +18 -23
  42. package/rules/fix/remove-argument.js +9 -11
  43. package/rules/fix/remove-member-expression-property.js +3 -7
  44. package/rules/fix/remove-method-call.js +4 -7
  45. package/rules/fix/remove-parentheses.js +2 -5
  46. package/rules/fix/remove-spaces-after.js +3 -7
  47. package/rules/fix/remove-specifier.js +46 -0
  48. package/rules/fix/rename-variable.js +5 -7
  49. package/rules/fix/replace-argument.js +2 -5
  50. package/rules/fix/replace-node-or-token-and-spaces-before.js +3 -6
  51. package/rules/fix/replace-reference-identifier.js +6 -9
  52. package/rules/fix/replace-string-raw.js +3 -3
  53. package/rules/fix/replace-template-element.js +2 -3
  54. package/rules/fix/switch-call-expression-to-new-expression.js +4 -7
  55. package/rules/fix/switch-new-expression-to-call-expression.js +6 -9
  56. package/rules/import-style.js +7 -5
  57. package/rules/index.js +262 -0
  58. package/rules/new-for-builtins.js +41 -6
  59. package/rules/no-abusive-eslint-disable.js +37 -23
  60. package/rules/no-accessor-recursion.js +160 -0
  61. package/rules/no-anonymous-default-export.js +21 -25
  62. package/rules/no-array-callback-reference.js +6 -5
  63. package/rules/no-array-for-each.js +33 -23
  64. package/rules/no-array-method-this-argument.js +10 -9
  65. package/rules/no-array-push-push.js +13 -15
  66. package/rules/no-array-reduce.js +6 -5
  67. package/rules/no-await-expression-member.js +5 -7
  68. package/rules/no-await-in-promise-methods.js +5 -4
  69. package/rules/no-console-spaces.js +8 -6
  70. package/rules/no-document-cookie.js +4 -3
  71. package/rules/no-empty-file.js +4 -3
  72. package/rules/no-for-loop.js +30 -25
  73. package/rules/no-hex-escape.js +5 -8
  74. package/rules/no-instanceof-builtins.js +225 -0
  75. package/rules/no-invalid-fetch-options.js +6 -5
  76. package/rules/no-invalid-remove-event-listener.js +5 -4
  77. package/rules/no-keyword-prefix.js +5 -3
  78. package/rules/no-length-as-slice-end.js +6 -5
  79. package/rules/no-lonely-if.js +6 -5
  80. package/rules/no-magic-array-flat-depth.js +5 -4
  81. package/rules/no-named-default.js +100 -0
  82. package/rules/no-negated-condition.js +10 -12
  83. package/rules/no-negation-in-equality-check.js +5 -11
  84. package/rules/no-nested-ternary.js +4 -3
  85. package/rules/no-new-array.js +7 -6
  86. package/rules/no-new-buffer.js +7 -6
  87. package/rules/no-null.js +9 -9
  88. package/rules/no-object-as-default-parameter.js +4 -3
  89. package/rules/no-process-exit.js +4 -3
  90. package/rules/no-single-promise-in-promise-methods.js +7 -11
  91. package/rules/no-static-only-class.js +9 -8
  92. package/rules/no-thenable.js +7 -12
  93. package/rules/no-this-assignment.js +3 -2
  94. package/rules/no-typeof-undefined.js +11 -9
  95. package/rules/no-unnecessary-await.js +8 -10
  96. package/rules/no-unnecessary-polyfills.js +16 -14
  97. package/rules/no-unreadable-array-destructuring.js +6 -5
  98. package/rules/no-unreadable-iife.js +4 -7
  99. package/rules/no-unused-properties.js +4 -3
  100. package/rules/no-useless-fallback-in-spread.js +7 -9
  101. package/rules/no-useless-length-check.js +8 -11
  102. package/rules/no-useless-promise-resolve-reject.js +5 -4
  103. package/rules/no-useless-spread.js +8 -14
  104. package/rules/no-useless-switch-case.js +5 -4
  105. package/rules/no-useless-undefined.js +19 -13
  106. package/rules/no-zero-fractions.js +11 -10
  107. package/rules/number-literal-case.js +38 -9
  108. package/rules/numeric-separators-style.js +16 -9
  109. package/rules/prefer-add-event-listener.js +7 -5
  110. package/rules/prefer-array-find.js +13 -13
  111. package/rules/prefer-array-flat-map.js +10 -6
  112. package/rules/prefer-array-flat.js +8 -9
  113. package/rules/prefer-array-index-of.js +4 -3
  114. package/rules/prefer-array-some.js +20 -16
  115. package/rules/prefer-at.js +24 -16
  116. package/rules/prefer-blob-reading-methods.js +4 -3
  117. package/rules/prefer-code-point.js +4 -3
  118. package/rules/prefer-date-now.js +5 -8
  119. package/rules/prefer-default-parameters.js +9 -10
  120. package/rules/prefer-dom-node-append.js +5 -4
  121. package/rules/prefer-dom-node-dataset.js +7 -9
  122. package/rules/prefer-dom-node-remove.js +7 -6
  123. package/rules/prefer-dom-node-text-content.js +4 -3
  124. package/rules/prefer-event-target.js +6 -5
  125. package/rules/prefer-export-from.js +9 -55
  126. package/rules/prefer-global-this.js +18 -7
  127. package/rules/prefer-includes.js +15 -8
  128. package/rules/prefer-json-parse-buffer.js +6 -5
  129. package/rules/prefer-keyboard-event-key.js +6 -5
  130. package/rules/prefer-logical-operator-over-ternary.js +7 -6
  131. package/rules/prefer-math-min-max.js +128 -4
  132. package/rules/prefer-math-trunc.js +6 -5
  133. package/rules/prefer-modern-dom-apis.js +5 -4
  134. package/rules/prefer-modern-math-apis.js +7 -10
  135. package/rules/prefer-module.js +8 -11
  136. package/rules/prefer-native-coercion-functions.js +5 -4
  137. package/rules/prefer-negative-index.js +6 -8
  138. package/rules/prefer-node-protocol.js +15 -13
  139. package/rules/prefer-number-properties.js +12 -8
  140. package/rules/prefer-object-from-entries.js +13 -11
  141. package/rules/prefer-optional-catch-binding.js +7 -6
  142. package/rules/prefer-prototype-methods.js +6 -5
  143. package/rules/prefer-query-selector.js +5 -4
  144. package/rules/prefer-reflect-apply.js +5 -4
  145. package/rules/prefer-regexp-test.js +7 -9
  146. package/rules/prefer-set-has.js +6 -5
  147. package/rules/prefer-set-size.js +6 -5
  148. package/rules/prefer-spread.js +12 -11
  149. package/rules/prefer-string-raw.js +11 -8
  150. package/rules/prefer-string-replace-all.js +8 -6
  151. package/rules/prefer-string-slice.js +7 -6
  152. package/rules/prefer-string-starts-ends-with.js +9 -8
  153. package/rules/prefer-string-trim-start-end.js +4 -3
  154. package/rules/prefer-structured-clone.js +10 -12
  155. package/rules/prefer-switch.js +24 -15
  156. package/rules/prefer-ternary.js +18 -14
  157. package/rules/prefer-top-level-await.js +5 -4
  158. package/rules/prefer-type-error.js +4 -3
  159. package/rules/prevent-abbreviations.js +20 -15
  160. package/rules/relative-url-style.js +12 -10
  161. package/rules/require-array-join-separator.js +8 -7
  162. package/rules/require-number-to-fixed-digits-argument.js +7 -6
  163. package/rules/require-post-message-target-origin.js +7 -6
  164. package/rules/shared/abbreviations.js +12 -4
  165. package/rules/shared/builtin-errors.js +14 -0
  166. package/rules/shared/dom-events.js +3 -3
  167. package/rules/shared/event-keys.js +4 -2
  168. package/rules/shared/negative-index.js +6 -10
  169. package/rules/shared/simple-array-search-rule.js +4 -8
  170. package/rules/shared/typed-array.js +3 -3
  171. package/rules/string-content.js +7 -5
  172. package/rules/switch-case-braces.js +10 -8
  173. package/rules/template-indent.js +14 -16
  174. package/rules/text-encoding-identifier-case.js +6 -5
  175. package/rules/throw-new-error.js +4 -3
  176. package/rules/utils/array-or-object-prototype-property.js +3 -9
  177. package/rules/utils/assert-token.js +2 -5
  178. package/rules/utils/boolean.js +4 -8
  179. package/rules/utils/builtins.js +3 -9
  180. package/rules/utils/cartesian-product-samples.js +2 -4
  181. package/rules/utils/create-deprecated-rules.js +20 -16
  182. package/rules/utils/escape-string.js +3 -5
  183. package/rules/utils/escape-template-element-raw.js +2 -3
  184. package/rules/utils/get-ancestor.js +2 -7
  185. package/rules/utils/{avoid-capture.js → get-available-variable-name.js} +8 -8
  186. package/rules/utils/get-builtin-rule.js +3 -5
  187. package/rules/utils/get-call-expression-arguments-text.js +6 -9
  188. package/rules/utils/get-call-expression-tokens.js +2 -9
  189. package/rules/utils/get-class-head-location.js +4 -8
  190. package/rules/utils/get-documentation-url.js +4 -5
  191. package/rules/utils/get-indent-string.js +2 -6
  192. package/rules/utils/get-previous-node.js +1 -5
  193. package/rules/utils/get-references.js +3 -7
  194. package/rules/utils/get-scopes.js +1 -3
  195. package/rules/utils/get-switch-case-head-location.js +3 -8
  196. package/rules/utils/get-variable-identifiers.js +2 -3
  197. package/rules/utils/global-reference-tracker.js +2 -7
  198. package/rules/utils/has-optional-chain-element.js +1 -5
  199. package/rules/utils/has-same-range.js +4 -3
  200. package/rules/utils/index.js +43 -45
  201. package/rules/utils/is-function-self-used-inside.js +2 -6
  202. package/rules/utils/is-left-hand-side.js +1 -3
  203. package/rules/utils/is-logical-expression.js +1 -3
  204. package/rules/utils/is-method-named.js +1 -3
  205. package/rules/utils/is-new-expression-with-parentheses.js +3 -7
  206. package/rules/utils/is-node-matches.js +2 -9
  207. package/rules/utils/is-node-value-not-dom-node.js +2 -3
  208. package/rules/utils/is-node-value-not-function.js +2 -3
  209. package/rules/utils/is-number.js +5 -6
  210. package/rules/utils/is-object-method.js +2 -3
  211. package/rules/utils/is-on-same-line.js +2 -5
  212. package/rules/utils/is-same-identifier.js +2 -5
  213. package/rules/utils/is-same-reference.js +2 -5
  214. package/rules/utils/is-shadowed.js +13 -15
  215. package/rules/utils/is-shorthand-export-local.js +2 -3
  216. package/rules/utils/is-shorthand-import-local.js +2 -3
  217. package/rules/utils/is-shorthand-property-assignment-pattern-left.js +2 -4
  218. package/rules/utils/is-shorthand-property-value.js +1 -3
  219. package/rules/utils/is-value-not-usable.js +3 -4
  220. package/rules/utils/lodash.js +18 -40
  221. package/rules/utils/needs-semicolon.js +3 -7
  222. package/rules/utils/numeric.js +11 -20
  223. package/rules/utils/parentheses.js +8 -15
  224. package/rules/utils/resolve-variable-name.js +2 -4
  225. package/rules/utils/rule.js +9 -26
  226. package/rules/utils/should-add-parentheses-to-await-expression-argument.js +1 -5
  227. package/rules/utils/should-add-parentheses-to-call-expression-callee.js +1 -5
  228. package/rules/utils/should-add-parentheses-to-conditional-expression-child.js +1 -5
  229. package/rules/utils/should-add-parentheses-to-expression-statement-expression.js +1 -5
  230. package/rules/utils/should-add-parentheses-to-logical-expression-child.js +1 -5
  231. package/rules/utils/should-add-parentheses-to-member-expression-object.js +3 -7
  232. package/rules/utils/should-add-parentheses-to-new-expression-callee.js +1 -5
  233. package/rules/utils/singular.js +3 -5
  234. package/rules/utils/to-location.js +2 -4
  235. package/configs/legacy-config-base.js +0 -10
  236. package/rules/fix/replace-string-literal.js +0 -11
  237. package/rules/no-instanceof-array.js +0 -66
@@ -1,8 +1,9 @@
1
- 'use strict';
2
- const globals = require('globals');
1
+ import globals from 'globals';
3
2
 
4
- module.exports = {
3
+ const config = {
5
4
  languageOptions: {
6
5
  globals: globals.builtin,
7
6
  },
8
7
  };
8
+
9
+ export default config;
package/index.d.ts CHANGED
@@ -2,11 +2,15 @@ import type {ESLint, Linter} from 'eslint';
2
2
 
3
3
  declare const eslintPluginUnicorn: ESLint.Plugin & {
4
4
  configs: {
5
- recommended: Linter.Config;
6
- all: Linter.Config;
5
+ recommended: Linter.FlatConfig;
6
+ all: Linter.FlatConfig;
7
+
8
+ /** @deprecated Use `all` instead. The `flat/` prefix is no longer needed. */
7
9
  'flat/all': Linter.FlatConfig;
10
+
11
+ /** @deprecated Use `recommended` instead. The `flat/` prefix is no longer needed. */
8
12
  'flat/recommended': Linter.FlatConfig;
9
13
  };
10
14
  };
11
15
 
12
- export = eslintPluginUnicorn;
16
+ export default eslintPluginUnicorn;
package/index.js CHANGED
@@ -1,29 +1,14 @@
1
- 'use strict';
2
- const createDeprecatedRules = require('./rules/utils/create-deprecated-rules.js');
3
- const {loadRules} = require('./rules/utils/rule.js');
4
- const legacyConfigBase = require('./configs/legacy-config-base.js');
5
- const flatConfigBase = require('./configs/flat-config-base.js');
6
- const {name, version} = require('./package.json');
1
+ import createDeprecatedRules from './rules/utils/create-deprecated-rules.js';
2
+ import flatConfigBase from './configs/flat-config-base.js';
3
+ import rules from './rules/index.js';
4
+ import packageJson from './package.json' with {type: 'json'};
7
5
 
8
6
  const deprecatedRules = createDeprecatedRules({
9
- // {ruleId: ReplacementRuleId | ReplacementRuleId[]}, if no replacement, use `{ruleId: []}`
10
- 'import-index': [],
11
- 'no-array-instanceof': 'unicorn/no-instanceof-array',
12
- 'no-fn-reference-in-iterator': 'unicorn/no-array-callback-reference',
13
- 'no-reduce': 'unicorn/no-array-reduce',
14
- 'no-unsafe-regex': [],
15
- 'prefer-dataset': 'unicorn/prefer-dom-node-dataset',
16
- 'prefer-event-key': 'unicorn/prefer-keyboard-event-key',
17
- 'prefer-exponentiation-operator': 'prefer-exponentiation-operator',
18
- 'prefer-flat-map': 'unicorn/prefer-array-flat-map',
19
- 'prefer-node-append': 'unicorn/prefer-dom-node-append',
20
- 'prefer-node-remove': 'unicorn/prefer-dom-node-remove',
21
- 'prefer-object-has-own': 'prefer-object-has-own',
22
- 'prefer-replace-all': 'unicorn/prefer-string-replace-all',
23
- 'prefer-starts-ends-with': 'unicorn/prefer-string-starts-ends-with',
24
- 'prefer-text-content': 'unicorn/prefer-dom-node-text-content',
25
- 'prefer-trim-start-end': 'unicorn/prefer-string-trim-start-end',
26
- 'regex-shorthand': 'unicorn/better-regex',
7
+ // {ruleId: {message: string, replacedBy: string[]}}
8
+ 'no-instanceof-array': {
9
+ message: 'Replaced by `unicorn/no-instanceof-builtins` which covers more cases.',
10
+ replacedBy: ['unicorn/no-instanceof-builtins'],
11
+ },
27
12
  });
28
13
 
29
14
  const externalRules = {
@@ -33,13 +18,13 @@ const externalRules = {
33
18
  'no-nested-ternary': 'off',
34
19
  };
35
20
 
36
- const rules = loadRules();
37
21
  const recommendedRules = Object.fromEntries(
38
22
  Object.entries(rules).map(([id, rule]) => [
39
23
  `unicorn/${id}`,
40
24
  rule.meta.docs.recommended ? 'error' : 'off',
41
25
  ]),
42
26
  );
27
+
43
28
  const allRules = Object.fromEntries(
44
29
  Object.keys(rules).map(id => [
45
30
  `unicorn/${id}`,
@@ -47,19 +32,22 @@ const allRules = Object.fromEntries(
47
32
  ]),
48
33
  );
49
34
 
50
- const createConfig = (rules, flatConfigName = false) => ({
51
- ...(
52
- flatConfigName
53
- ? {...flatConfigBase, name: flatConfigName, plugins: {unicorn}}
54
- : {...legacyConfigBase, plugins: ['unicorn']}
55
- ),
56
- rules: {...externalRules, ...rules},
35
+ const createConfig = (rules, flatConfigName) => ({
36
+ ...flatConfigBase,
37
+ name: flatConfigName,
38
+ plugins: {
39
+ unicorn,
40
+ },
41
+ rules: {
42
+ ...externalRules,
43
+ ...rules,
44
+ },
57
45
  });
58
46
 
59
47
  const unicorn = {
60
48
  meta: {
61
- name,
62
- version,
49
+ name: packageJson.name,
50
+ version: packageJson.version,
63
51
  },
64
52
  rules: {
65
53
  ...rules,
@@ -68,10 +56,17 @@ const unicorn = {
68
56
  };
69
57
 
70
58
  const configs = {
71
- recommended: createConfig(recommendedRules),
72
- all: createConfig(allRules),
59
+ recommended: createConfig(recommendedRules, 'unicorn/recommended'),
60
+ all: createConfig(allRules, 'unicorn/all'),
61
+
62
+ // TODO: Remove this at some point. Kept for now to avoid breaking users.
73
63
  'flat/recommended': createConfig(recommendedRules, 'unicorn/flat/recommended'),
74
64
  'flat/all': createConfig(allRules, 'unicorn/flat/all'),
75
65
  };
76
66
 
77
- module.exports = {...unicorn, configs};
67
+ const allConfigs = {
68
+ ...unicorn,
69
+ configs,
70
+ };
71
+
72
+ export default allConfigs;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-unicorn",
3
- "version": "56.0.1",
3
+ "version": "58.0.0",
4
4
  "description": "More than 100 powerful ESLint rules",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/eslint-plugin-unicorn",
@@ -10,28 +10,33 @@
10
10
  "email": "sindresorhus@gmail.com",
11
11
  "url": "https://sindresorhus.com"
12
12
  },
13
- "main": "index.js",
14
- "types": "index.d.ts",
13
+ "type": "module",
14
+ "exports": {
15
+ "types": "./index.d.ts",
16
+ "default": "./index.js"
17
+ },
15
18
  "sideEffects": false,
16
19
  "engines": {
17
- "node": ">=18.18"
20
+ "node": "^18.20.0 || ^20.10.0 || >=21.0.0"
18
21
  },
19
22
  "scripts": {
20
- "bundle-lodash": "echo \"export {defaultsDeep, camelCase, kebabCase, snakeCase, upperFirst, lowerFirst} from 'lodash-es';\" | npx esbuild --bundle --outfile=rules/utils/lodash.js --format=cjs",
21
- "create-rule": "node ./scripts/create-rule.mjs && npm run fix:eslint-docs",
23
+ "bundle-lodash": "echo export {defaultsDeep, camelCase, kebabCase, snakeCase, upperFirst, lowerFirst} from 'lodash-es'; | npx esbuild --bundle --outfile=rules/utils/lodash.js --format=esm",
24
+ "create-rule": "node ./scripts/create-rule.js && npm run create-rules-index-file && npm run fix:eslint-docs",
25
+ "create-rules-index-file": "node ./scripts/create-rules-index-file.js",
22
26
  "fix": "run-p --continue-on-error fix:*",
23
- "fix:eslint-docs": "eslint-doc-generator",
27
+ "fix:eslint-docs": "eslint-doc-generator workaround-for-eslint-doc-generator",
24
28
  "fix:js": "npm run lint:js -- --fix",
25
29
  "fix:markdown": "npm run lint:markdown -- --fix",
26
30
  "fix:snapshots": "ava --update-snapshots",
27
- "integration": "node ./test/integration/test.mjs",
31
+ "integration": "node ./test/integration/test.js",
28
32
  "lint": "run-p --continue-on-error lint:*",
29
33
  "lint:eslint-docs": "npm run fix:eslint-docs -- --check",
30
- "lint:js": "xo",
34
+ "lint:js": "eslint",
31
35
  "lint:markdown": "markdownlint \"**/*.md\"",
32
36
  "lint:package-json": "npmPkgJsonLint .",
33
- "run-rules-on-codebase": "eslint --config=./eslint.dogfooding.config.mjs",
34
- "smoke": "eslint-remote-tester --config ./test/smoke/eslint-remote-tester.config.mjs",
37
+ "rename-rule": "node ./scripts/rename-rule.js && npm run create-rules-index-file && npm run fix:eslint-docs",
38
+ "run-rules-on-codebase": "eslint --config=./eslint.dogfooding.config.js",
39
+ "smoke": "eslint-remote-tester --config ./test/smoke/eslint-remote-tester.config.js",
35
40
  "test": "npm-run-all --continue-on-error lint test:*",
36
41
  "test:js": "c8 ava"
37
42
  },
@@ -52,63 +57,65 @@
52
57
  "xo"
53
58
  ],
54
59
  "dependencies": {
55
- "@babel/helper-validator-identifier": "^7.24.7",
56
- "@eslint-community/eslint-utils": "^4.4.0",
57
- "ci-info": "^4.0.0",
60
+ "@babel/helper-validator-identifier": "^7.25.9",
61
+ "@eslint-community/eslint-utils": "^4.5.1",
62
+ "@eslint/plugin-kit": "^0.2.7",
63
+ "ci-info": "^4.2.0",
58
64
  "clean-regexp": "^1.0.0",
59
- "core-js-compat": "^3.38.1",
65
+ "core-js-compat": "^3.41.0",
60
66
  "esquery": "^1.6.0",
61
- "globals": "^15.9.0",
62
- "indent-string": "^4.0.0",
63
- "is-builtin-module": "^3.2.1",
64
- "jsesc": "^3.0.2",
67
+ "globals": "^16.0.0",
68
+ "indent-string": "^5.0.0",
69
+ "is-builtin-module": "^5.0.0",
70
+ "jsesc": "^3.1.0",
65
71
  "pluralize": "^8.0.0",
66
- "read-pkg-up": "^7.0.1",
72
+ "read-package-up": "^11.0.0",
67
73
  "regexp-tree": "^0.1.27",
68
- "regjsparser": "^0.10.0",
69
- "semver": "^7.6.3",
70
- "strip-indent": "^3.0.0"
74
+ "regjsparser": "^0.12.0",
75
+ "semver": "^7.7.1",
76
+ "strip-indent": "^4.0.0"
71
77
  },
72
78
  "devDependencies": {
73
- "@babel/code-frame": "^7.24.7",
74
- "@babel/core": "^7.25.2",
75
- "@babel/eslint-parser": "^7.25.1",
76
- "@eslint/eslintrc": "^3.1.0",
79
+ "@babel/code-frame": "^7.26.2",
80
+ "@babel/core": "^7.26.10",
81
+ "@babel/eslint-parser": "^7.26.10",
82
+ "@eslint/eslintrc": "^3.3.0",
77
83
  "@lubien/fixture-beta-package": "^1.0.0-beta.1",
78
- "@typescript-eslint/parser": "^8.4.0",
79
- "ava": "^6.1.3",
80
- "c8": "^10.1.2",
81
- "chalk": "^5.3.0",
84
+ "@typescript-eslint/parser": "^8.26.1",
85
+ "ava": "^6.2.0",
86
+ "c8": "^10.1.3",
82
87
  "enquirer": "^2.4.1",
83
- "eslint": "^9.10.0",
88
+ "eslint": "^9.22.0",
84
89
  "eslint-ava-rule-tester": "^5.0.1",
85
- "eslint-doc-generator": "1.7.0",
86
- "eslint-plugin-eslint-plugin": "^6.2.0",
87
- "eslint-plugin-internal-rules": "file:./scripts/internal-rules/",
90
+ "eslint-config-xo": "^0.46.0",
91
+ "eslint-doc-generator": "^2.1.2",
92
+ "eslint-plugin-eslint-plugin": "^6.4.0",
93
+ "eslint-plugin-jsdoc": "^50.6.8",
88
94
  "eslint-remote-tester": "^4.0.1",
89
- "eslint-remote-tester-repositories": "^2.0.0",
90
- "espree": "^10.1.0",
91
- "execa": "^8.0.1",
92
- "listr": "^0.14.3",
95
+ "eslint-remote-tester-repositories": "^2.0.1",
96
+ "espree": "^10.3.0",
97
+ "listr2": "^8.2.5",
93
98
  "lodash-es": "^4.17.21",
94
- "markdownlint-cli": "^0.41.0",
95
- "memoize": "^10.0.0",
99
+ "markdownlint-cli": "^0.44.0",
100
+ "memoize": "^10.1.0",
101
+ "nano-spawn": "^0.2.0",
102
+ "node-style-text": "^0.0.7",
96
103
  "npm-package-json-lint": "^8.0.0",
97
- "npm-run-all2": "^6.2.2",
104
+ "npm-run-all2": "^7.0.2",
105
+ "open-editor": "^5.1.0",
98
106
  "outdent": "^0.8.0",
99
- "pretty-ms": "^9.1.0",
100
- "typescript": "^5.5.4",
101
- "vue-eslint-parser": "^9.4.3",
102
- "xo": "^0.59.3",
103
- "yaml": "^2.5.1"
107
+ "pretty-ms": "^9.2.0",
108
+ "typescript": "^5.8.2",
109
+ "vue-eslint-parser": "^10.1.1",
110
+ "yaml": "^2.7.0"
104
111
  },
105
112
  "peerDependencies": {
106
- "eslint": ">=8.56.0"
113
+ "eslint": ">=9.22.0"
107
114
  },
108
115
  "ava": {
109
116
  "files": [
110
- "test/*.mjs",
111
- "test/unit/*.mjs"
117
+ "test/*.js",
118
+ "test/unit/*.js"
112
119
  ]
113
120
  },
114
121
  "c8": {
@@ -116,70 +123,5 @@
116
123
  "text",
117
124
  "lcov"
118
125
  ]
119
- },
120
- "xo": {
121
- "extends": [
122
- "plugin:internal-rules/all"
123
- ],
124
- "ignores": [
125
- ".cache-eslint-remote-tester",
126
- "eslint-remote-tester-results",
127
- "rules/utils/lodash.js",
128
- "test/integration/{fixtures,fixtures-local}/**"
129
- ],
130
- "rules": {
131
- "unicorn/escape-case": "off",
132
- "unicorn/expiring-todo-comments": "off",
133
- "unicorn/no-hex-escape": "off",
134
- "unicorn/no-null": "error",
135
- "unicorn/prefer-array-flat": [
136
- "error",
137
- {
138
- "functions": [
139
- "flat",
140
- "flatten"
141
- ]
142
- }
143
- ],
144
- "import/order": "off",
145
- "func-names": "off"
146
- },
147
- "overrides": [
148
- {
149
- "files": [
150
- "**/*.js"
151
- ],
152
- "parserOptions": {
153
- "sourceType": "script"
154
- },
155
- "rules": {
156
- "strict": "error",
157
- "unicorn/prefer-module": "off"
158
- }
159
- },
160
- {
161
- "files": [
162
- "rules/*.js"
163
- ],
164
- "plugins": [
165
- "eslint-plugin"
166
- ],
167
- "extends": [
168
- "plugin:eslint-plugin/all"
169
- ],
170
- "rules": {
171
- "eslint-plugin/require-meta-docs-description": [
172
- "error",
173
- {
174
- "pattern": ".+"
175
- }
176
- ],
177
- "eslint-plugin/require-meta-docs-url": "off",
178
- "eslint-plugin/require-meta-has-suggestions": "off",
179
- "eslint-plugin/require-meta-schema": "off",
180
- "eslint-plugin/require-meta-schema-description": "off"
181
- }
182
- }
183
- ]
184
126
  }
185
127
  }
package/readme.md CHANGED
@@ -15,16 +15,14 @@ You might want to check out [XO](https://github.com/xojs/xo), which includes thi
15
15
  npm install --save-dev eslint eslint-plugin-unicorn
16
16
  ```
17
17
 
18
- ## Usage (`eslint.config.js`)
18
+ **Requires ESLint `>=9.20.0`, [flat config](https://eslint.org/docs/latest/use/configure/configuration-files), and [ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#how-can-i-make-my-typescript-project-output-esm).**
19
19
 
20
- **Requires ESLint `>=8.56.0`.**
20
+ ## Usage
21
21
 
22
- Use a [preset config](#preset-configs-eslintconfigjs) or configure each rule in `eslint.config.js`.
22
+ Use a [preset config](#preset-configs) or configure each rule in `eslint.config.js`.
23
23
 
24
24
  If you don't use the preset, ensure you use the same `languageOptions` config as below.
25
25
 
26
- ### ES Module (Recommended)
27
-
28
26
  ```js
29
27
  import eslintPluginUnicorn from 'eslint-plugin-unicorn';
30
28
  import globals from 'globals';
@@ -46,65 +44,13 @@ export default [
46
44
  ];
47
45
  ```
48
46
 
49
- ### CommonJS
50
-
51
- ```js
52
- 'use strict';
53
- const eslintPluginUnicorn = require('eslint-plugin-unicorn');
54
- const globals = require('globals');
55
-
56
- module.exports = [
57
- {
58
- languageOptions: {
59
- globals: globals.builtin,
60
- },
61
- plugins: {
62
- unicorn: eslintPluginUnicorn,
63
- },
64
- rules: {
65
- 'unicorn/better-regex': 'error',
66
- 'unicorn/…': 'error',
67
- },
68
- },
69
- // …
70
- ];
71
- ```
72
-
73
- ## Usage (legacy: `.eslintrc.*` or `package.json`)
74
-
75
- Use a [preset config](#legacy-preset-configs-eslintrc-or-packagejson) or configure each rule in `package.json`.
76
-
77
- If you don't use the preset, ensure you use the same `env` and `parserOptions` config as below.
78
-
79
- ```json
80
- {
81
- "name": "my-awesome-project",
82
- "eslintConfig": {
83
- "env": {
84
- "es2024": true
85
- },
86
- "parserOptions": {
87
- "ecmaVersion": "latest",
88
- "sourceType": "module"
89
- },
90
- "plugins": [
91
- "unicorn"
92
- ],
93
- "rules": {
94
- "unicorn/better-regex": "error",
95
- "unicorn/…": "error"
96
- }
97
- }
98
- }
99
- ```
100
-
101
47
  ## Rules
102
48
 
103
49
  <!-- Do not manually modify this list. Run: `npm run fix:eslint-docs` -->
104
50
  <!-- begin auto-generated rules list -->
105
51
 
106
- 💼 [Configurations](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs-eslintconfigjs) enabled in.\
107
- ✅ Set in the `recommended` [configuration](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs-eslintconfigjs).\
52
+ 💼 [Configurations](https://github.com/sindresorhus/eslint-plugin-unicorn#recommended-config) enabled in.\
53
+ ✅ Set in the `recommended` [configuration](https://github.com/sindresorhus/eslint-plugin-unicorn#recommended-config).\
108
54
  🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
109
55
  💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
110
56
 
@@ -112,6 +58,8 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c
112
58
  | :----------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :- | :- | :- |
113
59
  | [better-regex](docs/rules/better-regex.md) | Improve regexes by making them shorter, consistent, and safer. | | 🔧 | |
114
60
  | [catch-error-name](docs/rules/catch-error-name.md) | Enforce a specific parameter name in catch clauses. | ✅ | 🔧 | |
61
+ | [consistent-assert](docs/rules/consistent-assert.md) | Enforce consistent assertion style with `node:assert`. | ✅ | 🔧 | |
62
+ | [consistent-date-clone](docs/rules/consistent-date-clone.md) | Prefer passing `Date` directly to the constructor when cloning. | ✅ | 🔧 | |
115
63
  | [consistent-destructuring](docs/rules/consistent-destructuring.md) | Use destructured variables over properties. | | 🔧 | 💡 |
116
64
  | [consistent-empty-array-spread](docs/rules/consistent-empty-array-spread.md) | Prefer consistent types when spreading a ternary in an array literal. | ✅ | 🔧 | |
117
65
  | [consistent-existence-index-check](docs/rules/consistent-existence-index-check.md) | Enforce consistent style for element existence checks with `indexOf()`, `lastIndexOf()`, `findIndex()`, and `findLastIndex()`. | ✅ | 🔧 | |
@@ -119,13 +67,14 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c
119
67
  | [custom-error-definition](docs/rules/custom-error-definition.md) | Enforce correct `Error` subclassing. | | 🔧 | |
120
68
  | [empty-brace-spaces](docs/rules/empty-brace-spaces.md) | Enforce no spaces between braces. | ✅ | 🔧 | |
121
69
  | [error-message](docs/rules/error-message.md) | Enforce passing a `message` value when creating a built-in error. | ✅ | | |
122
- | [escape-case](docs/rules/escape-case.md) | Require escape sequences to use uppercase values. | ✅ | 🔧 | |
70
+ | [escape-case](docs/rules/escape-case.md) | Require escape sequences to use uppercase or lowercase values. | ✅ | 🔧 | |
123
71
  | [expiring-todo-comments](docs/rules/expiring-todo-comments.md) | Add expiration conditions to TODO comments. | ✅ | | |
124
72
  | [explicit-length-check](docs/rules/explicit-length-check.md) | Enforce explicitly comparing the `length` or `size` property of a value. | ✅ | 🔧 | 💡 |
125
73
  | [filename-case](docs/rules/filename-case.md) | Enforce a case style for filenames. | ✅ | | |
126
74
  | [import-style](docs/rules/import-style.md) | Enforce specific import styles per module. | ✅ | | |
127
- | [new-for-builtins](docs/rules/new-for-builtins.md) | Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. | ✅ | 🔧 | |
75
+ | [new-for-builtins](docs/rules/new-for-builtins.md) | Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. | ✅ | 🔧 | 💡 |
128
76
  | [no-abusive-eslint-disable](docs/rules/no-abusive-eslint-disable.md) | Enforce specifying rules to disable in `eslint-disable` comments. | ✅ | | |
77
+ | [no-accessor-recursion](docs/rules/no-accessor-recursion.md) | Disallow recursive access to `this` within getters and setters. | ✅ | | |
129
78
  | [no-anonymous-default-export](docs/rules/no-anonymous-default-export.md) | Disallow anonymous functions and classes as the default export. | ✅ | | 💡 |
130
79
  | [no-array-callback-reference](docs/rules/no-array-callback-reference.md) | Prevent passing a function reference directly to iterator methods. | ✅ | | 💡 |
131
80
  | [no-array-for-each](docs/rules/no-array-for-each.md) | Prefer `for…of` over the `forEach` method. | ✅ | 🔧 | 💡 |
@@ -139,13 +88,14 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c
139
88
  | [no-empty-file](docs/rules/no-empty-file.md) | Disallow empty files. | ✅ | | |
140
89
  | [no-for-loop](docs/rules/no-for-loop.md) | Do not use a `for` loop that can be replaced with a `for-of` loop. | ✅ | 🔧 | 💡 |
141
90
  | [no-hex-escape](docs/rules/no-hex-escape.md) | Enforce the use of Unicode escapes instead of hexadecimal escapes. | ✅ | 🔧 | |
142
- | [no-instanceof-array](docs/rules/no-instanceof-array.md) | Require `Array.isArray()` instead of `instanceof Array`. | ✅ | 🔧 | |
91
+ | [no-instanceof-builtins](docs/rules/no-instanceof-builtins.md) | Disallow `instanceof` with built-in objects | ✅ | 🔧 | 💡 |
143
92
  | [no-invalid-fetch-options](docs/rules/no-invalid-fetch-options.md) | Disallow invalid options in `fetch()` and `new Request()`. | ✅ | | |
144
93
  | [no-invalid-remove-event-listener](docs/rules/no-invalid-remove-event-listener.md) | Prevent calling `EventTarget#removeEventListener()` with the result of an expression. | ✅ | | |
145
94
  | [no-keyword-prefix](docs/rules/no-keyword-prefix.md) | Disallow identifiers starting with `new` or `class`. | | | |
146
95
  | [no-length-as-slice-end](docs/rules/no-length-as-slice-end.md) | Disallow using `.length` as the `end` argument of `{Array,String,TypedArray}#slice()`. | ✅ | 🔧 | |
147
96
  | [no-lonely-if](docs/rules/no-lonely-if.md) | Disallow `if` statements as the only statement in `if` blocks without `else`. | ✅ | 🔧 | |
148
97
  | [no-magic-array-flat-depth](docs/rules/no-magic-array-flat-depth.md) | Disallow a magic number as the `depth` argument in `Array#flat(…).` | ✅ | | |
98
+ | [no-named-default](docs/rules/no-named-default.md) | Disallow named usage of default import and export. | ✅ | 🔧 | |
149
99
  | [no-negated-condition](docs/rules/no-negated-condition.md) | Disallow negated conditions. | ✅ | 🔧 | |
150
100
  | [no-negation-in-equality-check](docs/rules/no-negation-in-equality-check.md) | Disallow negated expression in equality check. | ✅ | | 💡 |
151
101
  | [no-nested-ternary](docs/rules/no-nested-ternary.md) | Disallow nested ternary expressions. | ✅ | 🔧 | |
@@ -240,7 +190,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c
240
190
 
241
191
  See [docs/deprecated-rules.md](docs/deprecated-rules.md)
242
192
 
243
- ## Preset configs (`eslint.config.js`)
193
+ ## Preset configs
244
194
 
245
195
  See the [ESLint docs](https://eslint.org/docs/latest/use/configure/configuration-files) for more information about extending config files.
246
196
 
@@ -250,31 +200,12 @@ See the [ESLint docs](https://eslint.org/docs/latest/use/configure/configuration
250
200
 
251
201
  This plugin exports a `recommended` config that enforces good practices.
252
202
 
253
- #### ES Module (Recommended)
254
-
255
203
  ```js
256
204
  import eslintPluginUnicorn from 'eslint-plugin-unicorn';
257
205
 
258
206
  export default [
259
207
  // …
260
- eslintPluginUnicorn.configs['flat/recommended'],
261
- {
262
- rules: {
263
- 'unicorn/better-regex': 'warn',
264
- },
265
- },
266
- ];
267
- ```
268
-
269
- #### CommonJS
270
-
271
- ```js
272
- 'use strict';
273
- const eslintPluginUnicorn = require('eslint-plugin-unicorn');
274
-
275
- module.exports = [
276
- // …
277
- eslintPluginUnicorn.configs['flat/recommended'],
208
+ eslintPluginUnicorn.configs.recommended,
278
209
  {
279
210
  rules: {
280
211
  'unicorn/better-regex': 'warn',
@@ -287,31 +218,12 @@ module.exports = [
287
218
 
288
219
  This plugin exports an `all` that makes use of all rules (except for deprecated ones).
289
220
 
290
- #### ES Module (Recommended)
291
-
292
221
  ```js
293
222
  import eslintPluginUnicorn from 'eslint-plugin-unicorn';
294
223
 
295
224
  export default [
296
225
  // …
297
- eslintPluginUnicorn.configs['flat/all'],
298
- {
299
- rules: {
300
- 'unicorn/better-regex': 'warn',
301
- },
302
- },
303
- ];
304
- ```
305
-
306
- #### CommonJS
307
-
308
- ```js
309
- 'use strict';
310
- const eslintPluginUnicorn = require('eslint-plugin-unicorn');
311
-
312
- module.exports = [
313
- // …
314
- eslintPluginUnicorn.configs['flat/all'],
226
+ eslintPluginUnicorn.configs.all,
315
227
  {
316
228
  rules: {
317
229
  'unicorn/better-regex': 'warn',
@@ -320,41 +232,6 @@ module.exports = [
320
232
  ];
321
233
  ```
322
234
 
323
- ## Legacy preset configs (`.eslintrc.*` or `package.json`)
324
-
325
- See the [ESLint docs](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated) for more information about extending deprecated legacy config files.
326
-
327
- **Note**: Preset configs will also enable the correct [parser options](https://eslint.org/docs/latest/use/configure/parser-deprecated) and [environment](https://eslint.org/docs/latest/use/configure/language-options-deprecated).
328
-
329
- ### Recommended legacy config
330
-
331
- This plugin exports a `recommended` legacy config that enforces good practices.
332
-
333
- ```json
334
- {
335
- "name": "my-awesome-project",
336
- "eslintConfig": {
337
- "extends": "plugin:unicorn/recommended",
338
- "rules": {
339
- "unicorn/better-regex": "warn"
340
- }
341
- }
342
- }
343
- ```
344
-
345
- ### All legacy config
346
-
347
- This plugin exports an `all` legacy config that makes use of all rules (except for deprecated ones).
348
-
349
- ```json
350
- {
351
- "name": "my-awesome-project",
352
- "eslintConfig": {
353
- "extends": "plugin:unicorn/all"
354
- }
355
- }
356
- ```
357
-
358
235
  ## Maintainers
359
236
 
360
237
  - [Sindre Sorhus](https://github.com/sindresorhus)
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  /**
4
2
  @typedef {
5
3
  {
@@ -100,13 +98,13 @@ function create(node, options, types) {
100
98
  @param {CallOrNewExpressionCheckOptions} [options]
101
99
  @returns {boolean}
102
100
  */
103
- const isCallExpression = (node, options) => create(node, options, ['CallExpression']);
101
+ export const isCallExpression = (node, options) => create(node, options, ['CallExpression']);
104
102
 
105
103
  /**
106
104
  @param {CallOrNewExpressionCheckOptions} [options]
107
105
  @returns {boolean}
108
106
  */
109
- const isNewExpression = (node, options) => {
107
+ export const isNewExpression = (node, options) => {
110
108
  if (typeof options?.optional === 'boolean') {
111
109
  throw new TypeError('Cannot check node.optional in `isNewExpression`.');
112
110
  }
@@ -118,10 +116,4 @@ const isNewExpression = (node, options) => {
118
116
  @param {CallOrNewExpressionCheckOptions} [options]
119
117
  @returns {boolean}
120
118
  */
121
- const isCallOrNewExpression = (node, options) => create(node, options, ['CallExpression', 'NewExpression']);
122
-
123
- module.exports = {
124
- isCallExpression,
125
- isNewExpression,
126
- isCallOrNewExpression,
127
- };
119
+ export const isCallOrNewExpression = (node, options) => create(node, options, ['CallExpression', 'NewExpression']);