update-post.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import type { Document, Model, Types } from 'mongoose';
  2. import { Schema } from 'mongoose';
  3. import { getOrCreateModel } from '../util/mongoose-utils';
  4. export interface IUpdatePost {
  5. pathPattern: string;
  6. patternPrefix: string;
  7. patternPrefix2: string;
  8. channel: string;
  9. provider: string;
  10. creator: Types.ObjectId;
  11. createdAt: Date;
  12. }
  13. export interface UpdatePostDocument extends IUpdatePost, Document {}
  14. export interface UpdatePostModel extends Model<UpdatePostDocument> {
  15. normalizeChannelName(channel): any;
  16. createPrefixesByPathPattern(pathPattern): any;
  17. getRegExpByPattern(pattern): any;
  18. findSettingsByPath(path): Promise<UpdatePostDocument[]>;
  19. findAll(offset?: number): Promise<UpdatePostDocument[]>;
  20. createUpdatePost(
  21. pathPattern: string,
  22. channel: string,
  23. creator: Types.ObjectId,
  24. ): Promise<UpdatePostDocument>;
  25. }
  26. /**
  27. * This is the setting for notify to 3rd party tool (like Slack).
  28. */
  29. const updatePostSchema = new Schema<UpdatePostDocument, UpdatePostModel>(
  30. {
  31. pathPattern: { type: String, required: true },
  32. patternPrefix: { type: String, required: true },
  33. patternPrefix2: { type: String, required: true },
  34. channel: { type: String, required: true },
  35. provider: { type: String, required: true },
  36. creator: { type: Schema.Types.ObjectId, ref: 'User', index: true },
  37. },
  38. {
  39. timestamps: true,
  40. },
  41. );
  42. updatePostSchema.statics.normalizeChannelName = (channel) =>
  43. channel.replace(/(#|,)/g, '');
  44. updatePostSchema.statics.createPrefixesByPathPattern = (pathPattern) => {
  45. const patternPrefix = ['*', '*'];
  46. // not begin with slash
  47. if (!pathPattern.match(/^\/.+/)) {
  48. return patternPrefix;
  49. }
  50. const pattern = pathPattern.split('/');
  51. pattern.shift();
  52. if (pattern[0] && pattern[0] !== '*') {
  53. patternPrefix[0] = pattern[0];
  54. }
  55. if (pattern[1] && pattern[1] !== '*') {
  56. patternPrefix[1] = pattern[1];
  57. }
  58. return patternPrefix;
  59. };
  60. updatePostSchema.statics.getRegExpByPattern = (pattern) => {
  61. let reg = pattern;
  62. if (!reg.match(/^\/.*/)) {
  63. reg = `/*${reg}*`;
  64. }
  65. reg = `^${reg}`;
  66. reg = reg.replace(/\//g, '\\/');
  67. reg = reg.replace(/(\*)/g, '.*');
  68. return new RegExp(reg);
  69. };
  70. updatePostSchema.statics.findSettingsByPath = async function (path) {
  71. const prefixes = this.createPrefixesByPathPattern(path);
  72. const settings = await this.find({
  73. $or: [
  74. { patternPrefix: prefixes[0], patternPrefix2: prefixes[1] },
  75. { patternPrefix: '*', patternPrefix2: '*' },
  76. { patternPrefix: prefixes[0], patternPrefix2: '*' },
  77. { patternPrefix: '*', patternPrefix2: prefixes[1] },
  78. ],
  79. });
  80. if (settings.length <= 0) {
  81. return settings;
  82. }
  83. const validSettings = settings.filter((setting) => {
  84. const patternRegex = this.getRegExpByPattern(setting.pathPattern);
  85. return patternRegex.test(path);
  86. });
  87. return validSettings;
  88. };
  89. updatePostSchema.statics.findAll = function (_offset = 0) {
  90. // biome-ignore lint/plugin: allow populate for backward compatibility
  91. return this.find().sort({ createdAt: 1 }).populate('creator').exec();
  92. };
  93. updatePostSchema.statics.createUpdatePost = async function (
  94. pathPattern,
  95. channel,
  96. creator,
  97. ) {
  98. const provider = 'slack'; // now slack only
  99. const prefixes = this.createPrefixesByPathPattern(pathPattern);
  100. return this.create({
  101. pathPattern,
  102. patternPrefix: prefixes[0],
  103. patternPrefix2: prefixes[1],
  104. channel: this.normalizeChannelName(channel),
  105. provider,
  106. creator,
  107. });
  108. };
  109. export default getOrCreateModel<UpdatePostDocument, UpdatePostModel>(
  110. 'UpdatePost',
  111. updatePostSchema,
  112. );