DataModule.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import config from "config";
  2. // import { createClient, RedisClientType } from "redis";
  3. import mongoose, {
  4. MongooseDefaultQueryMiddleware,
  5. MongooseDistinctQueryMiddleware,
  6. MongooseQueryOrDocumentMiddleware
  7. } from "mongoose";
  8. import JobContext from "../JobContext";
  9. import BaseModule, { ModuleStatus } from "../BaseModule";
  10. import { UniqueMethods } from "../types/Modules";
  11. import { Models, Schemas } from "../types/Models";
  12. export default class DataModule extends BaseModule {
  13. private models?: Models;
  14. // private redisClient?: RedisClientType;
  15. /**
  16. * Data Module
  17. */
  18. public constructor() {
  19. super("data");
  20. }
  21. /**
  22. * startup - Startup data module
  23. */
  24. public override async startup() {
  25. await super.startup();
  26. const { user, password, host, port, database } = config.get<{
  27. user: string;
  28. password: string;
  29. host: string;
  30. port: number;
  31. database: string;
  32. }>("mongo");
  33. const mongoUrl = `mongodb://${user}:${password}@${host}:${port}/${database}`;
  34. await mongoose.connect(mongoUrl);
  35. mongoose.set({
  36. runValidators: true,
  37. sanitizeFilter: true,
  38. strict: "throw",
  39. strictQuery: "throw"
  40. });
  41. mongoose.SchemaTypes.String.set("trim", true);
  42. await this.loadModels();
  43. // @ts-ignore
  44. // this.redisClient = createClient({ ...config.get("redis") });
  45. //
  46. // await this.redisClient.connect();
  47. //
  48. // const redisConfigResponse = await this.redisClient.sendCommand([
  49. // "CONFIG",
  50. // "GET",
  51. // "notify-keyspace-events"
  52. // ]);
  53. //
  54. // if (
  55. // !(
  56. // Array.isArray(redisConfigResponse) &&
  57. // redisConfigResponse[1] === "xE"
  58. // )
  59. // )
  60. // throw new Error(
  61. // `notify-keyspace-events is NOT configured correctly! It is set to: ${
  62. // (Array.isArray(redisConfigResponse) &&
  63. // redisConfigResponse[1]) ||
  64. // "unknown"
  65. // }`
  66. // );
  67. await super.started();
  68. }
  69. /**
  70. * shutdown - Shutdown data module
  71. */
  72. public override async shutdown() {
  73. await super.shutdown();
  74. // if (this.redisClient) await this.redisClient.quit();
  75. await mongoose.disconnect();
  76. }
  77. /**
  78. * loadModel - Import and load model schema
  79. *
  80. * @param modelName - Name of the model
  81. * @returns Model
  82. */
  83. private async loadModel<ModelName extends keyof Models>(
  84. modelName: ModelName
  85. ) {
  86. const { schema }: { schema: Schemas[ModelName] } = await import(
  87. `../schemas/${modelName.toString()}`
  88. );
  89. const preMethods: string[] = [
  90. "aggregate",
  91. "count",
  92. "countDocuments",
  93. "deleteOne",
  94. "deleteMany",
  95. "estimatedDocumentCount",
  96. "find",
  97. "findOne",
  98. "findOneAndDelete",
  99. "findOneAndRemove",
  100. "findOneAndReplace",
  101. "findOneAndUpdate",
  102. "init",
  103. "insertMany",
  104. "remove",
  105. "replaceOne",
  106. "save",
  107. "update",
  108. "updateOne",
  109. "updateMany",
  110. "validate"
  111. ];
  112. preMethods.forEach(preMethod => {
  113. // @ts-ignore
  114. schema.pre(preMethods, () => {
  115. console.log(`Pre-${preMethod}!`);
  116. });
  117. });
  118. return mongoose.model(modelName.toString(), schema);
  119. }
  120. /**
  121. * loadModels - Load and initialize all models
  122. *
  123. * @returns Promise
  124. */
  125. private async loadModels() {
  126. this.models = {
  127. abc: await this.loadModel("abc"),
  128. news: await this.loadModel("news"),
  129. station: await this.loadModel("station")
  130. };
  131. }
  132. /**
  133. * getModel - Get model
  134. *
  135. * @returns Model
  136. */
  137. public async getModel<ModelName extends keyof Models>(
  138. jobContext: JobContext,
  139. payload: ModelName | { name: ModelName }
  140. ) {
  141. if (!this.models) throw new Error("Models not loaded");
  142. if (this.getStatus() !== ModuleStatus.STARTED)
  143. throw new Error("Module not started");
  144. const name = typeof payload === "object" ? payload.name : payload;
  145. return this.models[name];
  146. }
  147. }
  148. export type DataModuleJobs = {
  149. [Property in keyof UniqueMethods<DataModule>]: {
  150. payload: Parameters<UniqueMethods<DataModule>[Property]>[1];
  151. returns: Awaited<ReturnType<UniqueMethods<DataModule>[Property]>>;
  152. };
  153. };