Skip to content

Commit 85d8c5d

Browse files
authored
feat(schema): generate enum type helpers (#91)
1 parent 52d9576 commit 85d8c5d

File tree

6 files changed

+76
-13
lines changed

6 files changed

+76
-13
lines changed

packages/runtime/test/typing/models.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ export type Profile = ModelResult<Schema, "Profile">;
1414
export type Tag = ModelResult<Schema, "Tag">;
1515
export type Region = ModelResult<Schema, "Region">;
1616
export type Meta = ModelResult<Schema, "Meta">;
17+
export const Role = schema.enums.Role;
18+
export type Role = (typeof Role)[keyof typeof Role];

packages/runtime/test/typing/schema.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ export const schema = {
3737
unique: true,
3838
attributes: [{ name: "@unique" }]
3939
},
40+
role: {
41+
type: "Role",
42+
attributes: [{ name: "@default", args: [{ name: "value", value: ExpressionUtils.literal("USER") }] }],
43+
default: "USER"
44+
},
4045
posts: {
4146
type: "Post",
4247
array: true,
@@ -241,6 +246,12 @@ export const schema = {
241246
}
242247
}
243248
},
249+
enums: {
250+
Role: {
251+
ADMIN: "ADMIN",
252+
USER: "USER"
253+
}
254+
},
244255
authType: "User",
245256
plugins: {}
246257
} as const satisfies SchemaDef;

packages/runtime/test/typing/typing-test.zmodel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@ datasource db {
33
url = "file:./test.db"
44
}
55

6+
enum Role {
7+
ADMIN
8+
USER
9+
}
10+
611
model User {
712
id Int @id @default(autoincrement())
813
createdAt DateTime @default(now())
914
updatedAt DateTime @updatedAt
1015
name String
1116
email String @unique
17+
role Role @default(USER)
1218
posts Post[]
1319
profile Profile?
1420
postCount Int @computed

packages/runtime/test/typing/verify-typing.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ZenStackClient } from '../../dist';
2+
import { Role } from './models';
23
import { schema } from './schema';
34
import SQLite from 'better-sqlite3';
45

@@ -26,12 +27,14 @@ async function main() {
2627
await aggregate();
2728
await groupBy();
2829
await queryBuilder();
30+
enums();
2931
}
3032

3133
async function find() {
3234
const user1 = await client.user.findFirst({
3335
where: {
3436
name: 'Alex',
37+
role: Role.USER,
3538
},
3639
});
3740
console.log(user1?.name);
@@ -562,4 +565,12 @@ async function queryBuilder() {
562565
console.log(r.name);
563566
}
564567

568+
function enums() {
569+
const a: Role = 'ADMIN';
570+
console.log(a);
571+
let b = Role.ADMIN;
572+
b = a;
573+
console.log(b);
574+
}
575+
565576
main();

packages/sdk/src/ts-schema-generator.ts

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,20 +1021,49 @@ export class TsSchemaGenerator {
10211021
// generate enums
10221022
const enums = model.declarations.filter(isEnum);
10231023
for (const e of enums) {
1024-
// generate:
1025-
// export const enum Enum = {
1026-
// value1 = 'value1',
1027-
// value2 = 'value2',
1028-
// }
1029-
let enumDecl = ts.factory.createEnumDeclaration(
1024+
// generate: export const Enum = schema.enums.Enum;
1025+
let enumDecl = ts.factory.createVariableStatement(
10301026
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
1031-
e.name,
1032-
e.fields.map((f) => ts.factory.createEnumMember(f.name, ts.factory.createStringLiteral(f.name))),
1027+
ts.factory.createVariableDeclarationList(
1028+
[
1029+
ts.factory.createVariableDeclaration(
1030+
e.name,
1031+
undefined,
1032+
undefined,
1033+
ts.factory.createPropertyAccessExpression(
1034+
ts.factory.createPropertyAccessExpression(
1035+
ts.factory.createIdentifier('schema'),
1036+
ts.factory.createIdentifier('enums'),
1037+
),
1038+
ts.factory.createIdentifier(e.name),
1039+
),
1040+
),
1041+
],
1042+
ts.NodeFlags.Const,
1043+
),
10331044
);
10341045
if (e.comments.length > 0) {
10351046
enumDecl = this.generateDocs(enumDecl, e);
10361047
}
10371048
statements.push(enumDecl);
1049+
1050+
// generate: export type Enum = (typeof Enum)[keyof typeof Enum];
1051+
let typeAlias = ts.factory.createTypeAliasDeclaration(
1052+
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
1053+
e.name,
1054+
undefined,
1055+
ts.factory.createIndexedAccessTypeNode(
1056+
ts.factory.createTypeQueryNode(ts.factory.createIdentifier(e.name)),
1057+
ts.factory.createTypeOperatorNode(
1058+
ts.SyntaxKind.KeyOfKeyword,
1059+
ts.factory.createTypeQueryNode(ts.factory.createIdentifier(e.name)),
1060+
),
1061+
),
1062+
);
1063+
if (e.comments.length > 0) {
1064+
typeAlias = this.generateDocs(typeAlias, e);
1065+
}
1066+
statements.push(typeAlias);
10381067
}
10391068

10401069
this.generateBannerComments(statements);
@@ -1047,7 +1076,10 @@ export class TsSchemaGenerator {
10471076
fs.writeFileSync(outputFile, result);
10481077
}
10491078

1050-
private generateDocs<T extends ts.TypeAliasDeclaration | ts.EnumDeclaration>(tsDecl: T, decl: DataModel | Enum): T {
1079+
private generateDocs<T extends ts.TypeAliasDeclaration | ts.VariableStatement>(
1080+
tsDecl: T,
1081+
decl: DataModel | Enum,
1082+
): T {
10511083
return ts.addSyntheticLeadingComment(
10521084
tsDecl,
10531085
ts.SyntaxKind.MultiLineCommentTrivia,

samples/blog/zenstack/models.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export type Post = ModelResult<Schema, "Post">;
2525
/**
2626
* User roles
2727
*/
28-
export enum Role {
29-
ADMIN = "ADMIN",
30-
USER = "USER"
31-
}
28+
export const Role = schema.enums.Role;
29+
/**
30+
* User roles
31+
*/
32+
export type Role = (typeof Role)[keyof typeof Role];

0 commit comments

Comments
 (0)