@wepublish/api-db-mongodb
Version:
We.publish Database adapter for mongoDB
230 lines • 9.19 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MongoDBCommentAdapter = void 0;
const api_1 = require("@wepublish/api");
const cursor_1 = require("./cursor");
const defaults_1 = require("./defaults");
const schema_1 = require("./schema");
function commentSortFieldForSort(sort) {
switch (sort) {
case api_1.CommentSort.CreatedAt:
return 'createdAt';
case api_1.CommentSort.ModifiedAt:
return 'modifiedAt';
}
}
function commentDateForSort(comment, sort) {
switch (sort) {
case api_1.CommentSort.CreatedAt:
return comment.createdAt;
case api_1.CommentSort.ModifiedAt:
return comment.modifiedAt;
}
}
class MongoDBCommentAdapter {
constructor(db, locale) {
this.comments = db.collection(schema_1.CollectionName.Comments);
this.locale = locale;
}
async addPublicComment({ input }) {
const { text } = input, data = __rest(input, ["text"]);
const { ops } = await this.comments.insertOne(Object.assign(Object.assign({}, data), { revisions: [
{
text,
createdAt: new Date()
}
], createdAt: new Date(), modifiedAt: new Date() }));
const _a = ops[0], { _id: id } = _a, comment = __rest(_a, ["_id"]);
return Object.assign(Object.assign({}, comment), { id,
text });
}
async updatePublicComment({ id, text, state }) {
const { value } = await this.comments.findOneAndUpdate({ _id: id }, {
$set: {
state,
modifiedAt: new Date()
},
$addToSet: {
revisions: {
text,
createdAt: new Date()
}
}
}, {
returnOriginal: false
});
if (!value)
return null;
const { _id: outID } = value, comment = __rest(value, ["_id"]);
return Object.assign(Object.assign({}, comment), { id: outID, text });
}
async getComments({ filter, sort, order, cursor, limit }) {
var _a;
const metaFilters = [];
if (filter === null || filter === void 0 ? void 0 : filter.state) {
metaFilters.push({ state: filter.state });
}
const limitCount = Math.min(limit.count, defaults_1.MaxResultsPerPage);
const sortDirection = limit.type === api_1.LimitType.First ? order : -order;
const cursorData = cursor.type !== api_1.InputCursorType.None ? cursor_1.Cursor.from(cursor.data) : undefined;
const expr = order === api_1.SortOrder.Ascending
? cursor.type === api_1.InputCursorType.After
? '$gt'
: '$lt'
: cursor.type === api_1.InputCursorType.After
? '$lt'
: '$gt';
const sortField = commentSortFieldForSort(sort);
const cursorFilter = cursorData
? {
$or: [
{ [sortField]: { [expr]: cursorData.date } },
{ _id: { [expr]: cursorData.id }, [sortField]: cursorData.date }
]
}
: {};
const [totalCount, comments] = await Promise.all([
this.comments.countDocuments({}, {
collation: { locale: this.locale, strength: 2 }
}),
this.comments
.aggregate([
// sort depending on state value
{
$addFields: {
stateSort: {
$indexOfArray: [
[
api_1.CommentState.PendingApproval,
api_1.CommentState.PendingUserChanges,
api_1.CommentState.Approved,
api_1.CommentState.Rejected
],
'$state'
]
}
}
},
{
$sort: {
stateSort: 1,
[sortField]: sortDirection
}
}
], { collation: { locale: this.locale, strength: 2 } })
.match(metaFilters.length ? { $and: metaFilters } : {})
.match(cursorFilter)
.skip((_a = limit.skip) !== null && _a !== void 0 ? _a : 0)
.limit(limitCount + 1)
.toArray()
]);
const nodes = comments.slice(0, limitCount);
if (limit.type === api_1.LimitType.Last) {
nodes.reverse();
}
const hasNextPage = limit.type === api_1.LimitType.First
? comments.length > limitCount
: cursor.type === api_1.InputCursorType.Before;
const hasPreviousPage = limit.type === api_1.LimitType.Last
? comments.length > limitCount
: cursor.type === api_1.InputCursorType.After;
const firstComment = nodes[0];
const lastComment = nodes[nodes.length - 1];
const startCursor = firstComment
? new cursor_1.Cursor(firstComment._id, commentDateForSort(firstComment, sort)).toString()
: null;
const endCursor = lastComment
? new cursor_1.Cursor(lastComment._id, commentDateForSort(lastComment, sort)).toString()
: null;
return {
nodes: comments.map((_a) => {
var { _id: id } = _a, comment = __rest(_a, ["_id"]);
return (Object.assign({ id }, comment));
}),
pageInfo: {
startCursor,
endCursor,
hasNextPage,
hasPreviousPage
},
totalCount
};
}
async getPublicCommentsForItemByID(args) {
const { id, userID } = args;
let userUnapprovedComments = [];
const comments = await this.comments
.aggregate([{ $sort: { modifiedAt: -1 } }], {
collation: { locale: this.locale, strength: 2 }
})
.match({
$and: [{ itemID: id }, { state: api_1.CommentState.Approved, parentID: null }]
})
.toArray();
if (userID) {
userUnapprovedComments = await this.comments
.aggregate([{ $sort: { 'modifiedAt.date': -1 } }], {
collation: { locale: this.locale, strength: 2 }
})
.match({
$and: [{ itemID: id }, { userID }, { state: { $ne: api_1.CommentState.Approved } }, { parentID: null }]
})
.toArray();
}
return [...userUnapprovedComments, ...comments].map((_a) => {
var { _id: id, revisions } = _a, comment = __rest(_a, ["_id", "revisions"]);
return (Object.assign({ id, text: revisions[revisions.length - 1].text }, comment));
});
}
async getCommentById(id) {
const value = await this.comments.findOne({ _id: id });
if (!value)
return null;
const { _id: outID } = value, comment = __rest(value, ["_id"]);
return Object.assign({ id: outID }, comment);
}
async getPublicChildrenCommentsByParentId(id, userID) {
const [childrenComments] = await Promise.all([
this.comments
.aggregate([{ $sort: { modifiedAt: -1 } }], {
collation: { locale: this.locale, strength: 2 }
})
.match({
$and: [{ parentID: id }, { $or: [{ state: api_1.CommentState.Approved }, { userID: userID }] }]
})
.toArray()
]);
return childrenComments.map((_a) => {
var { _id: id, revisions } = _a, comment = __rest(_a, ["_id", "revisions"]);
return (Object.assign({ id, text: revisions[revisions.length - 1].text }, comment));
});
}
async takeActionOnComment({ id, state, rejectionReason }) {
const { value } = await this.comments.findOneAndUpdate({ _id: id }, {
$set: {
state,
rejectionReason,
modifiedAt: new Date()
}
}, {
returnOriginal: false
});
if (!value)
return null;
const { _id: outID } = value, comment = __rest(value, ["_id"]);
return Object.assign(Object.assign({}, comment), { id: outID });
}
}
exports.MongoDBCommentAdapter = MongoDBCommentAdapter;
//# sourceMappingURL=comment.js.map
;