bookmark.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* eslint-disable no-return-await */
  2. import mongoose from 'mongoose';
  3. import mongoosePaginate from 'mongoose-paginate-v2';
  4. import uniqueValidator from 'mongoose-unique-validator';
  5. import loggerFactory from '~/utils/logger';
  6. const logger = loggerFactory('growi:models:bookmark');
  7. const ObjectId = mongoose.Schema.Types.ObjectId;
  8. /** @param {import('~/server/crowi').default} crowi Crowi instance */
  9. const factory = (crowi) => {
  10. const bookmarkEvent = crowi.event('bookmark');
  11. let bookmarkSchema = null;
  12. bookmarkSchema = new mongoose.Schema(
  13. {
  14. page: { type: ObjectId, ref: 'Page', index: true },
  15. user: { type: ObjectId, ref: 'User', index: true },
  16. },
  17. {
  18. timestamps: { createdAt: true, updatedAt: false },
  19. },
  20. );
  21. bookmarkSchema.index({ page: 1, user: 1 }, { unique: true });
  22. bookmarkSchema.plugin(mongoosePaginate);
  23. bookmarkSchema.plugin(uniqueValidator);
  24. bookmarkSchema.statics.countByPageId = async function (pageId) {
  25. return await this.count({ page: pageId });
  26. };
  27. /**
  28. * @return {object} key: page._id, value: bookmark count
  29. */
  30. bookmarkSchema.statics.getPageIdToCountMap = async function (pageIds) {
  31. const results = await this.aggregate()
  32. .match({ page: { $in: pageIds } })
  33. .group({ _id: '$page', count: { $sum: 1 } });
  34. // convert to map
  35. const idToCountMap = {};
  36. results.forEach((result) => {
  37. idToCountMap[result._id] = result.count;
  38. });
  39. return idToCountMap;
  40. };
  41. // bookmark チェック用
  42. bookmarkSchema.statics.findByPageIdAndUserId = function (pageId, userId) {
  43. return new Promise((resolve, reject) => {
  44. return this.findOne({ page: pageId, user: userId }, (err, doc) => {
  45. if (err) {
  46. return reject(err);
  47. }
  48. return resolve(doc);
  49. });
  50. });
  51. };
  52. bookmarkSchema.statics.add = async function (page, user) {
  53. // biome-ignore lint/complexity/noUselessThisAlias: ignore
  54. const Bookmark = this;
  55. const newBookmark = new Bookmark({ page, user });
  56. try {
  57. const bookmark = await newBookmark.save();
  58. bookmarkEvent.emit('create', page._id);
  59. return bookmark;
  60. } catch (err) {
  61. if (err.code === 11000) {
  62. // duplicate key (dummy response of new object)
  63. return newBookmark;
  64. }
  65. logger.debug('Bookmark.save failed', err);
  66. throw err;
  67. }
  68. };
  69. /**
  70. * Remove bookmark
  71. * used only when removing the page
  72. * @param {string} pageId
  73. */
  74. bookmarkSchema.statics.removeBookmarksByPageId = async function (pageId) {
  75. // biome-ignore lint/complexity/noUselessThisAlias: ignore
  76. const Bookmark = this;
  77. try {
  78. const data = await Bookmark.remove({ page: pageId });
  79. bookmarkEvent.emit('delete', pageId);
  80. return data;
  81. } catch (err) {
  82. logger.debug('Bookmark.remove failed (removeBookmarkByPage)', err);
  83. throw err;
  84. }
  85. };
  86. bookmarkSchema.statics.removeBookmark = async function (pageId, user) {
  87. // biome-ignore lint/complexity/noUselessThisAlias: ignore
  88. const Bookmark = this;
  89. try {
  90. const data = await Bookmark.findOneAndRemove({ page: pageId, user });
  91. bookmarkEvent.emit('delete', pageId);
  92. return data;
  93. } catch (err) {
  94. logger.debug('Bookmark.findOneAndRemove failed', err);
  95. throw err;
  96. }
  97. };
  98. return mongoose.model('Bookmark', bookmarkSchema);
  99. };
  100. export default factory;