import { Workspace, WorkspaceAcl } from '@/modules/workspaces/domain/types' import { DeleteWorkspaceRole, GetWorkspace, GetWorkspaceRoleForUser, GetWorkspaceRoles, GetWorkspaceRolesForUser, UpsertWorkspace, UpsertWorkspaceRole } from '@/modules/workspaces/domain/operations' import { Knex } from 'knex' import { Roles } from '@speckle/shared' const tables = { workspaces: (db: Knex) => db('workspaces'), workspacesAcl: (db: Knex) => db('workspace_acl') } export const getWorkspaceFactory = ({ db }: { db: Knex }): GetWorkspace => async ({ workspaceId }) => { const workspace = await tables .workspaces(db) .select('*') .where('id', '=', workspaceId) .first() return workspace || null } export const upsertWorkspaceFactory = ({ db }: { db: Knex }): UpsertWorkspace => async ({ workspace }) => { await tables .workspaces(db) .insert(workspace) .onConflict('id') .merge(['description', 'logoUrl', 'name', 'updatedAt']) } export const getWorkspaceRolesFactory = ({ db }: { db: Knex }): GetWorkspaceRoles => async ({ workspaceId }) => { return await tables.workspacesAcl(db).select('*').where({ workspaceId }) } export const getWorkspaceRoleForUserFactory = ({ db }: { db: Knex }): GetWorkspaceRoleForUser => async ({ userId, workspaceId }) => { return ( (await tables .workspacesAcl(db) .select('*') .where({ userId, workspaceId }) .first()) ?? null ) } export const getWorkspaceRolesForUserFactory = ({ db }: { db: Knex }): GetWorkspaceRolesForUser => async ({ userId }, options) => { const workspaceIdFilter = options?.workspaceIdFilter ?? [] const query = tables.workspacesAcl(db).select('*').where({ userId }) if (workspaceIdFilter.length > 0) { query.whereIn('workspaceId', workspaceIdFilter) } return await query } export const deleteWorkspaceRoleFactory = ({ db }: { db: Knex }): DeleteWorkspaceRole => async ({ userId, workspaceId }) => { const deletedRoles = await tables .workspacesAcl(db) .where({ workspaceId, userId }) .delete('*') if (deletedRoles.length === 0) { return null } // Given `workspaceId` and `userId` define a primary key for `workspace_acl` table, // query returns either 0 or 1 row in all cases return deletedRoles[0] } export const upsertWorkspaceRoleFactory = ({ db }: { db: Knex }): UpsertWorkspaceRole => async ({ userId, workspaceId, role }) => { // Verify requested role is valid workspace role const validRoles = Object.values(Roles.Workspace) if (!validRoles.includes(role)) { throw new Error(`Unexpected workspace role provided: ${role}`) } await tables .workspacesAcl(db) .insert({ userId, workspaceId, role }) .onConflict(['userId', 'workspaceId']) .merge(['role']) }