eslint-plugin-unicorn 56.0.0 → 57.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 +28 -36
  4. package/package.json +53 -109
  5. package/readme.md +16 -139
  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 +5 -8
  34. package/rules/expiring-todo-comments.js +29 -24
  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 +2 -5
  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 +1 -5
  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 +5 -9
  52. package/rules/fix/replace-string-raw.js +1 -3
  53. package/rules/fix/replace-template-element.js +1 -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 +8 -6
  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 +6 -12
  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 +8 -7
  92. package/rules/no-thenable.js +6 -4
  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 +11 -8
  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 +5 -4
  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 +21 -13
  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 +8 -7
  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 +23 -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 +10 -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 +2 -5
  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 +2 -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 +6 -13
  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,11 @@
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
7
  // {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',
8
+ 'no-instanceof-array': 'unicorn/no-instanceof-builtins',
27
9
  });
28
10
 
29
11
  const externalRules = {
@@ -33,13 +15,13 @@ const externalRules = {
33
15
  'no-nested-ternary': 'off',
34
16
  };
35
17
 
36
- const rules = loadRules();
37
18
  const recommendedRules = Object.fromEntries(
38
19
  Object.entries(rules).map(([id, rule]) => [
39
20
  `unicorn/${id}`,
40
21
  rule.meta.docs.recommended ? 'error' : 'off',
41
22
  ]),
42
23
  );
24
+
43
25
  const allRules = Object.fromEntries(
44
26
  Object.keys(rules).map(id => [
45
27
  `unicorn/${id}`,
@@ -47,19 +29,22 @@ const allRules = Object.fromEntries(
47
29
  ]),
48
30
  );
49
31
 
50
- const createConfig = (rules, flatConfigName = false) => ({
51
- ...(
52
- flatConfigName
53
- ? {...flatConfigBase, name: flatConfigName, plugins: {unicorn}}
54
- : {...legacyConfigBase, plugins: ['unicorn']}
55
- ),
56
- rules: {...externalRules, ...rules},
32
+ const createConfig = (rules, flatConfigName) => ({
33
+ ...flatConfigBase,
34
+ name: flatConfigName,
35
+ plugins: {
36
+ unicorn,
37
+ },
38
+ rules: {
39
+ ...externalRules,
40
+ ...rules,
41
+ },
57
42
  });
58
43
 
59
44
  const unicorn = {
60
45
  meta: {
61
- name,
62
- version,
46
+ name: packageJson.name,
47
+ version: packageJson.version,
63
48
  },
64
49
  rules: {
65
50
  ...rules,
@@ -68,10 +53,17 @@ const unicorn = {
68
53
  };
69
54
 
70
55
  const configs = {
71
- recommended: createConfig(recommendedRules),
72
- all: createConfig(allRules),
56
+ recommended: createConfig(recommendedRules, 'unicorn/recommended'),
57
+ all: createConfig(allRules, 'unicorn/all'),
58
+
59
+ // TODO: Remove this at some point. Kept for now to avoid breaking users.
73
60
  'flat/recommended': createConfig(recommendedRules, 'unicorn/flat/recommended'),
74
61
  'flat/all': createConfig(allRules, 'unicorn/flat/all'),
75
62
  };
76
63
 
77
- module.exports = {...unicorn, configs};
64
+ const allConfigs = {
65
+ ...unicorn,
66
+ configs,
67
+ };
68
+
69
+ export default allConfigs;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-unicorn",
3
- "version": "56.0.0",
3
+ "version": "57.0.0",
4
4
  "description": "More than 100 powerful ESLint rules",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/eslint-plugin-unicorn",
@@ -10,27 +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
20
  "node": ">=18.18"
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
- "integration": "node ./test/integration/test.mjs",
30
+ "fix:snapshots": "ava --update-snapshots",
31
+ "integration": "node ./test/integration/test.js",
27
32
  "lint": "run-p --continue-on-error lint:*",
28
33
  "lint:eslint-docs": "npm run fix:eslint-docs -- --check",
29
- "lint:js": "xo",
34
+ "lint:js": "eslint",
30
35
  "lint:markdown": "markdownlint \"**/*.md\"",
31
36
  "lint:package-json": "npmPkgJsonLint .",
32
- "run-rules-on-codebase": "eslint --config=./eslint.dogfooding.config.mjs",
33
- "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",
34
40
  "test": "npm-run-all --continue-on-error lint test:*",
35
41
  "test:js": "c8 ava"
36
42
  },
@@ -51,63 +57,65 @@
51
57
  "xo"
52
58
  ],
53
59
  "dependencies": {
54
- "@babel/helper-validator-identifier": "^7.24.7",
55
- "@eslint-community/eslint-utils": "^4.4.0",
56
- "ci-info": "^4.0.0",
60
+ "@babel/helper-validator-identifier": "^7.25.9",
61
+ "@eslint-community/eslint-utils": "^4.4.1",
62
+ "ci-info": "^4.1.0",
57
63
  "clean-regexp": "^1.0.0",
58
- "core-js-compat": "^3.38.1",
64
+ "core-js-compat": "^3.40.0",
59
65
  "esquery": "^1.6.0",
60
- "globals": "^15.9.0",
61
- "indent-string": "^4.0.0",
62
- "is-builtin-module": "^3.2.1",
63
- "jsesc": "^3.0.2",
66
+ "globals": "^15.15.0",
67
+ "indent-string": "^5.0.0",
68
+ "is-builtin-module": "^4.0.0",
69
+ "jsesc": "^3.1.0",
64
70
  "pluralize": "^8.0.0",
65
- "read-pkg-up": "^7.0.1",
71
+ "read-package-up": "^11.0.0",
66
72
  "regexp-tree": "^0.1.27",
67
- "regjsparser": "^0.10.0",
68
- "semver": "^7.6.3",
69
- "strip-indent": "^3.0.0"
73
+ "regjsparser": "^0.12.0",
74
+ "semver": "^7.7.1",
75
+ "strip-indent": "^4.0.0"
70
76
  },
71
77
  "devDependencies": {
72
- "@babel/code-frame": "^7.24.7",
73
- "@babel/core": "^7.25.2",
74
- "@babel/eslint-parser": "^7.25.1",
75
- "@eslint/eslintrc": "^3.1.0",
78
+ "@babel/code-frame": "^7.26.2",
79
+ "@babel/core": "^7.26.9",
80
+ "@babel/eslint-parser": "^7.26.8",
81
+ "@eslint/eslintrc": "^3.2.0",
76
82
  "@lubien/fixture-beta-package": "^1.0.0-beta.1",
77
- "@typescript-eslint/parser": "^8.4.0",
78
- "ava": "^6.1.3",
79
- "c8": "^10.1.2",
80
- "chalk": "^5.3.0",
83
+ "@typescript-eslint/parser": "^8.24.1",
84
+ "ava": "^6.2.0",
85
+ "c8": "^10.1.3",
81
86
  "enquirer": "^2.4.1",
82
- "eslint": "^9.10.0",
87
+ "eslint": "^9.20.1",
83
88
  "eslint-ava-rule-tester": "^5.0.1",
84
- "eslint-doc-generator": "1.7.0",
85
- "eslint-plugin-eslint-plugin": "^6.2.0",
89
+ "eslint-config-xo": "^0.46.0",
90
+ "eslint-doc-generator": "^2.0.2",
91
+ "eslint-plugin-eslint-plugin": "^6.4.0",
86
92
  "eslint-plugin-internal-rules": "file:./scripts/internal-rules/",
93
+ "eslint-plugin-jsdoc": "^50.6.3",
87
94
  "eslint-remote-tester": "^4.0.1",
88
95
  "eslint-remote-tester-repositories": "^2.0.0",
89
- "espree": "^10.1.0",
90
- "execa": "^8.0.1",
91
- "listr": "^0.14.3",
96
+ "espree": "^10.3.0",
97
+ "listr2": "^8.2.5",
92
98
  "lodash-es": "^4.17.21",
93
- "markdownlint-cli": "^0.41.0",
99
+ "markdownlint-cli": "^0.44.0",
94
100
  "memoize": "^10.0.0",
101
+ "nano-spawn": "^0.2.0",
102
+ "node-style-text": "^0.0.7",
95
103
  "npm-package-json-lint": "^8.0.0",
96
- "npm-run-all2": "^6.2.2",
104
+ "npm-run-all2": "^7.0.2",
105
+ "open-editor": "^5.1.0",
97
106
  "outdent": "^0.8.0",
98
- "pretty-ms": "^9.1.0",
99
- "typescript": "^5.5.4",
107
+ "pretty-ms": "^9.2.0",
108
+ "typescript": "^5.7.3",
100
109
  "vue-eslint-parser": "^9.4.3",
101
- "xo": "^0.59.3",
102
- "yaml": "^2.5.1"
110
+ "yaml": "^2.7.0"
103
111
  },
104
112
  "peerDependencies": {
105
- "eslint": ">=8.56.0"
113
+ "eslint": ">=9.20.0"
106
114
  },
107
115
  "ava": {
108
116
  "files": [
109
- "test/*.mjs",
110
- "test/unit/*.mjs"
117
+ "test/*.js",
118
+ "test/unit/*.js"
111
119
  ]
112
120
  },
113
121
  "c8": {
@@ -115,69 +123,5 @@
115
123
  "text",
116
124
  "lcov"
117
125
  ]
118
- },
119
- "xo": {
120
- "extends": [
121
- "plugin:internal-rules/all"
122
- ],
123
- "ignores": [
124
- ".cache-eslint-remote-tester",
125
- "eslint-remote-tester-results",
126
- "rules/utils/lodash.js",
127
- "test/integration/{fixtures,fixtures-local}/**"
128
- ],
129
- "rules": {
130
- "unicorn/escape-case": "off",
131
- "unicorn/expiring-todo-comments": "off",
132
- "unicorn/no-hex-escape": "off",
133
- "unicorn/no-null": "error",
134
- "unicorn/prefer-array-flat": [
135
- "error",
136
- {
137
- "functions": [
138
- "flat",
139
- "flatten"
140
- ]
141
- }
142
- ],
143
- "import/order": "off",
144
- "func-names": "off"
145
- },
146
- "overrides": [
147
- {
148
- "files": [
149
- "**/*.js"
150
- ],
151
- "parserOptions": {
152
- "sourceType": "script"
153
- },
154
- "rules": {
155
- "strict": "error",
156
- "unicorn/prefer-module": "off"
157
- }
158
- },
159
- {
160
- "files": [
161
- "rules/*.js"
162
- ],
163
- "plugins": [
164
- "eslint-plugin"
165
- ],
166
- "extends": [
167
- "plugin:eslint-plugin/all"
168
- ],
169
- "rules": {
170
- "eslint-plugin/require-meta-docs-description": [
171
- "error",
172
- {
173
- "pattern": ".+"
174
- }
175
- ],
176
- "eslint-plugin/require-meta-docs-url": "off",
177
- "eslint-plugin/require-meta-has-suggestions": "off",
178
- "eslint-plugin/require-meta-schema": "off"
179
- }
180
- }
181
- ]
182
126
  }
183
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,58 +44,6 @@ 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](#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` -->
@@ -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()`. | ✅ | 🔧 | |
@@ -124,8 +72,9 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c
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,41 +190,22 @@ 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
- See the [ESLint docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new) for more information about extending config files.
195
+ See the [ESLint docs](https://eslint.org/docs/latest/use/configure/configuration-files) for more information about extending config files.
246
196
 
247
- **Note**: Preset configs will also enable the correct [language options](https://eslint.org/docs/latest/use/configure/configuration-files-new#configuring-language-options).
197
+ **Note**: Preset configs will also enable the correct [language options](https://eslint.org/docs/latest/use/configure/language-options).
248
198
 
249
199
  ### Recommended config
250
200
 
251
- This plugin exports a [`recommended` config](configs/recommended.js) that enforces good practices.
252
-
253
- #### ES Module (Recommended)
201
+ This plugin exports a `recommended` config that enforces good practices.
254
202
 
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',
@@ -285,33 +216,14 @@ module.exports = [
285
216
 
286
217
  ### All config
287
218
 
288
- This plugin exports an [`all` config](configs/all.js) that makes use of all rules (except for deprecated ones).
289
-
290
- #### ES Module (Recommended)
219
+ This plugin exports an `all` that makes use of all rules (except for deprecated ones).
291
220
 
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
- ## Preset configs (`.eslintrc.*` or `package.json`)
324
-
325
- See the [ESLint docs](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending config files.
326
-
327
- **Note**: Preset configs will also enable the correct [parser options](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options) and [environment](https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments).
328
-
329
- ### Recommended config
330
-
331
- This plugin exports a [`recommended` config](configs/recommended.js) 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 config
346
-
347
- This plugin exports an [`all` config](configs/all.js) 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']);
@@ -1,5 +1,7 @@
1
- 'use strict';
1
+ const functionTypes = [
2
+ 'FunctionDeclaration',
3
+ 'FunctionExpression',
4
+ 'ArrowFunctionExpression',
5
+ ];
2
6
 
3
- const functionTypes = ['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'];
4
-
5
- module.exports = functionTypes;
7
+ export default functionTypes;