c047ac7be1
* chore(server): move cursor utils to db helper * move collection
192 lines
5.7 KiB
TypeScript
192 lines
5.7 KiB
TypeScript
import { UserEmails } from '@/modules/core/dbSchema'
|
|
import { compositeCursorTools } from '@/modules/shared/helpers/dbHelper'
|
|
import {
|
|
CreateWorkspaceJoinRequest,
|
|
GetWorkspaceJoinRequest,
|
|
UpdateWorkspaceJoinRequestStatus
|
|
} from '@/modules/workspaces/domain/operations'
|
|
import {
|
|
WorkspaceJoinRequest,
|
|
WorkspaceJoinRequestStatus
|
|
} from '@/modules/workspacesCore/domain/types'
|
|
import {
|
|
WorkspaceAcl,
|
|
WorkspaceJoinRequests
|
|
} from '@/modules/workspacesCore/helpers/db'
|
|
import { Roles } from '@speckle/shared'
|
|
import { Knex } from 'knex'
|
|
import { SetRequired } from 'type-fest'
|
|
|
|
const tables = {
|
|
workspaceJoinRequests: (db: Knex) =>
|
|
db<WorkspaceJoinRequest>(WorkspaceJoinRequests.name)
|
|
}
|
|
|
|
export const createWorkspaceJoinRequestFactory =
|
|
({ db }: { db: Knex }): CreateWorkspaceJoinRequest =>
|
|
async ({ workspaceJoinRequest }) => {
|
|
const res = await tables
|
|
.workspaceJoinRequests(db)
|
|
.insert(workspaceJoinRequest, '*')
|
|
.onConflict()
|
|
.ignore()
|
|
return res[0]
|
|
}
|
|
|
|
export const updateWorkspaceJoinRequestStatusFactory =
|
|
({ db }: { db: Knex }): UpdateWorkspaceJoinRequestStatus =>
|
|
async ({ workspaceId, userId, status }) => {
|
|
return await tables
|
|
.workspaceJoinRequests(db)
|
|
.insert({ workspaceId, userId, status })
|
|
.onConflict(['workspaceId', 'userId'])
|
|
.merge(['status'])
|
|
}
|
|
|
|
export const getWorkspaceJoinRequestFactory =
|
|
({ db }: { db: Knex }): GetWorkspaceJoinRequest =>
|
|
async ({ workspaceId, userId, status }) => {
|
|
const query = tables
|
|
.workspaceJoinRequests(db)
|
|
.where(WorkspaceJoinRequests.col.workspaceId, workspaceId)
|
|
.where(WorkspaceJoinRequests.col.userId, userId)
|
|
if (status) {
|
|
query.andWhere(WorkspaceJoinRequests.col.status, status)
|
|
}
|
|
|
|
return await query.first()
|
|
}
|
|
|
|
type WorkspaceJoinRequestFilter = {
|
|
workspaceId?: string
|
|
status?: WorkspaceJoinRequestStatus | null
|
|
userId: string
|
|
}
|
|
|
|
const adminWorkspaceJoinRequestsBaseQueryFactory =
|
|
(db: Knex) => (filter: SetRequired<WorkspaceJoinRequestFilter, 'workspaceId'>) => {
|
|
const query = tables
|
|
.workspaceJoinRequests(db)
|
|
.innerJoin(
|
|
WorkspaceAcl.name,
|
|
WorkspaceAcl.col.workspaceId,
|
|
WorkspaceJoinRequests.col.workspaceId
|
|
)
|
|
.join(UserEmails.name, UserEmails.col.userId, WorkspaceJoinRequests.col.userId)
|
|
// returning the primary here as a shortcut
|
|
// should be doing an intersection with the workspace domains, the users emails
|
|
// and be distincted to a single user
|
|
// but for now, multi email usage is low enough to not warrant that here
|
|
.where(UserEmails.col.primary, '=', true)
|
|
.where(WorkspaceAcl.col.role, Roles.Workspace.Admin)
|
|
.where(WorkspaceAcl.col.userId, filter.userId)
|
|
.where(WorkspaceJoinRequests.col.workspaceId, filter.workspaceId)
|
|
.whereNot(WorkspaceJoinRequests.col.status, 'dismissed')
|
|
if (filter.status) query.andWhere(WorkspaceJoinRequests.col.status, filter.status)
|
|
return query
|
|
}
|
|
|
|
export const getAdminWorkspaceJoinRequestsFactory =
|
|
({ db }: { db: Knex }) =>
|
|
async ({
|
|
filter,
|
|
cursor,
|
|
limit
|
|
}: {
|
|
filter: SetRequired<WorkspaceJoinRequestFilter, 'workspaceId'>
|
|
cursor?: string
|
|
limit: number
|
|
}) => {
|
|
const { applyCursorSortAndFilter, resolveNewCursor } = compositeCursorTools({
|
|
schema: WorkspaceJoinRequests,
|
|
cols: ['createdAt', 'userId']
|
|
})
|
|
const query = adminWorkspaceJoinRequestsBaseQueryFactory(db)(filter)
|
|
applyCursorSortAndFilter({
|
|
query,
|
|
cursor
|
|
})
|
|
|
|
query
|
|
.select<WorkspaceJoinRequest[]>([
|
|
...WorkspaceJoinRequests.cols,
|
|
UserEmails.col.email
|
|
])
|
|
.limit(limit)
|
|
|
|
const items = await query
|
|
const newCursor = resolveNewCursor(items)
|
|
|
|
return {
|
|
items,
|
|
cursor: newCursor
|
|
}
|
|
}
|
|
|
|
export const countAdminWorkspaceJoinRequestsFactory =
|
|
({ db }: { db: Knex }) =>
|
|
async ({
|
|
filter
|
|
}: {
|
|
filter: SetRequired<WorkspaceJoinRequestFilter, 'workspaceId'>
|
|
}) => {
|
|
const query = adminWorkspaceJoinRequestsBaseQueryFactory(db)(filter)
|
|
|
|
const [res] = await query.count()
|
|
return parseInt(res.count.toString())
|
|
}
|
|
|
|
const workspaceJoinRequestsBaseQueryFactory =
|
|
(db: Knex) => (filter: WorkspaceJoinRequestFilter) => {
|
|
const query = tables
|
|
.workspaceJoinRequests(db)
|
|
.where(WorkspaceJoinRequests.col.userId, filter.userId)
|
|
.whereNot(WorkspaceJoinRequests.col.status, 'dismissed')
|
|
if (filter.status) query.andWhere(WorkspaceJoinRequests.col.status, filter.status)
|
|
if (filter.userId) query.andWhere(WorkspaceJoinRequests.col.userId, filter.userId)
|
|
if (filter.workspaceId)
|
|
query.andWhere(WorkspaceJoinRequests.col.workspaceId, filter.workspaceId)
|
|
return query
|
|
}
|
|
|
|
export const getWorkspaceJoinRequestsFactory =
|
|
({ db }: { db: Knex }) =>
|
|
async ({
|
|
filter,
|
|
cursor,
|
|
limit
|
|
}: {
|
|
filter: WorkspaceJoinRequestFilter
|
|
cursor?: string
|
|
limit: number
|
|
}) => {
|
|
const query = workspaceJoinRequestsBaseQueryFactory(db)(filter)
|
|
const { applyCursorSortAndFilter, resolveNewCursor } = compositeCursorTools({
|
|
schema: WorkspaceJoinRequests,
|
|
cols: ['createdAt', 'userId']
|
|
})
|
|
applyCursorSortAndFilter({
|
|
query,
|
|
cursor
|
|
})
|
|
|
|
query.select<WorkspaceJoinRequest[]>(WorkspaceJoinRequests.cols).limit(limit)
|
|
|
|
const items = await query
|
|
const newCursor = resolveNewCursor(items)
|
|
|
|
return {
|
|
items,
|
|
cursor: newCursor
|
|
}
|
|
}
|
|
|
|
export const countWorkspaceJoinRequestsFactory =
|
|
({ db }: { db: Knex }) =>
|
|
async ({ filter }: { filter: WorkspaceJoinRequestFilter }) => {
|
|
const query = workspaceJoinRequestsBaseQueryFactory(db)(filter)
|
|
|
|
const [res] = await query.count()
|
|
return parseInt(res.count.toString())
|
|
}
|