page-operation.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { getOrCreateModel } from '@growi/core';
  2. import mongoose, {
  3. Schema, Model, Document, QueryOptions, FilterQuery,
  4. } from 'mongoose';
  5. import {
  6. IPageForResuming, IUserForResuming, IOptionsForResuming,
  7. } from '~/server/interfaces/page-operation';
  8. import loggerFactory from '../../utils/logger';
  9. import { ObjectIdLike } from '../interfaces/mongoose-utils';
  10. const logger = loggerFactory('growi:models:page-operation');
  11. type IObjectId = mongoose.Types.ObjectId;
  12. const ObjectId = mongoose.Schema.Types.ObjectId;
  13. export const PageActionType = {
  14. Rename: 'Rename',
  15. Duplicate: 'Duplicate',
  16. Delete: 'Delete',
  17. DeleteCompletely: 'DeleteCompletely',
  18. Revert: 'Revert',
  19. NormalizeParent: 'NormalizeParent',
  20. } as const;
  21. export type PageActionType = typeof PageActionType[keyof typeof PageActionType];
  22. export const PageActionStage = {
  23. Main: 'Main',
  24. Sub: 'Sub',
  25. } as const;
  26. export type PageActionStage = typeof PageActionStage[keyof typeof PageActionStage];
  27. /*
  28. * Main Schema
  29. */
  30. export interface IPageOperation {
  31. actionType: PageActionType,
  32. actionStage: PageActionStage,
  33. fromPath: string,
  34. toPath?: string,
  35. page: IPageForResuming,
  36. user: IUserForResuming,
  37. options?: IOptionsForResuming,
  38. incForUpdatingDescendantCount?: number,
  39. }
  40. export interface PageOperationDocument extends IPageOperation, Document {}
  41. export type PageOperationDocumentHasId = PageOperationDocument & { _id: ObjectIdLike };
  42. export interface PageOperationModel extends Model<PageOperationDocument> {
  43. findByIdAndUpdatePageActionStage(pageOpId: ObjectIdLike, stage: PageActionStage): Promise<PageOperationDocumentHasId | null>
  44. findMainOps(filter?: FilterQuery<PageOperationDocument>, projection?: any, options?: QueryOptions): Promise<PageOperationDocumentHasId[]>
  45. deleteAllByPageActionType(deleteTypeList: PageActionType[]): Promise<void>
  46. }
  47. const pageSchemaForResuming = new Schema<IPageForResuming>({
  48. _id: { type: ObjectId, ref: 'Page', index: true },
  49. parent: { type: ObjectId, ref: 'Page' },
  50. descendantCount: { type: Number },
  51. isEmpty: { type: Boolean },
  52. path: { type: String, required: true, index: true },
  53. revision: { type: ObjectId, ref: 'Revision' },
  54. status: { type: String },
  55. grant: { type: Number },
  56. grantedUsers: [{ type: ObjectId, ref: 'User' }],
  57. grantedGroup: { type: ObjectId, ref: 'UserGroup' },
  58. creator: { type: ObjectId, ref: 'User' },
  59. lastUpdateUser: { type: ObjectId, ref: 'User' },
  60. });
  61. const userSchemaForResuming = new Schema<IUserForResuming>({
  62. _id: { type: ObjectId, ref: 'User', required: true },
  63. });
  64. const optionsSchemaForResuming = new Schema<IOptionsForResuming>({
  65. createRedirectPage: { type: Boolean },
  66. updateMetadata: { type: Boolean },
  67. prevDescendantCount: { type: Number },
  68. }, { _id: false });
  69. const schema = new Schema<PageOperationDocument, PageOperationModel>({
  70. actionType: {
  71. type: String,
  72. enum: PageActionType,
  73. required: true,
  74. index: true,
  75. },
  76. actionStage: {
  77. type: String,
  78. enum: PageActionStage,
  79. required: true,
  80. index: true,
  81. },
  82. fromPath: { type: String, required: true, index: true },
  83. toPath: { type: String, index: true },
  84. page: { type: pageSchemaForResuming, required: true },
  85. user: { type: userSchemaForResuming, required: true },
  86. options: { type: optionsSchemaForResuming },
  87. incForUpdatingDescendantCount: { type: Number },
  88. });
  89. schema.statics.findByIdAndUpdatePageActionStage = async function(
  90. pageOpId: ObjectIdLike, stage: PageActionStage,
  91. ): Promise<PageOperationDocumentHasId | null> {
  92. return this.findByIdAndUpdate(pageOpId, {
  93. $set: { actionStage: stage },
  94. }, { new: true });
  95. };
  96. schema.statics.findMainOps = async function(
  97. filter?: FilterQuery<PageOperationDocument>, projection?: any, options?: QueryOptions,
  98. ): Promise<PageOperationDocumentHasId[]> {
  99. return this.find(
  100. { ...filter, actionStage: PageActionStage.Main },
  101. projection,
  102. options,
  103. );
  104. };
  105. schema.statics.deleteAllByPageActionType = async function(
  106. deleteTypeList: PageActionType[],
  107. ): Promise<void> {
  108. await this.deleteMany({ actionType: { $in: deleteTypeList } });
  109. logger.info(`Deleted all PageOperation documents except actionType: ${deleteTypeList}`);
  110. };
  111. export default getOrCreateModel<PageOperationDocument, PageOperationModel>('PageOperation', schema);