format-demo-eslint-plugin 1.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/README.md +32 -0
- package/configs/recommended.js +7 -0
- package/package.json +39 -0
- package/rules/no-broad-semantic-versioning.js +59 -0
- package/rules/no-http-url.js +27 -0
- package/rules/no-js-in-ts-project.js +58 -0
- package/rules/no-secret-info.js +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# format-demo-eslint-plugin
|
|
2
|
+
|
|
3
|
+
## 安装
|
|
4
|
+
|
|
5
|
+
除了本包,你需要同时安装 [ESlint](https://eslint.org/)
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
$ npm install format-demo-eslint-plugin eslint --save-dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 使用
|
|
12
|
+
|
|
13
|
+
### 引入插件
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
// .eslintrc.js
|
|
17
|
+
module.exports = {
|
|
18
|
+
plugin: ['format-demo-eslint-config'],
|
|
19
|
+
rules: {
|
|
20
|
+
'format-demo-eslint-plugin/no-secret-info': 'error',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 使用 presets
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
// .eslintrc.js
|
|
29
|
+
module.exports = {
|
|
30
|
+
extends: 'plugin:format-demo-eslint-plugin/recommended',
|
|
31
|
+
};
|
|
32
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "format-demo-eslint-plugin",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "自定义eslint插件",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "jest",
|
|
7
|
+
"prepublishOnly": "npm run test"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"configs/",
|
|
11
|
+
"rules/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"encode",
|
|
16
|
+
"eslint",
|
|
17
|
+
"eslint-plugin"
|
|
18
|
+
],
|
|
19
|
+
"main": "src/index.js",
|
|
20
|
+
"author": "chenghuai",
|
|
21
|
+
"homepage": "https://github.com/Huang-Yux/format_demo#readme",
|
|
22
|
+
"license": "ISC",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/Huang-Yux/format_demo.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/Huang-Yux/format_demo/issues"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"fs-extra": "^9.0.1",
|
|
32
|
+
"require-all": "^3.0.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"eslint": "^8.7.0",
|
|
36
|
+
"jest": "^26.6.3"
|
|
37
|
+
},
|
|
38
|
+
"gitHead": "400e366da374414a0b11d025d7f31d37a6a03643"
|
|
39
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
const RULE_NAME = 'no-broad-semantic-versioning';
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
name: RULE_NAME,
|
|
7
|
+
meta: {
|
|
8
|
+
type: 'problem',
|
|
9
|
+
fixable: null,
|
|
10
|
+
messages: {
|
|
11
|
+
noBroadSemanticVersioning:
|
|
12
|
+
'The "{{dependencyName}}" is not recommended to use "{{versioning}}"',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
create(context) {
|
|
17
|
+
if (path.basename(context.getFilename()) !== 'package.json') {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const cwd = context.getCwd();
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
Property: function handleRequires(node) {
|
|
25
|
+
if (
|
|
26
|
+
node.key &&
|
|
27
|
+
node.key.value &&
|
|
28
|
+
(node.key.value === 'dependencies' || node.key.value === 'devDependencies') &&
|
|
29
|
+
node.value &&
|
|
30
|
+
node.value.properties
|
|
31
|
+
) {
|
|
32
|
+
node.value.properties.forEach((property) => {
|
|
33
|
+
if (property.key && property.key.value) {
|
|
34
|
+
const dependencyName = property.key.value;
|
|
35
|
+
const dependencyVersion = property.value.value;
|
|
36
|
+
if (
|
|
37
|
+
// *
|
|
38
|
+
dependencyVersion.indexOf('*') > -1 ||
|
|
39
|
+
// x.x
|
|
40
|
+
dependencyVersion.indexOf('x') > -1 ||
|
|
41
|
+
// > x
|
|
42
|
+
dependencyVersion.indexOf('>') > -1
|
|
43
|
+
) {
|
|
44
|
+
context.report({
|
|
45
|
+
loc: property.loc,
|
|
46
|
+
messageId: 'noBroadSemanticVersioning',
|
|
47
|
+
data: {
|
|
48
|
+
dependencyName,
|
|
49
|
+
versioning: dependencyVersion,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const RULE_NAME = 'no-http-url';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
name: RULE_NAME,
|
|
5
|
+
meta: {
|
|
6
|
+
type: 'suggestion',
|
|
7
|
+
fixable: null,
|
|
8
|
+
messages: {
|
|
9
|
+
noHttpUrl: 'Recommended "{{url}}" switch to HTTPS',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
create(context) {
|
|
13
|
+
return {
|
|
14
|
+
Literal: function handleRequires(node) {
|
|
15
|
+
if (node.value && typeof node.value === 'string' && node.value.indexOf('http:') === 0) {
|
|
16
|
+
context.report({
|
|
17
|
+
node,
|
|
18
|
+
messageId: 'noHttpUrl',
|
|
19
|
+
data: {
|
|
20
|
+
url: node.value,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
const RULE_NAME = 'no-js-in-ts-project';
|
|
4
|
+
|
|
5
|
+
const JS_REG = /\.jsx?$/;
|
|
6
|
+
|
|
7
|
+
const DEFAULT_WHITE_LIST = [
|
|
8
|
+
'commitlint.config.js',
|
|
9
|
+
'eslintrc.js',
|
|
10
|
+
'prettierrc.js',
|
|
11
|
+
'stylelintrc.js',
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
name: RULE_NAME,
|
|
16
|
+
meta: {
|
|
17
|
+
type: 'suggestion',
|
|
18
|
+
fixable: null,
|
|
19
|
+
messages: {
|
|
20
|
+
noJSInTSProject: 'The "{{fileName}}" is not recommended in TS project',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
create(context) {
|
|
25
|
+
const fileName = context.getFilename();
|
|
26
|
+
const extName = path.extname(fileName);
|
|
27
|
+
const ruleOptions = context.options[0] || {};
|
|
28
|
+
let { whiteList = [], autoMerge = true } = ruleOptions;
|
|
29
|
+
if (whiteList.length === 0) {
|
|
30
|
+
whiteList = DEFAULT_WHITE_LIST;
|
|
31
|
+
} else if (autoMerge) {
|
|
32
|
+
whiteList = [...new Set([...DEFAULT_WHITE_LIST, ...whiteList])];
|
|
33
|
+
}
|
|
34
|
+
const whiteListReg = new RegExp(`(${whiteList.join('|')})$`);
|
|
35
|
+
|
|
36
|
+
if (!whiteListReg.test(fileName) && JS_REG.test(extName)) {
|
|
37
|
+
context.report({
|
|
38
|
+
loc: {
|
|
39
|
+
start: {
|
|
40
|
+
line: 0,
|
|
41
|
+
column: 0,
|
|
42
|
+
},
|
|
43
|
+
end: {
|
|
44
|
+
line: 0,
|
|
45
|
+
column: 0,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
messageId: 'noJSInTSProject',
|
|
49
|
+
data: {
|
|
50
|
+
fileName,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Necessary
|
|
56
|
+
return {};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const RULE_NAME = 'no-secret-info';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_DANGEROUS_KEYS = ['secret', 'token', 'password'];
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
meta: {
|
|
7
|
+
type: 'problem',
|
|
8
|
+
fixable: null,
|
|
9
|
+
messages: {
|
|
10
|
+
noSecretInfo: 'Detect that the "{{secret}}" might be a secret token, Please check!',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
create(context) {
|
|
15
|
+
const ruleOptions = context.options[0] || {};
|
|
16
|
+
let { dangerousKeys = [], autoMerge = true } = ruleOptions;
|
|
17
|
+
if (dangerousKeys.length === 0) {
|
|
18
|
+
dangerousKeys = DEFAULT_DANGEROUS_KEYS;
|
|
19
|
+
} else if (autoMerge) {
|
|
20
|
+
dangerousKeys = [...new Set(...DEFAULT_DANGEROUS_KEYS, ...dangerousKeys)];
|
|
21
|
+
}
|
|
22
|
+
const reg = new RegExp(dangerousKeys.join('|'));
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
Literal: function handleRequires(node) {
|
|
26
|
+
if (
|
|
27
|
+
node.value &&
|
|
28
|
+
node.parent &&
|
|
29
|
+
((node.parent.type === 'VariableDeclarator' &&
|
|
30
|
+
node.parent.id &&
|
|
31
|
+
node.parent.id.name &&
|
|
32
|
+
reg.test(node.parent.id.name.toLocaleLowerCase())) ||
|
|
33
|
+
(node.parent.type === 'Property' &&
|
|
34
|
+
node.parent.key &&
|
|
35
|
+
node.parent.key.name &&
|
|
36
|
+
reg.test(node.parent.key.name.toLocaleLowerCase())))
|
|
37
|
+
) {
|
|
38
|
+
context.report({
|
|
39
|
+
node,
|
|
40
|
+
messageId: 'noSecretInfo',
|
|
41
|
+
data: {
|
|
42
|
+
secret: node.value,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
};
|