| 
														
															@@ -1,6 +1,7 @@ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import async from "async"; 
														 | 
														
														 | 
														
															 import async from "async"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import config from "config"; 
														 | 
														
														 | 
														
															 import config from "config"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import mongoose, { Schema } from "mongoose"; 
														 | 
														
														 | 
														
															 import mongoose, { Schema } from "mongoose"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+import hash from "object-hash"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import { createClient, RedisClientType } from "redis"; 
														 | 
														
														 | 
														
															 import { createClient, RedisClientType } from "redis"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import BaseModule from "../BaseModule"; 
														 | 
														
														 | 
														
															 import BaseModule from "../BaseModule"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import ModuleManager from "../ModuleManager"; 
														 | 
														
														 | 
														
															 import ModuleManager from "../ModuleManager"; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -40,8 +41,10 @@ export default class DataModule extends BaseModule { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					async () => { 
														 | 
														
														 | 
														
															 					async () => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 						if (this.collections) { 
														 | 
														
														 | 
														
															 						if (this.collections) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							Object.values(this.collections).forEach( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								collection => collection.model.syncIndexes() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							await async.each( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								Object.values(this.collections), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								async collection => 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									collection.model.syncIndexes() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 							); 
														 | 
														
														 | 
														
															 							); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 						} else 
														 | 
														
														 | 
														
															 						} else 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 							throw new Error("Collections have not been loaded"); 
														 | 
														
														 | 
														
															 							throw new Error("Collections have not been loaded"); 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -168,15 +171,109 @@ export default class DataModule extends BaseModule { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		}); 
														 | 
														
														 | 
														
															 		}); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	} 
														 | 
														
														 | 
														
															 	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	// TODO decide on whether to throw an exception if no results found, possible configurable via param 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	// TODO split core into parseDocument(document, schema, { partial: boolean;  }) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	/** 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 * parseQuery - Ensure validity of query 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 * 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 * @param query - Query 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 * @param schema - Schema of collection document 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 * @param options - Parser options 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 * @returns Promise returning object with query values cast to schema types 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 * 			and whether query includes restricted attributes 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	 */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	private async parseQuery( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		query: any, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		schema: any, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		options?: { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			operators?: boolean; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	): Promise<{ castQuery: any; restricted: boolean }> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		if (!query || typeof query !== "object") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			throw new Error("Invalid query provided. Query must be an object."); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		const keys = Object.keys(query); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		if (keys.length === 0) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			throw new Error("Invalid query provided. Query must contain keys."); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		const operators = !(options && options.operators === false); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		const castQuery: any = {}; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		let restricted = false; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		await async.each(Object.entries(query), async ([key, value]) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			if (operators && (key === "$or" || key === "$and")) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				if (!Array.isArray(value)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					throw new Error( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						`Key "${key}" must contain array of queries` 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				castQuery[key] = []; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				await async.each(value, async _value => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					const { castQuery: _castQuery, restricted: _restricted } = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						await this.parseQuery(_value, schema, options); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					castQuery[key].push(_castQuery); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					restricted = restricted || _restricted; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				}); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			} else if (schema[key] !== undefined) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				if (schema[key].restricted) restricted = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				if ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					schema[key].type === undefined && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					Object.keys(schema[key]).length > 0 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					const { castQuery: _castQuery, restricted: _restricted } = 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						await this.parseQuery(value, schema[key], options); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					castQuery[key] = _castQuery; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					restricted = restricted || _restricted; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				} else if ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					operators && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					typeof value === "object" && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					Object.keys(value).length === 1 && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					Array.isArray(value.$in) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					if (value.$in.length > 0) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						castQuery[key] = { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							$in: await async.map( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								value.$in, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								async (_value: any) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									if ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										key === "_id" && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										!schema[key].type.isValid(_value) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										throw new Error( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+											"Invalid value for _id" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									if (typeof schema[key].type === "function") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										return new schema[key].type(_value); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									throw new Error( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										`Invalid schema type for ${key}` 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						}; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					else throw new Error(`Invalid value for ${key}`); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				} else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					if (key === "_id" && !schema[key].type.isValid(value)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						throw new Error("Invalid value for _id"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					if (typeof schema[key].type === "function") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						castQuery[key] = new schema[key].type(value); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					else throw new Error(`Invalid schema type for ${key}`); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			} else { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				throw new Error( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					`Invalid query provided. Key "${key}" not found` 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+				); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		}); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		return { castQuery, restricted }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	// TODO hide sensitive fields 
														 | 
														
														 | 
														
															 	// TODO hide sensitive fields 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	// TOOD don't store sensitive fields in cache 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	// TODO improve caching 
														 | 
														
														 | 
														
															 	// TODO improve caching 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	// TODO add option to only request certain fields 
														 | 
														
														 | 
														
															 	// TODO add option to only request certain fields 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	// TODO add support for computed fields 
														 | 
														
														 | 
														
															 	// TODO add support for computed fields 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	// TODO parse query 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	// TODO parse query - validation 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	// TODO add proper typescript support 
														 | 
														
														 | 
														
															 	// TODO add proper typescript support 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	// TODO add proper jsdoc 
														 | 
														
														 | 
														
															 	// TODO add proper jsdoc 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	// TODO add support for enum document attributes 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	// TODO add support for array document attributes 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	// TODO add support for reference document attributes 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	// TODO prevent caching if requiring restricted values 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	// TODO fix 2nd layer of schema 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	/** 
														 | 
														
														 | 
														
															 	/** 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	 * find - Find data 
														 | 
														
														 | 
														
															 	 * find - Find data 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	 * 
														 | 
														
														 | 
														
															 	 * 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -189,8 +286,7 @@ export default class DataModule extends BaseModule { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		values, // TODO: Add support 
														 | 
														
														 | 
														
															 		values, // TODO: Add support 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		limit = 1, // TODO have limit off by default? 
														 | 
														
														 | 
														
															 		limit = 1, // TODO have limit off by default? 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		page = 1, 
														 | 
														
														 | 
														
															 		page = 1, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		useCache = true, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		convertArrayToSingle = false 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+		useCache = true 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	}: { 
														 | 
														
														 | 
														
															 	}: { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		collection: T; 
														 | 
														
														 | 
														
															 		collection: T; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		query: Record<string, any>; 
														 | 
														
														 | 
														
															 		query: Record<string, any>; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -198,11 +294,10 @@ export default class DataModule extends BaseModule { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		limit?: number; 
														 | 
														
														 | 
														
															 		limit?: number; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		page?: number; 
														 | 
														
														 | 
														
															 		page?: number; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		useCache?: boolean; 
														 | 
														
														 | 
														
															 		useCache?: boolean; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		convertArrayToSingle?: boolean; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-	}): Promise<any> { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+	}): Promise<any | null> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		return new Promise((resolve, reject) => { 
														 | 
														
														 | 
														
															 		return new Promise((resolve, reject) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-			let addToCache = false; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-			let cacheKeyName: string | null = null; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			let queryHash: string | null = null; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+			let cacheable = useCache !== false; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			async.waterfall( 
														 | 
														
														 | 
														
															 			async.waterfall( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 				[ 
														 | 
														
														 | 
														
															 				[ 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -215,129 +310,100 @@ export default class DataModule extends BaseModule { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					}, 
														 | 
														
														 | 
														
															 					}, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					// Verify whether the query is valid-enough to continue 
														 | 
														
														 | 
														
															 					// Verify whether the query is valid-enough to continue 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					async () => { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if ( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							!query || 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							typeof query !== "object" || 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							Object.keys(query).length === 0 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							new Error( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								"Invalid query provided. Query must be an object." 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					}, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					async () => 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						this.parseQuery( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							query, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							this.collections![collection].schema.document 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					// If we can use cache, get from the cache, and if we get results return those, otherwise return null 
														 | 
														
														 | 
														
															 					// If we can use cache, get from the cache, and if we get results return those, otherwise return null 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					async () => { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// Not using cache, so return 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (!useCache) return null; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// More than one query key, so impossible to get from cache 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (Object.keys(query).length > 1) return null; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// First key and only key in query object 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						const queryPropertyName = Object.keys(query)[0]; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// Corresponding property from schema document 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						const documentProperty = 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							this.collections![collection].schema.document[ 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								queryPropertyName 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							]; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (!documentProperty) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							throw new Error( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								`Query property ${queryPropertyName} not found in document.` 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// If query name is not a cache key, just continue 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (!documentProperty.cacheKey) return null; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						const values = []; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if ( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							Object.prototype.hasOwnProperty.call( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								query[queryPropertyName], 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								"$in" 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							values.push(...query[queryPropertyName].$in); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						else values.push(query[queryPropertyName]); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						const cachedDocuments: any[] = []; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						await async.each(values, async value => 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							this.redis 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								?.GET( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-									`${collection}.${queryPropertyName}.${value.toString()}` 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								.then((cachedDocument: any) => { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-									if (cachedDocument) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-										cachedDocuments.push( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-											JSON.parse(cachedDocument) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-										); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								}) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					async ({ castQuery, restricted }: any) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						// Not using cache or query contains restricted values, so return 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						if (!cacheable || restricted) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							return { castQuery, cachedDocuments: null }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						queryHash = hash( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							{ collection, castQuery, values, limit, page }, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								algorithm: "sha1" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 						); 
														 | 
														
														 | 
														
															 						); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// TODO optimize this 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (cachedDocuments.length !== values.length) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							addToCache = true; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							cacheKeyName = queryPropertyName; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							return null; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						} 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						return cachedDocuments; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						const cachedQuery = await this.redis?.GET( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							`query.find.${queryHash}` 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						return { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							castQuery, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							cachedDocuments: cachedQuery 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								? JSON.parse(cachedQuery) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								: null 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						}; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					}, 
														 | 
														
														 | 
														
															 					}, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					// If we didn't get documents from the cache, get them from mongo 
														 | 
														
														 | 
														
															 					// If we didn't get documents from the cache, get them from mongo 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					async (cachedDocuments: any[] | null) => { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (cachedDocuments) return cachedDocuments; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					async ({ castQuery, cachedDocuments }: any) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						if (cachedDocuments) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							cacheable = false; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							return cachedDocuments; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						const getFindValues = async (object: any) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							const find: any = {}; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							await async.each( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								Object.entries(object), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								async ([key, value]) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									if ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										value.type === undefined && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										Object.keys(value).length > 0 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										const _find = await getFindValues( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+											value 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										if (Object.keys(_find).length > 0) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+											find[key] = _find; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									} else if (!value.restricted) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+										find[key] = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							return find; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						}; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						const find: any = await getFindValues( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							this.collections![collection].schema.document 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 						return this.collections?.[collection].model 
														 | 
														
														 | 
														
															 						return this.collections?.[collection].model 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							.find(query) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							.find(castQuery, find) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 							.limit(limit) 
														 | 
														
														 | 
														
															 							.limit(limit) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 							.skip((page - 1) * limit); 
														 | 
														
														 | 
														
															 							.skip((page - 1) * limit); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					}, 
														 | 
														
														 | 
														
															 					}, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					// Convert documents from Mongoose model to regular objects, and if we got no documents throw an error 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					async (documents: any[]) => { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (documents.length === 0) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							throw new Error("No results found."); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						return documents.map(document => { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							if (!document._doc) return document; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							const rawDocument = document._doc; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							rawDocument._id = rawDocument._id.toString(); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							return rawDocument; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						}); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					}, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					// Convert documents from Mongoose model to regular objects 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					async (documents: any[]) => 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						async.map(documents, async (document: any) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							const { castQuery } = await this.parseQuery( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								document._doc || document, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								this.collections![collection].schema.document, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								{ operators: false } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							return castQuery; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						}), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					// Add documents to the cache 
														 | 
														
														 | 
														
															 					// Add documents to the cache 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					async (documents: any[]) => { 
														 | 
														
														 | 
														
															 					async (documents: any[]) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// TODO only add new things to cache 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						// Adds the fetched documents to the cache, but doesn't wait for it to complete 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						if (addToCache && cacheKeyName) { 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							async.each( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								documents, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								// TODO verify that the cache key name property actually exists for these documents 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-								async (document: any) => 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-									this.redis!.SET( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-										`${collection}.${cacheKeyName}.${document[ 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-											cacheKeyName! 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-										].toString()}`, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-										JSON.stringify(document), 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-										{ 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-											EX: 60 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-										} 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-									) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						// Adds query results to cache but doesnt await 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						if (cacheable && queryHash) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+							this.redis!.SET( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								`query.find.${queryHash}`, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								JSON.stringify(documents), 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+									EX: 60 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+								} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 							); 
														 | 
														
														 | 
														
															 							); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 						} 
														 | 
														
														 | 
														
															 						} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 						return documents; 
														 | 
														
														 | 
														
															 						return documents; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					} 
														 | 
														
														 | 
														
															 					} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 				], 
														 | 
														
														 | 
														
															 				], 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 				(err, documents?: any[]) => { 
														 | 
														
														 | 
														
															 				(err, documents?: any[]) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 					if (err) reject(err); 
														 | 
														
														 | 
														
															 					if (err) reject(err); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					else if (convertArrayToSingle) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						resolve( 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-							documents!.length === 1 ? documents![0] : documents 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-						); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-					else resolve(documents); 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					else if (!documents || documents!.length === 0) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+						resolve(limit === 1 ? null : []); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+					else resolve(limit === 1 ? documents![0] : documents); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 				} 
														 | 
														
														 | 
														
															 				} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 			); 
														 | 
														
														 | 
														
															 			); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 		}); 
														 | 
														
														 | 
														
															 		}); 
														 |