bookmark-folder.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { isValidObjectId } from '@growi/core/src/utils/objectid-utils';
  2. import {
  3. Types, Document, Model, Schema,
  4. } from 'mongoose';
  5. import { IBookmarkFolder, BookmarkFolderItems } from '~/interfaces/bookmark-info';
  6. import loggerFactory from '../../utils/logger';
  7. import { getOrCreateModel } from '../util/mongoose-utils';
  8. import { InvalidParentBookmarkFolderError } from './errors';
  9. const logger = loggerFactory('growi:models:bookmark-folder');
  10. export interface BookmarkFolderDocument extends Document {
  11. _id: Types.ObjectId
  12. name: string
  13. owner: Types.ObjectId
  14. parent?: [this]
  15. }
  16. export interface BookmarkFolderModel extends Model<BookmarkFolderDocument>{
  17. createByParameters(params: IBookmarkFolder): BookmarkFolderDocument
  18. findFolderAndChildren(user: Types.ObjectId | string, parentId?: Types.ObjectId | string): BookmarkFolderItems[]
  19. findChildFolderById(parentBookmarkFolder: Types.ObjectId | string): Promise<BookmarkFolderDocument[]>
  20. deleteFolderAndChildren(bookmarkFolderId: string): {deletedCount: number}
  21. updateBookmarkFolder(bookmarkFolderId: string, name: string, parent: string): BookmarkFolderDocument | null
  22. }
  23. const bookmarkFolderSchema = new Schema<BookmarkFolderDocument, BookmarkFolderModel>({
  24. name: { type: String },
  25. owner: { type: Schema.Types.ObjectId, ref: 'User', index: true },
  26. parent: { type: Schema.Types.ObjectId, ref: 'BookmarkFolder', required: false },
  27. }, {
  28. toObject: { virtuals: true },
  29. });
  30. bookmarkFolderSchema.virtual('children', {
  31. ref: 'BookmarkFolder',
  32. localField: '_id',
  33. foreignField: 'parent',
  34. });
  35. bookmarkFolderSchema.statics.createByParameters = async function(params: IBookmarkFolder): Promise<BookmarkFolderDocument> {
  36. const { name, owner, parent } = params;
  37. let bookmarkFolder;
  38. if (parent == null) {
  39. bookmarkFolder = await this.create({ name, owner }) as unknown as BookmarkFolderDocument;
  40. }
  41. else {
  42. // Check if parent folder id is valid and parent folder exists
  43. const isParentFolderIdValid = isValidObjectId(parent as string);
  44. if (!isParentFolderIdValid) {
  45. throw new InvalidParentBookmarkFolderError('Parent folder id is invalid');
  46. }
  47. const parentFolder = await this.findById(parent);
  48. if (parentFolder == null) {
  49. throw new InvalidParentBookmarkFolderError('Parent folder not found');
  50. }
  51. bookmarkFolder = await this.create({ name, owner, parent: parentFolder._id }) as unknown as BookmarkFolderDocument;
  52. }
  53. return bookmarkFolder;
  54. };
  55. bookmarkFolderSchema.statics.findFolderAndChildren = async function(
  56. userId: Types.ObjectId | string,
  57. parentId?: Types.ObjectId | string,
  58. ): Promise<BookmarkFolderItems[]> {
  59. const parentFolder = await this.findById(parentId) as unknown as BookmarkFolderDocument;
  60. const bookmarkFolders = await this.find({ owner: userId, parent: parentFolder })
  61. .populate({ path: 'children' }).exec() as unknown as BookmarkFolderItems[];
  62. return bookmarkFolders;
  63. };
  64. bookmarkFolderSchema.statics.findChildFolderById = async function(parentFolderId: Types.ObjectId | string): Promise<BookmarkFolderDocument[]> {
  65. const parentFolder = await this.findById(parentFolderId) as unknown as BookmarkFolderDocument;
  66. const childFolders = await this.find({ parent: parentFolder });
  67. return childFolders;
  68. };
  69. bookmarkFolderSchema.statics.deleteFolderAndChildren = async function(boookmarkFolderId: Types.ObjectId | string): Promise<{deletedCount: number}> {
  70. // Delete parent and all children folder
  71. const bookmarkFolder = await this.findByIdAndDelete(boookmarkFolderId);
  72. let deletedCount = 0;
  73. if (bookmarkFolder != null) {
  74. const childFolders = await this.deleteMany({ parent: bookmarkFolder?.id });
  75. deletedCount = childFolders.deletedCount + 1;
  76. }
  77. return { deletedCount };
  78. };
  79. bookmarkFolderSchema.statics.updateBookmarkFolder = async function(bookmarkFolderId: string, name: string, parent: string):
  80. Promise<BookmarkFolderDocument | null> {
  81. const parentFolder = await this.findById(parent);
  82. const updateFields = {
  83. name, parent: parentFolder?._id || null,
  84. };
  85. const bookmarkFolder = await this.findByIdAndUpdate(bookmarkFolderId, { $set: updateFields }, { new: true });
  86. return bookmarkFolder;
  87. };
  88. export default getOrCreateModel<BookmarkFolderDocument, BookmarkFolderModel>('BookmarkFolder', bookmarkFolderSchema);