subscription.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import {
  2. SubscriptionStatusType, AllSubscriptionStatusType, Ref, IPage, IUser, ISubscription,
  3. } from '@growi/core';
  4. import {
  5. Types, Document, Model, Schema,
  6. } from 'mongoose';
  7. import { AllSupportedTargetModels } from '~/interfaces/activity';
  8. import { getOrCreateModel } from '../util/mongoose-utils';
  9. export interface SubscriptionDocument extends ISubscription, Document {}
  10. export interface SubscriptionModel extends Model<SubscriptionDocument> {
  11. findByUserIdAndTargetId(userId: Types.ObjectId | string, targetId: Types.ObjectId | string): any
  12. upsertSubscription(user: Ref<IUser>, targetModel: string, target: Ref<IPage>, status: string): any
  13. subscribeByPageId(userId: Types.ObjectId, pageId: Types.ObjectId, status: string): any
  14. getSubscription(target: Ref<IPage>): Promise<Ref<IUser>[]>
  15. getUnsubscription(target: Ref<IPage>): Promise<Ref<IUser>[]>
  16. getSubscriptions(targets: Ref<IPage>[]): Promise<Ref<IUser>[]>
  17. }
  18. const subscriptionSchema = new Schema<SubscriptionDocument, SubscriptionModel>({
  19. user: {
  20. type: Schema.Types.ObjectId,
  21. ref: 'User',
  22. index: true,
  23. required: true,
  24. },
  25. targetModel: {
  26. type: String,
  27. required: true,
  28. enum: AllSupportedTargetModels,
  29. },
  30. target: {
  31. type: Schema.Types.ObjectId,
  32. ref: 'Page',
  33. refPath: 'targetModel',
  34. required: true,
  35. },
  36. status: {
  37. type: String,
  38. required: true,
  39. enum: AllSubscriptionStatusType,
  40. },
  41. }, {
  42. timestamps: true,
  43. });
  44. subscriptionSchema.methods.isSubscribing = function() {
  45. return this.status === SubscriptionStatusType.SUBSCRIBE;
  46. };
  47. subscriptionSchema.methods.isUnsubscribing = function() {
  48. return this.status === SubscriptionStatusType.UNSUBSCRIBE;
  49. };
  50. subscriptionSchema.statics.findByUserIdAndTargetId = function(userId, targetId) {
  51. return this.findOne({ user: userId, target: targetId });
  52. };
  53. subscriptionSchema.statics.upsertSubscription = function(user, targetModel, target, status) {
  54. const query = { user, targetModel, target };
  55. const doc = { ...query, status };
  56. const options = {
  57. upsert: true, new: true, setDefaultsOnInsert: true, runValidators: true,
  58. };
  59. return this.findOneAndUpdate(query, doc, options);
  60. };
  61. subscriptionSchema.statics.subscribeByPageId = function(userId, pageId, status) {
  62. return this.upsertSubscription(userId, 'Page', pageId, status);
  63. };
  64. subscriptionSchema.statics.getSubscription = async function(target: Ref<IPage>) {
  65. return this.find({ target, status: SubscriptionStatusType.SUBSCRIBE }).distinct('user');
  66. };
  67. subscriptionSchema.statics.getUnsubscription = async function(target: Ref<IPage>) {
  68. return this.find({ target, status: SubscriptionStatusType.UNSUBSCRIBE }).distinct('user');
  69. };
  70. subscriptionSchema.statics.getSubscriptions = async function(targets: Ref<IPage>[]) {
  71. return this.find({ target: { $in: targets }, status: SubscriptionStatusType.SUBSCRIBE }).distinct('user');
  72. };
  73. export default getOrCreateModel<SubscriptionDocument, SubscriptionModel>('Subscription', subscriptionSchema);