main.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import * as readline from "node:readline";
  2. import { NewsStatus } from "@models/News/NewsStatus";
  3. import ModuleManager from "@/ModuleManager";
  4. import LogBook from "@/LogBook";
  5. import JobQueue from "@/JobQueue";
  6. import JobStatistics from "@/JobStatistics";
  7. // import DataModule from "@/modules/DataModule";
  8. import EventsModule from "./modules/EventsModule";
  9. // import { NewsModel } from "./modules/DataModule/models/news/schema";
  10. // import { FilterType } from "./modules/DataModule/plugins/getData";
  11. import News from "./modules/DataModule/models/News";
  12. import GetData from "./modules/DataModule/models/News/jobs/GetData";
  13. process.removeAllListeners("uncaughtException");
  14. process.on("uncaughtException", err => {
  15. if (err.name === "ECONNREFUSED" || err.name === "UNCERTAIN_STATE") return;
  16. LogBook.log({
  17. message: err.message,
  18. type: "error",
  19. category: "uncaught-exceptions",
  20. data: { error: err }
  21. });
  22. });
  23. ModuleManager.startup().then(async () => {
  24. // const Model = await DataModule.getModel<NewsModel>("news");
  25. // // console.log("Model", Model);
  26. // const abcs = await Model.findOne({}).newest();
  27. // console.log("Abcs", abcs);
  28. // console.log(
  29. // "getData",
  30. // await Model.getData({
  31. // page: 1,
  32. // pageSize: 3,
  33. // properties: [
  34. // "title",
  35. // "markdown",
  36. // "status",
  37. // "showToNewUsers",
  38. // "createdBy"
  39. // ],
  40. // sort: {},
  41. // queries: [
  42. // {
  43. // data: "v7",
  44. // filter: { property: "title" },
  45. // filterType: FilterType.CONTAINS
  46. // }
  47. // ],
  48. // operator: "and"
  49. // })
  50. // );
  51. // Model.create({
  52. // name: "Test name",
  53. // someNumbers: [1, 2, 3, 4],
  54. // songs: [],
  55. // aNumber: 941
  56. // });
  57. // Events schedule (was notifications)
  58. // const now = Date.now();
  59. // EventsModule.schedule("test", 30000);
  60. // await EventsModule.subscribe("schedule", "test", async () => {
  61. // console.log(`SCHEDULED: ${now} :: ${Date.now()}`);
  62. // });
  63. // // Events (was cache pub/sub)
  64. // await EventsModule.subscribe("event", "test", async value => {
  65. // console.log(`PUBLISHED: ${value}`);
  66. // });
  67. // await EventsModule.publish("test", "a value!");
  68. console.log(
  69. await News.findAll({
  70. include: ["createdByModel"],
  71. where: {
  72. status: NewsStatus.PUBLISHED
  73. }
  74. })
  75. );
  76. console.log(
  77. await new GetData({
  78. page: 1,
  79. pageSize: 10,
  80. properties: ["id"],
  81. sort: {
  82. id: "ascending"
  83. },
  84. queries: [],
  85. operator: "and"
  86. }).execute()
  87. );
  88. });
  89. // TOOD remove, or put behind debug option
  90. // eslint-disable-next-line
  91. // @ts-ignore
  92. global.ModuleManager = ModuleManager;
  93. // eslint-disable-next-line
  94. // @ts-ignore
  95. global.JobQueue = JobQueue;
  96. // eslint-disable-next-line
  97. // @ts-ignore
  98. global.rs = () => {
  99. process.exit();
  100. };
  101. const rl = readline.createInterface({
  102. input: process.stdin,
  103. output: process.stdout,
  104. completer: (command: string) => {
  105. const parts = command.split(" ");
  106. const commands = ["eval "];
  107. if (parts.length === 1) {
  108. const hits = commands.filter(c => c.startsWith(parts[0]));
  109. return [hits.length ? hits : commands, command];
  110. }
  111. return [];
  112. },
  113. removeHistoryDuplicates: true
  114. });
  115. const shutdown = async () => {
  116. if (rl) {
  117. rl.removeAllListeners();
  118. rl.close();
  119. }
  120. await ModuleManager.shutdown().catch(() => process.exit(1));
  121. process.exit(0);
  122. };
  123. process.on("SIGINT", shutdown);
  124. process.on("SIGQUIT", shutdown);
  125. process.on("SIGTERM", shutdown);
  126. const runCommand = (line: string) => {
  127. const [command, ...args] = line.split(" ");
  128. switch (command) {
  129. case "help": {
  130. console.log("Commands:");
  131. console.log("status - Show module manager and job queue status");
  132. console.log("stats - Shows jobs stats");
  133. console.log("queue - Shows a table of all jobs in the queue");
  134. console.log("active - Shows a table of all jobs currently running");
  135. console.log("eval - Run a command");
  136. console.log("debug");
  137. console.log("log - Change LogBook settings");
  138. break;
  139. }
  140. case "status": {
  141. console.log("Module Manager Status:");
  142. console.table(ModuleManager.getStatus());
  143. console.log("Job Queue Status:");
  144. console.table(JobQueue.getStatus());
  145. break;
  146. }
  147. case "stats": {
  148. console.log("Job Statistics:");
  149. console.table(JobStatistics.getStats());
  150. break;
  151. }
  152. case "queue": {
  153. const queueStatus = JobQueue.getQueueStatus().queue;
  154. if (queueStatus.length === 0)
  155. console.log("There are no jobs in the queue.");
  156. else
  157. console.log(
  158. `There are ${queueStatus.length} jobs in the queue.`
  159. );
  160. console.table(queueStatus);
  161. break;
  162. }
  163. case "active": {
  164. const activeStatus = JobQueue.getQueueStatus().active;
  165. if (activeStatus.length === 0)
  166. console.log("There are no active jobs.");
  167. else console.log(`There are ${activeStatus.length} active jobs.`);
  168. console.table(activeStatus);
  169. break;
  170. }
  171. case "eval": {
  172. const evalCommand = args.join(" ");
  173. console.log(`Running eval command: ${evalCommand}`);
  174. // eslint-disable-next-line no-eval
  175. const response = eval(evalCommand);
  176. console.log(`Eval response: `, response);
  177. break;
  178. }
  179. case "debug": {
  180. // eslint-disable-next-line no-debugger
  181. debugger;
  182. break;
  183. }
  184. case "log": {
  185. const [output, key, action, ...values] = args;
  186. if (
  187. output === undefined ||
  188. key === undefined ||
  189. action === undefined
  190. ) {
  191. console.log(
  192. `Missing required parameters (log <output> <key> <action> [values])`
  193. );
  194. break;
  195. }
  196. let value: any[] | undefined;
  197. if (values !== undefined && values.length >= 1) {
  198. value = values.map(_filter => JSON.parse(_filter));
  199. if (value.length === 1) [value] = value;
  200. }
  201. LogBook
  202. // eslint-disable-next-line
  203. // @ts-ignore
  204. .updateOutput(output, key, action, value)
  205. .then(() => console.log("Successfully updated outputs"))
  206. .catch((err: Error) =>
  207. console.log(`Error updating outputs "${err.message}"`)
  208. );
  209. break;
  210. }
  211. case "getjobs": {
  212. console.log(ModuleManager.getJobs());
  213. break;
  214. }
  215. case "getevents": {
  216. console.log(EventsModule.getAllEvents());
  217. break;
  218. }
  219. default: {
  220. if (!/^\s*$/.test(command))
  221. console.log(`Command "${command}" not found`);
  222. }
  223. }
  224. };
  225. rl.on("line", runCommand);