| 
					
				 | 
			
			
				@@ -1,11 +1,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import config from "config"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// import { createClient, RedisClientType } from "redis"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import mongoose, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Connection, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	isObjectIdOrHexString, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	MongooseDefaultQueryMiddleware, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	MongooseDistinctQueryMiddleware, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	MongooseQueryOrDocumentMiddleware, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	SchemaTypes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Types 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } from "mongoose"; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -20,104 +16,13 @@ import BaseModule, { ModuleStatus } from "@/BaseModule"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { UniqueMethods } from "@/types/Modules"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { AnyModel, Models } from "@/types/Models"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { Schemas } from "@/types/Schemas"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import JobQueue from "@/JobQueue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import EventsModule from "./EventsModule"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * Experimental: function to get all nested keys from a MongoDB query object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function getAllKeys(obj: object) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	const keys: string[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	function processObject(obj: object, parentKey = "") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let returnChanged = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (let key in obj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (obj.hasOwnProperty(key)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (key.startsWith("$")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// @ts-ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					processNestedObject(obj[key], parentKey); // Process nested keys without including the current key 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					continue; // Skip the current key 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const currentKey = parentKey ? `${parentKey}.${key}` : key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// @ts-ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (typeof obj[key] === "object" && obj[key] !== null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// @ts-ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (Array.isArray(obj[key])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						// @ts-ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if (processArray(obj[key], currentKey)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							returnChanged = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// @ts-ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					else if (processObject(obj[key], currentKey)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						returnChanged = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						// eslint-disable-next-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				keys.push(currentKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				returnChanged = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return returnChanged; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	function processArray(arr: Array<any>, parentKey: string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		let returnChanged = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		for (let i = 0; i < arr.length; i += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const currentKey = parentKey; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (typeof arr[i] === "object" && arr[i] !== null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (Array.isArray(arr[i])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (processArray(arr[i], currentKey)) returnChanged = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} else if (processObject(arr[i], currentKey)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					returnChanged = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return returnChanged; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	function processNestedObject(obj: object, parentKey: string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (typeof obj === "object" && obj !== null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (Array.isArray(obj)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				processArray(obj, parentKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				processObject(obj, parentKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	processObject(obj); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return keys; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 export class DataModule extends BaseModule { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	private _models?: Models; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	private _mongoConnection?: Connection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	//	private _redisClient?: RedisClientType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * Data Module 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -147,31 +52,6 @@ export class DataModule extends BaseModule { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		await this._defineModelJobs(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// @ts-ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//        this._redisClient = createClient({ ...config.get("redis") }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//		await this._redisClient.connect(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//		const redisConfigResponse = await this._redisClient.sendCommand([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//			"CONFIG", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//			"GET", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//			"notify-keyspace-events" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//		]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//		if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//			!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//				Array.isArray(redisConfigResponse) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//				redisConfigResponse[1] === "xE" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//			) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//		) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//			throw new Error( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//				`notify-keyspace-events is NOT configured correctly! It is set to: ${ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//					(Array.isArray(redisConfigResponse) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//						redisConfigResponse[1]) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//					"unknown" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//				}` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		await super._started(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -180,7 +60,6 @@ export class DataModule extends BaseModule { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	public override async shutdown() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		await super.shutdown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		//		if (this._redisClient) await this._redisClient.quit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		patchEventEmitter.removeAllListeners(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (this._mongoConnection) await this._mongoConnection.close(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		await this._stopped(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -218,95 +97,6 @@ export class DataModule extends BaseModule { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		ModelName extends keyof Models, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		SchemaType extends Schemas[keyof ModelName] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	>(modelName: ModelName, schema: SchemaType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const methods: string[] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"aggregate", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"count", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"countDocuments", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"deleteOne", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"deleteMany", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"estimatedDocumentCount", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"find", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"findOne", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"findOneAndDelete", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"findOneAndRemove", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"findOneAndReplace", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"findOneAndUpdate", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// "init", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"insertMany", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"remove", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"replaceOne", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"save", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"update", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"updateOne", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			"updateMany" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// "validate" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		methods.forEach(method => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// NOTE: some Mongo selectors may also search through linked documents. Prevent that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			schema.pre(method, async function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log(`Pre-${method}! START`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.options?.userContext && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					["find", "update", "deleteOne", "save"].indexOf(method) === 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						-1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					throw new Error("Method not allowed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log(`Pre-${method}!`, this.options?.userContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (["find", "update", "deleteOne"].indexOf(method) !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const filter = this.getFilter(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const filterKeys = getAllKeys(filter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					filterKeys.forEach(filterKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						const splitFilterKeys = filterKey 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							.split(".") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							.reduce( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								(keys: string[], key: string) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-									keys.length > 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-										? [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-												...keys, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-												`${ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-													keys[keys.length - 1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-												}.${key}` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-										  ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-										: [key], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								[] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						splitFilterKeys.forEach(splitFilterKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							const path = this.schema.path(splitFilterKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							if (!path) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								throw new Error( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-									"Attempted to query with non-existant property" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							if (path.options.restricted) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								throw new Error( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-									"Attempted to query with restricted property" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// console.log(`Pre-${method}!`, filterKeys); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					// Here we want to always exclude some properties depending on the model, like passwords/tokens 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.projection({ restrictedName: 0 }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log(`Pre-${method}! END`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			schema.post(method, async docOrDocs => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log(`Post-${method} START!`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log(`Post-${method}!`, docOrDocs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log(`Post-${method}!`, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// console.log(`Post-${method} END!`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const { enabled, eventCreated, eventUpdated, eventDeleted } = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			schema.get("patchHistory") ?? {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |