Home / Function/ deriveRoleChangeActions() — supabase Function Reference

deriveRoleChangeActions() — supabase Function Reference

Architecture documentation for the deriveRoleChangeActions() function in UpdateRolesPanel.utils.ts from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  990256d1_dc74_dcf7_cfc5_63ea22448f3e["deriveRoleChangeActions()"]
  08b3c701_2442_915a_319d_41013f9dc8ec["UpdateRolesConfirmationModal()"]
  08b3c701_2442_915a_319d_41013f9dc8ec -->|calls| 990256d1_dc74_dcf7_cfc5_63ea22448f3e
  style 990256d1_dc74_dcf7_cfc5_63ea22448f3e fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Organization/TeamSettings/UpdateRolesPanel/UpdateRolesPanel.utils.ts lines 100–189

export const deriveRoleChangeActions = (
  existingRoles: OrganizationRole[],
  changesToRoles: {
    removed: ProjectRoleConfiguration[]
    added: ProjectRoleConfiguration[]
    updated: {
      ref?: string
      name?: string
      originalRole: number
      originalBaseRole?: number
      updatedRole: number
    }[]
  }
) => {
  const { removed, added, updated } = changesToRoles
  const toRemove: number[] = []
  const toAssign: { roleId: number; refs: string[] }[] = []
  const toUpdate: { roleId: number; refs: string[] }[] = []

  const groupByAddedRoles = groupBy(added, 'roleId')
  const groupByRemovedRoles = groupBy(removed, 'roleId')
  const groupByUpdatingFromRoles = groupBy(updated, 'originalRole')
  const groupByUpdatingToRoles = groupBy(updated, 'updatedRole')
  const existingProjectRolesByBaseIds = existingRoles
    .filter((r) => (r?.projects ?? []).length > 0)
    .map((r) => r.base_role_id)

  existingRoles.forEach((role) => {
    const projectRefsApplied = role.projects.map((x) => x.ref)
    if (projectRefsApplied.length === 0) {
      // [Joshen] In this case we're removing an org scope role, skip all the chekcs
      return toRemove.push(role.id)
    }

    const toRemoveRole = projectRefsApplied.every((ref) => {
      const isRemoved = removed.map((r) => r.ref).some((x) => x === ref)
      const isUpdated = updated.map((r) => r.ref).some((x) => x === ref)
      return isRemoved || isUpdated
    })
    const isRoleGettingAdded = added.some((r) => r.roleId === role.base_role_id)
    const isRoleGettingUpdatedTo = updated.some((r) => r.updatedRole === role.base_role_id)

    if (toRemoveRole && !isRoleGettingAdded && !isRoleGettingUpdatedTo) {
      return toRemove.push(role.id)
    }

    const projectsToAddToRole = (groupByAddedRoles[role.base_role_id]?.map((r) => r.ref) ??
      []) as string[]
    const projectsToRemoveFromRole = (groupByRemovedRoles[role.id]?.map((r) => r.ref) ??
      []) as string[]
    const projectsUpdatingFromRole = (groupByUpdatingFromRoles[role.id]?.map((r) => r.ref) ??
      []) as string[]
    const projectsUpdatingToRole = (groupByUpdatingToRoles[role.base_role_id]?.map((r) => r.ref) ??
      []) as string[]
    const projectRefsAppliedUpdated = projectRefsApplied
      .filter((x) => !projectsToRemoveFromRole.includes(x))
      .filter((x) => !projectsUpdatingFromRole.includes(x))
      .concat(projectsToAddToRole)
      .concat(projectsUpdatingToRole)

    if (!isEqual(projectRefsApplied, projectRefsAppliedUpdated)) {
      toUpdate.push({ roleId: role.id, refs: projectRefsAppliedUpdated })
    }
  })

  Object.keys(groupByAddedRoles).forEach((roleId) => {
    if (!existingProjectRolesByBaseIds.includes(Number(roleId))) {
      toAssign.push({
        roleId: Number(roleId),
        refs: groupByAddedRoles[roleId].map((x) => x.ref).filter((x) => x !== undefined),
      })
    }
  })

  Object.keys(groupByUpdatingToRoles).forEach((roleId) => {
    if (!existingProjectRolesByBaseIds.includes(Number(roleId))) {
      toAssign.push({
        roleId: Number(roleId),
        refs: groupByUpdatingToRoles[roleId].map((x) => x.ref).filter((x) => x !== undefined),
      })
    }
  })

  // [Joshen] Am sorting the results just so its more deterministic when writing tests
  return {
    toRemove: toRemove.sort((a, b) => a - b),
    toAssign: toAssign.map((x) => ({ ...x, refs: x.refs.sort((a, b) => a.localeCompare(b)) })),
    toUpdate: toUpdate.map((x) => ({ ...x, refs: x.refs.sort((a, b) => a.localeCompare(b)) })),
  }
}

Subdomains

Frequently Asked Questions

What does deriveRoleChangeActions() do?
deriveRoleChangeActions() is a function in the supabase codebase.
What calls deriveRoleChangeActions()?
deriveRoleChangeActions() is called by 1 function(s): UpdateRolesConfirmationModal.

Analyze Your Own Codebase

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

Try Supermodel Free