@nest-boot/eslint-plugin 7.0.0-beta.0 → 7.0.0-beta.2

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 (80) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/CHANGELOG.md +2 -14
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +2 -5
  5. package/dist/index.js.map +1 -1
  6. package/dist/rules/graphql/graphql-field-config-from-types.d.ts +6 -0
  7. package/dist/rules/graphql/graphql-field-config-from-types.js +417 -0
  8. package/dist/rules/graphql/graphql-field-config-from-types.js.map +1 -0
  9. package/dist/rules/graphql/graphql-field-definite-assignment.d.ts +2 -0
  10. package/dist/rules/graphql/graphql-field-definite-assignment.js +125 -0
  11. package/dist/rules/graphql/graphql-field-definite-assignment.js.map +1 -0
  12. package/dist/rules/import/import-bullmq.d.ts +2 -0
  13. package/dist/rules/import/import-bullmq.js +36 -0
  14. package/dist/rules/import/import-bullmq.js.map +1 -0
  15. package/dist/rules/import/import-graphql.d.ts +2 -0
  16. package/dist/rules/import/import-graphql.js +36 -0
  17. package/dist/rules/import/import-graphql.js.map +1 -0
  18. package/dist/rules/import/import-mikro-orm.d.ts +2 -0
  19. package/dist/rules/import/import-mikro-orm.js +36 -0
  20. package/dist/rules/import/import-mikro-orm.js.map +1 -0
  21. package/dist/rules/index.d.ts +9 -0
  22. package/dist/rules/index.js +16 -11
  23. package/dist/rules/index.js.map +1 -1
  24. package/dist/rules/mikro-orm/entity-field-definite-assignment.d.ts +2 -0
  25. package/dist/rules/mikro-orm/entity-field-definite-assignment.js +125 -0
  26. package/dist/rules/mikro-orm/entity-field-definite-assignment.js.map +1 -0
  27. package/dist/rules/mikro-orm/entity-property-config-from-types.d.ts +3 -0
  28. package/dist/rules/mikro-orm/entity-property-config-from-types.js +881 -0
  29. package/dist/rules/mikro-orm/entity-property-config-from-types.js.map +1 -0
  30. package/dist/tsconfig.build.tsbuildinfo +1 -0
  31. package/dist/utils/createRule.d.ts +2 -0
  32. package/dist/utils/createRule.js +1 -1
  33. package/dist/utils/createRule.js.map +1 -1
  34. package/dist/utils/decorators.d.ts +29 -0
  35. package/dist/utils/decorators.js +74 -0
  36. package/dist/utils/decorators.js.map +1 -0
  37. package/dist/utils/tester.d.ts +2 -0
  38. package/dist/utils/tester.js +27 -0
  39. package/dist/utils/tester.js.map +1 -0
  40. package/eslint.config.mjs +38 -2
  41. package/jest.config.ts +12 -0
  42. package/package.json +22 -14
  43. package/src/index.ts +1 -1
  44. package/src/rules/graphql/graphql-field-config-from-types.spec.ts +242 -0
  45. package/src/rules/graphql/graphql-field-config-from-types.ts +557 -0
  46. package/src/rules/graphql/graphql-field-definite-assignment.spec.ts +135 -0
  47. package/src/rules/graphql/graphql-field-definite-assignment.ts +147 -0
  48. package/src/rules/import/import-bullmq.spec.ts +69 -0
  49. package/src/rules/import/import-bullmq.ts +35 -0
  50. package/src/rules/import/import-graphql.spec.ts +65 -0
  51. package/src/rules/import/import-graphql.ts +36 -0
  52. package/src/rules/import/import-mikro-orm.spec.ts +65 -0
  53. package/src/rules/import/import-mikro-orm.ts +36 -0
  54. package/src/rules/index.ts +15 -13
  55. package/src/rules/mikro-orm/entity-field-definite-assignment.spec.ts +91 -0
  56. package/src/rules/mikro-orm/entity-field-definite-assignment.ts +141 -0
  57. package/src/rules/mikro-orm/entity-property-config-from-types.spec.ts +262 -0
  58. package/src/rules/mikro-orm/entity-property-config-from-types.ts +1111 -0
  59. package/src/utils/createRule.ts +3 -1
  60. package/src/utils/decorators.spec.ts +214 -0
  61. package/src/utils/decorators.ts +93 -0
  62. package/src/utils/tester.ts +22 -0
  63. package/tsconfig.build.json +5 -0
  64. package/tsconfig.json +6 -7
  65. package/dist/rules/entity-constructor.js +0 -78
  66. package/dist/rules/entity-constructor.js.map +0 -1
  67. package/dist/rules/entity-property-no-optional-or-non-null-assertion.js +0 -63
  68. package/dist/rules/entity-property-no-optional-or-non-null-assertion.js.map +0 -1
  69. package/dist/rules/entity-property-nullable.js +0 -81
  70. package/dist/rules/entity-property-nullable.js.map +0 -1
  71. package/dist/rules/graphql-field-arguments-match-property-type.js +0 -118
  72. package/dist/rules/graphql-field-arguments-match-property-type.js.map +0 -1
  73. package/dist/rules/graphql-resolver-method-return-type.js +0 -145
  74. package/dist/rules/graphql-resolver-method-return-type.js.map +0 -1
  75. package/dist/tsconfig.tsbuildinfo +0 -1
  76. package/src/rules/entity-constructor.ts +0 -97
  77. package/src/rules/entity-property-no-optional-or-non-null-assertion.ts +0 -81
  78. package/src/rules/entity-property-nullable.ts +0 -112
  79. package/src/rules/graphql-field-arguments-match-property-type.ts +0 -186
  80. package/src/rules/graphql-resolver-method-return-type.ts +0 -207
@@ -1,3 +1,5 @@
1
1
  import { ESLintUtils } from "@typescript-eslint/utils";
2
2
 
3
- export const createRule = ESLintUtils.RuleCreator.withoutDocs;
3
+ export const createRule = ESLintUtils.RuleCreator(
4
+ (name) => `https://example.com/eslint/rules/${name}`,
5
+ );
@@ -0,0 +1,214 @@
1
+ import { describe, expect, it } from "@jest/globals";
2
+ import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
3
+
4
+ import {
5
+ getClassDecorator,
6
+ getPropertyDecorator,
7
+ hasClassDecorator,
8
+ hasPropertyDecorator,
9
+ } from "./decorators";
10
+
11
+ describe("decorators", () => {
12
+ describe("hasClassDecorator", () => {
13
+ it("should return true when class has the specified decorator", () => {
14
+ const classDeclaration: TSESTree.ClassDeclaration = {
15
+ type: AST_NODE_TYPES.ClassDeclaration,
16
+ decorators: [
17
+ {
18
+ type: AST_NODE_TYPES.Decorator,
19
+ expression: {
20
+ type: AST_NODE_TYPES.CallExpression,
21
+ callee: {
22
+ type: AST_NODE_TYPES.Identifier,
23
+ name: "Entity",
24
+ },
25
+ },
26
+ } as TSESTree.Decorator,
27
+ ],
28
+ } as TSESTree.ClassDeclaration;
29
+
30
+ expect(hasClassDecorator(classDeclaration, "Entity")).toBe(true);
31
+ });
32
+
33
+ it("should return true when class has one of the specified decorators", () => {
34
+ const classDeclaration: TSESTree.ClassDeclaration = {
35
+ type: AST_NODE_TYPES.ClassDeclaration,
36
+ decorators: [
37
+ {
38
+ type: AST_NODE_TYPES.Decorator,
39
+ expression: {
40
+ type: AST_NODE_TYPES.CallExpression,
41
+ callee: {
42
+ type: AST_NODE_TYPES.Identifier,
43
+ name: "ObjectType",
44
+ },
45
+ },
46
+ } as TSESTree.Decorator,
47
+ ],
48
+ } as TSESTree.ClassDeclaration;
49
+
50
+ expect(
51
+ hasClassDecorator(classDeclaration, [
52
+ "ObjectType",
53
+ "InputType",
54
+ "ArgsType",
55
+ ]),
56
+ ).toBe(true);
57
+ });
58
+
59
+ it("should return false when class does not have the specified decorator", () => {
60
+ const classDeclaration: TSESTree.ClassDeclaration = {
61
+ type: AST_NODE_TYPES.ClassDeclaration,
62
+ decorators: [
63
+ {
64
+ type: AST_NODE_TYPES.Decorator,
65
+ expression: {
66
+ type: AST_NODE_TYPES.CallExpression,
67
+ callee: {
68
+ type: AST_NODE_TYPES.Identifier,
69
+ name: "SomeOtherDecorator",
70
+ },
71
+ },
72
+ } as TSESTree.Decorator,
73
+ ],
74
+ } as TSESTree.ClassDeclaration;
75
+
76
+ expect(hasClassDecorator(classDeclaration, "Entity")).toBe(false);
77
+ });
78
+
79
+ it("should return false when class has no decorators", () => {
80
+ const classDeclaration = {
81
+ type: AST_NODE_TYPES.ClassDeclaration,
82
+ decorators: [],
83
+ } as unknown as TSESTree.ClassDeclaration;
84
+
85
+ expect(hasClassDecorator(classDeclaration, "Entity")).toBe(false);
86
+ });
87
+ });
88
+
89
+ describe("hasPropertyDecorator", () => {
90
+ it("should return true when property has the specified decorator", () => {
91
+ const propertyDefinition: TSESTree.PropertyDefinition = {
92
+ type: AST_NODE_TYPES.PropertyDefinition,
93
+ decorators: [
94
+ {
95
+ type: AST_NODE_TYPES.Decorator,
96
+ expression: {
97
+ type: AST_NODE_TYPES.CallExpression,
98
+ callee: {
99
+ type: AST_NODE_TYPES.Identifier,
100
+ name: "Field",
101
+ },
102
+ },
103
+ } as TSESTree.Decorator,
104
+ ],
105
+ } as TSESTree.PropertyDefinition;
106
+
107
+ expect(hasPropertyDecorator(propertyDefinition, "Field")).toBe(true);
108
+ });
109
+
110
+ it("should return true when property has one of the specified decorators", () => {
111
+ const propertyDefinition: TSESTree.PropertyDefinition = {
112
+ type: AST_NODE_TYPES.PropertyDefinition,
113
+ decorators: [
114
+ {
115
+ type: AST_NODE_TYPES.Decorator,
116
+ expression: {
117
+ type: AST_NODE_TYPES.CallExpression,
118
+ callee: {
119
+ type: AST_NODE_TYPES.Identifier,
120
+ name: "Property",
121
+ },
122
+ },
123
+ } as TSESTree.Decorator,
124
+ ],
125
+ } as TSESTree.PropertyDefinition;
126
+
127
+ expect(
128
+ hasPropertyDecorator(propertyDefinition, ["Property", "Field"]),
129
+ ).toBe(true);
130
+ });
131
+
132
+ it("should return false when property does not have the specified decorator", () => {
133
+ const propertyDefinition: TSESTree.PropertyDefinition = {
134
+ type: AST_NODE_TYPES.PropertyDefinition,
135
+ decorators: [
136
+ {
137
+ type: AST_NODE_TYPES.Decorator,
138
+ expression: {
139
+ type: AST_NODE_TYPES.CallExpression,
140
+ callee: {
141
+ type: AST_NODE_TYPES.Identifier,
142
+ name: "SomeOtherDecorator",
143
+ },
144
+ },
145
+ } as TSESTree.Decorator,
146
+ ],
147
+ } as TSESTree.PropertyDefinition;
148
+
149
+ expect(hasPropertyDecorator(propertyDefinition, "Field")).toBe(false);
150
+ });
151
+ });
152
+
153
+ describe("getClassDecorator", () => {
154
+ it("should return the decorator when class has it", () => {
155
+ const decorator: TSESTree.Decorator = {
156
+ type: AST_NODE_TYPES.Decorator,
157
+ expression: {
158
+ type: AST_NODE_TYPES.CallExpression,
159
+ callee: {
160
+ type: AST_NODE_TYPES.Identifier,
161
+ name: "Entity",
162
+ },
163
+ },
164
+ } as TSESTree.Decorator;
165
+
166
+ const classDeclaration: TSESTree.ClassDeclaration = {
167
+ type: AST_NODE_TYPES.ClassDeclaration,
168
+ decorators: [decorator],
169
+ } as TSESTree.ClassDeclaration;
170
+
171
+ expect(getClassDecorator(classDeclaration, "Entity")).toBe(decorator);
172
+ });
173
+
174
+ it("should return null when class does not have the decorator", () => {
175
+ const classDeclaration = {
176
+ type: AST_NODE_TYPES.ClassDeclaration,
177
+ decorators: [],
178
+ } as unknown as TSESTree.ClassDeclaration;
179
+
180
+ expect(getClassDecorator(classDeclaration, "Entity")).toBeNull();
181
+ });
182
+ });
183
+
184
+ describe("getPropertyDecorator", () => {
185
+ it("should return the decorator when property has it", () => {
186
+ const decorator: TSESTree.Decorator = {
187
+ type: AST_NODE_TYPES.Decorator,
188
+ expression: {
189
+ type: AST_NODE_TYPES.CallExpression,
190
+ callee: {
191
+ type: AST_NODE_TYPES.Identifier,
192
+ name: "Field",
193
+ },
194
+ },
195
+ } as TSESTree.Decorator;
196
+
197
+ const propertyDefinition: TSESTree.PropertyDefinition = {
198
+ type: AST_NODE_TYPES.PropertyDefinition,
199
+ decorators: [decorator],
200
+ } as TSESTree.PropertyDefinition;
201
+
202
+ expect(getPropertyDecorator(propertyDefinition, "Field")).toBe(decorator);
203
+ });
204
+
205
+ it("should return null when property does not have the decorator", () => {
206
+ const propertyDefinition = {
207
+ type: AST_NODE_TYPES.PropertyDefinition,
208
+ decorators: [],
209
+ } as unknown as TSESTree.PropertyDefinition;
210
+
211
+ expect(getPropertyDecorator(propertyDefinition, "Field")).toBeNull();
212
+ });
213
+ });
214
+ });
@@ -0,0 +1,93 @@
1
+ import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
2
+
3
+ /**
4
+ * 检查类是否有指定的装饰器
5
+ * @param classDeclaration 类声明节点
6
+ * @param decoratorNames 装饰器名称(可以是字符串或字符串数组)
7
+ * @returns 是否有指定的装饰器
8
+ */
9
+ export function hasClassDecorator(
10
+ classDeclaration: TSESTree.ClassDeclaration,
11
+ decoratorNames: string | string[],
12
+ ): boolean {
13
+ const names = Array.isArray(decoratorNames)
14
+ ? decoratorNames
15
+ : [decoratorNames];
16
+
17
+ return classDeclaration.decorators.some((decorator: TSESTree.Decorator) => {
18
+ if (decorator.expression.type !== AST_NODE_TYPES.CallExpression) {
19
+ return false;
20
+ }
21
+ if (decorator.expression.callee.type !== AST_NODE_TYPES.Identifier) {
22
+ return false;
23
+ }
24
+ return names.includes(decorator.expression.callee.name);
25
+ });
26
+ }
27
+
28
+ /**
29
+ * 检查属性是否有指定的装饰器
30
+ * @param propertyDefinition 属性定义节点
31
+ * @param decoratorNames 装饰器名称(可以是字符串或字符串数组)
32
+ * @returns 是否有指定的装饰器
33
+ */
34
+ export function hasPropertyDecorator(
35
+ propertyDefinition: TSESTree.PropertyDefinition,
36
+ decoratorNames: string | string[],
37
+ ): boolean {
38
+ const names = Array.isArray(decoratorNames)
39
+ ? decoratorNames
40
+ : [decoratorNames];
41
+
42
+ return propertyDefinition.decorators.some((decorator: TSESTree.Decorator) => {
43
+ if (decorator.expression.type !== AST_NODE_TYPES.CallExpression) {
44
+ return false;
45
+ }
46
+ if (decorator.expression.callee.type !== AST_NODE_TYPES.Identifier) {
47
+ return false;
48
+ }
49
+ return names.includes(decorator.expression.callee.name);
50
+ });
51
+ }
52
+
53
+ /**
54
+ * 获取类的装饰器
55
+ * @param classDeclaration 类声明节点
56
+ * @param decoratorName 装饰器名称
57
+ * @returns 装饰器节点,如果不存在则返回 null
58
+ */
59
+ export function getClassDecorator(
60
+ classDeclaration: TSESTree.ClassDeclaration,
61
+ decoratorName: string,
62
+ ): TSESTree.Decorator | null {
63
+ return (
64
+ classDeclaration.decorators.find((decorator: TSESTree.Decorator) => {
65
+ return (
66
+ decorator.expression.type === AST_NODE_TYPES.CallExpression &&
67
+ decorator.expression.callee.type === AST_NODE_TYPES.Identifier &&
68
+ decorator.expression.callee.name === decoratorName
69
+ );
70
+ }) ?? null
71
+ );
72
+ }
73
+
74
+ /**
75
+ * 获取属性的装饰器
76
+ * @param propertyDefinition 属性定义节点
77
+ * @param decoratorName 装饰器名称
78
+ * @returns 装饰器节点,如果不存在则返回 null
79
+ */
80
+ export function getPropertyDecorator(
81
+ propertyDefinition: TSESTree.PropertyDefinition,
82
+ decoratorName: string,
83
+ ): TSESTree.Decorator | null {
84
+ return (
85
+ propertyDefinition.decorators.find((decorator: TSESTree.Decorator) => {
86
+ return (
87
+ decorator.expression.type === AST_NODE_TYPES.CallExpression &&
88
+ decorator.expression.callee.type === AST_NODE_TYPES.Identifier &&
89
+ decorator.expression.callee.name === decoratorName
90
+ );
91
+ }) ?? null
92
+ );
93
+ }
@@ -0,0 +1,22 @@
1
+ import { afterAll, describe, it } from "@jest/globals";
2
+ import parser from "@typescript-eslint/parser";
3
+ import { RuleTester } from "@typescript-eslint/rule-tester";
4
+ import path from "path";
5
+
6
+ RuleTester.afterAll = afterAll;
7
+ RuleTester.it = it;
8
+ RuleTester.itOnly = it.only;
9
+ RuleTester.describe = describe;
10
+
11
+ export const tester = new RuleTester({
12
+ languageOptions: {
13
+ parser,
14
+ parserOptions: {
15
+ projectService: {
16
+ allowDefaultProject: ["*.ts*"],
17
+ defaultProject: "tsconfig.json",
18
+ },
19
+ tsconfigRootDir: path.join(__dirname, "../.."),
20
+ },
21
+ },
22
+ });
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["src"],
4
+ "exclude": ["src/**/*.spec.ts"]
5
+ }
package/tsconfig.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "extends": "@nest-boot/tsconfig/library.json",
3
- "include": ["src"],
4
3
  "compilerOptions": {
5
4
  "module": "NodeNext",
6
5
  "moduleResolution": "NodeNext",
7
- "target": "ES2021",
8
- "lib": ["ES2021"],
9
- "outDir": "./dist",
10
- "declaration": false,
11
- "declarationMap": false,
12
- },
6
+ "baseUrl": ".",
7
+ "paths": {
8
+ "@/*": ["./src/*"]
9
+ },
10
+ "outDir": "./dist"
11
+ }
13
12
  }
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const utils_1 = require("@typescript-eslint/utils");
4
- const createRule_1 = require("../utils/createRule");
5
- exports.default = (0, createRule_1.createRule)({
6
- meta: {
7
- type: "problem",
8
- docs: {
9
- description: "没有默认值的实体字段需要在构造函数中初始化",
10
- },
11
- fixable: "code",
12
- schema: [],
13
- messages: {
14
- entityConstructor: "没有默认值的实体字段需要在构造函数中初始化",
15
- },
16
- },
17
- defaultOptions: [{}],
18
- create(context) {
19
- return {
20
- ClassDeclaration(node) {
21
- // 检查是否有 @Entity 装饰器
22
- if (node.id !== null &&
23
- node.decorators.some((decorator) => {
24
- return (decorator.expression.type === utils_1.AST_NODE_TYPES.CallExpression &&
25
- decorator.expression.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
26
- decorator.expression.callee.name === "Entity");
27
- })) {
28
- const constructor = node.body.body.find((method) => {
29
- return (method.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
30
- method.kind === "constructor");
31
- });
32
- if (typeof constructor === "undefined") {
33
- const propertyKeys = [];
34
- // 遍历类属性
35
- node.body.body.forEach((property) => {
36
- if (property.type === utils_1.AST_NODE_TYPES.PropertyDefinition &&
37
- property.key.type === utils_1.AST_NODE_TYPES.Identifier) {
38
- propertyKeys.push({
39
- name: property.key.name,
40
- required: property.value === null,
41
- });
42
- }
43
- });
44
- if (propertyKeys.length > 0) {
45
- context.report({
46
- node,
47
- messageId: "entityConstructor",
48
- fix(fixer) {
49
- const constructorCode = /* typescript */ `
50
- constructor(data: Pick<${node.id?.name}, ${propertyKeys
51
- .filter((key) => key.required)
52
- .map((key) => `"${key.name}"`)
53
- .join(` | `)}> & Partial<Pick<${node.id?.name}, ${propertyKeys
54
- .filter((key) => !key.required)
55
- .map((key) => `"${key.name}"`)
56
- .join(` | `)}>>) {
57
- ${propertyKeys
58
- .filter((key) => key.required)
59
- .map((key) => `this.${key.name} = data.${key.name};`)
60
- .join(`\n`)}
61
-
62
- ${propertyKeys
63
- .filter((key) => !key.required)
64
- .map((key) => `data.${key.name} !== void 0 && (this.${key.name} = data.${key.name});`)
65
- .join(`\n`)}
66
- }
67
- `;
68
- return fixer.insertTextBefore(node.body.body[0], constructorCode);
69
- },
70
- });
71
- }
72
- }
73
- }
74
- },
75
- };
76
- },
77
- });
78
- //# sourceMappingURL=entity-constructor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity-constructor.js","sourceRoot":"","sources":["../../src/rules/entity-constructor.ts"],"names":[],"mappings":"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"}
@@ -1,63 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const utils_1 = require("@typescript-eslint/utils");
4
- const createRule_1 = require("../utils/createRule");
5
- exports.default = (0, createRule_1.createRule)({
6
- meta: {
7
- type: "problem",
8
- docs: {
9
- description: "实体字段不能使用可选属性和非空断言",
10
- },
11
- fixable: "code",
12
- schema: [],
13
- messages: {
14
- entityPropertyNoOptionalOrNonNullAssertion: "实体字段不能使用可选属性和非空断言。",
15
- },
16
- },
17
- defaultOptions: [{}],
18
- create(context) {
19
- return {
20
- ClassDeclaration(node) {
21
- if (node.decorators.some((decorator) => {
22
- return (decorator.expression.type === utils_1.AST_NODE_TYPES.CallExpression &&
23
- decorator.expression.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
24
- decorator.expression.callee.name === "Entity");
25
- })) {
26
- // 遍历类属性
27
- node.body.body.forEach((property) => {
28
- // 检查是否有 @Property、@ManyToOne 或 @PrimaryKey 装饰器
29
- if (property.type === utils_1.AST_NODE_TYPES.PropertyDefinition &&
30
- property.decorators &&
31
- property.decorators.some((decorator) => {
32
- return (decorator.expression.type === utils_1.AST_NODE_TYPES.CallExpression &&
33
- decorator.expression.callee.type ===
34
- utils_1.AST_NODE_TYPES.Identifier &&
35
- ["Property", "ManyToOne", "PrimaryKey"].includes(decorator.expression.callee.name));
36
- })) {
37
- if (property.optional || property.definite) {
38
- context.report({
39
- node: property,
40
- messageId: "entityPropertyNoOptionalOrNonNullAssertion",
41
- fix: (fixer) => {
42
- const tokenBefore = context.sourceCode.getTokenBefore(property.key);
43
- const propertyStart = tokenBefore && tokenBefore.range[1] < property.range[0]
44
- ? tokenBefore.range[1]
45
- : property.range[0];
46
- const propertyEnd = property.range[1];
47
- // 从属性中移除 ? 或 ! 符号
48
- const fixedPropertyText = context.sourceCode
49
- .getText()
50
- .slice(propertyStart, propertyEnd)
51
- .replace(/\?|!/, "");
52
- return fixer.replaceTextRange([propertyStart, propertyEnd], fixedPropertyText);
53
- },
54
- });
55
- }
56
- }
57
- });
58
- }
59
- },
60
- };
61
- },
62
- });
63
- //# sourceMappingURL=entity-property-no-optional-or-non-null-assertion.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity-property-no-optional-or-non-null-assertion.js","sourceRoot":"","sources":["../../src/rules/entity-property-no-optional-or-non-null-assertion.ts"],"names":[],"mappings":";;AAAA,oDAA0D;AAE1D,oDAAiD;AAEjD,kBAAe,IAAA,uBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,mBAAmB;SACjC;QACD,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,0CAA0C,EACxC,oBAAoB;SACvB;KACF;IACD,cAAc,EAAE,CAAC,EAAE,CAAC;IACpB,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,gBAAgB,CAAC,IAAI;gBACnB,IACE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;oBACjC,OAAO,CACL,SAAS,CAAC,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,cAAc;wBAC3D,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,sBAAc,CAAC,UAAU;wBAC9D,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAC9C,CAAC;gBACJ,CAAC,CAAC,EACF,CAAC;oBACD,QAAQ;oBACR,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;wBAClC,+CAA+C;wBAC/C,IACE,QAAQ,CAAC,IAAI,KAAK,sBAAc,CAAC,kBAAkB;4BACnD,QAAQ,CAAC,UAAU;4BACnB,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;gCACrC,OAAO,CACL,SAAS,CAAC,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,cAAc;oCAC3D,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI;wCAC9B,sBAAc,CAAC,UAAU;oCAC3B,CAAC,UAAU,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,QAAQ,CAC9C,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CACjC,CACF,CAAC;4BACJ,CAAC,CAAC,EACF,CAAC;4BACD,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gCAC3C,OAAO,CAAC,MAAM,CAAC;oCACb,IAAI,EAAE,QAAQ;oCACd,SAAS,EAAE,4CAA4C;oCACvD,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;wCACb,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CACnD,QAAQ,CAAC,GAAG,CACb,CAAC;wCACF,MAAM,aAAa,GACjB,WAAW,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;4CACrD,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;4CACtB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wCACxB,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wCAEtC,kBAAkB;wCAClB,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU;6CACzC,OAAO,EAAE;6CACT,KAAK,CAAC,aAAa,EAAE,WAAW,CAAC;6CACjC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;wCAEvB,OAAO,KAAK,CAAC,gBAAgB,CAC3B,CAAC,aAAa,EAAE,WAAW,CAAC,EAC5B,iBAAiB,CAClB,CAAC;oCACJ,CAAC;iCACF,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -1,81 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const utils_1 = require("@typescript-eslint/utils");
4
- const createRule_1 = require("../utils/createRule");
5
- exports.default = (0, createRule_1.createRule)({
6
- meta: {
7
- type: "problem",
8
- docs: {
9
- description: "实体字段可为空时属性类型",
10
- },
11
- fixable: "code",
12
- schema: [],
13
- messages: {
14
- entityPropertyNullable: "@Property({ nullable: true }) 属性类型需包含 null。",
15
- },
16
- },
17
- defaultOptions: [{}],
18
- create(context) {
19
- return {
20
- ClassDeclaration(node) {
21
- // 检查是否有 @Entity 装饰器
22
- if (node.decorators.some((decorator) => {
23
- return (decorator.expression.type === utils_1.AST_NODE_TYPES.CallExpression &&
24
- decorator.expression.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
25
- decorator.expression.callee.name === "Entity");
26
- })) {
27
- // 遍历类属性
28
- node.body.body.forEach((property) => {
29
- // 检查是否有 @Property() 装饰器
30
- if (property.type === utils_1.AST_NODE_TYPES.PropertyDefinition) {
31
- const propertyDecorator = property.decorators.find((decorator) => {
32
- return (decorator.expression.type ===
33
- utils_1.AST_NODE_TYPES.CallExpression &&
34
- decorator.expression.callee.type ===
35
- utils_1.AST_NODE_TYPES.Identifier &&
36
- decorator.expression.callee.name === "Property");
37
- });
38
- if (typeof propertyDecorator === "undefined") {
39
- return;
40
- }
41
- // 检查 @Property() 装饰器 nullable 参数是否为 true
42
- if (propertyDecorator.expression.type ===
43
- utils_1.AST_NODE_TYPES.CallExpression &&
44
- propertyDecorator.expression.arguments[0]?.type ===
45
- utils_1.AST_NODE_TYPES.ObjectExpression &&
46
- propertyDecorator.expression.arguments[0]?.properties?.some((prop) => {
47
- return (prop.type === utils_1.AST_NODE_TYPES.Property &&
48
- prop.key.type === utils_1.AST_NODE_TYPES.Identifier &&
49
- prop.key.name === "nullable" &&
50
- prop.value.type === utils_1.AST_NODE_TYPES.Literal &&
51
- prop.value.value === true);
52
- })) {
53
- const typeAnnotation = property.typeAnnotation;
54
- if (typeof typeAnnotation === "undefined") {
55
- return;
56
- }
57
- // 检查属性类型是否包含 null
58
- if (!(typeAnnotation.type === utils_1.AST_NODE_TYPES.TSTypeAnnotation &&
59
- typeAnnotation.typeAnnotation.type ===
60
- utils_1.AST_NODE_TYPES.TSUnionType &&
61
- typeAnnotation.typeAnnotation.types.some((type) => type.type === utils_1.AST_NODE_TYPES.TSNullKeyword))) {
62
- context.report({
63
- node: property,
64
- messageId: "entityPropertyNullable",
65
- fix: (fixer) => {
66
- const typeAnnotationStart = typeAnnotation.range[0];
67
- const typeAnnotationEnd = typeAnnotation.range[1];
68
- const originalType = context.sourceCode.getText(typeAnnotation);
69
- return fixer.replaceTextRange([typeAnnotationStart, typeAnnotationEnd], `${originalType} | null${property.value ? "" : " = null"}`);
70
- },
71
- });
72
- }
73
- }
74
- }
75
- });
76
- }
77
- },
78
- };
79
- },
80
- });
81
- //# sourceMappingURL=entity-property-nullable.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity-property-nullable.js","sourceRoot":"","sources":["../../src/rules/entity-property-nullable.ts"],"names":[],"mappings":"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"}