import { isString } from '@vue/shared' import { computed, createSharedComposable, ref, useApi, useGlobal } from '#imports' import type { ProjectRole, Role, Roles } from '#imports' /** * Provides the roles a user currently has * * * `userRoles` - the roles a user has outside of projects * * `projectRoles` - the roles a user has in the current project (if one was loaded) * * `allRoles` - all roles a user has (userRoles + projectRoles) * * `hasRole` - a function to check if a user has a specific role * * `loadProjectRoles` - a function to load the project roles for a specific project (by id) */ export const useRoles = createSharedComposable(() => { const { user, previewAs } = useGlobal() const { api } = useApi() const projectRoles = ref>({}) const userRoles = computed>(() => { let roles = user.value?.roles ?? {} // if string populate key-value paired object if (isString(roles)) { roles = roles.split(',').reduce((acc, role) => { acc[role] = true return acc }, {}) } return roles }) const allRoles = computed(() => ({ ...userRoles.value, ...projectRoles.value, })) async function loadProjectRoles( projectId: string, options: { isSharedBase?: boolean; sharedBaseId?: string; isSharedErd?: boolean; sharedErdId?: string } = {}, ) { if (options?.isSharedBase) { const user = await api.auth.me( { project_id: projectId, }, { headers: { 'xc-shared-base-id': options?.sharedBaseId, }, }, ) projectRoles.value = user.roles } else if (options?.isSharedErd) { const user = await api.auth.me( { project_id: projectId, }, { headers: { 'xc-shared-erd-id': options?.sharedErdId, }, }, ) projectRoles.value = user.roles } else if (projectId) { const user = await api.auth.me({ project_id: projectId }) projectRoles.value = user.roles } else { projectRoles.value = {} } } function hasRole(role: Role | ProjectRole | string, includePreviewRoles = false) { if (previewAs.value && includePreviewRoles) { return previewAs.value === role } return allRoles.value[role] } return { allRoles, userRoles, projectRoles, loadProjectRoles, hasRole } })