news.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. statics: {
  99. published() {
  100. return this.find().published();
  101. },
  102. newest(context: JobContext, payload: { showToNewUsers?: boolean }) {
  103. return this.find().newest(payload.showToNewUsers);
  104. }
  105. },
  106. // @ts-ignore need to somehow use GetDataSchemaOptions
  107. getData: {
  108. enabled: true,
  109. specialProperties: {
  110. createdBy: [
  111. {
  112. $addFields: {
  113. createdByOID: {
  114. $convert: {
  115. input: "$createdBy",
  116. to: "objectId",
  117. onError: "unknown",
  118. onNull: "unknown"
  119. }
  120. }
  121. }
  122. },
  123. {
  124. $lookup: {
  125. from: "users",
  126. localField: "createdByOID",
  127. foreignField: "_id",
  128. as: "createdByUser"
  129. }
  130. },
  131. {
  132. $unwind: {
  133. path: "$createdByUser",
  134. preserveNullAndEmptyArrays: true
  135. }
  136. },
  137. {
  138. $addFields: {
  139. createdByUsername: {
  140. $ifNull: ["$createdByUser.username", "unknown"]
  141. }
  142. }
  143. },
  144. {
  145. $project: {
  146. createdByOID: 0,
  147. createdByUser: 0
  148. }
  149. }
  150. ]
  151. },
  152. specialQueries: {
  153. createdBy: newQuery => ({
  154. $or: [newQuery, { createdByUsername: newQuery.createdBy }]
  155. })
  156. }
  157. }
  158. }
  159. );
  160. export type NewsSchemaType = typeof schema;