Selaa lähdekoodia

refactor: worked more on fixing TS errors in DataModule

Kristian Vos 2 vuotta sitten
vanhempi
commit
88ddf8de9d
1 muutettua tiedostoa jossa 53 lisäystä ja 26 poistoa
  1. 53 26
      backend/src/modules/DataModule.ts

+ 53 - 26
backend/src/modules/DataModule.ts

@@ -8,7 +8,7 @@ import BaseModule from "../BaseModule";
 import ModuleManager from "../ModuleManager";
 import Schema, { Types } from "../Schema";
 import { Collections } from "../types/Collections";
-import { Document } from "../types/Document";
+import { Document as SchemaDocument } from "../types/Document";
 import { UniqueMethods } from "../types/Modules";
 
 interface ProjectionObject {
@@ -22,6 +22,20 @@ type NormalizedProjection = {
 	mode: "includeAllBut" | "excludeAllBut";
 };
 
+type SchemaDocumentSimpleValue = string | number | boolean | Date | ObjectId;
+
+interface MongoFilter {
+	[property: string]:
+		| SchemaDocumentSimpleValue
+		| SchemaDocumentSimpleValue[]
+		| MongoFilter;
+}
+
+// WIP
+interface Document {
+	[property: string]: null;
+}
+
 export default class DataModule extends BaseModule {
 	private collections?: Collections;
 
@@ -299,7 +313,7 @@ export default class DataModule extends BaseModule {
 	 */
 	private async parseFindProjection(
 		projection: NormalizedProjection,
-		schema: Document,
+		schema: SchemaDocument,
 		allowedRestricted: any
 	) {
 		// The mongo projection object we're going to build
@@ -505,7 +519,10 @@ export default class DataModule extends BaseModule {
 		return newAllowedRestricted;
 	}
 
-	private getCastedValue(value, schemaType: Types) {
+	private getCastedValue(
+		value: SchemaDocumentSimpleValue,
+		schemaType: Types
+	) {
 		if (schemaType === Types.String) {
 			// Check if value is a string, and if not, convert the value to a string
 			const castedValue =
@@ -530,12 +547,14 @@ export default class DataModule extends BaseModule {
 			// Check if value is a Date, and if not, convert the value to a Date
 			const castedValue =
 				Object.prototype.toString.call(value) === "[object Date]"
-					? value
-					: new Date(value);
+					? (value as Date)
+					: new Date(value.toString());
 			// TODO possibly allow this via a validate boolean option?
 			// We don't allow invalid dates, so throw an error
-			// eslint-disable-next-line
-			if (isNaN(castedValue)) throw new Error(`Cast error, date cannot be invalid, at key ${key} with value ${value}`);
+			if (new Date(castedValue).toString() === "Invalid Date")
+				throw new Error(
+					`Cast error, date cannot be invalid, with value ${value}`
+				);
 			// Any additional validation comes here
 			return castedValue;
 		}
@@ -547,6 +566,10 @@ export default class DataModule extends BaseModule {
 			return castedValue;
 		}
 		if (schemaType === Types.ObjectId) {
+			if (typeof value !== "string" && !(value instanceof ObjectId))
+				throw new Error(
+					`Cast error, ObjectId invalid, with value ${value}`
+				);
 			// Cast the value as an ObjectId and let Mongoose handle the rest
 			const castedValue = new ObjectId(value);
 			// Any additional validation comes here
@@ -568,13 +591,13 @@ export default class DataModule extends BaseModule {
 	 */
 	private async parseFindFilter(
 		filter: any,
-		schema: Document,
+		schema: SchemaDocument,
 		allowedRestricted: boolean | string[] | null | undefined,
 		options?: {
 			operators?: boolean;
 		}
 	): Promise<{
-		mongoFilter;
+		mongoFilter: MongoFilter;
 		containsRestrictedProperties: boolean;
 		canCache: boolean;
 	}> {
@@ -594,7 +617,7 @@ export default class DataModule extends BaseModule {
 		// Whether to parse operators or not
 		const operators = !(options && options.operators === false);
 		// The MongoDB filter we're building
-		const mongoFilter = {};
+		const mongoFilter: MongoFilter = {};
 		// If the filter references any properties that are restricted, this will be true, so that find knows not to cache the query object
 		let containsRestrictedProperties = false;
 		// Whether this filter is cachable or not
@@ -731,7 +754,7 @@ export default class DataModule extends BaseModule {
 								`Key "${currentKey}" is of type schema, which is not allowed with $in`
 							);
 						// Set the type to be the array item type if it's about an array
-						if (type === Types.Array) type = schema[key].item.type;
+						if (type === Types.Array) type = schema[key].item!.type;
 
 						// Loop through all $in array items, check if they're not null/undefined, cast them, and return a new array
 						if (value.$in.length > 0)
@@ -785,7 +808,7 @@ export default class DataModule extends BaseModule {
 							_containsRestrictedProperties
 					} = await this.parseFindFilter(
 						subFilter,
-						schema[currentKey].schema,
+						schema[currentKey].schema!,
 						deeperAllowedRestricted,
 						options
 					);
@@ -803,7 +826,7 @@ export default class DataModule extends BaseModule {
 						);
 
 					// The type of the array items
-					const itemType = schema[currentKey].item.type;
+					const itemType = schema[currentKey].item!.type;
 
 					// Handle nested arrays, which are not supported
 					if (itemType === Types.Array)
@@ -834,7 +857,7 @@ export default class DataModule extends BaseModule {
 								_containsRestrictedProperties
 						} = await this.parseFindFilter(
 							subFilter,
-							schema[currentKey].item.schema,
+							schema[currentKey].item!.schema!,
 							deeperAllowedRestricted,
 							options
 						);
@@ -892,11 +915,11 @@ export default class DataModule extends BaseModule {
 	 * @returns
 	 */
 	private async stripDocument(
-		document: any,
-		schema: any,
+		document: Document,
+		schema: SchemaDocument,
 		projection: NormalizedProjection,
 		allowedRestricted: boolean | string[] | null | undefined
-	) {
+	): Promise<Document> {
 		// TODO possibly do different things with required properties?
 		// TODO possibly do different things with properties with default?
 
@@ -940,7 +963,7 @@ export default class DataModule extends BaseModule {
 					// Generate a stripped document/object for the current key/value
 					const strippedDocument = await this.stripDocument(
 						value,
-						schema[key].schema,
+						schema[key].schema!,
 						deeperProjection,
 						deeperAllowedRestricted
 					);
@@ -965,7 +988,7 @@ export default class DataModule extends BaseModule {
 					if (!Array.isArray(value)) return [...memo, [key, null]];
 
 					// The type of the array items
-					const itemType = schema[key].item.type;
+					const itemType = schema[key].item!.type;
 
 					const items = await async.map(value, async item => {
 						// Handle schema objects inside an array
@@ -989,7 +1012,7 @@ export default class DataModule extends BaseModule {
 							// Generate a stripped document/object for the current key/value
 							const strippedDocument = await this.stripDocument(
 								item,
-								schema[key].item.schema,
+								schema[key].item!.schema!,
 								deeperProjection,
 								deeperAllowedRestricted
 							);
@@ -1078,7 +1101,7 @@ export default class DataModule extends BaseModule {
 			page?: number;
 			useCache?: boolean;
 		}
-	): Promise<any | null> {
+	): Promise<Document | Document[] | null> {
 		return new Promise((resolve, reject) => {
 			let queryHash: string | null = null;
 			let cacheable = useCache !== false;
@@ -1087,7 +1110,7 @@ export default class DataModule extends BaseModule {
 
 			let normalizedProjection: NormalizedProjection;
 
-			let mongoFilter;
+			let mongoFilter: MongoFilter;
 			let mongoProjection: ProjectionObject;
 
 			async.waterfall(
@@ -1181,7 +1204,11 @@ export default class DataModule extends BaseModule {
 					},
 
 					// Get documents from Mongo if we got no cached documents
-					async ({ cachedDocuments }: any) => {
+					async ({
+						cachedDocuments
+					}: {
+						cachedDocuments: Document[] | null;
+					}) => {
 						// We got cached documents, so continue with those
 						if (cachedDocuments) {
 							cacheable = false;
@@ -1209,7 +1236,7 @@ export default class DataModule extends BaseModule {
 					},
 
 					// Add documents to the cache
-					async (documents: any[]) => {
+					async (documents: Document[]) => {
 						// Adds query results to cache but doesnt await
 						if (cacheable && queryHash) {
 							this.redisClient!.SET(
@@ -1224,8 +1251,8 @@ export default class DataModule extends BaseModule {
 					},
 
 					// Strips the document of any unneeded properties or properties that are restricted
-					async (documents: any[]) =>
-						async.map(documents, async (document: any) =>
+					async (documents: Document[]) =>
+						async.map(documents, async (document: Document) =>
 							this.stripDocument(
 								document,
 								schema.getDocument(),