@nest-boot/eslint-plugin 5.1.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/.eslintrc.js +19 -0
- package/README.md +45 -0
- package/docs/rules/entity-property-no-optional-or-non-null-assertion.md +31 -0
- package/docs/rules/entity-property-nullable-type.md +31 -0
- package/lib/index.js +22 -0
- package/lib/rules/entity-property-no-optional-or-non-null-assertion.js +58 -0
- package/lib/rules/entity-property-nullable-type.js +88 -0
- package/package.json +34 -0
- package/tests/lib/rules/entity-property-no-optional-or-non-null-assertion.js +31 -0
- package/tests/lib/rules/entity-property-nullable-type.js +31 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
root: true,
|
|
5
|
+
extends: [
|
|
6
|
+
"eslint:recommended",
|
|
7
|
+
"plugin:eslint-plugin/recommended",
|
|
8
|
+
"plugin:node/recommended",
|
|
9
|
+
],
|
|
10
|
+
env: {
|
|
11
|
+
node: true,
|
|
12
|
+
},
|
|
13
|
+
overrides: [
|
|
14
|
+
{
|
|
15
|
+
files: ["tests/**/*.js"],
|
|
16
|
+
env: { mocha: true },
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
};
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# eslint-plugin-nest-boot
|
|
2
|
+
|
|
3
|
+
Nest Boot 定制规则
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
You'll first need to install [ESLint](https://eslint.org/):
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm i eslint --save-dev
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Next, install `eslint-plugin-nest-boot`:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install eslint-plugin-nest-boot --save-dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Add `nest-boot` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"plugins": ["nest-boot"]
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Then configure the rules you want to use under the rules section.
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"rules": {
|
|
34
|
+
"nest-boot/rule-name": 2
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
|
|
41
|
+
<!-- begin auto-generated rules list -->
|
|
42
|
+
|
|
43
|
+
TODO: Run eslint-doc-generator to generate the rules list.
|
|
44
|
+
|
|
45
|
+
<!-- end auto-generated rules list -->
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 实体字段不能使用可选属性和非空断言 (`entity-property-no-optional-or-non-null-assertion`)
|
|
2
|
+
|
|
3
|
+
Please describe the origin of the rule here.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule aims to...
|
|
8
|
+
|
|
9
|
+
Examples of **incorrect** code for this rule:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
// fill me in
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Examples of **correct** code for this rule:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
// fill me in
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Options
|
|
22
|
+
|
|
23
|
+
If there are any options, describe them here. Otherwise, delete this section.
|
|
24
|
+
|
|
25
|
+
## When Not To Use It
|
|
26
|
+
|
|
27
|
+
Give a short description of when it would be appropriate to turn off this rule.
|
|
28
|
+
|
|
29
|
+
## Further Reading
|
|
30
|
+
|
|
31
|
+
If there are other links that describe the issue this rule addresses, please include them here in a bulleted list.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 实体字段可为空时属性类型 (`entity-property-nullable-type`)
|
|
2
|
+
|
|
3
|
+
Please describe the origin of the rule here.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule aims to...
|
|
8
|
+
|
|
9
|
+
Examples of **incorrect** code for this rule:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
// fill me in
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Examples of **correct** code for this rule:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
// fill me in
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Options
|
|
22
|
+
|
|
23
|
+
If there are any options, describe them here. Otherwise, delete this section.
|
|
24
|
+
|
|
25
|
+
## When Not To Use It
|
|
26
|
+
|
|
27
|
+
Give a short description of when it would be appropriate to turn off this rule.
|
|
28
|
+
|
|
29
|
+
## Further Reading
|
|
30
|
+
|
|
31
|
+
If there are other links that describe the issue this rule addresses, please include them here in a bulleted list.
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Nest Boot 定制规则
|
|
3
|
+
* @author @nest-boot/eslint-plugin
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const requireIndex = require("requireindex");
|
|
12
|
+
|
|
13
|
+
//------------------------------------------------------------------------------
|
|
14
|
+
// Plugin Definition
|
|
15
|
+
//------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
// import all rules in lib/rules
|
|
19
|
+
module.exports.rules = requireIndex(__dirname + "/rules");
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 实体字段不能使用可选属性和非空断言
|
|
3
|
+
* @author 实体字段不能使用可选属性和非空断言
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Rule Definition
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
/** @type {import('eslint').Rule.RuleModule} */
|
|
12
|
+
module.exports = {
|
|
13
|
+
meta: {
|
|
14
|
+
type: null, // `problem`, `suggestion`, or `layout`
|
|
15
|
+
docs: {
|
|
16
|
+
description: "实体字段不能使用可选属性和非空断言",
|
|
17
|
+
recommended: false,
|
|
18
|
+
url: null, // URL to the documentation page for this rule
|
|
19
|
+
},
|
|
20
|
+
fixable: null, // Or `code` or `whitespace`
|
|
21
|
+
schema: [], // Add a schema if the rule has options
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
create(context) {
|
|
25
|
+
return {
|
|
26
|
+
ClassDeclaration(node) {
|
|
27
|
+
// 检查是否有 @Entity 装饰器
|
|
28
|
+
if (
|
|
29
|
+
node.decorators &&
|
|
30
|
+
node.decorators.some(
|
|
31
|
+
(decorator) => decorator.expression.callee.name === "Entity",
|
|
32
|
+
)
|
|
33
|
+
) {
|
|
34
|
+
// 遍历类属性
|
|
35
|
+
node.body.body.forEach((property) => {
|
|
36
|
+
// 检查是否有 @Property、@ManyToOne 或 @PrimaryKey 装饰器
|
|
37
|
+
if (
|
|
38
|
+
property.type === "PropertyDefinition" &&
|
|
39
|
+
property.decorators &&
|
|
40
|
+
property.decorators.some((decorator) => {
|
|
41
|
+
return ["Property", "ManyToOne", "PrimaryKey"].includes(
|
|
42
|
+
decorator.expression.callee.name,
|
|
43
|
+
);
|
|
44
|
+
})
|
|
45
|
+
) {
|
|
46
|
+
if (property.optional || property.definite) {
|
|
47
|
+
context.report({
|
|
48
|
+
node: property,
|
|
49
|
+
message: "实体属性不能有 ? 或 ! 断言。",
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 实体字段可为空时属性类型
|
|
3
|
+
* @author 实体字段可为空时属性类型
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Rule Definition
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
/** @type {import('eslint').Rule.RuleModule} */
|
|
12
|
+
module.exports = {
|
|
13
|
+
meta: {
|
|
14
|
+
type: null, // `problem`, `suggestion`, or `layout`
|
|
15
|
+
docs: {
|
|
16
|
+
description: "实体字段可为空时属性类型",
|
|
17
|
+
recommended: false,
|
|
18
|
+
url: null, // URL to the documentation page for this rule
|
|
19
|
+
},
|
|
20
|
+
fixable: null, // Or `code` or `whitespace`
|
|
21
|
+
schema: [], // Add a schema if the rule has options
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
create(context) {
|
|
25
|
+
// variables should be defined here
|
|
26
|
+
|
|
27
|
+
//----------------------------------------------------------------------
|
|
28
|
+
// Helpers
|
|
29
|
+
//----------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
// any helper functions should go here or else delete this section
|
|
32
|
+
|
|
33
|
+
//----------------------------------------------------------------------
|
|
34
|
+
// Public
|
|
35
|
+
//----------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
ClassDeclaration(node) {
|
|
39
|
+
// 检查是否有 @Entity 装饰器
|
|
40
|
+
if (
|
|
41
|
+
node.decorators &&
|
|
42
|
+
node.decorators.some(
|
|
43
|
+
(decorator) => decorator.expression.callee.name === "Entity",
|
|
44
|
+
)
|
|
45
|
+
) {
|
|
46
|
+
// 遍历类属性
|
|
47
|
+
node.body.body.forEach((property) => {
|
|
48
|
+
// 检查是否有 @Property 装饰器
|
|
49
|
+
if (property.type === "PropertyDefinition" && property.decorators) {
|
|
50
|
+
const propertyDecorator = property.decorators.find(
|
|
51
|
+
(decorator) => decorator.expression.callee.name === "Property",
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
// 检查是否有 @Property(nullable: true) 装饰器
|
|
55
|
+
if (
|
|
56
|
+
propertyDecorator &&
|
|
57
|
+
propertyDecorator.expression.arguments[0] &&
|
|
58
|
+
propertyDecorator.expression.arguments[0].properties &&
|
|
59
|
+
propertyDecorator.expression.arguments[0].properties.some(
|
|
60
|
+
(prop) =>
|
|
61
|
+
prop.key.name === "nullable" &&
|
|
62
|
+
prop.value.type === "Literal" &&
|
|
63
|
+
prop.value.value === true,
|
|
64
|
+
)
|
|
65
|
+
) {
|
|
66
|
+
// 检查属性类型是否包含 null
|
|
67
|
+
if (
|
|
68
|
+
!property.typeAnnotation ||
|
|
69
|
+
property.typeAnnotation.typeAnnotation.type !==
|
|
70
|
+
"TSUnionType" ||
|
|
71
|
+
!property.typeAnnotation.typeAnnotation.types.some(
|
|
72
|
+
(type) => type.type === "TSNullKeyword",
|
|
73
|
+
)
|
|
74
|
+
) {
|
|
75
|
+
context.report({
|
|
76
|
+
node: property,
|
|
77
|
+
message:
|
|
78
|
+
"@Property({ nullable: true }) 属性类型需包含 null。",
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nest-boot/eslint-plugin",
|
|
3
|
+
"version": "5.1.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"main": "./lib/index.js",
|
|
6
|
+
"exports": "./lib/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"lint": "npm-run-all \"lint:*\"",
|
|
9
|
+
"lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
|
|
10
|
+
"lint:js": "eslint .",
|
|
11
|
+
"test": "mocha tests --recursive",
|
|
12
|
+
"update:eslint-docs": "eslint-doc-generator"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"requireindex": "^1.2.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"eslint": "^8.19.0",
|
|
19
|
+
"eslint-doc-generator": "^1.0.0",
|
|
20
|
+
"eslint-plugin-eslint-plugin": "^5.0.0",
|
|
21
|
+
"eslint-plugin-node": "^11.1.0",
|
|
22
|
+
"mocha": "^10.0.0",
|
|
23
|
+
"npm-run-all": "^4.1.5"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"eslint": "^8.0.0"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"volta": {
|
|
32
|
+
"extends": "../../package.json"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 实体字段不能使用可选属性和非空断言
|
|
3
|
+
* @author 实体字段不能使用可选属性和非空断言
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const rule = require("../../../lib/rules/entity-property-no-optional-or-non-null-assertion"),
|
|
12
|
+
RuleTester = require("eslint").RuleTester;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
//------------------------------------------------------------------------------
|
|
16
|
+
// Tests
|
|
17
|
+
//------------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
const ruleTester = new RuleTester();
|
|
20
|
+
ruleTester.run("entity-property-no-optional-or-non-null-assertion", rule, {
|
|
21
|
+
valid: [
|
|
22
|
+
// give me some code that won't trigger a warning
|
|
23
|
+
],
|
|
24
|
+
|
|
25
|
+
invalid: [
|
|
26
|
+
{
|
|
27
|
+
code: "",
|
|
28
|
+
errors: [{ message: "Fill me in.", type: "Me too" }],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 实体字段可为空时属性类型
|
|
3
|
+
* @author 实体字段可为空时属性类型需要包含 null
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const rule = require("../../../lib/rules/entity-property-nullable-type"),
|
|
12
|
+
RuleTester = require("eslint").RuleTester;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
//------------------------------------------------------------------------------
|
|
16
|
+
// Tests
|
|
17
|
+
//------------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
const ruleTester = new RuleTester();
|
|
20
|
+
ruleTester.run("entity-property-nullable-type", rule, {
|
|
21
|
+
valid: [
|
|
22
|
+
// give me some code that won't trigger a warning
|
|
23
|
+
],
|
|
24
|
+
|
|
25
|
+
invalid: [
|
|
26
|
+
{
|
|
27
|
+
code: "",
|
|
28
|
+
errors: [{ message: "Fill me in.", type: "Me too" }],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
});
|