news.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import {
  2. HydratedDocument,
  3. Model,
  4. QueryWithHelpers,
  5. Schema,
  6. SchemaTypes,
  7. Types
  8. } from "mongoose";
  9. import { GetData } from "./plugins/getData";
  10. import { BaseSchema } from "../types/Schemas";
  11. import JobContext from "../JobContext";
  12. export enum NewsStatus {
  13. DRAFT = "draft",
  14. PUBLISHED = "published",
  15. ARCHIVED = "archived"
  16. }
  17. export interface NewsSchema extends BaseSchema {
  18. title: string;
  19. markdown: string;
  20. status: NewsStatus;
  21. showToNewUsers: boolean;
  22. createdBy: Types.ObjectId;
  23. }
  24. export interface NewsQueryHelpers {
  25. published(
  26. this: QueryWithHelpers<
  27. any,
  28. HydratedDocument<NewsSchema>,
  29. NewsQueryHelpers
  30. >,
  31. published?: boolean
  32. ): QueryWithHelpers<
  33. HydratedDocument<NewsSchema>[],
  34. HydratedDocument<NewsSchema>,
  35. NewsQueryHelpers
  36. >;
  37. newest(
  38. this: QueryWithHelpers<
  39. any,
  40. HydratedDocument<NewsSchema>,
  41. NewsQueryHelpers
  42. >,
  43. showToNewUsers?: boolean
  44. ): QueryWithHelpers<
  45. HydratedDocument<NewsSchema>[],
  46. HydratedDocument<NewsSchema>,
  47. NewsQueryHelpers
  48. >;
  49. }
  50. export interface NewsModel
  51. extends Model<NewsSchema, NewsQueryHelpers>,
  52. GetData {
  53. published: (context: JobContext) => Promise<NewsSchema[]>;
  54. newest: (
  55. context: JobContext,
  56. payload: { showToNewUsers?: boolean }
  57. ) => Promise<NewsSchema[]>;
  58. }
  59. export const schema = new Schema<NewsSchema, NewsModel, {}, NewsQueryHelpers>(
  60. {
  61. title: {
  62. type: SchemaTypes.String,
  63. required: true
  64. },
  65. markdown: {
  66. type: SchemaTypes.String,
  67. required: true
  68. },
  69. status: {
  70. type: SchemaTypes.String,
  71. enum: Object.values(NewsStatus),
  72. default: NewsStatus.DRAFT,
  73. required: true
  74. },
  75. showToNewUsers: {
  76. type: SchemaTypes.Boolean,
  77. default: false,
  78. required: true
  79. },
  80. createdBy: {
  81. type: SchemaTypes.ObjectId,
  82. required: true
  83. }
  84. },
  85. {
  86. // @ts-ignore
  87. documentVersion: 3,
  88. query: {
  89. published() {
  90. return this.where({ status: NewsStatus.PUBLISHED });
  91. },
  92. newest(showToNewUsers = false) {
  93. const query = this.published().sort({ createdAt: "desc" });
  94. if (showToNewUsers) return query.where({ showToNewUsers });
  95. return query;
  96. }
  97. },
  98. jobConfig: {
  99. published: {
  100. async method() {
  101. return this.find().published();
  102. },
  103. hasPermission: true
  104. },
  105. newest: {
  106. async method() {
  107. return this.find().newest(payload?.showToNewUsers);
  108. },
  109. hasPermission: true
  110. }
  111. },
  112. // @ts-ignore need to somehow use GetDataSchemaOptions
  113. getData: {
  114. enabled: true,
  115. specialProperties: {
  116. createdBy: [
  117. {
  118. $addFields: {
  119. createdByOID: {
  120. $convert: {
  121. input: "$createdBy",
  122. to: "objectId",
  123. onError: "unknown",
  124. onNull: "unknown"
  125. }
  126. }
  127. }
  128. },
  129. {
  130. $lookup: {
  131. from: "users",
  132. localField: "createdByOID",
  133. foreignField: "_id",
  134. as: "createdByUser"
  135. }
  136. },
  137. {
  138. $unwind: {
  139. path: "$createdByUser",
  140. preserveNullAndEmptyArrays: true
  141. }
  142. },
  143. {
  144. $addFields: {
  145. createdByUsername: {
  146. $ifNull: ["$createdByUser.username", "unknown"]
  147. }
  148. }
  149. },
  150. {
  151. $project: {
  152. createdByOID: 0,
  153. createdByUser: 0
  154. }
  155. }
  156. ]
  157. },
  158. specialQueries: {
  159. createdBy: newQuery => ({
  160. $or: [newQuery, { createdByUsername: newQuery.createdBy }]
  161. })
  162. }
  163. }
  164. }
  165. );
  166. export type NewsSchemaType = typeof schema;