Event.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { HydratedDocument } from "mongoose";
  2. import { UserSchema } from "@models/users/schema";
  3. export default abstract class Event {
  4. protected static _namespace: string;
  5. protected static _name: string;
  6. protected static _type: "event" | "schedule" = "event";
  7. protected static _hasPermission:
  8. | boolean
  9. | CallableFunction
  10. | (boolean | CallableFunction)[] = false;
  11. protected _data: any;
  12. protected _scope?: string;
  13. public constructor(data: any, scope?: string) {
  14. this._data = data;
  15. this._scope = scope;
  16. }
  17. public static getNamespace() {
  18. return this._namespace;
  19. }
  20. public static getName() {
  21. return this._name;
  22. }
  23. public static getPath() {
  24. return `${this.getNamespace()}.${this.getName()}`;
  25. }
  26. public static getKey(scope?: string) {
  27. const path = this.getPath();
  28. if (scope) return `${path}:${scope}`;
  29. return path;
  30. }
  31. public static parseKey(key: string) {
  32. const [path, scope] = key.split(":");
  33. return {
  34. path,
  35. scope
  36. };
  37. }
  38. public static getType() {
  39. return this._type;
  40. }
  41. public static async hasPermission(
  42. user: HydratedDocument<UserSchema> | null,
  43. scope?: string
  44. ) {
  45. const options = Array.isArray(this._hasPermission)
  46. ? this._hasPermission
  47. : [this._hasPermission];
  48. return options.reduce(async (previous, option) => {
  49. if (await previous) return true;
  50. if (typeof option === "boolean") return option;
  51. if (typeof option === "function") return option(user, scope);
  52. return false;
  53. }, Promise.resolve(false));
  54. }
  55. public static makeMessage(data: any) {
  56. if (["object", "array"].includes(typeof data))
  57. return JSON.stringify(data);
  58. return data;
  59. }
  60. public static parseMessage(message: string) {
  61. let parsedMessage = message;
  62. if (parsedMessage.startsWith("[") || parsedMessage.startsWith("{"))
  63. try {
  64. parsedMessage = JSON.parse(parsedMessage);
  65. } catch (err) {
  66. console.error(err);
  67. }
  68. else if (parsedMessage.startsWith('"') && parsedMessage.endsWith('"'))
  69. parsedMessage = parsedMessage
  70. .substring(1)
  71. .substring(0, parsedMessage.length - 2);
  72. return parsedMessage;
  73. }
  74. public getNamespace() {
  75. return (this.constructor as typeof Event).getNamespace();
  76. }
  77. public getName() {
  78. return (this.constructor as typeof Event).getName();
  79. }
  80. public getPath() {
  81. return (this.constructor as typeof Event).getPath();
  82. }
  83. public getKey() {
  84. return (this.constructor as typeof Event).getKey(this._scope);
  85. }
  86. public getData() {
  87. return this._data;
  88. }
  89. public makeMessage() {
  90. return (this.constructor as typeof Event).makeMessage(this._data);
  91. }
  92. }
  93. export type EventClass = {
  94. new (...params: ConstructorParameters<typeof Event>): Event;
  95. };