eslint-plugin-unicorn 40.0.0 → 41.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/configs/all.js +5 -13
- package/configs/recommended.js +11 -2
- package/index.js +2 -2
- package/package.json +43 -10
- package/readme.md +18 -123
- package/rules/better-regex.js +2 -2
- package/rules/catch-error-name.js +2 -2
- package/rules/consistent-destructuring.js +2 -2
- package/rules/consistent-function-scoping.js +10 -9
- package/rules/expiring-todo-comments.js +20 -11
- package/rules/filename-case.js +1 -11
- package/rules/fix/append-argument.js +1 -1
- package/rules/fix/remove-argument.js +2 -1
- package/rules/import-style.js +1 -1
- package/rules/new-for-builtins.js +2 -2
- package/rules/no-array-callback-reference.js +2 -3
- package/rules/no-array-for-each.js +2 -1
- package/rules/no-array-push-push.js +1 -1
- package/rules/no-await-expression-member.js +0 -1
- package/rules/no-document-cookie.js +2 -2
- package/rules/no-empty-file.js +0 -1
- package/rules/no-hex-escape.js +1 -1
- package/rules/no-invalid-remove-event-listener.js +1 -2
- package/rules/no-keyword-prefix.js +2 -2
- package/rules/no-nested-ternary.js +1 -1
- package/rules/no-new-buffer.js +1 -1
- package/rules/no-null.js +1 -1
- package/rules/no-object-as-default-parameter.js +1 -1
- package/rules/no-process-exit.js +4 -4
- package/rules/no-static-only-class.js +1 -1
- package/rules/no-thenable.js +4 -6
- package/rules/no-unsafe-regex.js +2 -2
- package/rules/no-useless-fallback-in-spread.js +0 -3
- package/rules/no-useless-promise-resolve-reject.js +1 -4
- package/rules/no-useless-undefined.js +4 -2
- package/rules/no-zero-fractions.js +1 -1
- package/rules/number-literal-case.js +1 -1
- package/rules/numeric-separators-style.js +1 -1
- package/rules/prefer-array-find.js +2 -2
- package/rules/prefer-array-flat.js +2 -2
- package/rules/prefer-at.js +42 -27
- package/rules/prefer-code-point.js +0 -1
- package/rules/prefer-default-parameters.js +5 -5
- package/rules/prefer-export-from.js +28 -6
- package/rules/prefer-includes.js +2 -2
- package/rules/prefer-json-parse-buffer.js +3 -4
- package/rules/prefer-keyboard-event-key.js +1 -1
- package/rules/prefer-math-trunc.js +1 -1
- package/rules/prefer-negative-index.js +1 -1
- package/rules/prefer-number-properties.js +2 -2
- package/rules/prefer-optional-catch-binding.js +1 -1
- package/rules/prefer-prototype-methods.js +3 -3
- package/rules/prefer-reflect-apply.js +6 -6
- package/rules/prefer-set-has.js +3 -3
- package/rules/prefer-string-replace-all.js +1 -1
- package/rules/prefer-ternary.js +1 -1
- package/rules/prefer-type-error.js +1 -1
- package/rules/relative-url-style.js +92 -34
- package/rules/selectors/not-dom-node.js +2 -1
- package/rules/string-content.js +1 -1
- package/rules/template-indent.js +3 -3
- package/rules/text-encoding-identifier-case.js +69 -0
- package/rules/throw-new-error.js +1 -1
- package/rules/utils/create-deprecated-rules.js +0 -1
- package/rules/utils/get-builtin-rule.js +0 -7
- package/rules/utils/get-references.js +3 -3
- package/rules/utils/get-variable-identifiers.js +2 -3
- package/rules/utils/is-function-self-used-inside.js +1 -1
- package/rules/utils/is-same-reference.js +4 -4
- package/rules/utils/rule.js +1 -1
- package/rules/utils/should-add-parentheses-to-logical-expression-child.js +2 -1
- package/rules/utils/should-add-parentheses-to-member-expression-object.js +1 -1
- package/configs/base.js +0 -13
- package/configs/conflicting-rules.js +0 -6
- package/rules/utils/get-key-name.js +0 -38
package/configs/all.js
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const
|
|
2
|
+
const {rules, ...baseConfigs} = require('./recommended.js');
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
|
-
...
|
|
6
|
-
rules:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.filter(
|
|
10
|
-
ruleEntry =>
|
|
11
|
-
!Object.keys(conflictingRules.rules).includes(ruleEntry[0]),
|
|
12
|
-
)
|
|
13
|
-
.map(ruleEntry => [ruleEntry[0], 'error']),
|
|
14
|
-
),
|
|
15
|
-
...conflictingRules.rules,
|
|
16
|
-
},
|
|
5
|
+
...baseConfigs,
|
|
6
|
+
rules: Object.fromEntries(Object.entries(rules).map(
|
|
7
|
+
([ruleId, severity]) => [ruleId, ruleId.startsWith('unicorn/') ? 'error' : severity],
|
|
8
|
+
)),
|
|
17
9
|
};
|
package/configs/recommended.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
module.exports = {
|
|
3
|
-
|
|
3
|
+
env: {
|
|
4
|
+
es2022: true,
|
|
5
|
+
},
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaVersion: 'latest',
|
|
8
|
+
sourceType: 'module',
|
|
9
|
+
},
|
|
10
|
+
plugins: [
|
|
11
|
+
'unicorn',
|
|
12
|
+
],
|
|
4
13
|
rules: {
|
|
5
14
|
'unicorn/better-regex': 'error',
|
|
6
15
|
'unicorn/catch-error-name': 'error',
|
|
@@ -105,7 +114,7 @@ module.exports = {
|
|
|
105
114
|
'unicorn/require-post-message-target-origin': 'off',
|
|
106
115
|
'unicorn/string-content': 'off',
|
|
107
116
|
'unicorn/template-indent': 'warn',
|
|
117
|
+
'unicorn/text-encoding-identifier-case': 'error',
|
|
108
118
|
'unicorn/throw-new-error': 'error',
|
|
109
|
-
...require('./conflicting-rules.js').rules,
|
|
110
119
|
},
|
|
111
120
|
};
|
package/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const createDeprecatedRules = require('./rules/utils/create-deprecated-rules.js');
|
|
3
3
|
const {loadRules} = require('./rules/utils/rule.js');
|
|
4
4
|
const recommendedConfig = require('./configs/recommended.js');
|
|
5
|
-
const
|
|
5
|
+
const allRulesEnabledConfig = require('./configs/all.js');
|
|
6
6
|
|
|
7
7
|
const deprecatedRules = createDeprecatedRules({
|
|
8
8
|
// {ruleId: ReplacementRuleId | ReplacementRuleId[]}, if no replacement, use `{ruleId: []}`
|
|
@@ -30,6 +30,6 @@ module.exports = {
|
|
|
30
30
|
},
|
|
31
31
|
configs: {
|
|
32
32
|
recommended: recommendedConfig,
|
|
33
|
-
all,
|
|
33
|
+
all: allRulesEnabledConfig,
|
|
34
34
|
},
|
|
35
35
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-unicorn",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "41.0.1",
|
|
4
4
|
"description": "Various awesome ESLint rules",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/eslint-plugin-unicorn",
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"node": ">=12"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"create-rule": "node ./scripts/create-rule.mjs && npm run generate-
|
|
17
|
+
"create-rule": "node ./scripts/create-rule.mjs && npm run generate-rule-notices && npm run generate-rules-table",
|
|
18
18
|
"fix": "run-p --continue-on-error fix:*",
|
|
19
19
|
"fix:js": "npm run lint:js -- --fix",
|
|
20
20
|
"fix:md": "npm run lint:md -- --fix",
|
|
21
|
+
"generate-rule-notices": "node ./scripts/generate-rule-notices.mjs",
|
|
21
22
|
"generate-rules-table": "node ./scripts/generate-rules-table.mjs",
|
|
22
|
-
"generate-usage-example": "node ./scripts/generate-usage-example.mjs",
|
|
23
23
|
"integration": "node ./test/integration/test.mjs",
|
|
24
24
|
"lint": "run-p --continue-on-error lint:*",
|
|
25
25
|
"lint:js": "xo",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"run-rules-on-codebase": "node ./test/run-rules-on-codebase/lint.mjs",
|
|
29
29
|
"smoke": "eslint-remote-tester --config ./test/smoke/eslint-remote-tester.config.js",
|
|
30
30
|
"test": "npm-run-all --continue-on-error lint test:*",
|
|
31
|
-
"test:js": "
|
|
31
|
+
"test:js": "c8 ava"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
34
|
"index.js",
|
|
@@ -68,11 +68,13 @@
|
|
|
68
68
|
"@lubien/fixture-beta-package": "^1.0.0-beta.1",
|
|
69
69
|
"@typescript-eslint/parser": "^5.7.0",
|
|
70
70
|
"ava": "^3.15.0",
|
|
71
|
+
"c8": "^7.11.0",
|
|
71
72
|
"chalk": "^5.0.0",
|
|
72
73
|
"enquirer": "^2.3.6",
|
|
73
|
-
"eslint": "^8.
|
|
74
|
+
"eslint": "^8.8.0",
|
|
74
75
|
"eslint-ava-rule-tester": "^4.0.0",
|
|
75
76
|
"eslint-plugin-eslint-plugin": "^4.1.0",
|
|
77
|
+
"eslint-plugin-internal-rules": "file:./scripts/internal-rules/",
|
|
76
78
|
"eslint-remote-tester": "^2.0.1",
|
|
77
79
|
"eslint-remote-tester-repositories": "^0.0.3",
|
|
78
80
|
"execa": "^6.0.0",
|
|
@@ -82,14 +84,13 @@
|
|
|
82
84
|
"mem": "^9.0.1",
|
|
83
85
|
"npm-package-json-lint": "^5.4.2",
|
|
84
86
|
"npm-run-all": "^4.1.5",
|
|
85
|
-
"nyc": "^15.1.0",
|
|
86
87
|
"outdent": "^0.8.0",
|
|
87
88
|
"typescript": "^4.5.4",
|
|
88
89
|
"vue-eslint-parser": "^8.0.1",
|
|
89
|
-
"xo": "^0.
|
|
90
|
+
"xo": "^0.48.0"
|
|
90
91
|
},
|
|
91
92
|
"peerDependencies": {
|
|
92
|
-
"eslint": ">=
|
|
93
|
+
"eslint": ">=8.8.0"
|
|
93
94
|
},
|
|
94
95
|
"ava": {
|
|
95
96
|
"files": [
|
|
@@ -97,7 +98,7 @@
|
|
|
97
98
|
"test/unit/*.mjs"
|
|
98
99
|
]
|
|
99
100
|
},
|
|
100
|
-
"
|
|
101
|
+
"c8": {
|
|
101
102
|
"reporter": [
|
|
102
103
|
"text",
|
|
103
104
|
"lcov"
|
|
@@ -110,7 +111,16 @@
|
|
|
110
111
|
"test/integration/{fixtures,fixtures-local}/**"
|
|
111
112
|
],
|
|
112
113
|
"rules": {
|
|
113
|
-
"unicorn/no-null": "error"
|
|
114
|
+
"unicorn/no-null": "error",
|
|
115
|
+
"unicorn/prefer-array-flat": [
|
|
116
|
+
"error",
|
|
117
|
+
{
|
|
118
|
+
"functions": [
|
|
119
|
+
"flat",
|
|
120
|
+
"flatten"
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
]
|
|
114
124
|
},
|
|
115
125
|
"overrides": [
|
|
116
126
|
{
|
|
@@ -146,7 +156,30 @@
|
|
|
146
156
|
"eslint-plugin/require-meta-has-suggestions": "off",
|
|
147
157
|
"eslint-plugin/require-meta-schema": "off"
|
|
148
158
|
}
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"files": [
|
|
162
|
+
"rules/**/*.js"
|
|
163
|
+
],
|
|
164
|
+
"plugins": [
|
|
165
|
+
"internal-rules"
|
|
166
|
+
],
|
|
167
|
+
"rules": {
|
|
168
|
+
"internal-rules/prefer-negative-boolean-attribute": "error"
|
|
169
|
+
}
|
|
149
170
|
}
|
|
150
171
|
]
|
|
172
|
+
},
|
|
173
|
+
"npmpackagejsonlint": {
|
|
174
|
+
"rules": {
|
|
175
|
+
"prefer-caret-version-devDependencies": [
|
|
176
|
+
"error",
|
|
177
|
+
{
|
|
178
|
+
"exceptions": [
|
|
179
|
+
"eslint-plugin-internal-rules"
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
}
|
|
151
184
|
}
|
|
152
185
|
}
|
package/readme.md
CHANGED
|
@@ -17,16 +17,14 @@ npm install --save-dev eslint eslint-plugin-unicorn
|
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Use a [preset config](#preset-configs) or configure each rules in `package.json`.
|
|
21
21
|
|
|
22
|
-
<!-- Do not manually modify this table. Run: `npm run generate-usage-example` -->
|
|
23
|
-
<!-- USAGE_EXAMPLE_START -->
|
|
24
22
|
```json
|
|
25
23
|
{
|
|
26
24
|
"name": "my-awesome-project",
|
|
27
25
|
"eslintConfig": {
|
|
28
26
|
"env": {
|
|
29
|
-
"
|
|
27
|
+
"es2022": true
|
|
30
28
|
},
|
|
31
29
|
"parserOptions": {
|
|
32
30
|
"ecmaVersion": "latest",
|
|
@@ -37,109 +35,11 @@ Configure it in `package.json`.
|
|
|
37
35
|
],
|
|
38
36
|
"rules": {
|
|
39
37
|
"unicorn/better-regex": "error",
|
|
40
|
-
"unicorn
|
|
41
|
-
"unicorn/consistent-destructuring": "error",
|
|
42
|
-
"unicorn/consistent-function-scoping": "error",
|
|
43
|
-
"unicorn/custom-error-definition": "off",
|
|
44
|
-
"unicorn/empty-brace-spaces": "error",
|
|
45
|
-
"unicorn/error-message": "error",
|
|
46
|
-
"unicorn/escape-case": "error",
|
|
47
|
-
"unicorn/expiring-todo-comments": "error",
|
|
48
|
-
"unicorn/explicit-length-check": "error",
|
|
49
|
-
"unicorn/filename-case": "error",
|
|
50
|
-
"unicorn/import-index": "off",
|
|
51
|
-
"unicorn/import-style": "error",
|
|
52
|
-
"unicorn/new-for-builtins": "error",
|
|
53
|
-
"unicorn/no-abusive-eslint-disable": "error",
|
|
54
|
-
"unicorn/no-array-callback-reference": "error",
|
|
55
|
-
"unicorn/no-array-for-each": "error",
|
|
56
|
-
"unicorn/no-array-method-this-argument": "error",
|
|
57
|
-
"unicorn/no-array-push-push": "error",
|
|
58
|
-
"unicorn/no-array-reduce": "error",
|
|
59
|
-
"unicorn/no-await-expression-member": "error",
|
|
60
|
-
"unicorn/no-console-spaces": "error",
|
|
61
|
-
"unicorn/no-document-cookie": "error",
|
|
62
|
-
"unicorn/no-empty-file": "error",
|
|
63
|
-
"unicorn/no-for-loop": "error",
|
|
64
|
-
"unicorn/no-hex-escape": "error",
|
|
65
|
-
"unicorn/no-instanceof-array": "error",
|
|
66
|
-
"unicorn/no-invalid-remove-event-listener": "error",
|
|
67
|
-
"unicorn/no-keyword-prefix": "off",
|
|
68
|
-
"unicorn/no-lonely-if": "error",
|
|
69
|
-
"no-nested-ternary": "off",
|
|
70
|
-
"unicorn/no-nested-ternary": "error",
|
|
71
|
-
"unicorn/no-new-array": "error",
|
|
72
|
-
"unicorn/no-new-buffer": "error",
|
|
73
|
-
"unicorn/no-null": "error",
|
|
74
|
-
"unicorn/no-object-as-default-parameter": "error",
|
|
75
|
-
"unicorn/no-process-exit": "error",
|
|
76
|
-
"unicorn/no-static-only-class": "error",
|
|
77
|
-
"unicorn/no-thenable": "error",
|
|
78
|
-
"unicorn/no-this-assignment": "error",
|
|
79
|
-
"unicorn/no-unreadable-array-destructuring": "error",
|
|
80
|
-
"unicorn/no-unsafe-regex": "off",
|
|
81
|
-
"unicorn/no-unused-properties": "off",
|
|
82
|
-
"unicorn/no-useless-fallback-in-spread": "error",
|
|
83
|
-
"unicorn/no-useless-length-check": "error",
|
|
84
|
-
"unicorn/no-useless-promise-resolve-reject": "error",
|
|
85
|
-
"unicorn/no-useless-spread": "error",
|
|
86
|
-
"unicorn/no-useless-undefined": "error",
|
|
87
|
-
"unicorn/no-zero-fractions": "error",
|
|
88
|
-
"unicorn/number-literal-case": "error",
|
|
89
|
-
"unicorn/numeric-separators-style": "error",
|
|
90
|
-
"unicorn/prefer-add-event-listener": "error",
|
|
91
|
-
"unicorn/prefer-array-find": "error",
|
|
92
|
-
"unicorn/prefer-array-flat": "error",
|
|
93
|
-
"unicorn/prefer-array-flat-map": "error",
|
|
94
|
-
"unicorn/prefer-array-index-of": "error",
|
|
95
|
-
"unicorn/prefer-array-some": "error",
|
|
96
|
-
"unicorn/prefer-at": "off",
|
|
97
|
-
"unicorn/prefer-code-point": "error",
|
|
98
|
-
"unicorn/prefer-date-now": "error",
|
|
99
|
-
"unicorn/prefer-default-parameters": "error",
|
|
100
|
-
"unicorn/prefer-dom-node-append": "error",
|
|
101
|
-
"unicorn/prefer-dom-node-dataset": "error",
|
|
102
|
-
"unicorn/prefer-dom-node-remove": "error",
|
|
103
|
-
"unicorn/prefer-dom-node-text-content": "error",
|
|
104
|
-
"unicorn/prefer-export-from": "error",
|
|
105
|
-
"unicorn/prefer-includes": "error",
|
|
106
|
-
"unicorn/prefer-json-parse-buffer": "error",
|
|
107
|
-
"unicorn/prefer-keyboard-event-key": "error",
|
|
108
|
-
"unicorn/prefer-math-trunc": "error",
|
|
109
|
-
"unicorn/prefer-modern-dom-apis": "error",
|
|
110
|
-
"unicorn/prefer-module": "error",
|
|
111
|
-
"unicorn/prefer-negative-index": "error",
|
|
112
|
-
"unicorn/prefer-node-protocol": "error",
|
|
113
|
-
"unicorn/prefer-number-properties": "error",
|
|
114
|
-
"unicorn/prefer-object-from-entries": "error",
|
|
115
|
-
"unicorn/prefer-optional-catch-binding": "error",
|
|
116
|
-
"unicorn/prefer-prototype-methods": "error",
|
|
117
|
-
"unicorn/prefer-query-selector": "error",
|
|
118
|
-
"unicorn/prefer-reflect-apply": "error",
|
|
119
|
-
"unicorn/prefer-regexp-test": "error",
|
|
120
|
-
"unicorn/prefer-set-has": "error",
|
|
121
|
-
"unicorn/prefer-spread": "error",
|
|
122
|
-
"unicorn/prefer-string-replace-all": "off",
|
|
123
|
-
"unicorn/prefer-string-slice": "error",
|
|
124
|
-
"unicorn/prefer-string-starts-ends-with": "error",
|
|
125
|
-
"unicorn/prefer-string-trim-start-end": "error",
|
|
126
|
-
"unicorn/prefer-switch": "error",
|
|
127
|
-
"unicorn/prefer-ternary": "error",
|
|
128
|
-
"unicorn/prefer-top-level-await": "off",
|
|
129
|
-
"unicorn/prefer-type-error": "error",
|
|
130
|
-
"unicorn/prevent-abbreviations": "error",
|
|
131
|
-
"unicorn/relative-url-style": "error",
|
|
132
|
-
"unicorn/require-array-join-separator": "error",
|
|
133
|
-
"unicorn/require-number-to-fixed-digits-argument": "error",
|
|
134
|
-
"unicorn/require-post-message-target-origin": "off",
|
|
135
|
-
"unicorn/string-content": "off",
|
|
136
|
-
"unicorn/template-indent": "warn",
|
|
137
|
-
"unicorn/throw-new-error": "error"
|
|
38
|
+
"unicorn/…": "error"
|
|
138
39
|
}
|
|
139
40
|
}
|
|
140
41
|
}
|
|
141
42
|
```
|
|
142
|
-
<!-- USAGE_EXAMPLE_END -->
|
|
143
43
|
|
|
144
44
|
## Rules
|
|
145
45
|
|
|
@@ -149,9 +49,8 @@ Each rule has emojis denoting:
|
|
|
149
49
|
- 🔧 if some problems reported by the rule are automatically fixable by the `--fix` [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) option
|
|
150
50
|
- 💡 if some problems reported by the rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions)
|
|
151
51
|
|
|
152
|
-
<!-- Do not manually modify
|
|
153
|
-
<!--
|
|
154
|
-
|
|
52
|
+
<!-- Do not manually modify RULES_TABLE part. Run: `npm run generate-rules-table` -->
|
|
53
|
+
<!-- RULES_TABLE -->
|
|
155
54
|
| Name | Description | ✅ | 🔧 | 💡 |
|
|
156
55
|
| :-- | :-- | :-- | :-- | :-- |
|
|
157
56
|
| [better-regex](docs/rules/better-regex.md) | Improve regexes by making them shorter, consistent, and safer. | ✅ | 🔧 | |
|
|
@@ -245,25 +144,29 @@ Each rule has emojis denoting:
|
|
|
245
144
|
| [prefer-top-level-await](docs/rules/prefer-top-level-await.md) | Prefer top-level await over top-level promises and async function calls. | | | 💡 |
|
|
246
145
|
| [prefer-type-error](docs/rules/prefer-type-error.md) | Enforce throwing `TypeError` in type checking conditions. | ✅ | 🔧 | |
|
|
247
146
|
| [prevent-abbreviations](docs/rules/prevent-abbreviations.md) | Prevent abbreviations. | ✅ | 🔧 | |
|
|
248
|
-
| [relative-url-style](docs/rules/relative-url-style.md) | Enforce consistent relative URL style. | ✅ | 🔧 |
|
|
147
|
+
| [relative-url-style](docs/rules/relative-url-style.md) | Enforce consistent relative URL style. | ✅ | 🔧 | 💡 |
|
|
249
148
|
| [require-array-join-separator](docs/rules/require-array-join-separator.md) | Enforce using the separator argument with `Array#join()`. | ✅ | 🔧 | |
|
|
250
149
|
| [require-number-to-fixed-digits-argument](docs/rules/require-number-to-fixed-digits-argument.md) | Enforce using the digits argument with `Number#toFixed()`. | ✅ | 🔧 | |
|
|
251
150
|
| [require-post-message-target-origin](docs/rules/require-post-message-target-origin.md) | Enforce using the `targetOrigin` argument with `window.postMessage()`. | | | 💡 |
|
|
252
151
|
| [string-content](docs/rules/string-content.md) | Enforce better string content. | | 🔧 | 💡 |
|
|
253
|
-
| [template-indent](docs/rules/template-indent.md) | Fix whitespace-insensitive template indentation. |
|
|
152
|
+
| [template-indent](docs/rules/template-indent.md) | Fix whitespace-insensitive template indentation. | ✅ | 🔧 | |
|
|
153
|
+
| [text-encoding-identifier-case](docs/rules/text-encoding-identifier-case.md) | Enforce consistent case for text encoding identifiers. | ✅ | | 💡 |
|
|
254
154
|
| [throw-new-error](docs/rules/throw-new-error.md) | Require `new` when throwing an error. | ✅ | 🔧 | |
|
|
155
|
+
<!-- /RULES_TABLE -->
|
|
255
156
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
## Deprecated Rules
|
|
157
|
+
### Deprecated Rules
|
|
259
158
|
|
|
260
159
|
See [docs/deprecated-rules.md](docs/deprecated-rules.md)
|
|
261
160
|
|
|
262
|
-
##
|
|
161
|
+
## Preset configs
|
|
263
162
|
|
|
264
|
-
|
|
163
|
+
See the [ESLint docs](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending config files.
|
|
265
164
|
|
|
266
|
-
|
|
165
|
+
**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).
|
|
166
|
+
|
|
167
|
+
### Recommended config
|
|
168
|
+
|
|
169
|
+
This plugin exports a [`recommended` config](configs/recommended.js) that enforces good practices.
|
|
267
170
|
|
|
268
171
|
```json
|
|
269
172
|
{
|
|
@@ -274,16 +177,10 @@ Enable it in your `package.json` with the `extends` option:
|
|
|
274
177
|
}
|
|
275
178
|
```
|
|
276
179
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
**Note**: This config 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).
|
|
280
|
-
|
|
281
|
-
## All config
|
|
180
|
+
### All config
|
|
282
181
|
|
|
283
182
|
This plugin exports an [`all` config](configs/all.js) that makes use of all rules (except for deprecated ones).
|
|
284
183
|
|
|
285
|
-
Enable it in your `package.json` with the `extends` option:
|
|
286
|
-
|
|
287
184
|
```json
|
|
288
185
|
{
|
|
289
186
|
"name": "my-awesome-project",
|
|
@@ -293,8 +190,6 @@ Enable it in your `package.json` with the `extends` option:
|
|
|
293
190
|
}
|
|
294
191
|
```
|
|
295
192
|
|
|
296
|
-
See the [ESLint docs](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending config files.
|
|
297
|
-
|
|
298
193
|
## Maintainers
|
|
299
194
|
|
|
300
195
|
- [Sindre Sorhus](https://github.com/sindresorhus)
|
package/rules/better-regex.js
CHANGED
|
@@ -25,7 +25,7 @@ const create = context => {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
return {
|
|
28
|
-
'Literal[regex]'
|
|
28
|
+
'Literal[regex]'(node) {
|
|
29
29
|
const {raw: original, regex} = node;
|
|
30
30
|
|
|
31
31
|
// Regular Expressions with `u` flag are not well handled by `regexp-tree`
|
|
@@ -63,7 +63,7 @@ const create = context => {
|
|
|
63
63
|
fix: fixer => fixer.replaceText(node, optimized),
|
|
64
64
|
};
|
|
65
65
|
},
|
|
66
|
-
[newRegExp]
|
|
66
|
+
[newRegExp](node) {
|
|
67
67
|
const [patternNode, flagsNode] = node.arguments;
|
|
68
68
|
|
|
69
69
|
if (typeof patternNode.value !== 'string') {
|
|
@@ -50,7 +50,7 @@ const create = context => {
|
|
|
50
50
|
|| name.endsWith(expectedName.charAt(0).toUpperCase() + expectedName.slice(1));
|
|
51
51
|
|
|
52
52
|
return {
|
|
53
|
-
[selector]
|
|
53
|
+
[selector](node) {
|
|
54
54
|
const originalName = node.name;
|
|
55
55
|
|
|
56
56
|
if (
|
|
@@ -65,7 +65,7 @@ const create = context => {
|
|
|
65
65
|
|
|
66
66
|
// This was reported https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1075#issuecomment-768072967
|
|
67
67
|
// But can't reproduce, just ignore this case
|
|
68
|
-
/*
|
|
68
|
+
/* c8 ignore next 3 */
|
|
69
69
|
if (!variable) {
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
@@ -57,7 +57,7 @@ const create = context => {
|
|
|
57
57
|
const declarations = new Map();
|
|
58
58
|
|
|
59
59
|
return {
|
|
60
|
-
[declaratorSelector]
|
|
60
|
+
[declaratorSelector](node) {
|
|
61
61
|
// Ignore any complex expressions (e.g. arrays, functions)
|
|
62
62
|
if (!isSimpleExpression(node.init)) {
|
|
63
63
|
return;
|
|
@@ -69,7 +69,7 @@ const create = context => {
|
|
|
69
69
|
objectPattern: node.id,
|
|
70
70
|
});
|
|
71
71
|
},
|
|
72
|
-
[memberSelector]
|
|
72
|
+
[memberSelector](node) {
|
|
73
73
|
const declaration = declarations.get(source.getText(node.object));
|
|
74
74
|
|
|
75
75
|
if (!declaration) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const {getFunctionHeadLocation, getFunctionNameWithKind} = require('eslint-utils');
|
|
3
3
|
const getReferences = require('./utils/get-references.js');
|
|
4
|
+
const {isNodeMatches} = require('./utils/is-node-matches.js');
|
|
4
5
|
|
|
5
6
|
const MESSAGE_ID = 'consistent-function-scoping';
|
|
6
7
|
const messages = {
|
|
@@ -45,13 +46,13 @@ function checkReferences(scope, parent, scopeManager) {
|
|
|
45
46
|
const identifierScope = scopeManager.acquire(identifier);
|
|
46
47
|
|
|
47
48
|
// If we have a scope, the earlier checks should have worked so ignore them here
|
|
48
|
-
/*
|
|
49
|
+
/* c8 ignore next 3 */
|
|
49
50
|
if (identifierScope) {
|
|
50
51
|
return false;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
const identifierParentScope = scopeManager.acquire(identifier.parent);
|
|
54
|
-
/*
|
|
55
|
+
/* c8 ignore next 3 */
|
|
55
56
|
if (!identifierParentScope) {
|
|
56
57
|
return false;
|
|
57
58
|
}
|
|
@@ -77,7 +78,7 @@ function checkReferences(scope, parent, scopeManager) {
|
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
// https://reactjs.org/docs/hooks-reference.html
|
|
80
|
-
const reactHooks =
|
|
81
|
+
const reactHooks = [
|
|
81
82
|
'useState',
|
|
82
83
|
'useEffect',
|
|
83
84
|
'useContext',
|
|
@@ -88,13 +89,13 @@ const reactHooks = new Set([
|
|
|
88
89
|
'useImperativeHandle',
|
|
89
90
|
'useLayoutEffect',
|
|
90
91
|
'useDebugValue',
|
|
91
|
-
]);
|
|
92
|
+
].flatMap(hookName => [hookName, `React.${hookName}`]);
|
|
93
|
+
|
|
92
94
|
const isReactHook = scope =>
|
|
93
95
|
scope.block
|
|
94
96
|
&& scope.block.parent
|
|
95
97
|
&& scope.block.parent.callee
|
|
96
|
-
&& scope.block.parent.callee
|
|
97
|
-
&& reactHooks.has(scope.block.parent.callee.name);
|
|
98
|
+
&& isNodeMatches(scope.block.parent.callee, reactHooks);
|
|
98
99
|
|
|
99
100
|
const isArrowFunctionWithThis = scope =>
|
|
100
101
|
scope.type === 'function'
|
|
@@ -158,17 +159,17 @@ const create = context => {
|
|
|
158
159
|
const functions = [];
|
|
159
160
|
|
|
160
161
|
return {
|
|
161
|
-
':function'
|
|
162
|
+
':function'() {
|
|
162
163
|
functions.push(false);
|
|
163
164
|
},
|
|
164
|
-
JSXElement
|
|
165
|
+
JSXElement() {
|
|
165
166
|
// Turn off this rule if we see a JSX element because scope
|
|
166
167
|
// references does not include JSXElement nodes.
|
|
167
168
|
if (functions.length > 0) {
|
|
168
169
|
functions[functions.length - 1] = true;
|
|
169
170
|
}
|
|
170
171
|
},
|
|
171
|
-
':function:exit'
|
|
172
|
+
':function:exit'(node) {
|
|
172
173
|
const currentFunctionHasJsx = functions.pop();
|
|
173
174
|
if (currentFunctionHasJsx) {
|
|
174
175
|
return;
|
|
@@ -186,13 +186,13 @@ function parseTodoMessage(todoString) {
|
|
|
186
186
|
return afterArguments;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
function reachedDate(past) {
|
|
190
|
-
const now = new Date().toISOString().slice(0, 10);
|
|
189
|
+
function reachedDate(past, now) {
|
|
191
190
|
return Date.parse(past) < Date.parse(now);
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
function tryToCoerceVersion(rawVersion) {
|
|
195
|
-
|
|
194
|
+
// `version` in `package.json` and comment can't be empty
|
|
195
|
+
/* c8 ignore next 3 */
|
|
196
196
|
if (!rawVersion) {
|
|
197
197
|
return false;
|
|
198
198
|
}
|
|
@@ -215,12 +215,14 @@ function tryToCoerceVersion(rawVersion) {
|
|
|
215
215
|
|
|
216
216
|
// Get only the first member for cases such as `1.0.0 - 2.9999.9999`
|
|
217
217
|
const parts = version.split(' ');
|
|
218
|
-
|
|
218
|
+
// We don't have this `package.json` to test
|
|
219
|
+
/* c8 ignore next 3 */
|
|
219
220
|
if (parts.length > 1) {
|
|
220
221
|
version = parts[0];
|
|
221
222
|
}
|
|
222
223
|
|
|
223
|
-
|
|
224
|
+
// We don't have this `package.json` to test
|
|
225
|
+
/* c8 ignore next 3 */
|
|
224
226
|
if (semver.valid(version)) {
|
|
225
227
|
return version;
|
|
226
228
|
}
|
|
@@ -230,7 +232,8 @@ function tryToCoerceVersion(rawVersion) {
|
|
|
230
232
|
// But coerce can't parse pre-releases.
|
|
231
233
|
return semver.parse(version) || semver.coerce(version);
|
|
232
234
|
} catch {
|
|
233
|
-
|
|
235
|
+
// We don't have this `package.json` to test
|
|
236
|
+
/* c8 ignore next 3 */
|
|
234
237
|
return false;
|
|
235
238
|
}
|
|
236
239
|
}
|
|
@@ -249,6 +252,7 @@ const create = context => {
|
|
|
249
252
|
ignore: [],
|
|
250
253
|
ignoreDatesOnPullRequests: true,
|
|
251
254
|
allowWarningComments: true,
|
|
255
|
+
date: new Date().toISOString().slice(0, 10),
|
|
252
256
|
...context.options[0],
|
|
253
257
|
};
|
|
254
258
|
|
|
@@ -325,15 +329,15 @@ const create = context => {
|
|
|
325
329
|
});
|
|
326
330
|
} else if (dates.length === 1) {
|
|
327
331
|
uses++;
|
|
328
|
-
const [
|
|
332
|
+
const [expirationDate] = dates;
|
|
329
333
|
|
|
330
334
|
const shouldIgnore = options.ignoreDatesOnPullRequests && ci.isPR;
|
|
331
|
-
if (!shouldIgnore && reachedDate(date)) {
|
|
335
|
+
if (!shouldIgnore && reachedDate(expirationDate, options.date)) {
|
|
332
336
|
context.report({
|
|
333
337
|
loc: comment.loc,
|
|
334
338
|
messageId: MESSAGE_ID_EXPIRED_TODO,
|
|
335
339
|
data: {
|
|
336
|
-
expirationDate
|
|
340
|
+
expirationDate,
|
|
337
341
|
message: parseTodoMessage(comment.value),
|
|
338
342
|
},
|
|
339
343
|
});
|
|
@@ -403,11 +407,12 @@ const create = context => {
|
|
|
403
407
|
const todoVersion = tryToCoerceVersion(dependency.version);
|
|
404
408
|
const targetPackageVersion = tryToCoerceVersion(targetPackageRawVersion);
|
|
405
409
|
|
|
406
|
-
/*
|
|
410
|
+
/* c8 ignore start */
|
|
407
411
|
if (!hasTargetPackage || !targetPackageVersion) {
|
|
408
412
|
// Can't compare `¯\_(ツ)_/¯`
|
|
409
413
|
continue;
|
|
410
414
|
}
|
|
415
|
+
/* c8 ignore end */
|
|
411
416
|
|
|
412
417
|
const compare = semverComparisonForOperator(dependency.condition);
|
|
413
418
|
|
|
@@ -431,7 +436,7 @@ const create = context => {
|
|
|
431
436
|
const targetPackageRawEngineVersion = packageEngines.node;
|
|
432
437
|
const hasTargetEngine = Boolean(targetPackageRawEngineVersion);
|
|
433
438
|
|
|
434
|
-
/*
|
|
439
|
+
/* c8 ignore next 3 */
|
|
435
440
|
if (!hasTargetEngine) {
|
|
436
441
|
continue;
|
|
437
442
|
}
|
|
@@ -531,6 +536,10 @@ const schema = [
|
|
|
531
536
|
type: 'boolean',
|
|
532
537
|
default: false,
|
|
533
538
|
},
|
|
539
|
+
date: {
|
|
540
|
+
type: 'string',
|
|
541
|
+
format: 'date',
|
|
542
|
+
},
|
|
534
543
|
},
|
|
535
544
|
},
|
|
536
545
|
];
|
package/rules/filename-case.js
CHANGED
|
@@ -130,17 +130,7 @@ Turns `[a, b, c]` into `a, b, or c`.
|
|
|
130
130
|
@param {string[]} words
|
|
131
131
|
@returns {string}
|
|
132
132
|
*/
|
|
133
|
-
|
|
134
|
-
if (words.length === 1) {
|
|
135
|
-
return words[0];
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (words.length === 2) {
|
|
139
|
-
return `${words[0]} or ${words[1]}`;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return `${words.slice(0, -1).join(', ')}, or ${words[words.length - 1]}`;
|
|
143
|
-
}
|
|
133
|
+
const englishishJoinWords = words => new Intl.ListFormat('en-US', {type: 'disjunction'}).format(words);
|
|
144
134
|
|
|
145
135
|
/** @param {import('eslint').Rule.RuleContext} context */
|
|
146
136
|
const create = context => {
|
|
@@ -4,7 +4,7 @@ const {isCommaToken} = require('eslint-utils');
|
|
|
4
4
|
function appendArgument(fixer, node, text, sourceCode) {
|
|
5
5
|
// This function should also work for `NewExpression`
|
|
6
6
|
// But parentheses of `NewExpression` could be omitted, add this check to prevent accident use on it
|
|
7
|
-
/*
|
|
7
|
+
/* c8 ignore next 3 */
|
|
8
8
|
if (node.type !== 'CallExpression') {
|
|
9
9
|
throw new Error(`Unexpected node "${node.type}".`);
|
|
10
10
|
}
|
|
@@ -17,13 +17,14 @@ function removeArgument(fixer, node, sourceCode) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// If the removed argument is the only argument, the trailing comma must be removed too
|
|
20
|
-
/*
|
|
20
|
+
/* c8 ignore start */
|
|
21
21
|
if (callExpression.arguments.length === 1) {
|
|
22
22
|
const tokenAfter = sourceCode.getTokenBefore(lastToken);
|
|
23
23
|
if (isCommaToken(tokenAfter)) {
|
|
24
24
|
end = tokenAfter[1];
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
/* c8 ignore end */
|
|
27
28
|
|
|
28
29
|
return fixer.replaceTextRange([start, end], '');
|
|
29
30
|
}
|