revision.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import type {
  2. HasObjectId,
  3. IRevision,
  4. Origin,
  5. } from '@growi/core';
  6. import { allOrigin } from '@growi/core';
  7. import {
  8. Schema, Types, type Document, type Model,
  9. } from 'mongoose';
  10. import mongoosePaginate from 'mongoose-paginate-v2';
  11. import loggerFactory from '~/utils/logger';
  12. import { getOrCreateModel } from '../util/mongoose-utils';
  13. import type { PageDocument } from './page';
  14. const logger = loggerFactory('growi:models:revision');
  15. export interface IRevisionDocument extends IRevision, Document {
  16. }
  17. type UpdateRevisionListByPageId = (pageId: string, updateData: Partial<IRevision>) => Promise<void>;
  18. type PrepareRevision = (
  19. pageData: PageDocument, body: string, previousBody: string | null, user: HasObjectId, origin?: Origin, options?: { format: string }
  20. ) => IRevisionDocument;
  21. export interface IRevisionModel extends Model<IRevisionDocument> {
  22. updateRevisionListByPageId: UpdateRevisionListByPageId,
  23. prepareRevision: PrepareRevision,
  24. }
  25. // Use this to allow empty strings to pass the `required` validator
  26. Schema.Types.String.checkRequired(v => typeof v === 'string');
  27. const revisionSchema = new Schema<IRevisionDocument, IRevisionModel>({
  28. pageId: {
  29. type: String, required: true, index: true,
  30. },
  31. body: {
  32. type: String,
  33. required: true,
  34. get: (data) => {
  35. // replace CR/CRLF to LF above v3.1.5
  36. // see https://github.com/weseek/growi/issues/463
  37. return data ? data.replace(/\r\n?/g, '\n') : '';
  38. },
  39. },
  40. format: { type: String, default: 'markdown' },
  41. author: { type: Types.ObjectId, ref: 'User' },
  42. hasDiffToPrev: { type: Boolean },
  43. origin: { type: String, enum: allOrigin },
  44. }, {
  45. timestamps: { createdAt: true, updatedAt: false },
  46. });
  47. revisionSchema.plugin(mongoosePaginate);
  48. const updateRevisionListByPageId: UpdateRevisionListByPageId = async function(this: IRevisionModel, pageId, updateData) {
  49. await this.updateMany({ pageId }, { $set: updateData });
  50. };
  51. revisionSchema.statics.updateRevisionListByPageId = updateRevisionListByPageId;
  52. const prepareRevision: PrepareRevision = function(this: IRevisionModel, pageData, body, previousBody, user, origin, options = { format: 'markdown' }) {
  53. if (!user._id) {
  54. throw new Error('Error: user should have _id');
  55. }
  56. const newRevision = new this();
  57. newRevision.pageId = pageData._id;
  58. newRevision.body = body;
  59. newRevision.format = options.format;
  60. newRevision.author = user._id;
  61. newRevision.origin = origin;
  62. if (pageData.revision != null) {
  63. newRevision.hasDiffToPrev = body !== previousBody;
  64. }
  65. return newRevision;
  66. };
  67. revisionSchema.statics.prepareRevision = prepareRevision;
  68. export const Revision = getOrCreateModel<IRevisionDocument, IRevisionModel>('Revision', revisionSchema);