-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
105 lines (93 loc) · 2.48 KB
/
index.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
// TODO: This file is temporary until Drizzle ORM RLS is finished.
import { entityKind, SQL, sql, type DrizzleEntityClass } from "drizzle-orm";
import {
pgPolicy,
PgRole,
type AnyPgColumn,
type PgPolicyToOption,
} from "drizzle-orm/pg-core";
export function is<T extends DrizzleEntityClass<any>>(
value: any,
type: T
): value is InstanceType<T> {
if (!value || typeof value !== "object") {
return false;
}
if (value instanceof type) {
// eslint-disable-line no-instanceof/no-instanceof
return true;
}
if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
throw new Error(
`Class "${
type.name ?? "<unknown>"
}" doesn't look like a Drizzle entity. If this is incorrect and the class is provided by Drizzle, please report this as a bug.`
);
}
let cls = value.constructor;
if (cls) {
// Traverse the prototype chain to find the entityKind
while (cls) {
if (entityKind in cls && cls[entityKind] === type[entityKind]) {
return true;
}
cls = Object.getPrototypeOf(cls);
}
}
return false;
}
export const crudPolicy = (options: {
role: PgPolicyToOption;
read?: SQL | boolean;
modify?: SQL | boolean;
}) => {
const read: SQL =
options.read === true
? sql`true`
: options.read === false || options.read === undefined
? sql`false`
: options.read;
const modify: SQL =
options.modify === true
? sql`true`
: options.modify === false || options.modify === undefined
? sql`false`
: options.modify;
let rolesName = "";
if (Array.isArray(options.role)) {
rolesName = options.role
.map((it) => {
return is(it, PgRole) ? it.name : (it as string);
})
.join("-");
} else {
rolesName = is(options.role, PgRole)
? options.role.name
: (options.role as string);
}
return [
pgPolicy(`crud-${rolesName}-policy-insert`, {
for: "insert",
to: options.role,
withCheck: modify,
}),
pgPolicy(`crud-${rolesName}-policy-update`, {
for: "update",
to: options.role,
using: modify,
withCheck: modify,
}),
pgPolicy(`crud-${rolesName}-policy-delete`, {
for: "delete",
to: options.role,
using: modify,
}),
pgPolicy(`crud-${rolesName}-policy-select`, {
for: "select",
to: options.role,
using: read,
}),
];
};
export const authUid = (userIdColumn: AnyPgColumn) =>
sql`(select auth.user_id() = ${userIdColumn})`;