Home / Function/ useApplyPrivilegeOperations() — supabase Function Reference

useApplyPrivilegeOperations() — supabase Function Reference

Architecture documentation for the useApplyPrivilegeOperations() function in Privileges.utils.ts from the supabase codebase.

Entity Profile

Relationship Graph

Source Code

apps/studio/components/interfaces/Database/Privileges/Privileges.utils.ts lines 268–360

export function useApplyPrivilegeOperations(callback?: () => void) {
  const { data: project } = useSelectedProjectQuery()
  const queryClient = useQueryClient()

  const [isLoading, setIsLoading] = useState(false)

  const apply = useCallback(
    async (operations: PrivilegeOperation[]) => {
      if (!project) return console.error('No project selected')

      setIsLoading(true)

      const tableOperations = operations.filter((op) => op.object === 'table')
      const columnOperations = operations.filter((op) => op.object === 'column')

      const grantTableOperations = tableOperations
        .filter((op) => op.type === 'grant')
        .map((op) => ({
          relationId: Number(op.id),
          grantee: op.grantee,
          privilegeType: op.privilege_type as TablePrivilegesGrant['privilegeType'],
        }))
      const revokeTableOperations = tableOperations
        .filter((op) => op.type === 'revoke')
        .map((op) => ({
          relationId: Number(op.id),
          grantee: op.grantee,
          privilegeType: op.privilege_type as TablePrivilegesRevoke['privilegeType'],
        }))

      const grantColumnOperations = columnOperations
        .filter((op) => op.type === 'grant')
        .map((op) => ({
          column_id: String(op.id),
          grantee: op.grantee,
          privilege_type: op.privilege_type as ColumnPrivilegesRevoke['privilege_type'],
        }))
      const revokeColumnOperations = columnOperations
        .filter((op) => op.type === 'revoke')
        .map((op) => ({
          column_id: String(op.id),
          grantee: op.grantee,
          privilege_type: op.privilege_type as ColumnPrivilegesRevoke['privilege_type'],
        }))

      // annoyingly these can't be run all at once
      // as postgres can't process them in parallel

      if (revokeTableOperations.length > 0) {
        await revokeTablePrivileges({
          projectRef: project.ref,
          connectionString: project.connectionString,
          revokes: revokeTableOperations,
        })
      }
      if (grantTableOperations.length > 0) {
        await grantTablePrivileges({
          projectRef: project.ref,
          connectionString: project.connectionString,
          grants: grantTableOperations,
        })
      }
      if (revokeColumnOperations.length > 0) {
        await revokeColumnPrivileges({
          projectRef: project.ref,
          connectionString: project.connectionString,
          revokes: revokeColumnOperations,
        })
      }
      if (grantColumnOperations.length > 0) {
        await grantColumnPrivileges({
          projectRef: project.ref,
          connectionString: project.connectionString,
          grants: grantColumnOperations,
        })
      }

      await Promise.all([
        queryClient.invalidateQueries({ queryKey: privilegeKeys.tablePrivilegesList(project.ref) }),
        queryClient.invalidateQueries({
          queryKey: privilegeKeys.columnPrivilegesList(project.ref),
        }),
      ])

      setIsLoading(false)

      callback?.()
    },
    [callback, project, queryClient]
  )

  return { apply, isLoading }
}

Subdomains

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free