PolicyEditorPanel.utils.ts106 lines · main
1import type { PGPolicy } from '@supabase/pg-meta'
2import { ident, keyword, safeSql, type SafeSqlFragment } from '@supabase/pg-meta/src/pg-format'
3import { isEqual } from 'lodash'
4
5// [Joshen] Not used but keeping this for now in case we do an inline editor
6export const generatePlaceholder = (policy?: PGPolicy) => {
7 if (policy === undefined) {
8 return `
9-- Press tab to use this code\n
10 \n
11CREATE POLICY *name* ON *table_name*\n
12AS PERMISSIVE -- PERMISSIVE | RESTRICTIVE\n
13FOR ALL -- ALL | SELECT | INSERT | UPDATE | DELETE\n
14TO *role_name* -- Default: public\n
15USING ( *using_expression* )\n
16WITH CHECK ( *check_expression* );
17`.trim()
18 } else {
19 let expression = ''
20 if (policy.definition !== null && policy.definition !== undefined) {
21 expression += `USING ( *${policy.definition}* )${
22 policy.check === null || policy.check === undefined ? ';' : ''
23 }\n`
24 }
25 if (policy.check !== null && policy.check !== undefined) {
26 expression += `WITH CHECK ( *${policy.check}* );\n`
27 }
28
29 return `
30-- Press tab to use this code\n
31 \n
32BEGIN;\n
33 \n
34-- To update your policy definition\n
35ALTER POLICY "${policy.name}"\n
36ON "${policy.schema}"."${policy.table}"\n
37TO *${policy.roles.join(', ')}*\n
38${expression}
39 \n
40-- To rename your policy\n
41ALTER POLICY "${policy.name}"\n
42ON "${policy.schema}"."${policy.table}"\n
43RENAME TO "*New Policy Name*";\n
44 \n
45COMMIT;
46`.trim()
47 }
48}
49
50export const generateCreatePolicyQuery = ({
51 name,
52 schema,
53 table,
54 behavior,
55 command,
56 roles,
57 using,
58 check,
59}: {
60 name: string
61 schema: string
62 table: string
63 behavior: string
64 command: string
65 roles: SafeSqlFragment
66 using?: SafeSqlFragment
67 check?: SafeSqlFragment
68}): SafeSqlFragment => {
69 const skeleton = safeSql`create policy ${ident(name)} on ${ident(schema)}.${ident(table)} as ${keyword(behavior)} for ${keyword(command)} to ${roles}`
70 if (command === 'insert') {
71 return safeSql`${skeleton} with check (${check ?? safeSql``});`
72 }
73 const withUsing = safeSql`${skeleton} using (${using ?? safeSql``})`
74 if ((check ?? '').length > 0) {
75 return safeSql`${withUsing} with check (${check ?? safeSql``});`
76 }
77 return safeSql`${withUsing};`
78}
79
80export const checkIfPolicyHasChanged = (
81 selectedPolicy: PGPolicy,
82 policyForm: {
83 name: string
84 roles: string[]
85 check: string | null
86 definition: string | null
87 }
88) => {
89 if (selectedPolicy.command === 'INSERT' && selectedPolicy.check !== policyForm.check) {
90 return true
91 }
92 if (
93 selectedPolicy.command !== 'INSERT' &&
94 (selectedPolicy.definition !== policyForm.definition ||
95 selectedPolicy.check !== policyForm.check)
96 ) {
97 return true
98 }
99 if (selectedPolicy.name !== policyForm.name) {
100 return true
101 }
102 if (!isEqual(selectedPolicy.roles, policyForm.roles)) {
103 return true
104 }
105 return false
106}