forked from rocicorp/hello-zero
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.ts
124 lines (114 loc) · 2.66 KB
/
schema.ts
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
122
123
124
// These data structures define your client-side schema.
// They must be equal to or a subset of the server-side schema.
// Note the "relationships" field, which defines first-class
// relationships between tables.
// See https://github.com/rocicorp/mono/blob/main/apps/zbugs/src/domain/schema.ts
// for more complex examples, including many-to-many.
import {
createSchema,
createTableSchema,
definePermissions,
ExpressionBuilder,
TableSchema,
Row,
NOBODY_CAN,
ANYONE_CAN,
} from "@rocicorp/zero";
const userSchema = createTableSchema({
tableName: "user",
columns: {
id: "string",
name: "string",
partner: "boolean",
},
primaryKey: "id",
});
const mediumSchema = createTableSchema({
tableName: "medium",
columns: {
id: "string",
name: "string",
},
primaryKey: "id",
});
const messageSchema = createTableSchema({
tableName: "message",
columns: {
id: "string",
senderID: "string",
mediumID: "string",
body: "string",
timestamp: "number",
},
primaryKey: "id",
relationships: {
sender: {
sourceField: "senderID",
destSchema: userSchema,
destField: "id",
},
medium: {
sourceField: "mediumID",
destSchema: mediumSchema,
destField: "id",
},
},
});
export const schema = createSchema({
version: 1,
tables: {
user: userSchema,
medium: mediumSchema,
message: messageSchema,
},
});
export type Schema = typeof schema;
export type Message = Row<typeof messageSchema>;
export type Medium = Row<typeof mediumSchema>;
export type User = Row<typeof schema.tables.user>;
// The contents of your decoded JWT.
type AuthData = {
sub: string | null;
};
export const permissions = definePermissions<AuthData, Schema>(schema, () => {
const allowIfLoggedIn = (
authData: AuthData,
{ cmpLit }: ExpressionBuilder<TableSchema>
) => cmpLit(authData.sub, "IS NOT", null);
const allowIfMessageSender = (
authData: AuthData,
{ cmp }: ExpressionBuilder<typeof messageSchema>
) => cmp("senderID", "=", authData.sub ?? "");
return {
medium: {
row: {
insert: NOBODY_CAN,
update: {
preMutation: NOBODY_CAN,
},
delete: NOBODY_CAN,
},
},
user: {
row: {
insert: NOBODY_CAN,
update: {
preMutation: NOBODY_CAN,
},
delete: NOBODY_CAN,
},
},
message: {
row: {
// anyone can insert
insert: ANYONE_CAN,
// only sender can edit their own messages
update: {
preMutation: [allowIfMessageSender],
},
// must be logged in to delete
delete: [allowIfLoggedIn],
},
},
};
});