DataModule.ts 4.1 KB

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