PolicyEditorPanel.utils.ts 2.8 KB

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