Skip to content

Commit 4a2d0d7

Browse files
authored
feat: Add enum value-level descriptions and deprecation metadata
1 parent 074c2de commit 4a2d0d7

File tree

4 files changed

+91
-41
lines changed

4 files changed

+91
-41
lines changed

@generated/user/user-update-without-articles.input.ts

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,54 +15,55 @@ import { ProfileUpdateOneWithoutUserNestedInput } from '../profile/profile-updat
1515

1616
@InputType()
1717
export class UserUpdateWithoutArticlesInput {
18-
@Field(() => StringFieldUpdateOperationsInput, { nullable: true })
19-
id?: StringFieldUpdateOperationsInput;
2018

21-
@Field(() => StringFieldUpdateOperationsInput, { nullable: true })
22-
email?: StringFieldUpdateOperationsInput;
19+
@Field(() => StringFieldUpdateOperationsInput, {nullable:true})
20+
id?: StringFieldUpdateOperationsInput;
2321

24-
@Field(() => StringFieldUpdateOperationsInput, { nullable: true })
25-
name?: StringFieldUpdateOperationsInput;
22+
@Field(() => StringFieldUpdateOperationsInput, {nullable:true})
23+
email?: StringFieldUpdateOperationsInput;
2624

27-
@Field(() => StringFieldUpdateOperationsInput, { nullable: true })
28-
password?: StringFieldUpdateOperationsInput;
25+
@Field(() => StringFieldUpdateOperationsInput, {nullable:true})
26+
name?: StringFieldUpdateOperationsInput;
2927

30-
@Field(() => NullableStringFieldUpdateOperationsInput, { nullable: true })
31-
bio?: NullableStringFieldUpdateOperationsInput;
28+
@Field(() => StringFieldUpdateOperationsInput, {nullable:true})
29+
password?: StringFieldUpdateOperationsInput;
3230

33-
@Field(() => NullableStringFieldUpdateOperationsInput, { nullable: true })
34-
image?: NullableStringFieldUpdateOperationsInput;
31+
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
32+
bio?: NullableStringFieldUpdateOperationsInput;
3533

36-
@Field(() => NullableIntFieldUpdateOperationsInput, { nullable: true })
37-
countComments?: NullableIntFieldUpdateOperationsInput;
34+
@Field(() => NullableStringFieldUpdateOperationsInput, {nullable:true})
35+
image?: NullableStringFieldUpdateOperationsInput;
3836

39-
@Field(() => NullableFloatFieldUpdateOperationsInput, { nullable: true })
40-
rating?: NullableFloatFieldUpdateOperationsInput;
37+
@Field(() => NullableIntFieldUpdateOperationsInput, {nullable:true})
38+
countComments?: NullableIntFieldUpdateOperationsInput;
4139

42-
@Field(() => NullableDecimalFieldUpdateOperationsInput, { nullable: true })
43-
@Type(() => NullableDecimalFieldUpdateOperationsInput)
44-
money?: NullableDecimalFieldUpdateOperationsInput;
40+
@Field(() => NullableFloatFieldUpdateOperationsInput, {nullable:true})
41+
rating?: NullableFloatFieldUpdateOperationsInput;
4542

46-
@Field(() => NullableEnumRoleFieldUpdateOperationsInput, { nullable: true })
47-
role?: NullableEnumRoleFieldUpdateOperationsInput;
43+
@Field(() => NullableDecimalFieldUpdateOperationsInput, {nullable:true})
44+
@Type(() => NullableDecimalFieldUpdateOperationsInput)
45+
money?: NullableDecimalFieldUpdateOperationsInput;
4846

49-
@Field(() => UserUpdateManyWithoutFollowersNestedInput, { nullable: true })
50-
@Type(() => UserUpdateManyWithoutFollowersNestedInput)
51-
following?: UserUpdateManyWithoutFollowersNestedInput;
47+
@Field(() => NullableEnumRoleFieldUpdateOperationsInput, {nullable:true})
48+
role?: NullableEnumRoleFieldUpdateOperationsInput;
5249

53-
@Field(() => UserUpdateManyWithoutFollowingNestedInput, { nullable: true })
54-
@Type(() => UserUpdateManyWithoutFollowingNestedInput)
55-
followers?: UserUpdateManyWithoutFollowingNestedInput;
50+
@Field(() => UserUpdateManyWithoutFollowersNestedInput, {nullable:true})
51+
@Type(() => UserUpdateManyWithoutFollowersNestedInput)
52+
following?: UserUpdateManyWithoutFollowersNestedInput;
5653

57-
@Field(() => ArticleUpdateManyWithoutFavoritedByNestedInput, { nullable: true })
58-
@Type(() => ArticleUpdateManyWithoutFavoritedByNestedInput)
59-
favoriteArticles?: ArticleUpdateManyWithoutFavoritedByNestedInput;
54+
@Field(() => UserUpdateManyWithoutFollowingNestedInput, {nullable:true})
55+
@Type(() => UserUpdateManyWithoutFollowingNestedInput)
56+
followers?: UserUpdateManyWithoutFollowingNestedInput;
6057

61-
@Field(() => CommentUpdateManyWithoutAuthorNestedInput, { nullable: true })
62-
@Type(() => CommentUpdateManyWithoutAuthorNestedInput)
63-
comments?: CommentUpdateManyWithoutAuthorNestedInput;
58+
@Field(() => ArticleUpdateManyWithoutFavoritedByNestedInput, {nullable:true})
59+
@Type(() => ArticleUpdateManyWithoutFavoritedByNestedInput)
60+
favoriteArticles?: ArticleUpdateManyWithoutFavoritedByNestedInput;
6461

65-
@Field(() => ProfileUpdateOneWithoutUserNestedInput, { nullable: true })
66-
@Type(() => ProfileUpdateOneWithoutUserNestedInput)
67-
profile?: ProfileUpdateOneWithoutUserNestedInput;
62+
@Field(() => CommentUpdateManyWithoutAuthorNestedInput, {nullable:true})
63+
@Type(() => CommentUpdateManyWithoutAuthorNestedInput)
64+
comments?: CommentUpdateManyWithoutAuthorNestedInput;
65+
66+
@Field(() => ProfileUpdateOneWithoutUserNestedInput, {nullable:true})
67+
@Type(() => ProfileUpdateOneWithoutUserNestedInput)
68+
profile?: ProfileUpdateOneWithoutUserNestedInput;
6869
}

prisma/schema.prisma

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,19 @@ model Comment {
104104
articleId String?
105105
}
106106

107+
/// user access control
107108
enum Role {
109+
/// default user access control
108110
USER
111+
/// have full access control
112+
NINGA
113+
/// @deprecated Use USER instead
114+
ADMIN
115+
REVIEWER // no comment and won't show in registerenum valuemaps
109116
}
110117

111118
model Profile {
119+
/// @deprecated Use new name instead
112120
id Int @id @default(autoincrement())
113121
user User @relation(fields: [userId], references: [id])
114122
userId String @unique

src/handlers/prisma-enum-doc.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// utils/prisma-enum-doc.ts
2+
3+
type EnumValueDocInfo = { description: string } | { deprecationReason: string };
4+
5+
export function extractEnumValueDocs(
6+
values: readonly { name: string; [key: string]: any }[],
7+
): Record<string, EnumValueDocInfo> {
8+
return Object.fromEntries(
9+
values
10+
.map((value): [string, EnumValueDocInfo] | null => {
11+
const { name } = value;
12+
const documentation: unknown = value.documentation;
13+
14+
if (typeof documentation !== 'string') return null;
15+
16+
if (documentation.startsWith('@deprecated')) {
17+
return [name, { deprecationReason: documentation.slice(11).trim() }];
18+
}
19+
20+
return [name, { description: documentation }];
21+
})
22+
.filter((entry): entry is [string, EnumValueDocInfo] => entry !== null),
23+
);
24+
}

src/handlers/register-enum.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { EnumDeclarationStructure, StructureKind } from 'ts-morph';
22

33
import { ImportDeclarationMap } from '../helpers/import-declaration-map';
44
import { EventArguments, SchemaEnum } from '../types';
5+
import { extractEnumValueDocs } from './prisma-enum-doc';
56

67
export function registerEnum(enumType: SchemaEnum, args: EventArguments) {
7-
const { getSourceFile, enums, config } = args;
8+
const { config, enums, getSourceFile } = args;
89

910
if (!config.emitBlocks.prismaEnums && !enums[enumType.name]) return;
1011

1112
const dataModelEnum = enums[enumType.name];
13+
const enumTypesData = dataModelEnum?.values || [];
1214
const sourceFile = getSourceFile({
1315
name: enumType.name,
1416
type: 'enum',
@@ -17,10 +19,25 @@ export function registerEnum(enumType: SchemaEnum, args: EventArguments) {
1719
const importDeclarations = new ImportDeclarationMap();
1820

1921
importDeclarations.set('registerEnumType', {
20-
namedImports: [{ name: 'registerEnumType' }],
2122
moduleSpecifier: '@nestjs/graphql',
23+
namedImports: [{ name: 'registerEnumType' }],
2224
});
2325

26+
// Extract valuesMap from enum documentation
27+
const valuesMap = extractEnumValueDocs(enumTypesData);
28+
29+
// Remove entries with no description or deprecationReason
30+
const filteredValuesMap = Object.fromEntries(
31+
Object.entries(valuesMap).filter(([_, v]) => Object.keys(v).length > 0),
32+
);
33+
34+
// Format only if needed
35+
const hasValuesMap = Object.keys(filteredValuesMap).length > 0;
36+
const formattedValuesMap = hasValuesMap
37+
? JSON.stringify(filteredValuesMap, null, 2).replace(/"([^"]+)":/g, '$1:')
38+
: '';
39+
const valuesMapEntry = hasValuesMap ? `, valuesMap: ${formattedValuesMap}` : '';
40+
2441
const enumStructure: EnumDeclarationStructure = {
2542
kind: StructureKind.Enum,
2643
isExported: true,
@@ -36,9 +53,9 @@ export function registerEnum(enumType: SchemaEnum, args: EventArguments) {
3653
...importDeclarations.toStatements(),
3754
enumStructure,
3855
'\n',
39-
`registerEnumType(${enumType.name}, { name: '${
40-
enumType.name
41-
}', description: ${JSON.stringify(dataModelEnum?.documentation)} })`,
56+
`registerEnumType(${enumType.name}, { name: '${enumType.name}', description: ${JSON.stringify(
57+
dataModelEnum?.documentation,
58+
)}${valuesMapEntry} })`,
4259
],
4360
});
4461
}

0 commit comments

Comments
 (0)