chore(server): comments IoC 17 - remainind dataloaders
This commit is contained in:
@@ -4,7 +4,11 @@ import {
|
||||
ViewerResourceGroup,
|
||||
ViewerResourceItem
|
||||
} from '@/modules/comments/domain/types'
|
||||
import { CommentLinkRecord, CommentRecord } from '@/modules/comments/helpers/types'
|
||||
import {
|
||||
CommentLinkRecord,
|
||||
CommentRecord,
|
||||
CommentViewRecord
|
||||
} from '@/modules/comments/helpers/types'
|
||||
import {
|
||||
CreateCommentInput,
|
||||
CreateCommentReplyInput,
|
||||
@@ -110,6 +114,62 @@ export type GetPaginatedProjectCommentsTotalCount = (
|
||||
}
|
||||
) => Promise<number>
|
||||
|
||||
export type GetUserCommentsViewedAt = (
|
||||
commentIds: string[],
|
||||
userId: string
|
||||
) => Promise<CommentViewRecord[]>
|
||||
|
||||
export type GetCommitCommentCounts = (
|
||||
commitIds: string[],
|
||||
options?: Partial<{
|
||||
threadsOnly: boolean
|
||||
includeArchived: boolean
|
||||
}>
|
||||
) => Promise<
|
||||
{
|
||||
commitId: string
|
||||
count: number
|
||||
}[]
|
||||
>
|
||||
|
||||
export type GetBranchCommentCounts = (
|
||||
branchIds: string[],
|
||||
options?: Partial<{
|
||||
threadsOnly: boolean
|
||||
includeArchived: boolean
|
||||
}>
|
||||
) => Promise<
|
||||
{
|
||||
count: number
|
||||
id: string
|
||||
}[]
|
||||
>
|
||||
|
||||
export type GetCommentReplyCounts = (
|
||||
threadIds: string[],
|
||||
options?: Partial<{
|
||||
includeArchived: boolean
|
||||
}>
|
||||
) => Promise<
|
||||
{
|
||||
threadId: string
|
||||
count: number
|
||||
}[]
|
||||
>
|
||||
|
||||
export type GetCommentReplyAuthorIds = (
|
||||
threadIds: string[],
|
||||
options?: Partial<{
|
||||
includeArchived: boolean
|
||||
}>
|
||||
) => Promise<{ [parentCommentId: string]: string[] }>
|
||||
|
||||
export type GetCommentParents = (replyIds: string[]) => Promise<
|
||||
(CommentRecord & {
|
||||
replyId: string
|
||||
})[]
|
||||
>
|
||||
|
||||
export type ResolvePaginatedProjectCommentsLatestModelResources = (
|
||||
resourceIdString: string | null | undefined
|
||||
) => Promise<BranchLatestCommit[]>
|
||||
|
||||
@@ -35,15 +35,20 @@ import { getBranchLatestCommits } from '@/modules/core/repositories/branches'
|
||||
import {
|
||||
CheckStreamResourceAccess,
|
||||
DeleteComment,
|
||||
GetBranchCommentCounts,
|
||||
GetComment,
|
||||
GetCommentParents,
|
||||
GetCommentReplyAuthorIds,
|
||||
GetCommentReplyCounts,
|
||||
GetCommentsResources,
|
||||
GetCommitCommentCounts,
|
||||
GetPaginatedBranchCommentsPage,
|
||||
GetPaginatedCommitCommentsPage,
|
||||
GetPaginatedCommitCommentsTotalCount,
|
||||
GetPaginatedProjectCommentsPage,
|
||||
GetPaginatedProjectCommentsTotalCount,
|
||||
GetUserCommentsViewedAt,
|
||||
InsertCommentLinks,
|
||||
InsertCommentPayload,
|
||||
InsertComments,
|
||||
MarkCommentUpdated,
|
||||
MarkCommentViewed,
|
||||
@@ -121,15 +126,18 @@ export const getCommentsResourcesFactory =
|
||||
return keyBy(results, 'commentId')
|
||||
}
|
||||
|
||||
export async function getCommentsViewedAt(commentIds: string[], userId: string) {
|
||||
if (!commentIds?.length || !userId) return []
|
||||
export const getCommentsViewedAtFactory =
|
||||
(deps: { db: Knex }): GetUserCommentsViewedAt =>
|
||||
async (commentIds: string[], userId: string) => {
|
||||
if (!commentIds?.length || !userId) return []
|
||||
|
||||
const q = CommentViews.knex<CommentViewRecord[]>()
|
||||
.where(CommentViews.col.userId, userId)
|
||||
.whereIn(CommentViews.col.commentId, commentIds)
|
||||
const q = tables
|
||||
.commentViews(deps.db)
|
||||
.where(CommentViews.col.userId, userId)
|
||||
.whereIn(CommentViews.col.commentId, commentIds)
|
||||
|
||||
return await q
|
||||
}
|
||||
return await q
|
||||
}
|
||||
|
||||
type GetBatchedStreamCommentsOptions = BatchedSelectOptions & {
|
||||
/**
|
||||
@@ -228,36 +236,39 @@ export const getStreamCommentCountsFactory =
|
||||
return results.map((r) => ({ ...r, count: parseInt(r.count) }))
|
||||
}
|
||||
|
||||
export async function getCommitCommentCounts(
|
||||
commitIds: string[],
|
||||
options?: Partial<{ threadsOnly: boolean; includeArchived: boolean }>
|
||||
) {
|
||||
if (!commitIds?.length) return []
|
||||
const { threadsOnly, includeArchived } = options || {}
|
||||
export const getCommitCommentCountsFactory =
|
||||
(deps: { db: Knex }): GetCommitCommentCounts =>
|
||||
async (
|
||||
commitIds: string[],
|
||||
options?: Partial<{ threadsOnly: boolean; includeArchived: boolean }>
|
||||
) => {
|
||||
if (!commitIds?.length) return []
|
||||
const { threadsOnly, includeArchived } = options || {}
|
||||
|
||||
const q = CommentLinks.knex()
|
||||
.select(CommentLinks.col.resourceId)
|
||||
.where(CommentLinks.col.resourceType, ResourceType.Commit)
|
||||
.whereIn(CommentLinks.col.resourceId, commitIds)
|
||||
.count()
|
||||
.groupBy(CommentLinks.col.resourceId)
|
||||
const q = tables
|
||||
.commentLinks(deps.db)
|
||||
.select(CommentLinks.col.resourceId)
|
||||
.where(CommentLinks.col.resourceType, ResourceType.Commit)
|
||||
.whereIn(CommentLinks.col.resourceId, commitIds)
|
||||
.count()
|
||||
.groupBy(CommentLinks.col.resourceId)
|
||||
|
||||
if (threadsOnly || !includeArchived) {
|
||||
q.innerJoin(Comments.name, Comments.col.id, CommentLinks.col.commentId)
|
||||
if (threadsOnly || !includeArchived) {
|
||||
q.innerJoin(Comments.name, Comments.col.id, CommentLinks.col.commentId)
|
||||
|
||||
if (threadsOnly) {
|
||||
q.where(Comments.col.parentComment, null)
|
||||
if (threadsOnly) {
|
||||
q.where(Comments.col.parentComment, null)
|
||||
}
|
||||
|
||||
if (!includeArchived) {
|
||||
q.where(Comments.col.archived, false)
|
||||
}
|
||||
}
|
||||
|
||||
if (!includeArchived) {
|
||||
q.where(Comments.col.archived, false)
|
||||
}
|
||||
const results = (await q) as { resourceId: string; count: string }[]
|
||||
return results.map((r) => ({ commitId: r.resourceId, count: parseInt(r.count) }))
|
||||
}
|
||||
|
||||
const results = (await q) as { resourceId: string; count: string }[]
|
||||
return results.map((r) => ({ commitId: r.resourceId, count: parseInt(r.count) }))
|
||||
}
|
||||
|
||||
export const getStreamCommentCountFactory =
|
||||
(deps: { db: Knex }) =>
|
||||
async (
|
||||
@@ -268,89 +279,95 @@ export const getStreamCommentCountFactory =
|
||||
return res?.count || 0
|
||||
}
|
||||
|
||||
export async function getBranchCommentCounts(
|
||||
branchIds: string[],
|
||||
options?: Partial<{ threadsOnly: boolean; includeArchived: boolean }>
|
||||
) {
|
||||
if (!branchIds.length) return []
|
||||
const { threadsOnly, includeArchived } = options || {}
|
||||
export const getBranchCommentCountsFactory =
|
||||
(deps: { db: Knex }): GetBranchCommentCounts =>
|
||||
async (
|
||||
branchIds: string[],
|
||||
options?: Partial<{ threadsOnly: boolean; includeArchived: boolean }>
|
||||
) => {
|
||||
if (!branchIds.length) return []
|
||||
const { threadsOnly, includeArchived } = options || {}
|
||||
|
||||
const q = Branches.knex()
|
||||
.select(Branches.col.id)
|
||||
.whereIn(Branches.col.id, branchIds)
|
||||
.innerJoin(BranchCommits.name, BranchCommits.col.branchId, Branches.col.id)
|
||||
.innerJoin(CommentLinks.name, function () {
|
||||
this.on(CommentLinks.col.resourceId, BranchCommits.col.commitId).andOnVal(
|
||||
CommentLinks.col.resourceType,
|
||||
'commit' as CommentLinkResourceType
|
||||
)
|
||||
})
|
||||
.innerJoin(Comments.name, Comments.col.id, CommentLinks.col.commentId)
|
||||
.count()
|
||||
.groupBy(Branches.col.id)
|
||||
const q = tables
|
||||
.branches(deps.db)
|
||||
.select(Branches.col.id)
|
||||
.whereIn(Branches.col.id, branchIds)
|
||||
.innerJoin(BranchCommits.name, BranchCommits.col.branchId, Branches.col.id)
|
||||
.innerJoin(CommentLinks.name, function () {
|
||||
this.on(CommentLinks.col.resourceId, BranchCommits.col.commitId).andOnVal(
|
||||
CommentLinks.col.resourceType,
|
||||
'commit' as CommentLinkResourceType
|
||||
)
|
||||
})
|
||||
.innerJoin(Comments.name, Comments.col.id, CommentLinks.col.commentId)
|
||||
.count()
|
||||
.groupBy(Branches.col.id)
|
||||
|
||||
if (threadsOnly) {
|
||||
q.andWhere(Comments.col.parentComment, null)
|
||||
if (threadsOnly) {
|
||||
q.andWhere(Comments.col.parentComment, null)
|
||||
}
|
||||
|
||||
if (!includeArchived) {
|
||||
q.andWhere(Comments.col.archived, false)
|
||||
}
|
||||
|
||||
const results = (await q) as { id: string; count: string }[]
|
||||
return results.map((r) => ({ ...r, count: parseInt(r.count) }))
|
||||
}
|
||||
|
||||
if (!includeArchived) {
|
||||
q.andWhere(Comments.col.archived, false)
|
||||
export const getCommentReplyCountsFactory =
|
||||
(deps: { db: Knex }): GetCommentReplyCounts =>
|
||||
async (threadIds: string[], options?: Partial<{ includeArchived: boolean }>) => {
|
||||
if (!threadIds.length) return []
|
||||
const { includeArchived } = options || {}
|
||||
|
||||
const q = tables
|
||||
.comments(deps.db)
|
||||
.select(Comments.col.parentComment)
|
||||
.whereIn(Comments.col.parentComment, threadIds)
|
||||
.count()
|
||||
.groupBy(Comments.col.parentComment)
|
||||
|
||||
if (!includeArchived) {
|
||||
q.andWhere(Comments.col.archived, false)
|
||||
}
|
||||
|
||||
const results = (await q) as { parentComment: string; count: string }[]
|
||||
return results.map((r) => ({ threadId: r.parentComment, count: parseInt(r.count) }))
|
||||
}
|
||||
|
||||
const results = (await q) as { id: string; count: string }[]
|
||||
return results.map((r) => ({ ...r, count: parseInt(r.count) }))
|
||||
}
|
||||
export const getCommentReplyAuthorIdsFactory =
|
||||
(deps: { db: Knex }): GetCommentReplyAuthorIds =>
|
||||
async (threadIds: string[], options?: Partial<{ includeArchived: boolean }>) => {
|
||||
if (!threadIds.length) return {}
|
||||
const { includeArchived } = options || {}
|
||||
|
||||
export async function getCommentReplyCounts(
|
||||
threadIds: string[],
|
||||
options?: Partial<{ includeArchived: boolean }>
|
||||
) {
|
||||
if (!threadIds.length) return []
|
||||
const { includeArchived } = options || {}
|
||||
const q = tables
|
||||
.comments(deps.db)
|
||||
.select<{ parentComment: string; authorId: string }[]>([
|
||||
Comments.col.parentComment,
|
||||
Comments.col.authorId
|
||||
])
|
||||
.whereIn(Comments.col.parentComment, threadIds)
|
||||
.groupBy(Comments.col.parentComment, Comments.col.authorId)
|
||||
|
||||
const q = Comments.knex()
|
||||
.select(Comments.col.parentComment)
|
||||
.whereIn(Comments.col.parentComment, threadIds)
|
||||
.count()
|
||||
.groupBy(Comments.col.parentComment)
|
||||
if (!includeArchived) {
|
||||
q.andWhere(Comments.col.archived, false)
|
||||
}
|
||||
|
||||
if (!includeArchived) {
|
||||
q.andWhere(Comments.col.archived, false)
|
||||
const results = await q
|
||||
return reduce(
|
||||
results,
|
||||
(result, item) => {
|
||||
;(result[item.parentComment] || (result[item.parentComment] = [])).push(
|
||||
item.authorId
|
||||
)
|
||||
return result
|
||||
},
|
||||
{} as Record<string, string[]>
|
||||
)
|
||||
}
|
||||
|
||||
const results = (await q) as { parentComment: string; count: string }[]
|
||||
return results.map((r) => ({ threadId: r.parentComment, count: parseInt(r.count) }))
|
||||
}
|
||||
|
||||
export async function getCommentReplyAuthorIds(
|
||||
threadIds: string[],
|
||||
options?: Partial<{ includeArchived: boolean }>
|
||||
) {
|
||||
if (!threadIds.length) return {}
|
||||
const { includeArchived } = options || {}
|
||||
|
||||
const q = Comments.knex()
|
||||
.select([Comments.col.parentComment, Comments.col.authorId])
|
||||
.whereIn(Comments.col.parentComment, threadIds)
|
||||
.groupBy(Comments.col.parentComment, Comments.col.authorId)
|
||||
|
||||
if (!includeArchived) {
|
||||
q.andWhere(Comments.col.archived, false)
|
||||
}
|
||||
|
||||
const results = (await q) as { parentComment: string; authorId: string }[]
|
||||
return reduce(
|
||||
results,
|
||||
(result, item) => {
|
||||
;(result[item.parentComment] || (result[item.parentComment] = [])).push(
|
||||
item.authorId
|
||||
)
|
||||
return result
|
||||
},
|
||||
{} as Record<string, string[]>
|
||||
)
|
||||
}
|
||||
|
||||
const getPaginatedCommitCommentsBaseQueryFactory =
|
||||
(deps: { db: Knex }) =>
|
||||
<T = CommentRecord[]>(
|
||||
@@ -675,17 +692,20 @@ export const getPaginatedProjectCommentsTotalCountFactory =
|
||||
return parseInt(row.count || '0')
|
||||
}
|
||||
|
||||
export async function getCommentParents(replyIds: string[]) {
|
||||
const q = Comments.knex()
|
||||
.select<Array<CommentRecord & { replyId: string }>>([
|
||||
knex.raw('?? as "replyId"', [Comments.col.id]),
|
||||
knex.raw('"c2".*')
|
||||
])
|
||||
.innerJoin(`${Comments.name} as c2`, `c2.id`, Comments.col.parentComment)
|
||||
.whereIn(Comments.col.id, replyIds)
|
||||
.whereNotNull(Comments.col.parentComment)
|
||||
return await q
|
||||
}
|
||||
export const getCommentParentsFactory =
|
||||
(deps: { db: Knex }): GetCommentParents =>
|
||||
async (replyIds: string[]) => {
|
||||
const q = tables
|
||||
.comments(deps.db)
|
||||
.select<Array<CommentRecord & { replyId: string }>>([
|
||||
knex.raw('?? as "replyId"', [Comments.col.id]),
|
||||
knex.raw('"c2".*')
|
||||
])
|
||||
.innerJoin(`${Comments.name} as c2`, `c2.id`, Comments.col.parentComment)
|
||||
.whereIn(Comments.col.id, replyIds)
|
||||
.whereNotNull(Comments.col.parentComment)
|
||||
return await q
|
||||
}
|
||||
|
||||
export const markCommentViewedFactory =
|
||||
(deps: { db: Knex }): MarkCommentViewed =>
|
||||
@@ -698,18 +718,6 @@ export const markCommentViewedFactory =
|
||||
return !!(await query)
|
||||
}
|
||||
|
||||
export async function insertComment(
|
||||
input: InsertCommentPayload,
|
||||
options?: Partial<{ trx: Knex.Transaction }>
|
||||
): Promise<CommentRecord> {
|
||||
const finalInput = { ...input, id: input.id || generateCommentId() }
|
||||
const q = Comments.knex().insert(finalInput, '*')
|
||||
if (options?.trx) q.transacting(options.trx)
|
||||
|
||||
const [res] = await q
|
||||
return res as CommentRecord
|
||||
}
|
||||
|
||||
export const markCommentUpdatedFactory =
|
||||
(deps: { db: Knex }): MarkCommentUpdated =>
|
||||
async (commentId: string) => {
|
||||
|
||||
@@ -32,13 +32,13 @@ import {
|
||||
} from '@/modules/core/repositories/commits'
|
||||
import { ResourceIdentifier, Scope } from '@/modules/core/graph/generated/graphql'
|
||||
import {
|
||||
getBranchCommentCounts,
|
||||
getCommentParents,
|
||||
getCommentReplyAuthorIds,
|
||||
getCommentReplyCounts,
|
||||
getBranchCommentCountsFactory,
|
||||
getCommentParentsFactory,
|
||||
getCommentReplyAuthorIdsFactory,
|
||||
getCommentReplyCountsFactory,
|
||||
getCommentsResourcesFactory,
|
||||
getCommentsViewedAt,
|
||||
getCommitCommentCounts,
|
||||
getCommentsViewedAtFactory,
|
||||
getCommitCommentCountsFactory,
|
||||
getStreamCommentCountsFactory
|
||||
} from '@/modules/comments/repositories/comments'
|
||||
import {
|
||||
@@ -99,6 +99,12 @@ const getFunctionAutomationCounts = getFunctionAutomationCountsFactory({ db })
|
||||
const getStreamCommentCounts = getStreamCommentCountsFactory({ db })
|
||||
const getAutomationRunsTriggers = getAutomationRunsTriggersFactory({ db })
|
||||
const getCommentsResources = getCommentsResourcesFactory({ db })
|
||||
const getCommentsViewedAt = getCommentsViewedAtFactory({ db })
|
||||
const getCommitCommentCounts = getCommitCommentCountsFactory({ db })
|
||||
const getBranchCommentCounts = getBranchCommentCountsFactory({ db })
|
||||
const getCommentReplyCounts = getCommentReplyCountsFactory({ db })
|
||||
const getCommentReplyAuthorIds = getCommentReplyAuthorIdsFactory({ db })
|
||||
const getCommentParents = getCommentParentsFactory({ db })
|
||||
|
||||
/**
|
||||
* TODO: Lazy load DataLoaders to reduce memory usage
|
||||
|
||||
Reference in New Issue
Block a user