-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathprisma.ts
More file actions
94 lines (82 loc) · 2.84 KB
/
prisma.ts
File metadata and controls
94 lines (82 loc) · 2.84 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
import { Prisma, PrismaClient } from "@prisma/client";
import { JsonValue } from "@prisma/client/runtime/library";
import { isObject } from "radash";
const prisma = new PrismaClient();
/**
* Creates a Prisma extension that injects RLS session variables into every
* operation via set_config. Handles standalone queries, interactive
* transactions, and batch transactions.
*
* Based on: https://gist.github.com/danielrose7/a0c6a98e7de5f63dffb86ec05d34dab9
* Related: https://github.com/prisma/prisma/issues/20678
*/
const createRlsExtension = (rlsSql: Prisma.Sql) =>
Prisma.defineExtension((client) =>
client.$extends({
client: {
$transaction: (async (
...txnParams: Parameters<typeof client.$transaction>
) => {
const [first, options] = txnParams;
if (Array.isArray(first)) {
const [, ...results] = await client.$transaction(
[client.$executeRaw(rlsSql), ...first],
options
);
return results;
}
return client.$transaction(async (tx) => {
await tx.$executeRaw(rlsSql);
return (first as Function)(tx);
}, options);
}) as typeof client.$transaction,
},
query: {
$allModels: {
async $allOperations({ args, query, ...rest }) {
const existingTxn = (rest as any).__internalParams?.transaction;
if (existingTxn) return query(args);
const [, result] = await client.$transaction([
client.$executeRaw(rlsSql),
query(args),
]);
return result;
},
},
async $allOperations({ args, model, query, ...rest }) {
if (model) return query(args);
const existingTxn = (rest as any).__internalParams?.transaction;
if (existingTxn) return query(args);
const [, result] = await client.$transaction([
client.$executeRaw(rlsSql),
query(args),
]);
return result;
},
},
})
);
export const getBypassRlsPrisma = () =>
prisma.$extends(
createRlsExtension(
Prisma.sql`SELECT set_config('app.current_workspace_id', '0', TRUE), set_config('app.bypass_rls', 'on', TRUE)`
)
) as unknown as PrismaClient;
export const getPrisma = (workspaceId?: number) => {
if (workspaceId?.toString()) {
return prisma.$extends(
createRlsExtension(
Prisma.sql`SELECT set_config('app.current_workspace_id', ${workspaceId.toString()}, TRUE)`
)
) as unknown as PrismaClient;
}
return prisma;
};
export const take = (limit: number = 50) => {
return Math.min(100, limit);
};
export const jsonObject = <T extends Record<string, any>>(
value: string | object | JsonValue
): T => {
return isObject(value) ? (value as T) : (JSON.parse(value as string) as T);
};