News.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import {
  2. DataTypes,
  3. Model,
  4. InferAttributes,
  5. InferCreationAttributes,
  6. CreationOptional
  7. } from "sequelize";
  8. import { NewsStatus } from "@models/News/NewsStatus";
  9. import EventsModule from "@/modules/EventsModule";
  10. import User from "./User";
  11. import { ObjectIdType } from "@/modules/DataModule";
  12. export class News extends Model<
  13. InferAttributes<News>,
  14. InferCreationAttributes<News>
  15. > {
  16. declare _id: CreationOptional<ObjectIdType>;
  17. declare title: string;
  18. declare markdown: string;
  19. declare status: CreationOptional<NewsStatus>;
  20. declare showToNewUsers: CreationOptional<boolean>;
  21. declare createdAt: CreationOptional<Date>;
  22. declare updatedAt: CreationOptional<Date>;
  23. }
  24. export const schema = {
  25. _id: {
  26. type: DataTypes.OBJECTID,
  27. allowNull: false,
  28. primaryKey: true
  29. },
  30. title: {
  31. type: DataTypes.STRING,
  32. allowNull: false
  33. },
  34. markdown: {
  35. type: DataTypes.TEXT,
  36. allowNull: false
  37. },
  38. status: {
  39. type: DataTypes.ENUM(...Object.values(NewsStatus)),
  40. defaultValue: NewsStatus.DRAFT,
  41. allowNull: false
  42. },
  43. showToNewUsers: {
  44. type: DataTypes.BOOLEAN,
  45. defaultValue: false,
  46. allowNull: false
  47. },
  48. createdAt: DataTypes.DATE,
  49. updatedAt: DataTypes.DATE,
  50. _name: {
  51. type: DataTypes.VIRTUAL,
  52. get() {
  53. return `news`;
  54. }
  55. }
  56. };
  57. export const options = {};
  58. export const setup = async () => {
  59. News.afterSave(async record => {
  60. const oldDoc = record.previous();
  61. const doc = record.get();
  62. if (oldDoc.status === doc.status) return;
  63. if (doc.status === NewsStatus.PUBLISHED) {
  64. const EventClass = EventsModule.getEvent(`data.news.published`);
  65. await EventsModule.publish(
  66. new EventClass({
  67. doc
  68. })
  69. );
  70. } else if (oldDoc.status === NewsStatus.PUBLISHED) {
  71. const EventClass = EventsModule.getEvent(`data.news.unpublished`);
  72. await EventsModule.publish(
  73. new EventClass(
  74. {
  75. oldDoc
  76. },
  77. oldDoc._id!.toString()
  78. )
  79. );
  80. }
  81. });
  82. News.afterDestroy(async record => {
  83. const oldDoc = record.previous();
  84. if (oldDoc.status === NewsStatus.PUBLISHED) {
  85. const EventClass = EventsModule.getEvent(`data.news.unpublished`);
  86. await EventsModule.publish(
  87. new EventClass(
  88. {
  89. oldDoc
  90. },
  91. oldDoc._id!.toString()
  92. )
  93. );
  94. }
  95. });
  96. News.addHook("afterFind", (_news, options) => {
  97. if (!_news) return;
  98. // TODO improve TS
  99. let news: Model<
  100. InferAttributes<
  101. News,
  102. {
  103. omit: never;
  104. }
  105. >,
  106. InferCreationAttributes<
  107. News,
  108. {
  109. omit: never;
  110. }
  111. >
  112. >[] = [];
  113. if (Array.isArray(_news)) news = _news;
  114. // @ts-ignore - possibly not needed after TS update
  115. else news.push(_news);
  116. news.forEach(news => {
  117. news.dataValues.createdBy = {
  118. _id: news.dataValues.createdBy,
  119. _name: "minifiedUsers"
  120. };
  121. });
  122. });
  123. };
  124. export const setupAssociations = () => {
  125. News.belongsTo(User, { foreignKey: "createdBy" });
  126. User.hasMany(News, { foreignKey: "createdBy" });
  127. };
  128. export default News;