84 lines
1.9 KiB
JavaScript
84 lines
1.9 KiB
JavaScript
import knex from './knex';
|
|
import { fetchUsers } from './users';
|
|
import { verifyPrivilege } from './privileges';
|
|
import { HttpError } from './errors';
|
|
|
|
function curateDatabaseComment(comment, { users }) {
|
|
return {
|
|
id: comment.id,
|
|
body: comment.body,
|
|
parentId: comment.parent_id,
|
|
userId: comment.user_id,
|
|
user: users.find((user) => user.id === comment.user_id),
|
|
createdAt: comment.created_at,
|
|
};
|
|
}
|
|
|
|
function threadComments(thread, commentsByParentId) {
|
|
if (!thread) {
|
|
return [];
|
|
}
|
|
|
|
return thread.map((comment) => ({
|
|
...comment,
|
|
comments: threadComments(commentsByParentId[comment.id], commentsByParentId),
|
|
}));
|
|
}
|
|
|
|
function nestComments(comments) {
|
|
const commentsByParentId = comments.reduce((acc, comment) => {
|
|
if (!acc[comment.parentId]) {
|
|
acc[comment.parentId] = [];
|
|
}
|
|
|
|
acc[comment.parentId].push(comment);
|
|
|
|
return acc;
|
|
}, {});
|
|
|
|
return threadComments(commentsByParentId.null, commentsByParentId);
|
|
}
|
|
|
|
async function fetchPostComments(postId, { limit = 100 } = {}) {
|
|
const comments = await knex('comments')
|
|
.where('post_id', postId)
|
|
.orderBy('created_at', 'desc')
|
|
.limit(limit);
|
|
|
|
const users = await fetchUsers(comments.map((comment) => comment.user_id));
|
|
const curatedComments = comments.map((comment) => curateDatabaseComment(comment, { users }));
|
|
|
|
const nestedComments = nestComments(curatedComments);
|
|
|
|
return nestedComments;
|
|
}
|
|
|
|
async function addComment(comment, postId, user) {
|
|
await verifyPrivilege('addComment', user);
|
|
|
|
if (!comment.body) {
|
|
throw new HttpError({
|
|
statusMessage: 'Comment cannot be empty',
|
|
statusCode: 400,
|
|
});
|
|
}
|
|
|
|
const [commentEntry] = await knex('comments')
|
|
.insert({
|
|
body: comment.body,
|
|
post_id: postId,
|
|
parent_id: comment.parentId,
|
|
user_id: user.id,
|
|
})
|
|
.returning('*');
|
|
|
|
const users = await fetchUsers([commentEntry.user_id]);
|
|
|
|
return curateDatabaseComment(commentEntry, { users });
|
|
}
|
|
|
|
export {
|
|
fetchPostComments,
|
|
addComment,
|
|
};
|