@nest-boot/eslint-plugin 7.0.0-beta.1 → 7.0.0-beta.3
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/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +4 -16
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -6
- package/dist/index.js.map +1 -1
- package/dist/rules/graphql/graphql-field-config-from-types.d.ts +6 -0
- package/dist/rules/graphql/graphql-field-config-from-types.js +417 -0
- package/dist/rules/graphql/graphql-field-config-from-types.js.map +1 -0
- package/dist/rules/graphql/graphql-field-definite-assignment.d.ts +2 -0
- package/dist/rules/graphql/graphql-field-definite-assignment.js +125 -0
- package/dist/rules/graphql/graphql-field-definite-assignment.js.map +1 -0
- package/dist/rules/import/import-bullmq.d.ts +2 -0
- package/dist/rules/import/import-bullmq.js +36 -0
- package/dist/rules/import/import-bullmq.js.map +1 -0
- package/dist/rules/import/import-graphql.d.ts +2 -0
- package/dist/rules/import/import-graphql.js +36 -0
- package/dist/rules/import/import-graphql.js.map +1 -0
- package/dist/rules/import/import-mikro-orm.d.ts +2 -0
- package/dist/rules/import/import-mikro-orm.js +36 -0
- package/dist/rules/import/import-mikro-orm.js.map +1 -0
- package/dist/rules/index.d.ts +9 -0
- package/dist/rules/index.js +16 -11
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/mikro-orm/entity-field-definite-assignment.d.ts +2 -0
- package/dist/rules/mikro-orm/entity-field-definite-assignment.js +125 -0
- package/dist/rules/mikro-orm/entity-field-definite-assignment.js.map +1 -0
- package/dist/rules/mikro-orm/entity-property-config-from-types.d.ts +3 -0
- package/dist/rules/mikro-orm/entity-property-config-from-types.js +881 -0
- package/dist/rules/mikro-orm/entity-property-config-from-types.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/utils/createRule.d.ts +2 -0
- package/dist/utils/createRule.js +1 -1
- package/dist/utils/createRule.js.map +1 -1
- package/dist/utils/decorators.d.ts +29 -0
- package/dist/utils/decorators.js +74 -0
- package/dist/utils/decorators.js.map +1 -0
- package/dist/utils/tester.d.ts +2 -0
- package/dist/utils/tester.js +27 -0
- package/dist/utils/tester.js.map +1 -0
- package/eslint.config.mjs +28 -2
- package/jest.config.ts +12 -0
- package/package.json +22 -17
- package/src/index.ts +8 -2
- package/src/rules/graphql/graphql-field-config-from-types.spec.ts +242 -0
- package/src/rules/graphql/graphql-field-config-from-types.ts +557 -0
- package/src/rules/graphql/graphql-field-definite-assignment.spec.ts +135 -0
- package/src/rules/graphql/graphql-field-definite-assignment.ts +147 -0
- package/src/rules/import/import-bullmq.spec.ts +69 -0
- package/src/rules/import/import-bullmq.ts +35 -0
- package/src/rules/import/import-graphql.spec.ts +65 -0
- package/src/rules/import/import-graphql.ts +36 -0
- package/src/rules/import/import-mikro-orm.spec.ts +65 -0
- package/src/rules/import/import-mikro-orm.ts +36 -0
- package/src/rules/index.ts +15 -13
- package/src/rules/mikro-orm/entity-field-definite-assignment.spec.ts +91 -0
- package/src/rules/mikro-orm/entity-field-definite-assignment.ts +141 -0
- package/src/rules/mikro-orm/entity-property-config-from-types.spec.ts +262 -0
- package/src/rules/mikro-orm/entity-property-config-from-types.ts +1111 -0
- package/src/utils/createRule.ts +3 -1
- package/src/utils/decorators.spec.ts +214 -0
- package/src/utils/decorators.ts +93 -0
- package/src/utils/tester.ts +22 -0
- package/tsconfig.build.json +5 -0
- package/tsconfig.json +6 -7
- package/dist/rules/entity-constructor.js +0 -78
- package/dist/rules/entity-constructor.js.map +0 -1
- package/dist/rules/entity-property-no-optional-or-non-null-assertion.js +0 -63
- package/dist/rules/entity-property-no-optional-or-non-null-assertion.js.map +0 -1
- package/dist/rules/entity-property-nullable.js +0 -81
- package/dist/rules/entity-property-nullable.js.map +0 -1
- package/dist/rules/graphql-field-arguments-match-property-type.js +0 -118
- package/dist/rules/graphql-field-arguments-match-property-type.js.map +0 -1
- package/dist/rules/graphql-resolver-method-return-type.js +0 -145
- package/dist/rules/graphql-resolver-method-return-type.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/rules/entity-constructor.ts +0 -97
- package/src/rules/entity-property-no-optional-or-non-null-assertion.ts +0 -81
- package/src/rules/entity-property-nullable.ts +0 -112
- package/src/rules/graphql-field-arguments-match-property-type.ts +0 -186
- package/src/rules/graphql-resolver-method-return-type.ts +0 -207
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
|
|
3
|
+
import { createRule } from "../../utils/createRule";
|
|
4
|
+
import {
|
|
5
|
+
hasClassDecorator,
|
|
6
|
+
hasPropertyDecorator,
|
|
7
|
+
} from "../../utils/decorators";
|
|
8
|
+
|
|
9
|
+
export default createRule<
|
|
10
|
+
[],
|
|
11
|
+
"addDefiniteAssignment" | "removeDefiniteAssignment"
|
|
12
|
+
>({
|
|
13
|
+
name: "graphql-field-definite-assignment",
|
|
14
|
+
meta: {
|
|
15
|
+
type: "problem",
|
|
16
|
+
docs: {
|
|
17
|
+
description:
|
|
18
|
+
"确保 GraphQL @Field 装饰器的属性正确使用 definite assignment assertion (!)。没有初始化值的属性应添加 !,有初始化值的属性应移除 !。",
|
|
19
|
+
},
|
|
20
|
+
fixable: "code",
|
|
21
|
+
schema: [],
|
|
22
|
+
messages: {
|
|
23
|
+
addDefiniteAssignment:
|
|
24
|
+
"属性 '{{propertyName}}' 使用了 @Field 装饰器但没有初始化值,应添加 definite assignment assertion (!)。",
|
|
25
|
+
removeDefiniteAssignment:
|
|
26
|
+
"属性 '{{propertyName}}' 使用了 @Field 装饰器且有初始化值,应移除 definite assignment assertion (!)。",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
defaultOptions: [],
|
|
30
|
+
create(context) {
|
|
31
|
+
const source = context.sourceCode;
|
|
32
|
+
|
|
33
|
+
const isGraphqlModelClass = (node: TSESTree.ClassDeclaration): boolean => {
|
|
34
|
+
return hasClassDecorator(node, ["ObjectType", "InputType", "ArgsType"]);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const getPropertyName = (
|
|
38
|
+
member: TSESTree.PropertyDefinition,
|
|
39
|
+
): string | null => {
|
|
40
|
+
if (member.key.type === AST_NODE_TYPES.Identifier) {
|
|
41
|
+
return member.key.name;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const hasInitializer = (member: TSESTree.PropertyDefinition): boolean => {
|
|
47
|
+
return !!member.value;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const hasDefiniteAssignment = (
|
|
51
|
+
member: TSESTree.PropertyDefinition,
|
|
52
|
+
): boolean => {
|
|
53
|
+
return member.definite;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const isOptionalProperty = (
|
|
57
|
+
member: TSESTree.PropertyDefinition,
|
|
58
|
+
): boolean => {
|
|
59
|
+
// 检查 AST 节点的 optional 标记
|
|
60
|
+
if (member.optional) return true;
|
|
61
|
+
|
|
62
|
+
// 检查源代码中是否有 ? 符号(在属性名和冒号之间)
|
|
63
|
+
const keyEnd = member.key.range[1];
|
|
64
|
+
const text = source.text;
|
|
65
|
+
for (let i = keyEnd; i < member.range[1]; i++) {
|
|
66
|
+
if (text[i] === "?") return true;
|
|
67
|
+
if (text[i] === ":" || text[i] === "!") break;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return false;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
ClassDeclaration(node) {
|
|
75
|
+
if (!isGraphqlModelClass(node)) return;
|
|
76
|
+
|
|
77
|
+
node.body.body.forEach((member: TSESTree.ClassElement) => {
|
|
78
|
+
if (member.type !== AST_NODE_TYPES.PropertyDefinition) return;
|
|
79
|
+
if (!hasPropertyDecorator(member, "Field")) return;
|
|
80
|
+
|
|
81
|
+
const propertyName = getPropertyName(member);
|
|
82
|
+
if (!propertyName) return;
|
|
83
|
+
|
|
84
|
+
// 可选属性(?:)不需要 definite assignment assertion
|
|
85
|
+
if (isOptionalProperty(member)) return;
|
|
86
|
+
|
|
87
|
+
const hasInit = hasInitializer(member);
|
|
88
|
+
const hasDefinite = hasDefiniteAssignment(member);
|
|
89
|
+
|
|
90
|
+
// 情况1: 没有初始化值,但也没有 definite assignment assertion
|
|
91
|
+
if (!hasInit && !hasDefinite) {
|
|
92
|
+
context.report({
|
|
93
|
+
node: member,
|
|
94
|
+
messageId: "addDefiniteAssignment",
|
|
95
|
+
data: {
|
|
96
|
+
propertyName,
|
|
97
|
+
},
|
|
98
|
+
fix: (fixer) => {
|
|
99
|
+
// 找到属性名称的结束位置
|
|
100
|
+
const keyEnd = member.key.range[1];
|
|
101
|
+
// 在属性名称后添加 !
|
|
102
|
+
return fixer.insertTextAfterRange([keyEnd, keyEnd], "!");
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 情况2: 有初始化值,但也有 definite assignment assertion
|
|
108
|
+
if (hasInit && hasDefinite) {
|
|
109
|
+
context.report({
|
|
110
|
+
node: member,
|
|
111
|
+
messageId: "removeDefiniteAssignment",
|
|
112
|
+
data: {
|
|
113
|
+
propertyName,
|
|
114
|
+
},
|
|
115
|
+
fix: (fixer) => {
|
|
116
|
+
// 找到 ! 的位置并移除
|
|
117
|
+
const keyEnd = member.key.range[1];
|
|
118
|
+
const text = source.text;
|
|
119
|
+
|
|
120
|
+
// 查找 ! 的位置(在属性名称和冒号之间)
|
|
121
|
+
let exclamationPos = -1;
|
|
122
|
+
for (let i = keyEnd; i < member.range[1]; i++) {
|
|
123
|
+
if (text[i] === "!") {
|
|
124
|
+
exclamationPos = i;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
// 如果遇到冒号,说明没有 !
|
|
128
|
+
if (text[i] === ":") {
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (exclamationPos !== -1) {
|
|
134
|
+
return fixer.removeRange([
|
|
135
|
+
exclamationPos,
|
|
136
|
+
exclamationPos + 1,
|
|
137
|
+
]);
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { tester } from "../../utils/tester";
|
|
2
|
+
import rule from "./import-bullmq";
|
|
3
|
+
|
|
4
|
+
tester.run("import-bullmq", rule, {
|
|
5
|
+
valid: [
|
|
6
|
+
// 正确的导入来源
|
|
7
|
+
/* typescript */ `
|
|
8
|
+
import { BullModule } from "@nest-boot/bullmq";
|
|
9
|
+
`,
|
|
10
|
+
// 从其他包导入
|
|
11
|
+
/* typescript */ `
|
|
12
|
+
import { Module } from "@nestjs/common";
|
|
13
|
+
`,
|
|
14
|
+
// 命名导入
|
|
15
|
+
/* typescript */ `
|
|
16
|
+
import { InjectQueue, Processor } from "@nest-boot/bullmq";
|
|
17
|
+
`,
|
|
18
|
+
// 默认导入
|
|
19
|
+
/* typescript */ `
|
|
20
|
+
import BullMQ from "@nest-boot/bullmq";
|
|
21
|
+
`,
|
|
22
|
+
// 从 bullmq 核心包导入(不应该被替换)
|
|
23
|
+
/* typescript */ `
|
|
24
|
+
import { Queue, Worker } from "bullmq";
|
|
25
|
+
`,
|
|
26
|
+
],
|
|
27
|
+
invalid: [
|
|
28
|
+
// 从 @nestjs/bullmq 导入,应该替换为 @nest-boot/bullmq
|
|
29
|
+
{
|
|
30
|
+
code: /* typescript */ `
|
|
31
|
+
import { BullModule } from "@nestjs/bullmq";
|
|
32
|
+
`,
|
|
33
|
+
output: /* typescript */ `
|
|
34
|
+
import { BullModule } from "@nest-boot/bullmq";
|
|
35
|
+
`,
|
|
36
|
+
errors: [{ messageId: "replaceBullmqImport" }],
|
|
37
|
+
},
|
|
38
|
+
// Processor 相关导入
|
|
39
|
+
{
|
|
40
|
+
code: /* typescript */ `
|
|
41
|
+
import { Processor, InjectQueue } from "@nestjs/bullmq";
|
|
42
|
+
`,
|
|
43
|
+
output: /* typescript */ `
|
|
44
|
+
import { Processor, InjectQueue } from "@nest-boot/bullmq";
|
|
45
|
+
`,
|
|
46
|
+
errors: [{ messageId: "replaceBullmqImport" }],
|
|
47
|
+
},
|
|
48
|
+
// 类型导入
|
|
49
|
+
{
|
|
50
|
+
code: /* typescript */ `
|
|
51
|
+
import type { BullModuleOptions } from "@nestjs/bullmq";
|
|
52
|
+
`,
|
|
53
|
+
output: /* typescript */ `
|
|
54
|
+
import type { BullModuleOptions } from "@nest-boot/bullmq";
|
|
55
|
+
`,
|
|
56
|
+
errors: [{ messageId: "replaceBullmqImport" }],
|
|
57
|
+
},
|
|
58
|
+
// 装饰器导入
|
|
59
|
+
{
|
|
60
|
+
code: /* typescript */ `
|
|
61
|
+
import { OnQueueActive, OnQueueCompleted } from "@nestjs/bullmq";
|
|
62
|
+
`,
|
|
63
|
+
output: /* typescript */ `
|
|
64
|
+
import { OnQueueActive, OnQueueCompleted } from "@nest-boot/bullmq";
|
|
65
|
+
`,
|
|
66
|
+
errors: [{ messageId: "replaceBullmqImport" }],
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createRule } from "../../utils/createRule";
|
|
2
|
+
|
|
3
|
+
export default createRule({
|
|
4
|
+
name: "import-bullmq",
|
|
5
|
+
meta: {
|
|
6
|
+
type: "problem",
|
|
7
|
+
docs: {
|
|
8
|
+
description:
|
|
9
|
+
"将从 @nestjs/bullmq 导入的包修复为从 @nest-boot/bullmq 导入",
|
|
10
|
+
},
|
|
11
|
+
fixable: "code",
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
replaceBullmqImport: "应从 @nest-boot/bullmq 导入,而不是 @nestjs/bullmq",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultOptions: [],
|
|
18
|
+
create(context) {
|
|
19
|
+
return {
|
|
20
|
+
ImportDeclaration(node) {
|
|
21
|
+
// 检查是否从 @nestjs/bullmq 导入
|
|
22
|
+
if (node.source.value === "@nestjs/bullmq") {
|
|
23
|
+
context.report({
|
|
24
|
+
node,
|
|
25
|
+
messageId: "replaceBullmqImport",
|
|
26
|
+
fix(fixer) {
|
|
27
|
+
// 将导入源替换为 @nest-boot/bullmq
|
|
28
|
+
return fixer.replaceText(node.source, '"@nest-boot/bullmq"');
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { tester } from "../../utils/tester";
|
|
2
|
+
import rule from "./import-graphql";
|
|
3
|
+
|
|
4
|
+
tester.run("import-graphql", rule, {
|
|
5
|
+
valid: [
|
|
6
|
+
// 正确的导入来源
|
|
7
|
+
/* typescript */ `
|
|
8
|
+
import { Field, ObjectType } from "@nest-boot/graphql";
|
|
9
|
+
`,
|
|
10
|
+
// 从其他包导入
|
|
11
|
+
/* typescript */ `
|
|
12
|
+
import { Module } from "@nestjs/common";
|
|
13
|
+
`,
|
|
14
|
+
// 命名导入
|
|
15
|
+
/* typescript */ `
|
|
16
|
+
import { Resolver, Query } from "@nest-boot/graphql";
|
|
17
|
+
`,
|
|
18
|
+
// 默认导入
|
|
19
|
+
/* typescript */ `
|
|
20
|
+
import GraphQL from "@nest-boot/graphql";
|
|
21
|
+
`,
|
|
22
|
+
],
|
|
23
|
+
invalid: [
|
|
24
|
+
// 从 @nestjs/graphql 导入,应该替换为 @nest-boot/graphql
|
|
25
|
+
{
|
|
26
|
+
code: /* typescript */ `
|
|
27
|
+
import { Field, ObjectType } from "@nestjs/graphql";
|
|
28
|
+
`,
|
|
29
|
+
output: /* typescript */ `
|
|
30
|
+
import { Field, ObjectType } from "@nest-boot/graphql";
|
|
31
|
+
`,
|
|
32
|
+
errors: [{ messageId: "replaceGraphqlImport" }],
|
|
33
|
+
},
|
|
34
|
+
// Resolver 相关导入
|
|
35
|
+
{
|
|
36
|
+
code: /* typescript */ `
|
|
37
|
+
import { Resolver, Query, Mutation } from "@nestjs/graphql";
|
|
38
|
+
`,
|
|
39
|
+
output: /* typescript */ `
|
|
40
|
+
import { Resolver, Query, Mutation } from "@nest-boot/graphql";
|
|
41
|
+
`,
|
|
42
|
+
errors: [{ messageId: "replaceGraphqlImport" }],
|
|
43
|
+
},
|
|
44
|
+
// 类型导入
|
|
45
|
+
{
|
|
46
|
+
code: /* typescript */ `
|
|
47
|
+
import type { GraphQLModule } from "@nestjs/graphql";
|
|
48
|
+
`,
|
|
49
|
+
output: /* typescript */ `
|
|
50
|
+
import type { GraphQLModule } from "@nest-boot/graphql";
|
|
51
|
+
`,
|
|
52
|
+
errors: [{ messageId: "replaceGraphqlImport" }],
|
|
53
|
+
},
|
|
54
|
+
// 混合导入
|
|
55
|
+
{
|
|
56
|
+
code: /* typescript */ `
|
|
57
|
+
import { Args, Int } from "@nestjs/graphql";
|
|
58
|
+
`,
|
|
59
|
+
output: /* typescript */ `
|
|
60
|
+
import { Args, Int } from "@nest-boot/graphql";
|
|
61
|
+
`,
|
|
62
|
+
errors: [{ messageId: "replaceGraphqlImport" }],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createRule } from "../../utils/createRule";
|
|
2
|
+
|
|
3
|
+
export default createRule({
|
|
4
|
+
name: "import-graphql",
|
|
5
|
+
meta: {
|
|
6
|
+
type: "problem",
|
|
7
|
+
docs: {
|
|
8
|
+
description:
|
|
9
|
+
"将从 @nestjs/graphql 导入的包修复为从 @nest-boot/graphql 导入",
|
|
10
|
+
},
|
|
11
|
+
fixable: "code",
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
replaceGraphqlImport:
|
|
15
|
+
"应从 @nest-boot/graphql 导入,而不是 @nestjs/graphql",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultOptions: [],
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
ImportDeclaration(node) {
|
|
22
|
+
// 检查是否从 @nestjs/graphql 导入
|
|
23
|
+
if (node.source.value === "@nestjs/graphql") {
|
|
24
|
+
context.report({
|
|
25
|
+
node,
|
|
26
|
+
messageId: "replaceGraphqlImport",
|
|
27
|
+
fix(fixer) {
|
|
28
|
+
// 将导入源替换为 @nest-boot/graphql
|
|
29
|
+
return fixer.replaceText(node.source, '"@nest-boot/graphql"');
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { tester } from "../../utils/tester";
|
|
2
|
+
import rule from "./import-mikro-orm";
|
|
3
|
+
|
|
4
|
+
tester.run("import-mikro-orm", rule, {
|
|
5
|
+
valid: [
|
|
6
|
+
// 正确的导入来源
|
|
7
|
+
/* typescript */ `
|
|
8
|
+
import { MikroOrmModule } from "@nest-boot/mikro-orm";
|
|
9
|
+
`,
|
|
10
|
+
// 从其他包导入
|
|
11
|
+
/* typescript */ `
|
|
12
|
+
import { Module } from "@nestjs/common";
|
|
13
|
+
`,
|
|
14
|
+
// 从 @mikro-orm/core 导入(不应该被替换)
|
|
15
|
+
/* typescript */ `
|
|
16
|
+
import { Entity, Property } from "@mikro-orm/core";
|
|
17
|
+
`,
|
|
18
|
+
// 命名导入
|
|
19
|
+
/* typescript */ `
|
|
20
|
+
import { InjectRepository } from "@nest-boot/mikro-orm";
|
|
21
|
+
`,
|
|
22
|
+
],
|
|
23
|
+
invalid: [
|
|
24
|
+
// 从 @mikro-orm/nestjs 导入,应该替换为 @nest-boot/mikro-orm
|
|
25
|
+
{
|
|
26
|
+
code: /* typescript */ `
|
|
27
|
+
import { MikroOrmModule } from "@mikro-orm/nestjs";
|
|
28
|
+
`,
|
|
29
|
+
output: /* typescript */ `
|
|
30
|
+
import { MikroOrmModule } from "@nest-boot/mikro-orm";
|
|
31
|
+
`,
|
|
32
|
+
errors: [{ messageId: "replaceMikroOrmImport" }],
|
|
33
|
+
},
|
|
34
|
+
// InjectRepository 导入
|
|
35
|
+
{
|
|
36
|
+
code: /* typescript */ `
|
|
37
|
+
import { InjectRepository } from "@mikro-orm/nestjs";
|
|
38
|
+
`,
|
|
39
|
+
output: /* typescript */ `
|
|
40
|
+
import { InjectRepository } from "@nest-boot/mikro-orm";
|
|
41
|
+
`,
|
|
42
|
+
errors: [{ messageId: "replaceMikroOrmImport" }],
|
|
43
|
+
},
|
|
44
|
+
// 类型导入
|
|
45
|
+
{
|
|
46
|
+
code: /* typescript */ `
|
|
47
|
+
import type { MikroOrmModuleOptions } from "@mikro-orm/nestjs";
|
|
48
|
+
`,
|
|
49
|
+
output: /* typescript */ `
|
|
50
|
+
import type { MikroOrmModuleOptions } from "@nest-boot/mikro-orm";
|
|
51
|
+
`,
|
|
52
|
+
errors: [{ messageId: "replaceMikroOrmImport" }],
|
|
53
|
+
},
|
|
54
|
+
// 混合导入
|
|
55
|
+
{
|
|
56
|
+
code: /* typescript */ `
|
|
57
|
+
import { MikroOrmModule, InjectRepository } from "@mikro-orm/nestjs";
|
|
58
|
+
`,
|
|
59
|
+
output: /* typescript */ `
|
|
60
|
+
import { MikroOrmModule, InjectRepository } from "@nest-boot/mikro-orm";
|
|
61
|
+
`,
|
|
62
|
+
errors: [{ messageId: "replaceMikroOrmImport" }],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createRule } from "../../utils/createRule";
|
|
2
|
+
|
|
3
|
+
export default createRule({
|
|
4
|
+
name: "import-mikro-orm",
|
|
5
|
+
meta: {
|
|
6
|
+
type: "problem",
|
|
7
|
+
docs: {
|
|
8
|
+
description:
|
|
9
|
+
"将从 @mikro-orm/nestjs 导入的包修复为从 @nest-boot/mikro-orm 导入",
|
|
10
|
+
},
|
|
11
|
+
fixable: "code",
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
replaceMikroOrmImport:
|
|
15
|
+
"应从 @nest-boot/mikro-orm 导入,而不是 @mikro-orm/nestjs",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultOptions: [],
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
ImportDeclaration(node) {
|
|
22
|
+
// 检查是否从 @mikro-orm/nestjs 导入
|
|
23
|
+
if (node.source.value === "@mikro-orm/nestjs") {
|
|
24
|
+
context.report({
|
|
25
|
+
node,
|
|
26
|
+
messageId: "replaceMikroOrmImport",
|
|
27
|
+
fix(fixer) {
|
|
28
|
+
// 将导入源替换为 @nest-boot/mikro-orm
|
|
29
|
+
return fixer.replaceText(node.source, '"@nest-boot/mikro-orm"');
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
});
|
package/src/rules/index.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import graphqlFieldConfigFromTypes from "./graphql/graphql-field-config-from-types";
|
|
2
|
+
import graphqlFieldDefiniteAssignment from "./graphql/graphql-field-definite-assignment";
|
|
3
|
+
import importBullmq from "./import/import-bullmq";
|
|
4
|
+
import importGraphql from "./import/import-graphql";
|
|
5
|
+
import importMikroOrm from "./import/import-mikro-orm";
|
|
6
|
+
import entityFieldDefiniteAssignment from "./mikro-orm/entity-field-definite-assignment";
|
|
7
|
+
import entityPropertyConfigFromTypes from "./mikro-orm/entity-property-config-from-types";
|
|
6
8
|
|
|
7
|
-
export
|
|
8
|
-
"
|
|
9
|
-
"entity-property-
|
|
10
|
-
|
|
11
|
-
"entity-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
"
|
|
9
|
+
export const rules = {
|
|
10
|
+
"graphql-field-config-from-types": graphqlFieldConfigFromTypes,
|
|
11
|
+
"entity-property-config-from-types": entityPropertyConfigFromTypes,
|
|
12
|
+
"graphql-field-definite-assignment": graphqlFieldDefiniteAssignment,
|
|
13
|
+
"entity-field-definite-assignment": entityFieldDefiniteAssignment,
|
|
14
|
+
"import-bullmq": importBullmq,
|
|
15
|
+
"import-graphql": importGraphql,
|
|
16
|
+
"import-mikro-orm": importMikroOrm,
|
|
15
17
|
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { tester } from "../../utils/tester";
|
|
2
|
+
import rule from "./entity-field-definite-assignment";
|
|
3
|
+
|
|
4
|
+
tester.run("entity-field-definite-assignment", rule, {
|
|
5
|
+
valid: [
|
|
6
|
+
// 有初始化值的属性,不需要 !
|
|
7
|
+
/* typescript */ `
|
|
8
|
+
@Entity()
|
|
9
|
+
class User {
|
|
10
|
+
@Property()
|
|
11
|
+
createdAt: Date = new Date();
|
|
12
|
+
}
|
|
13
|
+
`,
|
|
14
|
+
// 有 ! 的属性,没有初始化值
|
|
15
|
+
/* typescript */ `
|
|
16
|
+
@Entity()
|
|
17
|
+
class User {
|
|
18
|
+
@Property()
|
|
19
|
+
name!: string;
|
|
20
|
+
}
|
|
21
|
+
`,
|
|
22
|
+
// 可选属性,不需要 !
|
|
23
|
+
/* typescript */ `
|
|
24
|
+
@Entity()
|
|
25
|
+
class User {
|
|
26
|
+
@Property()
|
|
27
|
+
age?: number;
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
// 可空属性且有初始化值
|
|
31
|
+
/* typescript */ `
|
|
32
|
+
@Entity()
|
|
33
|
+
class User {
|
|
34
|
+
@Property({ nullable: true })
|
|
35
|
+
name: string | null = null;
|
|
36
|
+
}
|
|
37
|
+
`,
|
|
38
|
+
// 非 Entity 类不检查
|
|
39
|
+
/* typescript */ `
|
|
40
|
+
class NotAnEntity {
|
|
41
|
+
@Property()
|
|
42
|
+
field: string;
|
|
43
|
+
}
|
|
44
|
+
`,
|
|
45
|
+
// 没有 @Property 装饰器不检查
|
|
46
|
+
/* typescript */ `
|
|
47
|
+
@Entity()
|
|
48
|
+
class User {
|
|
49
|
+
field: string;
|
|
50
|
+
}
|
|
51
|
+
`,
|
|
52
|
+
],
|
|
53
|
+
invalid: [
|
|
54
|
+
// 没有初始化值,也没有 !
|
|
55
|
+
{
|
|
56
|
+
code: /* typescript */ `
|
|
57
|
+
@Entity()
|
|
58
|
+
class User {
|
|
59
|
+
@Property()
|
|
60
|
+
name: string;
|
|
61
|
+
}
|
|
62
|
+
`,
|
|
63
|
+
output: /* typescript */ `
|
|
64
|
+
@Entity()
|
|
65
|
+
class User {
|
|
66
|
+
@Property()
|
|
67
|
+
name!: string;
|
|
68
|
+
}
|
|
69
|
+
`,
|
|
70
|
+
errors: [{ messageId: "addDefiniteAssignment" }],
|
|
71
|
+
},
|
|
72
|
+
// 有初始化值,但也有 !
|
|
73
|
+
{
|
|
74
|
+
code: /* typescript */ `
|
|
75
|
+
@Entity()
|
|
76
|
+
class User {
|
|
77
|
+
@Property()
|
|
78
|
+
createdAt!: Date = new Date();
|
|
79
|
+
}
|
|
80
|
+
`,
|
|
81
|
+
output: /* typescript */ `
|
|
82
|
+
@Entity()
|
|
83
|
+
class User {
|
|
84
|
+
@Property()
|
|
85
|
+
createdAt: Date = new Date();
|
|
86
|
+
}
|
|
87
|
+
`,
|
|
88
|
+
errors: [{ messageId: "removeDefiniteAssignment" }],
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
});
|