eslint-plugin-unicorn 4.0.2 → 6.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/index.js +6 -2
- package/package.json +9 -10
- package/readme.md +3 -5
- package/rules/.DS_Store +0 -0
- package/rules/catch-error-name.js +13 -7
- package/rules/custom-error-definition.js +5 -6
- package/rules/error-message.js +1 -1
- package/rules/escape-case.js +1 -1
- package/rules/explicit-length-check.js +15 -9
- package/rules/filename-case.js +4 -2
- package/rules/import-index.js +1 -1
- package/rules/new-for-builtins.js +3 -3
- package/rules/no-abusive-eslint-disable.js +5 -4
- package/rules/no-array-instanceof.js +1 -1
- package/rules/no-fn-reference-in-iterator.js +2 -2
- package/rules/no-hex-escape.js +1 -1
- package/rules/no-new-buffer.js +1 -1
- package/rules/no-process-exit.js +2 -2
- package/rules/no-unsafe-regex.js +2 -2
- package/rules/number-literal-case.js +1 -1
- package/rules/prefer-add-event-listener.js +1 -1
- package/rules/prefer-exponentiation-operator.js +54 -0
- package/rules/prefer-spread.js +5 -3
- package/rules/prefer-starts-ends-with.js +5 -5
- package/rules/prefer-type-error.js +1 -1
- package/rules/regex-shorthand.js +13 -3
- package/rules/throw-new-error.js +1 -1
- package/rules/utils/get-docs-url.js +2 -2
package/index.js
CHANGED
|
@@ -13,8 +13,11 @@ module.exports = {
|
|
|
13
13
|
ecmaVersion: 2018,
|
|
14
14
|
sourceType: 'module'
|
|
15
15
|
},
|
|
16
|
+
plugins: [
|
|
17
|
+
'unicorn'
|
|
18
|
+
],
|
|
16
19
|
rules: {
|
|
17
|
-
'unicorn/catch-error-name': ['
|
|
20
|
+
'unicorn/catch-error-name': ['error', {name: 'error'}],
|
|
18
21
|
'unicorn/explicit-length-check': 'error',
|
|
19
22
|
'unicorn/filename-case': ['error', {case: 'kebabCase'}],
|
|
20
23
|
'unicorn/no-abusive-eslint-disable': 'error',
|
|
@@ -35,7 +38,8 @@ module.exports = {
|
|
|
35
38
|
'unicorn/prefer-spread': 'error',
|
|
36
39
|
'unicorn/error-message': 'error',
|
|
37
40
|
'unicorn/no-unsafe-regex': 'off',
|
|
38
|
-
'unicorn/prefer-add-event-listener': 'error'
|
|
41
|
+
'unicorn/prefer-add-event-listener': 'error',
|
|
42
|
+
'unicorn/prefer-exponentiation-operator': 'error'
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-unicorn",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "Various awesome ESLint rules",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/eslint-plugin-unicorn",
|
|
@@ -10,12 +10,11 @@
|
|
|
10
10
|
"url": "sindresorhus.com"
|
|
11
11
|
},
|
|
12
12
|
"engines": {
|
|
13
|
-
"node": ">=
|
|
13
|
+
"node": ">=6"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"test": "
|
|
17
|
-
"integration": "./test/integration/test.js"
|
|
18
|
-
"coveralls": "nyc report --reporter=text-lcov | coveralls"
|
|
16
|
+
"test": "nyc ava",
|
|
17
|
+
"integration": "./test/integration/test.js"
|
|
19
18
|
},
|
|
20
19
|
"files": [
|
|
21
20
|
"index.js",
|
|
@@ -46,17 +45,17 @@
|
|
|
46
45
|
"chalk": "^2.0.1",
|
|
47
46
|
"coveralls": "^3.0.0",
|
|
48
47
|
"del": "^3.0.0",
|
|
49
|
-
"eslint": "^
|
|
48
|
+
"eslint": "^5.0.0",
|
|
50
49
|
"eslint-ava-rule-tester": "^2.0.0",
|
|
51
|
-
"execa": "^0.
|
|
52
|
-
"listr": "^0.
|
|
53
|
-
"nyc": "^
|
|
50
|
+
"execa": "^0.10.0",
|
|
51
|
+
"listr": "^0.14.1",
|
|
52
|
+
"nyc": "^12.0.2",
|
|
54
53
|
"pify": "^3.0.0",
|
|
55
54
|
"tempy": "^0.2.1",
|
|
56
55
|
"xo": "*"
|
|
57
56
|
},
|
|
58
57
|
"peerDependencies": {
|
|
59
|
-
"eslint": ">=
|
|
58
|
+
"eslint": ">=5.0.0"
|
|
60
59
|
},
|
|
61
60
|
"ava": {
|
|
62
61
|
"files": [
|
package/readme.md
CHANGED
|
@@ -26,14 +26,14 @@ Configure it in `package.json`.
|
|
|
26
26
|
"es6": true
|
|
27
27
|
},
|
|
28
28
|
"parserOptions": {
|
|
29
|
-
"ecmaVersion":
|
|
29
|
+
"ecmaVersion": 2018,
|
|
30
30
|
"sourceType": "module"
|
|
31
31
|
},
|
|
32
32
|
"plugins": [
|
|
33
33
|
"unicorn"
|
|
34
34
|
],
|
|
35
35
|
"rules": {
|
|
36
|
-
"unicorn/catch-error-name": ["error", {"name": "
|
|
36
|
+
"unicorn/catch-error-name": ["error", {"name": "error"}],
|
|
37
37
|
"unicorn/explicit-length-check": "error",
|
|
38
38
|
"unicorn/filename-case": ["error", {"case": "kebabCase"}],
|
|
39
39
|
"unicorn/no-abusive-eslint-disable": "error",
|
|
@@ -85,6 +85,7 @@ Configure it in `package.json`.
|
|
|
85
85
|
- [error-message](docs/rules/error-message.md) - Enforce passing a `message` value when throwing a built-in error.
|
|
86
86
|
- [no-unsafe-regex](docs/rules/no-unsafe-regex.md) - Disallow unsafe regular expressions.
|
|
87
87
|
- [prefer-add-event-listener](docs/rules/prefer-add-event-listener.md) - Prefer `addEventListener` over `on`-functions. *(fixable)*
|
|
88
|
+
- [prefer-exponentiation-operator](docs/rules/prefer-exponentiation-operator.md) - Prefer the exponentiation operator over `Math.pow()` *(fixable)*
|
|
88
89
|
|
|
89
90
|
|
|
90
91
|
## Recommended config
|
|
@@ -97,9 +98,6 @@ Enable it in your `package.json` with the `extends` option:
|
|
|
97
98
|
{
|
|
98
99
|
"name": "my-awesome-project",
|
|
99
100
|
"eslintConfig": {
|
|
100
|
-
"plugins": [
|
|
101
|
-
"unicorn"
|
|
102
|
-
],
|
|
103
101
|
"extends": "plugin:unicorn/recommended"
|
|
104
102
|
}
|
|
105
103
|
}
|
package/rules/.DS_Store
ADDED
|
Binary file
|
|
@@ -4,13 +4,13 @@ const getDocsUrl = require('./utils/get-docs-url');
|
|
|
4
4
|
|
|
5
5
|
// Matches `someObj.then([FunctionExpression | ArrowFunctionExpression])`
|
|
6
6
|
function isLintablePromiseCatch(node) {
|
|
7
|
-
const callee = node
|
|
7
|
+
const {callee} = node;
|
|
8
8
|
|
|
9
9
|
if (callee.type !== 'MemberExpression') {
|
|
10
10
|
return false;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const property = callee
|
|
13
|
+
const {property} = callee;
|
|
14
14
|
|
|
15
15
|
if (property.type !== 'Identifier' || property.name !== 'catch') {
|
|
16
16
|
return false;
|
|
@@ -20,7 +20,7 @@ function isLintablePromiseCatch(node) {
|
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const arg0 = node.arguments
|
|
23
|
+
const [arg0] = node.arguments;
|
|
24
24
|
|
|
25
25
|
return arg0.type === 'FunctionExpression' || arg0.type === 'ArrowFunctionExpression';
|
|
26
26
|
}
|
|
@@ -38,11 +38,11 @@ function indexifyName(name, scope) {
|
|
|
38
38
|
|
|
39
39
|
const create = context => {
|
|
40
40
|
const options = Object.assign({}, {
|
|
41
|
-
name: '
|
|
41
|
+
name: 'error',
|
|
42
42
|
caughtErrorsIgnorePattern: '^_$'
|
|
43
43
|
}, context.options[0]);
|
|
44
44
|
|
|
45
|
-
const name = options
|
|
45
|
+
const {name} = options;
|
|
46
46
|
const caughtErrorsIgnorePattern = new RegExp(options.caughtErrorsIgnorePattern);
|
|
47
47
|
const stack = [];
|
|
48
48
|
|
|
@@ -68,7 +68,7 @@ const create = context => {
|
|
|
68
68
|
return {
|
|
69
69
|
CallExpression: node => {
|
|
70
70
|
if (isLintablePromiseCatch(node)) {
|
|
71
|
-
const params = node.arguments[0]
|
|
71
|
+
const {params} = node.arguments[0];
|
|
72
72
|
|
|
73
73
|
if (params.length > 0 && params[0].name === '_') {
|
|
74
74
|
push(!astUtils.containsIdentifier('_', node.arguments[0].body));
|
|
@@ -85,6 +85,12 @@ const create = context => {
|
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
CatchClause: node => {
|
|
88
|
+
// Optional catch binding
|
|
89
|
+
if (!node || !node.param) {
|
|
90
|
+
push(true);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
88
94
|
if (node.param.name === '_') {
|
|
89
95
|
push(!astUtils.someContainIdentifier('_', node.body.body));
|
|
90
96
|
return;
|
|
@@ -115,7 +121,7 @@ module.exports = {
|
|
|
115
121
|
create,
|
|
116
122
|
meta: {
|
|
117
123
|
docs: {
|
|
118
|
-
url: getDocsUrl()
|
|
124
|
+
url: getDocsUrl(__filename)
|
|
119
125
|
},
|
|
120
126
|
schema
|
|
121
127
|
}
|
|
@@ -18,10 +18,10 @@ const hasValidSuperClass = node => {
|
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
let name = node.superClass
|
|
21
|
+
let {name} = node.superClass;
|
|
22
22
|
|
|
23
23
|
if (node.superClass.type === 'MemberExpression') {
|
|
24
|
-
name = node.superClass.property
|
|
24
|
+
({name} = node.superClass.property);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
return nameRegexp.test(name);
|
|
@@ -48,7 +48,7 @@ const customErrorDefinition = (context, node) => {
|
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const name = node.id
|
|
51
|
+
const {name} = node.id;
|
|
52
52
|
const className = getClassName(name);
|
|
53
53
|
|
|
54
54
|
if (name !== className) {
|
|
@@ -58,8 +58,7 @@ const customErrorDefinition = (context, node) => {
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const body = node.body
|
|
62
|
-
|
|
61
|
+
const {body} = node.body;
|
|
63
62
|
const constructor = body.find(x => x.kind === 'constructor');
|
|
64
63
|
|
|
65
64
|
if (!constructor) {
|
|
@@ -132,7 +131,7 @@ module.exports = {
|
|
|
132
131
|
create,
|
|
133
132
|
meta: {
|
|
134
133
|
docs: {
|
|
135
|
-
url: getDocsUrl()
|
|
134
|
+
url: getDocsUrl(__filename)
|
|
136
135
|
},
|
|
137
136
|
fixable: 'code'
|
|
138
137
|
}
|
package/rules/error-message.js
CHANGED
package/rules/escape-case.js
CHANGED
|
@@ -36,13 +36,14 @@ function checkZeroType(context, node) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function checkNonZeroType(context, node, type) {
|
|
39
|
-
const value = node.right
|
|
40
|
-
const operator = node
|
|
39
|
+
const {value} = node.right;
|
|
40
|
+
const {operator} = node;
|
|
41
41
|
|
|
42
42
|
switch (type) {
|
|
43
43
|
case 'greater-than':
|
|
44
|
-
if (
|
|
45
|
-
(operatorTypes.
|
|
44
|
+
if (
|
|
45
|
+
(operatorTypes.gte.includes(operator) && value === 1) ||
|
|
46
|
+
(operatorTypes.ne.includes(operator) && value === 0)
|
|
46
47
|
) {
|
|
47
48
|
reportError(
|
|
48
49
|
context,
|
|
@@ -57,8 +58,9 @@ function checkNonZeroType(context, node, type) {
|
|
|
57
58
|
}
|
|
58
59
|
break;
|
|
59
60
|
case 'greater-than-or-equal':
|
|
60
|
-
if (
|
|
61
|
-
(operatorTypes.
|
|
61
|
+
if (
|
|
62
|
+
(operatorTypes.gt.includes(operator) && value === 0) ||
|
|
63
|
+
(operatorTypes.ne.includes(operator) && value === 0)
|
|
62
64
|
) {
|
|
63
65
|
reportError(
|
|
64
66
|
context,
|
|
@@ -73,8 +75,9 @@ function checkNonZeroType(context, node, type) {
|
|
|
73
75
|
}
|
|
74
76
|
break;
|
|
75
77
|
case 'not-equal':
|
|
76
|
-
if (
|
|
77
|
-
(operatorTypes.
|
|
78
|
+
if (
|
|
79
|
+
(operatorTypes.gt.includes(operator) && value === 0) ||
|
|
80
|
+
(operatorTypes.gte.includes(operator) && value === 1)
|
|
78
81
|
) {
|
|
79
82
|
reportError(
|
|
80
83
|
context,
|
|
@@ -133,6 +136,9 @@ const create = context => {
|
|
|
133
136
|
return {
|
|
134
137
|
IfStatement: node => {
|
|
135
138
|
checkExpression(context, node.test);
|
|
139
|
+
},
|
|
140
|
+
ConditionalExpression: node => {
|
|
141
|
+
checkExpression(context, node.test);
|
|
136
142
|
}
|
|
137
143
|
};
|
|
138
144
|
};
|
|
@@ -154,7 +160,7 @@ module.exports = {
|
|
|
154
160
|
create,
|
|
155
161
|
meta: {
|
|
156
162
|
docs: {
|
|
157
|
-
url: getDocsUrl()
|
|
163
|
+
url: getDocsUrl(__filename)
|
|
158
164
|
},
|
|
159
165
|
fixable: 'code',
|
|
160
166
|
schema
|
package/rules/filename-case.js
CHANGED
|
@@ -68,7 +68,9 @@ function splitFilename(filename) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
const create = context => {
|
|
71
|
-
const
|
|
71
|
+
const options = context.options[0] || {};
|
|
72
|
+
|
|
73
|
+
const chosenCase = cases[options.case || 'camelCase'];
|
|
72
74
|
const filenameWithExt = context.getFilename();
|
|
73
75
|
|
|
74
76
|
if (filenameWithExt === '<text>') {
|
|
@@ -116,7 +118,7 @@ module.exports = {
|
|
|
116
118
|
create,
|
|
117
119
|
meta: {
|
|
118
120
|
docs: {
|
|
119
|
-
url: getDocsUrl()
|
|
121
|
+
url: getDocsUrl(__filename)
|
|
120
122
|
},
|
|
121
123
|
schema
|
|
122
124
|
}
|
package/rules/import-index.js
CHANGED
|
@@ -36,7 +36,7 @@ const disallowNew = new Set([
|
|
|
36
36
|
const create = context => {
|
|
37
37
|
return {
|
|
38
38
|
CallExpression: node => {
|
|
39
|
-
const name = node.callee
|
|
39
|
+
const {name} = node.callee;
|
|
40
40
|
|
|
41
41
|
if (enforceNew.has(name)) {
|
|
42
42
|
context.report({
|
|
@@ -47,7 +47,7 @@ const create = context => {
|
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
NewExpression: node => {
|
|
50
|
-
const name = node.callee
|
|
50
|
+
const {name} = node.callee;
|
|
51
51
|
|
|
52
52
|
if (disallowNew.has(name)) {
|
|
53
53
|
context.report({
|
|
@@ -67,7 +67,7 @@ module.exports = {
|
|
|
67
67
|
create,
|
|
68
68
|
meta: {
|
|
69
69
|
docs: {
|
|
70
|
-
url: getDocsUrl()
|
|
70
|
+
url: getDocsUrl(__filename)
|
|
71
71
|
},
|
|
72
72
|
fixable: 'code'
|
|
73
73
|
}
|
|
@@ -5,11 +5,12 @@ const disableRegex = /^eslint-disable(-next-line|-line)?($|(\s+(@[\w-]+\/[\w-]+\
|
|
|
5
5
|
|
|
6
6
|
const create = context => ({
|
|
7
7
|
Program: node => {
|
|
8
|
-
node.comments
|
|
8
|
+
for (const comment of node.comments) {
|
|
9
9
|
const value = comment.value.trim();
|
|
10
10
|
const res = disableRegex.exec(value);
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (
|
|
13
|
+
res && // It's a eslint-disable comment
|
|
13
14
|
!res[2] // But it did not specify any rules
|
|
14
15
|
) {
|
|
15
16
|
context.report({
|
|
@@ -24,7 +25,7 @@ const create = context => ({
|
|
|
24
25
|
data: comment.loc.start
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
|
-
}
|
|
28
|
+
}
|
|
28
29
|
}
|
|
29
30
|
});
|
|
30
31
|
|
|
@@ -32,7 +33,7 @@ module.exports = {
|
|
|
32
33
|
create,
|
|
33
34
|
meta: {
|
|
34
35
|
docs: {
|
|
35
|
-
url: getDocsUrl()
|
|
36
|
+
url: getDocsUrl(__filename)
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
};
|
|
@@ -34,7 +34,7 @@ const fix = (context, node) => {
|
|
|
34
34
|
const create = context => ({
|
|
35
35
|
'CallExpression[callee.object.name!="Promise"]': node => {
|
|
36
36
|
if (isIteratorMethod(node) && hasFunctionArgument(node)) {
|
|
37
|
-
const arg = node.arguments
|
|
37
|
+
const [arg] = node.arguments;
|
|
38
38
|
|
|
39
39
|
context.report({
|
|
40
40
|
node: arg,
|
|
@@ -49,7 +49,7 @@ module.exports = {
|
|
|
49
49
|
create,
|
|
50
50
|
meta: {
|
|
51
51
|
docs: {
|
|
52
|
-
url: getDocsUrl()
|
|
52
|
+
url: getDocsUrl(__filename)
|
|
53
53
|
},
|
|
54
54
|
fixable: 'code'
|
|
55
55
|
}
|
package/rules/no-hex-escape.js
CHANGED
package/rules/no-new-buffer.js
CHANGED
package/rules/no-process-exit.js
CHANGED
|
@@ -12,7 +12,7 @@ const create = context => {
|
|
|
12
12
|
|
|
13
13
|
return {
|
|
14
14
|
CallExpression: node => {
|
|
15
|
-
const callee = node
|
|
15
|
+
const {callee} = node;
|
|
16
16
|
|
|
17
17
|
if (callee.type === 'MemberExpression' && callee.object.name === 'process') {
|
|
18
18
|
if (callee.property.name === 'on' || callee.property.name === 'once') {
|
|
@@ -40,7 +40,7 @@ module.exports = {
|
|
|
40
40
|
create,
|
|
41
41
|
meta: {
|
|
42
42
|
docs: {
|
|
43
|
-
url: getDocsUrl()
|
|
43
|
+
url: getDocsUrl(__filename)
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
};
|
package/rules/no-unsafe-regex.js
CHANGED
|
@@ -32,7 +32,7 @@ const create = context => {
|
|
|
32
32
|
let flags = null;
|
|
33
33
|
|
|
34
34
|
if (hasRegExp) {
|
|
35
|
-
pattern = args[0].regex
|
|
35
|
+
({pattern} = args[0].regex);
|
|
36
36
|
flags = args[1] && args[1].type === 'Literal' ? args[1].value : args[0].regex.flags;
|
|
37
37
|
} else {
|
|
38
38
|
pattern = args[0].value;
|
|
@@ -53,7 +53,7 @@ module.exports = {
|
|
|
53
53
|
create,
|
|
54
54
|
meta: {
|
|
55
55
|
docs: {
|
|
56
|
-
url: getDocsUrl()
|
|
56
|
+
url: getDocsUrl(__filename)
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const getDocsUrl = require('./utils/get-docs-url');
|
|
3
|
+
|
|
4
|
+
const isMathPow = node => {
|
|
5
|
+
const {callee} = node;
|
|
6
|
+
return (
|
|
7
|
+
callee.type === 'MemberExpression' &&
|
|
8
|
+
callee.object.type === 'Identifier' &&
|
|
9
|
+
callee.object.name === 'Math' &&
|
|
10
|
+
callee.property.type === 'Identifier' &&
|
|
11
|
+
callee.property.name === 'pow'
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const parseArgument = (context, arg) => {
|
|
16
|
+
if (arg.type === 'Identifier') {
|
|
17
|
+
return arg.name;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return context.getSourceCode().getText(arg);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const fix = (context, node, fixer) => {
|
|
24
|
+
const base = parseArgument(context, node.arguments[0]);
|
|
25
|
+
const exponent = parseArgument(context, node.arguments[1]);
|
|
26
|
+
|
|
27
|
+
const replacement = `${base} ** ${exponent}`;
|
|
28
|
+
|
|
29
|
+
return fixer.replaceText(node, replacement);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const create = context => {
|
|
33
|
+
return {
|
|
34
|
+
CallExpression(node) {
|
|
35
|
+
if (isMathPow(node)) {
|
|
36
|
+
context.report({
|
|
37
|
+
node,
|
|
38
|
+
message: 'Prefer the exponentiation operator over `Math.pow()`.',
|
|
39
|
+
fix: fixer => fix(context, node, fixer),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
create,
|
|
48
|
+
meta: {
|
|
49
|
+
docs: {
|
|
50
|
+
url: getDocsUrl(__filename)
|
|
51
|
+
},
|
|
52
|
+
fixable: 'code'
|
|
53
|
+
}
|
|
54
|
+
};
|
package/rules/prefer-spread.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const getDocsUrl = require('./utils/get-docs-url');
|
|
3
3
|
|
|
4
4
|
const isArrayFrom = node => {
|
|
5
|
-
const callee = node
|
|
5
|
+
const {callee} = node;
|
|
6
6
|
return (
|
|
7
7
|
callee.type === 'MemberExpression' &&
|
|
8
8
|
callee.object.type === 'Identifier' &&
|
|
@@ -12,6 +12,8 @@ const isArrayFrom = node => {
|
|
|
12
12
|
);
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
const isArrayLike = arg => arg && arg.type !== 'ObjectExpression';
|
|
16
|
+
|
|
15
17
|
const parseArgument = (context, arg) => {
|
|
16
18
|
if (arg.type === 'Identifier') {
|
|
17
19
|
return arg.name;
|
|
@@ -23,7 +25,7 @@ const parseArgument = (context, arg) => {
|
|
|
23
25
|
const create = context => {
|
|
24
26
|
return {
|
|
25
27
|
CallExpression(node) {
|
|
26
|
-
if (isArrayFrom(node)) {
|
|
28
|
+
if (isArrayFrom(node) && isArrayLike(node.arguments[0])) {
|
|
27
29
|
context.report({
|
|
28
30
|
node,
|
|
29
31
|
message: 'Prefer the spread operator over `Array.from()`.',
|
|
@@ -51,7 +53,7 @@ module.exports = {
|
|
|
51
53
|
create,
|
|
52
54
|
meta: {
|
|
53
55
|
docs: {
|
|
54
|
-
url: getDocsUrl()
|
|
56
|
+
url: getDocsUrl(__filename)
|
|
55
57
|
},
|
|
56
58
|
fixable: 'code'
|
|
57
59
|
}
|
|
@@ -11,7 +11,7 @@ const isSimpleString = string => doesNotContain(
|
|
|
11
11
|
const create = context => {
|
|
12
12
|
return {
|
|
13
13
|
CallExpression(node) {
|
|
14
|
-
const callee = node
|
|
14
|
+
const {callee} = node;
|
|
15
15
|
const prop = callee.property;
|
|
16
16
|
|
|
17
17
|
if (!(prop && callee.type === 'MemberExpression')) {
|
|
@@ -22,9 +22,9 @@ const create = context => {
|
|
|
22
22
|
|
|
23
23
|
let regex;
|
|
24
24
|
if (prop.name === 'test' && callee.object.regex) {
|
|
25
|
-
regex = callee.object
|
|
25
|
+
({regex} = callee.object);
|
|
26
26
|
} else if (prop.name === 'match' && args && args[0] && args[0].regex) {
|
|
27
|
-
regex = args[0]
|
|
27
|
+
({regex} = args[0]);
|
|
28
28
|
} else {
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
@@ -33,7 +33,7 @@ const create = context => {
|
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const pattern = regex
|
|
36
|
+
const {pattern} = regex;
|
|
37
37
|
if (pattern.startsWith('^') && isSimpleString(pattern.slice(1))) {
|
|
38
38
|
context.report({
|
|
39
39
|
node,
|
|
@@ -53,7 +53,7 @@ module.exports = {
|
|
|
53
53
|
create,
|
|
54
54
|
meta: {
|
|
55
55
|
docs: {
|
|
56
|
-
url: getDocsUrl()
|
|
56
|
+
url: getDocsUrl(__filename)
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
};
|
package/rules/regex-shorthand.js
CHANGED
|
@@ -8,7 +8,7 @@ const create = context => {
|
|
|
8
8
|
return {
|
|
9
9
|
'Literal[regex]': node => {
|
|
10
10
|
const oldPattern = node.regex.pattern;
|
|
11
|
-
const flags = node.regex
|
|
11
|
+
const {flags} = node.regex;
|
|
12
12
|
|
|
13
13
|
const newPattern = cleanRegexp(oldPattern, flags);
|
|
14
14
|
|
|
@@ -48,10 +48,20 @@ const create = context => {
|
|
|
48
48
|
const newPattern = cleanRegexp(oldPattern, flags);
|
|
49
49
|
|
|
50
50
|
if (oldPattern !== newPattern) {
|
|
51
|
+
let fixed;
|
|
52
|
+
if (hasRegExp) {
|
|
53
|
+
fixed = `/${newPattern}/`;
|
|
54
|
+
} else {
|
|
55
|
+
// Escape backslash and apostrophe because we wrap the result in single quotes.
|
|
56
|
+
fixed = (newPattern || '').replace(/\\/, '\\\\');
|
|
57
|
+
fixed = fixed.replace(/'/, '\'');
|
|
58
|
+
fixed = `'${fixed}'`;
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
context.report({
|
|
52
62
|
node,
|
|
53
63
|
message,
|
|
54
|
-
fix: fixer => fixer.replaceTextRange(args[0].range,
|
|
64
|
+
fix: fixer => fixer.replaceTextRange(args[0].range, fixed),
|
|
55
65
|
});
|
|
56
66
|
}
|
|
57
67
|
}
|
|
@@ -62,7 +72,7 @@ module.exports = {
|
|
|
62
72
|
create,
|
|
63
73
|
meta: {
|
|
64
74
|
docs: {
|
|
65
|
-
url: getDocsUrl()
|
|
75
|
+
url: getDocsUrl(__filename)
|
|
66
76
|
},
|
|
67
77
|
fixable: 'code'
|
|
68
78
|
}
|
package/rules/throw-new-error.js
CHANGED
|
@@ -4,7 +4,7 @@ const pkg = require('../../package');
|
|
|
4
4
|
|
|
5
5
|
const repoUrl = 'https://github.com/sindresorhus/eslint-plugin-unicorn';
|
|
6
6
|
|
|
7
|
-
module.exports =
|
|
8
|
-
ruleName =
|
|
7
|
+
module.exports = filename => {
|
|
8
|
+
const ruleName = path.basename(filename, '.js');
|
|
9
9
|
return `${repoUrl}/blob/v${pkg.version}/docs/rules/${ruleName}.md`;
|
|
10
10
|
};
|