Procházet zdrojové kódy

fix: remaining TS errors on the backend

Kristian Vos před 1 rokem
rodič
revize
fb86ebdeff

+ 51 - 0
backend/src/@types/mongoose.d.ts

@@ -0,0 +1,51 @@
+declare module "mongoose" {
+	// Add some additional possible config options to Mongoose's schema options
+	interface SchemaOptions<
+		DocType = unknown,
+		TInstanceMethods = {},
+		QueryHelpers = {},
+		TStaticMethods = {},
+		TVirtuals = {},
+		THydratedDocumentType = HydratedDocument<
+			DocType,
+			TInstanceMethods,
+			QueryHelpers
+		>
+	> {
+		patchHistory?: {
+			enabled: boolean;
+			patchHistoryDisabled?: boolean;
+			eventCreated?: string;
+			eventUpdated?: string;
+			eventDeleted?: string;
+		};
+
+		getData?: {
+			enabled: boolean;
+			blacklistedProperties?: string[];
+			specialProperties?: Record<string, PipelineStage[]>;
+			specialQueries?: Record<
+				string,
+				(query: Record<string, any>) => Record<string, any>
+			>;
+			specialFilters?: Record<
+				string,
+				(...args: any[]) => PipelineStage[]
+			>;
+		};
+
+		documentVersion?: number;
+
+		eventListeners?: {
+			[key: `${string}.created`]: (
+				doc: THydratedDocumentType
+			) => Promise<void>;
+			[key: `${string}.updated`]: (
+				doc: THydratedDocumentType
+			) => Promise<void>;
+			[key: `${string}.deleted`]: (
+				oldDoc: THydratedDocumentType
+			) => Promise<void>;
+		};
+	}
+}

+ 5 - 5
backend/src/modules/DataModule.ts

@@ -99,7 +99,7 @@ export class DataModule extends BaseModule {
 		})
 			.filter(([, event]) => !!event)
 			.forEach(([action, event]) => {
-				patchEventEmitter.on(event, async ({ doc, oldDoc }) => {
+				patchEventEmitter.on(event!, async ({ doc, oldDoc }) => {
 					const modelId = doc?._id ?? oldDoc?._id;
 
 					const Model = await this.getModel(modelName);
@@ -198,12 +198,12 @@ export class DataModule extends BaseModule {
 			),
 			async ([key, type]) => {
 				const { ref } =
-					(type instanceof SchemaTypes.ObjectId
-						? type?.options
-						: type.caster?.options) ?? {};
+					(type instanceof SchemaTypes.Array
+						? type.caster?.options
+						: type?.options) ?? {};
 
 				if (ref)
-					schema.path(key).get(value => {
+					schema.path(key).get((value: any) => {
 						if (
 							typeof value === "object" &&
 							type instanceof SchemaTypes.ObjectId

+ 2 - 2
backend/src/modules/DataModule/DataModuleJob.ts

@@ -1,7 +1,7 @@
 import { HydratedDocument, Model, isObjectIdOrHexString } from "mongoose";
 import Job, { JobOptions } from "@/Job";
 import DataModule from "../DataModule";
-import { UserModel } from "./models/users/schema";
+import { UserSchema } from "./models/users/schema";
 import { forEachIn } from "@/utils/forEachIn";
 
 export default abstract class DataModuleJob extends Job {
@@ -36,7 +36,7 @@ export default abstract class DataModuleJob extends Job {
 
 	public static async hasPermission(
 		model: HydratedDocument<Model<any>>,
-		user?: UserModel
+		user: HydratedDocument<UserSchema> | null
 	) {
 		const options = Array.isArray(this._hasPermission)
 			? this._hasPermission

+ 2 - 1
backend/src/modules/DataModule/models/news/config.ts

@@ -1,5 +1,6 @@
 import { NewsStatus } from "./NewsStatus";
 import getData from "./getData";
+import { NewsSchemaOptions } from "./schema";
 
 export default {
 	documentVersion: 3,
@@ -15,4 +16,4 @@ export default {
 		}
 	},
 	getData
-};
+} as NewsSchemaOptions;

+ 3 - 1
backend/src/modules/DataModule/models/news/getData.ts

@@ -1,3 +1,5 @@
+import { NewsSchemaOptions } from "./schema";
+
 export default {
 	enabled: true,
 	specialProperties: {
@@ -48,4 +50,4 @@ export default {
 			$or: [newQuery, { createdByUsername: newQuery.createdBy }]
 		})
 	}
-};
+} as NewsSchemaOptions["getData"];

+ 3 - 0
backend/src/modules/DataModule/models/news/schema.ts

@@ -3,6 +3,7 @@ import {
 	Model,
 	QueryWithHelpers,
 	Schema,
+	SchemaOptions,
 	SchemaTypes,
 	Types
 } from "mongoose";
@@ -88,3 +89,5 @@ export const schema = new Schema<NewsSchema, NewsModel, {}, NewsQueryHelpers>(
 );
 
 export type NewsSchemaType = typeof schema;
+
+export type NewsSchemaOptions = SchemaOptions<NewsSchema, {}, NewsQueryHelpers>;

+ 5 - 1
backend/src/modules/DataModule/models/sessions/schema.ts

@@ -15,7 +15,11 @@ export const schema = new Schema<SessionSchema, SessionModel>(
 			required: true
 		}
 	},
-	{ patchHistory: { enabled: false } }
+	{
+		patchHistory: {
+			enabled: false
+		}
+	}
 );
 
 export type SessionSchemaType = typeof schema;

+ 3 - 1
backend/src/modules/DataModule/models/stations/getData.ts

@@ -1,3 +1,5 @@
+import { StationSchemaOptions } from "./schema";
+
 export default {
 	enabled: true,
 	specialProperties: {
@@ -54,4 +56,4 @@ export default {
 			$or: [newQuery, { ownerUsername: newQuery.owner }]
 		})
 	}
-};
+} as StationSchemaOptions["getData"];

+ 3 - 1
backend/src/modules/DataModule/models/stations/schema.ts

@@ -1,4 +1,4 @@
-import { Model, Schema, SchemaTypes, Types } from "mongoose";
+import { Model, Schema, SchemaOptions, SchemaTypes, Types } from "mongoose";
 import { GetData } from "@/modules/DataModule/plugins/getData";
 import { BaseSchema } from "@/modules/DataModule/types/Schemas";
 import { StationType } from "./StationType";
@@ -155,3 +155,5 @@ export const schema = new Schema<StationSchema, StationModel>(
 );
 
 export type StationSchemaType = typeof schema;
+
+export type StationSchemaOptions = SchemaOptions<StationSchema>;

+ 5 - 13
backend/src/modules/DataModule/models/users/config.ts

@@ -1,26 +1,18 @@
-import { HydratedDocument } from "mongoose";
+import { SchemaOptions } from "mongoose";
 import CacheModule from "@/modules/CacheModule";
 import getData from "./getData";
-import { UserModel } from "./schema";
+import { UserSchema } from "./schema";
 
 export default {
 	documentVersion: 4,
 	eventListeners: {
-		"model.users.updated": ({
-			doc
-		}: {
-			doc: HydratedDocument<UserModel>;
-		}) => {
+		"model.users.updated": async doc => {
 			CacheModule.removeMany([
 				`user-permissions.${doc._id}`,
 				`model-permissions.*.user.${doc._id}`
 			]);
 		},
-		"model.users.deleted": ({
-			oldDoc
-		}: {
-			oldDoc: HydratedDocument<UserModel>;
-		}) => {
+		"model.users.deleted": async oldDoc => {
 			CacheModule.removeMany([
 				`user-permissions.${oldDoc._id}`,
 				`model-permissions.*.user.${oldDoc._id}`
@@ -28,4 +20,4 @@ export default {
 		}
 	},
 	getData
-};
+} as SchemaOptions<UserSchema>;

+ 3 - 1
backend/src/modules/DataModule/models/users/schema.ts

@@ -1,4 +1,4 @@
-import { Model, Schema, SchemaTypes, Types } from "mongoose";
+import { Model, Schema, SchemaOptions, SchemaTypes, Types } from "mongoose";
 import { BaseSchema } from "@/modules/DataModule/types/Schemas";
 import config from "./config";
 import { UserRole } from "./UserRole";
@@ -223,3 +223,5 @@ export const schema = new Schema<UserSchema, UserModel>(
 );
 
 export type UserSchemaType = typeof schema;
+
+export type UserSchemaOptions = SchemaOptions<UserSchema>;

+ 5 - 8
backend/src/modules/DataModule/permissions/isOwner.ts

@@ -1,13 +1,10 @@
-import { HydratedDocument, Schema, Types } from "mongoose";
+import { HydratedDocument } from "mongoose";
 import { UserSchema } from "../models/users/schema";
 
-export default <
-	ModelSchemaType extends Schema & {
-		createdBy?: Types.ObjectId;
-		owner?: Types.ObjectId;
-	}
->(
-	model: HydratedDocument<ModelSchemaType>,
+export default (
+	model:
+		| (HydratedDocument<any> & { owner?: any })
+		| (HydratedDocument<any> & { createdBy?: any }),
 	user?: HydratedDocument<UserSchema>
 ) => {
 	if (!(user && model)) return false;

+ 4 - 6
backend/src/modules/DataModule/permissions/isPublic.ts

@@ -1,8 +1,6 @@
-import { HydratedDocument, Schema } from "mongoose";
+import { HydratedDocument } from "mongoose";
 import { StationPrivacy } from "@/modules/DataModule/models/stations/StationPrivacy";
+import { StationSchema } from "../models/stations/schema";
 
-export default <
-	ModelSchemaType extends Schema & { privacy?: StationPrivacy.PUBLIC }
->(
-	model: HydratedDocument<ModelSchemaType>
-) => model && model?.privacy === StationPrivacy.PUBLIC;
+export default (model: HydratedDocument<StationSchema>) =>
+	model && model?.privacy === StationPrivacy.PUBLIC;

+ 2 - 6
backend/src/modules/DataModule/plugins/documentVersion.ts

@@ -1,8 +1,4 @@
-import { Schema, SchemaOptions, SchemaTypes } from "mongoose";
-
-export interface DocumentVersionSchemaOptions extends SchemaOptions {
-	documentVersion: number;
-}
+import { Schema, SchemaTypes } from "mongoose";
 
 export interface DocumentVersion {
 	documentVersion: number;
@@ -12,7 +8,7 @@ export default function documentVersionPlugin(schema: Schema) {
 	schema.add({
 		documentVersion: {
 			type: SchemaTypes.Number,
-			default: schema.options?.documentVersion ?? 1,
+			default: schema.get("documentVersion") ?? 1,
 			required: true
 		}
 	});

+ 5 - 15
backend/src/modules/DataModule/plugins/getData.ts

@@ -1,5 +1,4 @@
-import { PipelineStage, Schema, SchemaOptions } from "mongoose";
-import JobContext from "@/JobContext";
+import { PipelineStage, Schema } from "mongoose";
 
 export enum FilterType {
 	REGEX = "regex",
@@ -16,18 +15,6 @@ export enum FilterType {
 	SPECIAL = "special"
 }
 
-export interface GetDataSchemaOptions extends SchemaOptions {
-	getData?: {
-		blacklistedProperties?: string[];
-		specialProperties?: Record<string, PipelineStage[]>;
-		specialQueries?: Record<
-			string,
-			(query: Record<string, any>) => Record<string, any>
-		>;
-		specialFilters?: Record<string, (...args: any[]) => PipelineStage[]>;
-	};
-}
-
 export interface GetData {
 	getData(payload: {
 		page: number;
@@ -57,12 +44,15 @@ export default function getDataPlugin(schema: Schema) {
 			const { page, pageSize, properties, sort, queries, operator } =
 				payload;
 
+			const getData = schema.get("getData");
+			if (!getData)
+				throw new Error("Schema doesn't have getData defined.");
 			const {
 				blacklistedProperties,
 				specialFilters,
 				specialProperties,
 				specialQueries
-			} = schema.options?.getData ?? {};
+			} = getData;
 
 			const pipeline: PipelineStage[] = [];