-
-
Notifications
You must be signed in to change notification settings - Fork 143
Expand file tree
/
Copy pathmain.ts
More file actions
121 lines (108 loc) · 3.91 KB
/
main.ts
File metadata and controls
121 lines (108 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { ZenStackClient } from '@zenstackhq/orm';
import { PolicyPlugin } from '@zenstackhq/plugin-policy';
import SQLite from 'better-sqlite3';
import { sql, SqliteDialect } from 'kysely';
import { schema } from './zenstack/schema';
async function main() {
const db = new ZenStackClient(schema, {
dialect: new SqliteDialect({ database: new SQLite('./zenstack/dev.db') }),
computedFields: {
user: {
postCount: (eb, { modelAlias }) =>
eb
.selectFrom('Post')
.whereRef('Post.authorId', '=', sql.ref(`${modelAlias}.id`))
.select(({ fn }) => fn.countAll<number>().as('postCount')),
},
},
procedures: {
signUp: ({ client, args }) =>
client.user.create({
data: { ...args },
}),
listPublicPosts: ({}) => [],
},
}).$use({
id: 'cost-logger',
onQuery: async ({ model, operation, args, proceed }) => {
const start = Date.now();
const result = await proceed(args as any);
console.log(`[cost] ${model} ${operation} took ${Date.now() - start}ms`);
return result;
},
});
// clean up existing data
await db.post.deleteMany();
await db.profile.deleteMany();
await db.user.deleteMany();
db.user.findMany({ where: { id: '1' } });
// create users and some posts
const user1 = await db.user.create({
data: {
email: 'yiming@gmail.com',
role: 'ADMIN',
posts: {
create: [
{
title: 'Post1',
content: 'An unpublished post',
published: false,
},
{
title: 'Post2',
content: 'A published post',
published: true,
},
],
},
},
include: { posts: true },
});
console.log('User created:', user1);
const user2 = await db.user.create({
data: {
email: 'jiasheng@zenstack.dev',
role: 'USER',
posts: {
create: {
title: 'Post3',
content: 'Another unpublished post',
published: false,
},
},
},
include: { posts: true },
});
console.log('User created:', user2);
// find with where conditions mixed with low-level Kysely expression builder
const userWithProperDomain = await db.user.findMany({
where: {
role: 'USER',
$expr: (eb) => eb('email', 'like', '%@zenstack.dev'),
},
});
console.log('User found with mixed filter:', userWithProperDomain);
// filter with computed field
const userWithMorePosts = await db.user.findMany({
where: {
role: 'ADMIN',
postCount: {
gt: 1,
},
},
});
console.log('User found with computed field:', userWithMorePosts);
// policy-enabled read
const authDb = db.$use(new PolicyPlugin());
const user1Db = authDb.$setAuth({ id: user1.id });
const user2Db = authDb.$setAuth({ id: user2.id });
console.log('Posts readable to', user1.email);
console.table(await user1Db.post.findMany({ select: { title: true, published: true } }));
console.log('Posts readable to', user2.email);
console.table(await user2Db.post.findMany({ select: { title: true, published: true } }));
const newUser = await authDb.$procs.signUp({ args: { email: 'new@zenstack.dev', name: 'New User' } });
console.log('New user signed up via procedure:', newUser);
const publicPosts = await authDb.$procs.listPublicPosts();
console.log('Public posts via procedure:', publicPosts);
}
main();