1
12
13
14export const LEVELS = ["none", "view", "comment", "edit", "full_access"] as const;
15
16export type PermissionLevel = (typeof LEVELS)[number];
17
18
22export type AccessLevel = Exclude<PermissionLevel, "none">;
23
24
25export const ROLES = ["guest", "member", "admin", "owner"] as const;
26
27export type WorkspaceRole = (typeof ROLES)[number];
28
29const LEVEL_RANK: Record<PermissionLevel, number> = {
30 none: 0,
31 view: 1,
32 comment: 2,
33 edit: 3,
34 full_access: 4,
35};
36
37const LEVEL_TO_PRISMA: Record<PermissionLevel, string> = {
38 none: "NONE",
39 view: "VIEW",
40 comment: "COMMENT",
41 edit: "EDIT",
42 full_access: "FULL_ACCESS",
43};
44
45const ROLE_TO_PRISMA: Record<WorkspaceRole, string> = {
46 guest: "GUEST",
47 member: "MEMBER",
48 admin: "ADMIN",
49 owner: "OWNER",
50};
51
52
56export function levelRank(level: PermissionLevel): number {
57 const rank = LEVEL_RANK[level];
58 if (rank === undefined) throw new Error(`unknown permission level: ${String(level)}`);
59 return rank;
60}
61
62
63export function maxLevel(a: PermissionLevel, b: PermissionLevel): PermissionLevel {
64 return levelRank(a) >= levelRank(b) ? a : b;
65}
66
67
68export function minLevel(a: PermissionLevel, b: PermissionLevel): PermissionLevel {
69 return levelRank(a) <= levelRank(b) ? a : b;
70}
71
72
76export function levelAtLeast(level: PermissionLevel, required: PermissionLevel): boolean {
77 return levelRank(level) >= levelRank(required);
78}
79
80
84export function levelToPrisma(level: PermissionLevel): string {
85 return LEVEL_TO_PRISMA[level];
86}
87
88
92export function levelFromPrisma(value: string): PermissionLevel {
93 const entry = (Object.entries(LEVEL_TO_PRISMA) as [PermissionLevel, string][]).find(
94 ([, prisma]) => prisma === value,
95 );
96 if (entry === undefined) throw new Error(`unknown PermissionLevel prisma value: ${value}`);
97 return entry[0];
98}
99
100
101export function roleToPrisma(role: WorkspaceRole): string {
102 return ROLE_TO_PRISMA[role];
103}
104
105
106export function roleFromPrisma(value: string): WorkspaceRole {
107 const entry = (Object.entries(ROLE_TO_PRISMA) as [WorkspaceRole, string][]).find(
108 ([, prisma]) => prisma === value,
109 );
110 if (entry === undefined) throw new Error(`unknown WorkspaceRole prisma value: ${value}`);
111 return entry[0];
112}
113
114
115export const RESOURCE_TYPES = [
116 "workspace",
117 "teamspace",
118 "page",
119 "database",
120 "record",
121 "file",
122] as const;
123
124export type ResourceType = (typeof RESOURCE_TYPES)[number];
125