Browse Source

refactor: Prefix private attributes with _

Owen Diffey 1 year ago
parent
commit
2eedee2df1

+ 9 - 0
backend/.eslintrc

@@ -46,6 +46,15 @@
 		"@typescript-eslint/no-empty-function": 0,
 		"@typescript-eslint/no-this-alias": 0,
 		"@typescript-eslint/no-non-null-assertion": 0,
+		"@typescript-eslint/naming-convention": [
+			"error",
+			{
+				"selector": "memberLike",
+				"modifiers": ["private"],
+				"format": null,
+				"leadingUnderscore": "require"
+			}
+		],
 		"no-void": 0,
 		"import/no-extraneous-dependencies": [
 			"error",

+ 3 - 3
backend/src/BaseModule.ts

@@ -99,9 +99,9 @@ export default abstract class BaseModule {
 	}
 
 	/**
-	 * loadJobs - Load jobs available via api module
+	 * _loadJobs - Load jobs available via api module
 	 */
-	private async loadJobs() {
+	private async _loadJobs() {
 		this.jobs = {};
 
 		const module = Object.getPrototypeOf(this);
@@ -172,7 +172,7 @@ export default abstract class BaseModule {
 	 * started - called with the module has started
 	 */
 	protected async started() {
-		await this.loadJobs();
+		await this._loadJobs();
 		this.log(`Module (${this.name}) started`);
 		this.setStatus(ModuleStatus.STARTED);
 	}

+ 22 - 20
backend/src/JobContext.ts

@@ -14,13 +14,13 @@ export default class JobContext {
 
 	public readonly jobQueue: JobQueue;
 
-	private session?: SessionSchema;
+	private _session?: SessionSchema;
 
-	private readonly socketId?: string;
+	private readonly _socketId?: string;
 
-	private user?: UserSchema;
+	private _user?: UserSchema;
 
-	private permissions?: Record<string, boolean>;
+	private _permissions?: Record<string, boolean>;
 
 	public constructor(
 		job: Job,
@@ -28,8 +28,8 @@ export default class JobContext {
 	) {
 		this.job = job;
 		this.jobQueue = JobQueue.getPrimaryInstance();
-		this.session = options?.session;
-		this.socketId = options?.socketId;
+		this._session = options?.session;
+		this._socketId = options?.socketId;
 	}
 
 	/**
@@ -42,15 +42,15 @@ export default class JobContext {
 	}
 
 	public getSession() {
-		return this.session;
+		return this._session;
 	}
 
 	public setSession(session?: SessionSchema) {
-		this.session = session;
+		this._session = session;
 	}
 
 	public getSocketId() {
-		return this.socketId;
+		return this._socketId;
 	}
 
 	/**
@@ -79,8 +79,8 @@ export default class JobContext {
 		options?: JobOptions
 	): Promise<ReturnType> {
 		return new Job(jobName.toString(), moduleName, payload, {
-			session: this.session,
-			socketId: this.socketId,
+			session: this._session,
+			socketId: this._socketId,
 			...(options ?? {})
 		}).execute();
 	}
@@ -90,36 +90,38 @@ export default class JobContext {
 	}
 
 	public async getUser(refresh = false) {
-		if (!this.session?.userId) throw new Error("No user found for session");
+		if (!this._session?.userId)
+			throw new Error("No user found for session");
 
-		if (this.user && !refresh) return this.user;
+		if (this._user && !refresh) return this._user;
 
 		const User = await this.getModel("user");
 
-		this.user = await User.findById(this.session.userId);
+		this._user = await User.findById(this._session.userId);
 
-		if (!this.user) throw new Error("No user found for session");
+		if (!this._user) throw new Error("No user found for session");
 
-		return this.user;
+		return this._user;
 	}
 
 	public async assertLoggedIn() {
-		if (!this.session?.userId) throw new Error("No user found for session");
+		if (!this._session?.userId)
+			throw new Error("No user found for session");
 	}
 
 	public async getUserPermissions(
 		scope?: { stationId?: Types.ObjectId },
 		refresh = false
 	) {
-		if (this.permissions && !refresh) return this.permissions;
+		if (this._permissions && !refresh) return this._permissions;
 
-		this.permissions = await this.executeJob(
+		this._permissions = await this.executeJob(
 			"api",
 			"getUserPermissions",
 			scope ?? {}
 		);
 
-		return this.permissions;
+		return this._permissions;
 	}
 
 	public async assertPermission(

+ 45 - 45
backend/src/JobQueue.ts

@@ -6,19 +6,19 @@ import { Jobs, Modules } from "./types/Modules";
 export default class JobQueue {
 	static primaryInstance = new this();
 
-	private concurrency: number;
+	private _concurrency: number;
 
-	private isPaused: boolean;
+	private _isPaused: boolean;
 
-	private jobs: Job[];
+	private _jobs: Job[];
 
-	private queue: Job[];
+	private _queue: Job[];
 
-	private active: Job[];
+	private _active: Job[];
 
-	private processLock: boolean;
+	private _processLock: boolean;
 
-	private callbacks: Record<
+	private _callbacks: Record<
 		string,
 		{
 			resolve: (value: any) => void;
@@ -30,13 +30,13 @@ export default class JobQueue {
 	 * Job Queue
 	 */
 	public constructor() {
-		this.concurrency = 10000;
-		this.isPaused = true;
-		this.jobs = [];
-		this.queue = [];
-		this.active = [];
-		this.callbacks = {};
-		this.processLock = false;
+		this._concurrency = 10000;
+		this._isPaused = true;
+		this._jobs = [];
+		this._queue = [];
+		this._active = [];
+		this._callbacks = {};
+		this._processLock = false;
 	}
 
 	/**
@@ -46,7 +46,7 @@ export default class JobQueue {
 	 * @returns Job if found
 	 */
 	public getJob(jobId: string) {
-		return this.jobs.find(job => job.getUuid() === jobId);
+		return this._jobs.find(job => job.getUuid() === jobId);
 	}
 
 	/**
@@ -55,15 +55,15 @@ export default class JobQueue {
 	 * Pause processing of jobs in queue, active jobs will not be paused.
 	 */
 	public pause() {
-		this.isPaused = true;
+		this._isPaused = true;
 	}
 
 	/**
 	 * resume - Resume queue
 	 */
 	public resume() {
-		this.isPaused = false;
-		this.process();
+		this._isPaused = false;
+		this._process();
 	}
 
 	/**
@@ -133,11 +133,11 @@ export default class JobQueue {
 	): Promise<string> {
 		const job = new Job(jobName.toString(), moduleName, payload, options);
 
-		this.callbacks[job.getUuid()] = callback;
+		this._callbacks[job.getUuid()] = callback;
 
-		this.jobs.push(job);
-		this.queue.push(job);
-		this.process();
+		this._jobs.push(job);
+		this._queue.push(job);
+		this._process();
 
 		return job.getUuid();
 	}
@@ -145,22 +145,22 @@ export default class JobQueue {
 	/**
 	 * process - Process queue
 	 */
-	private async process() {
+	private async _process() {
 		// If the process is locked, don't continue. This prevents running process at the same time which could lead to issues
-		if (this.processLock) return;
+		if (this._processLock) return;
 		// If the queue is paused, we've reached the maximum number of active jobs, or there are no jobs in the queue, don't continue
 		if (
-			this.isPaused ||
-			this.active.length >= this.concurrency ||
-			this.queue.length === 0
+			this._isPaused ||
+			this._active.length >= this._concurrency ||
+			this._queue.length === 0
 		)
 			return;
 
 		// Lock the process function
-		this.processLock = true;
+		this._processLock = true;
 
 		// Sort jobs based on priority, with a lower priority being preferred
-		const jobs = this.queue.sort(
+		const jobs = this._queue.sort(
 			(a, b) => a.getPriority() - b.getPriority()
 		);
 
@@ -173,32 +173,32 @@ export default class JobQueue {
 			if (job.getModule().getStatus() !== ModuleStatus.STARTED) continue;
 
 			// Remove the job from the queue and add it to the active jobs array
-			this.queue.splice(this.queue.indexOf(job), 1);
+			this._queue.splice(this._queue.indexOf(job), 1);
 
 			// Execute the job
-			this.active.push(job);
+			this._active.push(job);
 
-			const callback = this.callbacks[job.getUuid()];
+			const callback = this._callbacks[job.getUuid()];
 			job.execute()
 				.then(callback.resolve)
 				.catch(callback.reject)
 				.finally(() => {
-					delete this.callbacks[job.getUuid()];
+					delete this._callbacks[job.getUuid()];
 
 					// If the current job is in the active jobs array, remove it, and then run the process function to run another job
-					const activeJobIndex = this.active.indexOf(job);
+					const activeJobIndex = this._active.indexOf(job);
 					if (activeJobIndex > -1) {
-						this.active.splice(activeJobIndex, 1);
+						this._active.splice(activeJobIndex, 1);
 					}
 
-					this.process();
+					this._process();
 				});
 			// Stop the for loop
-			if (this.active.length >= this.concurrency) break;
+			if (this._active.length >= this._concurrency) break;
 		}
 
 		// Unlock the process after the for loop is finished, so it can be run again
-		this.processLock = false;
+		this._processLock = false;
 	}
 
 	/**
@@ -208,10 +208,10 @@ export default class JobQueue {
 	 */
 	public getStatus() {
 		return {
-			isPaused: this.isPaused,
-			queueLength: this.queue.length,
-			activeLength: this.active.length,
-			concurrency: this.concurrency
+			isPaused: this._isPaused,
+			queueLength: this._queue.length,
+			activeLength: this._active.length,
+			concurrency: this._concurrency
 		};
 	}
 
@@ -224,9 +224,9 @@ export default class JobQueue {
 	public getQueueStatus(type?: JobStatus) {
 		const status: Record<string, ReturnType<Job["toJSON"]>[]> = {};
 		if (!type || type === JobStatus.ACTIVE)
-			status.active = this.active.map(job => job.toJSON());
+			status.active = this._active.map(job => job.toJSON());
 		if (!type || type === JobStatus.QUEUED)
-			status.queue = this.queue.map(job => job.toJSON());
+			status.queue = this._queue.map(job => job.toJSON());
 		return status;
 	}
 
@@ -235,7 +235,7 @@ export default class JobQueue {
 	 *
 	 */
 	public getJobs() {
-		return this.jobs;
+		return this._jobs;
 	}
 
 	static getPrimaryInstance(): JobQueue {

+ 10 - 10
backend/src/JobStatistics.ts

@@ -1,7 +1,7 @@
 export default class JobStatistics {
 	static primaryInstance = new this();
 
-	private stats: Record<
+	private _stats: Record<
 		string,
 		{
 			successful: number;
@@ -13,7 +13,7 @@ export default class JobStatistics {
 	>;
 
 	public constructor() {
-		this.stats = {};
+		this._stats = {};
 	}
 
 	/**
@@ -23,8 +23,8 @@ export default class JobStatistics {
 	 */
 	public getStats() {
 		return {
-			...this.stats,
-			total: Object.values(this.stats).reduce(
+			...this._stats,
+			total: Object.values(this._stats).reduce(
 				(a, b) => ({
 					successful: a.successful + b.successful,
 					failed: a.failed + b.failed,
@@ -55,8 +55,8 @@ export default class JobStatistics {
 		type: "successful" | "failed" | "total" | "added" | "averageTime",
 		duration?: number
 	) {
-		if (!this.stats[jobName])
-			this.stats[jobName] = {
+		if (!this._stats[jobName])
+			this._stats[jobName] = {
 				successful: 0,
 				failed: 0,
 				total: 0,
@@ -64,10 +64,10 @@ export default class JobStatistics {
 				averageTime: 0
 			};
 		if (type === "averageTime" && duration)
-			this.stats[jobName].averageTime +=
-				(duration - this.stats[jobName].averageTime) /
-				this.stats[jobName].total;
-		else this.stats[jobName][type] += 1;
+			this._stats[jobName].averageTime +=
+				(duration - this._stats[jobName].averageTime) /
+				this._stats[jobName].total;
+		else this._stats[jobName][type] += 1;
 	}
 
 	static getPrimaryInstance(): JobStatistics {

+ 31 - 30
backend/src/LogBook.ts

@@ -35,20 +35,20 @@ export default class LogBook {
 	static primaryInstance = new this();
 
 	// A list of log objects stored in memory, if enabled generally
-	private logs: Log[];
+	private _logs: Log[];
 
-	private default: LogOutputs;
+	private _default: LogOutputs;
 
 	// Settings for different outputs. Currently only memory and outputs is supported as an output
 	// Constructed first via defaults, then via settings set in the config, and then you can make any other changes via a backend command (not persistent)
-	private outputs: LogOutputs;
+	private _outputs: LogOutputs;
 
 	/**
 	 * Log Book
 	 */
 	public constructor() {
-		this.logs = [];
-		this.default = {
+		this._logs = [];
+		this._default = {
 			console: {
 				timestamp: true,
 				title: true,
@@ -76,12 +76,12 @@ export default class LogBook {
 		if (config.has("logging"))
 			(["console", "memory"] as (keyof LogOutputs)[]).forEach(output => {
 				if (config.has(`logging.${output}`))
-					this.default[output] = {
-						...this.default[output],
+					this._default[output] = {
+						...this._default[output],
 						...config.get(`logging.${output}`)
 					};
 			});
-		this.outputs = this.default;
+		this._outputs = this._default;
 	}
 
 	/**
@@ -109,7 +109,7 @@ export default class LogBook {
 
 				// Loop through outputs to see if they have any include/exclude filters
 				(
-					Object.entries(this.outputs) as [
+					Object.entries(this._outputs) as [
 						keyof LogOutputs,
 						LogOutputs[keyof LogOutputs]
 					][]
@@ -139,16 +139,16 @@ export default class LogBook {
 			logObject.data?.jobName ?? logObject.category ?? undefined;
 
 		// If memory is not excluded and memory is enabled, store the log object in the memory (logs array) of this logbook instance
-		if (!exclude.memory && this.outputs.memory.enabled)
-			this.logs.push(logObject);
+		if (!exclude.memory && this._outputs.memory.enabled)
+			this._logs.push(logObject);
 
 		// If console is not excluded, format the log object, and then write the formatted message to the console
 		if (!exclude.console) {
-			const message = this.formatMessage(logObject, String(title));
+			const message = this._formatMessage(logObject, String(title));
 			const logArgs: (string | Record<string, unknown>)[] = [message];
 
 			// Append logObject data, if enabled and it's not falsy
-			if (this.outputs.console.data && logObject.data)
+			if (this._outputs.console.data && logObject.data)
 				logArgs.push(logObject.data);
 
 			switch (logObject.type) {
@@ -173,7 +173,7 @@ export default class LogBook {
 	 * @param length - The total amount of space we have to work with
 	 * @returns
 	 */
-	private centerString(string: string, length: number) {
+	private _centerString(string: string, length: number) {
 		const spaces = Array(
 			Math.floor((length - Math.max(0, string.length)) / 2)
 		).join(" ");
@@ -189,11 +189,11 @@ export default class LogBook {
 	 * @param title - Log title
 	 * @returns Formatted log string
 	 */
-	private formatMessage(log: Log, title: string | undefined): string {
+	private _formatMessage(log: Log, title: string | undefined): string {
 		let message = "";
 
 		// If we want to show colors, prepend the color code
-		if (this.outputs.console.color)
+		if (this._outputs.console.color)
 			switch (log.type) {
 				case "success":
 					message += COLOR_GREEN;
@@ -211,28 +211,28 @@ export default class LogBook {
 			}
 
 		// If we want to show timestamps, e.g. 2022-11-28T18:13:28.081Z
-		if (this.outputs.console.timestamp)
+		if (this._outputs.console.timestamp)
 			message += `| ${new Date(log.timestamp).toISOString()} `;
 
 		// If we want to show titles, show it centered and capped at 20 characters
-		if (this.outputs.console.title)
-			message += `| ${this.centerString(
+		if (this._outputs.console.title)
+			message += `| ${this._centerString(
 				title ? title.substring(0, 20) : "",
 				24
 			)} `;
 
 		// If we want to show the log type, show it centered, in uppercase
-		if (this.outputs.console.type)
-			message += `| ${this.centerString(
+		if (this._outputs.console.type)
+			message += `| ${this._centerString(
 				log.type ? log.type.toUpperCase() : "INFO",
 				10
 			)} `;
 
 		// If we want to the message, show it
-		if (this.outputs.console.message) message += `| ${log.message} `;
+		if (this._outputs.console.message) message += `| ${log.message} `;
 
 		// Reset the color at the end of the message, if we have colors enabled
-		if (this.outputs.console.color) message += COLOR_RESET;
+		if (this._outputs.console.color) message += COLOR_RESET;
 		return message;
 	}
 
@@ -260,14 +260,15 @@ export default class LogBook {
 					if (!values || typeof values !== "object")
 						throw new Error("No filters provided");
 					const filters = Array.isArray(values) ? values : [values];
-					if (action === "set") this.outputs[output][key] = filters;
+					if (action === "set") this._outputs[output][key] = filters;
 					if (action === "add")
-						this.outputs[output][key] = [
-							...(this.outputs[output][key] || []),
+						this._outputs[output][key] = [
+							...(this._outputs[output][key] || []),
 							...filters
 						];
 				} else if (action === "reset") {
-					this.outputs[output][key] = this.default[output][key] || [];
+					this._outputs[output][key] =
+						this._default[output][key] || [];
 				} else
 					throw new Error(
 						`Action "${action}" not found for ${key} in ${output}`
@@ -279,7 +280,7 @@ export default class LogBook {
 				if (output === "memory" && action === "set") {
 					if (values === undefined)
 						throw new Error("No value provided");
-					this.outputs[output][key] = !!values;
+					this._outputs[output][key] = !!values;
 				} else
 					throw new Error(
 						`Action "${action}" not found for ${key} in ${output}`
@@ -291,9 +292,9 @@ export default class LogBook {
 				if (output !== "memory" && action === "set") {
 					if (values === undefined)
 						throw new Error("No value provided");
-					this.outputs[output][key] = !!values;
+					this._outputs[output][key] = !!values;
 				} else if (output !== "memory" && action === "reset") {
-					this.outputs[output][key] = this.default[output][key];
+					this._outputs[output][key] = this._default[output][key];
 				} else
 					throw new Error(
 						`Action "${action}" not found for ${key} in ${output}`

+ 3 - 3
backend/src/Migration.ts

@@ -1,14 +1,14 @@
 import { Connection } from "mongoose";
 
 export default class Migration {
-	private mongoConnection: Connection;
+	private _mongoConnection: Connection;
 
 	constructor(mongoConnection: Connection) {
-		this.mongoConnection = mongoConnection;
+		this._mongoConnection = mongoConnection;
 	}
 
 	protected getDb() {
-		return this.mongoConnection.db;
+		return this._mongoConnection.db;
 	}
 
 	public async up() {}

+ 19 - 19
backend/src/ModuleManager.ts

@@ -5,7 +5,7 @@ import { Modules, ModuleClass } from "./types/Modules";
 export default class ModuleManager {
 	static primaryInstance = new this();
 
-	private modules?: Modules;
+	private _modules?: Modules;
 
 	/**
 	 * getStatus - Get status of modules
@@ -14,7 +14,7 @@ export default class ModuleManager {
 	 */
 	public getStatus() {
 		const status: Record<string, ModuleStatus> = {};
-		Object.entries(this.modules || {}).forEach(([name, module]) => {
+		Object.entries(this._modules || {}).forEach(([name, module]) => {
 			status[name] = module.getStatus();
 		});
 		return status;
@@ -25,7 +25,7 @@ export default class ModuleManager {
 	 *
 	 */
 	public getModule(moduleName: keyof Modules) {
-		return this.modules && this.modules[moduleName];
+		return this._modules && this._modules[moduleName];
 	}
 
 	/**
@@ -34,7 +34,7 @@ export default class ModuleManager {
 	 * @param moduleName - Name of the module
 	 * @returns Module
 	 */
-	private async loadModule<T extends keyof Modules>(moduleName: T) {
+	private async _loadModule<T extends keyof Modules>(moduleName: T) {
 		const mapper = {
 			api: "APIModule",
 			data: "DataModule",
@@ -52,20 +52,20 @@ export default class ModuleManager {
 	 *
 	 * @returns Promise
 	 */
-	private async loadModules() {
-		this.modules = {
-			api: await this.loadModule("api"),
-			data: await this.loadModule("data"),
-			events: await this.loadModule("events"),
-			stations: await this.loadModule("stations"),
-			websocket: await this.loadModule("websocket")
+	private async _loadModules() {
+		this._modules = {
+			api: await this._loadModule("api"),
+			data: await this._loadModule("data"),
+			events: await this._loadModule("events"),
+			stations: await this._loadModule("stations"),
+			websocket: await this._loadModule("websocket")
 		};
 	}
 
 	/**
 	 * startModule - Start module
 	 */
-	private async startModule(module: Modules[keyof Modules]) {
+	private async _startModule(module: Modules[keyof Modules]) {
 		switch (module.getStatus()) {
 			case ModuleStatus.STARTING:
 			case ModuleStatus.STARTED:
@@ -86,7 +86,7 @@ export default class ModuleManager {
 			if (!dependency) throw new Error("Dependent module not found");
 
 			// eslint-disable-next-line no-await-in-loop
-			await this.startModule(dependency);
+			await this._startModule(dependency);
 		}
 
 		await module.startup().catch(async err => {
@@ -100,13 +100,13 @@ export default class ModuleManager {
 	 */
 	public async startup() {
 		try {
-			await this.loadModules();
+			await this._loadModules();
 
-			if (!this.modules) throw new Error("No modules were loaded");
+			if (!this._modules) throw new Error("No modules were loaded");
 
-			for (const module of Object.values(this.modules)) {
+			for (const module of Object.values(this._modules)) {
 				// eslint-disable-next-line no-await-in-loop
-				await this.startModule(module);
+				await this._startModule(module);
 			}
 
 			JobQueue.getPrimaryInstance().resume();
@@ -120,8 +120,8 @@ export default class ModuleManager {
 	 * shutdown - Handle shutdown
 	 */
 	public async shutdown() {
-		if (this.modules) {
-			const modules = Object.entries(this.modules).filter(([, module]) =>
+		if (this._modules) {
+			const modules = Object.entries(this._modules).filter(([, module]) =>
 				[
 					ModuleStatus.STARTED,
 					ModuleStatus.STARTING,

+ 21 - 21
backend/src/modules/APIModule.ts

@@ -10,7 +10,7 @@ import { StationType } from "../schemas/station";
 import permissions from "../permissions";
 
 export default class APIModule extends BaseModule {
-	private subscriptions: Record<string, Set<string>>;
+	private _subscriptions: Record<string, Set<string>>;
 
 	/**
 	 * API Module
@@ -19,7 +19,7 @@ export default class APIModule extends BaseModule {
 		super("api");
 
 		this.dependentModules = ["data", "events", "websocket"];
-		this.subscriptions = {};
+		this._subscriptions = {};
 	}
 
 	/**
@@ -37,7 +37,7 @@ export default class APIModule extends BaseModule {
 	public override async shutdown() {
 		await super.shutdown();
 
-		await this.removeAllSubscriptions();
+		await this._removeAllSubscriptions();
 
 		await super.stopped();
 	}
@@ -91,7 +91,7 @@ export default class APIModule extends BaseModule {
 	/**
 	 * getCookieValueFromHeader - Get value of a cookie from cookie header string
 	 */
-	private getCookieValueFromHeader(cookieName: string, header: string) {
+	private _getCookieValueFromHeader(cookieName: string, header: string) {
 		const cookie = header
 			.split("; ")
 			.find(
@@ -113,7 +113,7 @@ export default class APIModule extends BaseModule {
 		socket.setSocketId(socketId);
 
 		let sessionId = request.headers.cookie
-			? this.getCookieValueFromHeader(
+			? this._getCookieValueFromHeader(
 					config.get<string>("cookie"),
 					request.headers.cookie
 			  )
@@ -218,9 +218,9 @@ export default class APIModule extends BaseModule {
 		return rolePermissions;
 	}
 
-	private async subscriptionCallback(channel: string, value?: any) {
+	private async _subscriptionCallback(channel: string, value?: any) {
 		const promises = [];
-		for await (const socketId of this.subscriptions[channel].values()) {
+		for await (const socketId of this._subscriptions[channel].values()) {
 			promises.push(
 				this.jobQueue.runJob("websocket", "dispatch", {
 					socketId,
@@ -245,18 +245,18 @@ export default class APIModule extends BaseModule {
 
 		if (!socketId) throw new Error("No socketId specified");
 
-		if (!this.subscriptions[channel])
-			this.subscriptions[channel] = new Set();
+		if (!this._subscriptions[channel])
+			this._subscriptions[channel] = new Set();
 
-		if (this.subscriptions[channel].has(socketId)) return;
+		if (this._subscriptions[channel].has(socketId)) return;
 
-		this.subscriptions[channel].add(socketId);
+		this._subscriptions[channel].add(socketId);
 
-		if (this.subscriptions[channel].size === 1)
+		if (this._subscriptions[channel].size === 1)
 			await context.executeJob("events", "subscribe", {
 				type: "event",
 				channel,
-				callback: value => this.subscriptionCallback(channel, value)
+				callback: value => this._subscriptionCallback(channel, value)
 			});
 	}
 
@@ -272,19 +272,19 @@ export default class APIModule extends BaseModule {
 
 		if (
 			!(
-				this.subscriptions[channel] &&
-				this.subscriptions[channel].has(socketId)
+				this._subscriptions[channel] &&
+				this._subscriptions[channel].has(socketId)
 			)
 		)
 			return;
 
-		this.subscriptions[channel].delete(socketId);
+		this._subscriptions[channel].delete(socketId);
 
-		if (this.subscriptions[channel].size === 0)
+		if (this._subscriptions[channel].size === 0)
 			await context.executeJob("events", "unsubscribe", {
 				type: "event",
 				channel,
-				callback: value => this.subscriptionCallback(channel, value)
+				callback: value => this._subscriptionCallback(channel, value)
 			});
 	}
 
@@ -297,7 +297,7 @@ export default class APIModule extends BaseModule {
 		if (!socketId) throw new Error("No socketId specified");
 
 		await Promise.all(
-			Object.entries(this.subscriptions)
+			Object.entries(this._subscriptions)
 				.filter(([, socketIds]) => socketIds.has(socketId))
 				.map(([channel]) =>
 					context.executeJob("api", "unsubscribe", {
@@ -308,9 +308,9 @@ export default class APIModule extends BaseModule {
 		);
 	}
 
-	private async removeAllSubscriptions() {
+	private async _removeAllSubscriptions() {
 		await Promise.all(
-			Object.entries(this.subscriptions).map(
+			Object.entries(this._subscriptions).map(
 				async ([channel, socketIds]) => {
 					const promises = [];
 					for await (const socketId of socketIds.values()) {

+ 52 - 49
backend/src/modules/DataModule.ts

@@ -107,11 +107,11 @@ function getAllKeys(obj: object) {
 }
 
 export default class DataModule extends BaseModule {
-	private models?: Models;
+	private _models?: Models;
 
-	private mongoConnection?: Connection;
+	private _mongoConnection?: Connection;
 
-	//	private redisClient?: RedisClientType;
+	//	private _redisClient?: RedisClientType;
 
 	/**
 	 * Data Module
@@ -132,22 +132,22 @@ export default class DataModule extends BaseModule {
 	public override async startup() {
 		await super.startup();
 
-		await this.createMongoConnection();
+		await this._createMongoConnection();
 
-		await this.runMigrations();
+		await this._runMigrations();
 
-		await this.loadModels();
+		await this._loadModels();
 
-		await this.syncModelIndexes();
+		await this._syncModelIndexes();
 
-		await this.defineModelJobs();
+		await this._defineModelJobs();
 
 		// @ts-ignore
-		//        this.redisClient = createClient({ ...config.get("redis") });
+		//        this._redisClient = createClient({ ...config.get("redis") });
 		//
-		//		await this.redisClient.connect();
+		//		await this._redisClient.connect();
 		//
-		//		const redisConfigResponse = await this.redisClient.sendCommand([
+		//		const redisConfigResponse = await this._redisClient.sendCommand([
 		//			"CONFIG",
 		//			"GET",
 		//			"notify-keyspace-events"
@@ -175,16 +175,16 @@ export default class DataModule extends BaseModule {
 	 */
 	public override async shutdown() {
 		await super.shutdown();
-		//		if (this.redisClient) await this.redisClient.quit();
+		//		if (this._redisClient) await this._redisClient.quit();
 		patchEventEmitter.removeAllListeners();
-		if (this.mongoConnection) await this.mongoConnection.close();
+		if (this._mongoConnection) await this._mongoConnection.close();
 		await this.stopped();
 	}
 
 	/**
 	 * createMongoConnection - Create mongo connection
 	 */
-	private async createMongoConnection() {
+	private async _createMongoConnection() {
 		const { user, password, host, port, database } = config.get<{
 			user: string;
 			password: string;
@@ -194,20 +194,20 @@ export default class DataModule extends BaseModule {
 		}>("mongo");
 		const mongoUrl = `mongodb://${user}:${password}@${host}:${port}/${database}`;
 
-		this.mongoConnection = await mongoose
+		this._mongoConnection = await mongoose
 			.createConnection(mongoUrl)
 			.asPromise();
 
-		this.mongoConnection.set("runValidators", true);
-		this.mongoConnection.set("sanitizeFilter", true);
-		this.mongoConnection.set("strict", "throw");
-		this.mongoConnection.set("strictQuery", "throw");
+		this._mongoConnection.set("runValidators", true);
+		this._mongoConnection.set("sanitizeFilter", true);
+		this._mongoConnection.set("strict", "throw");
+		this._mongoConnection.set("strictQuery", "throw");
 	}
 
 	/**
 	 * registerEvents - Register events for schema with event module
 	 */
-	private async registerEvents<
+	private async _registerEvents<
 		ModelName extends keyof Models,
 		SchemaType extends Schemas[keyof ModelName]
 	>(modelName: ModelName, schema: SchemaType) {
@@ -327,10 +327,10 @@ export default class DataModule extends BaseModule {
 	 * @param modelName - Name of the model
 	 * @returns Model
 	 */
-	private async loadModel<ModelName extends keyof Models>(
+	private async _loadModel<ModelName extends keyof Models>(
 		modelName: ModelName
 	): Promise<Models[ModelName]> {
-		if (!this.mongoConnection) throw new Error("Mongo is not available");
+		if (!this._mongoConnection) throw new Error("Mongo is not available");
 
 		const { schema }: { schema: Schemas[ModelName] } = await import(
 			`../schemas/${modelName.toString()}`
@@ -358,9 +358,9 @@ export default class DataModule extends BaseModule {
 
 		if (getDataEnabled) schema.plugin(getDataPlugin);
 
-		await this.registerEvents(modelName, schema);
+		await this._registerEvents(modelName, schema);
 
-		return this.mongoConnection.model(modelName.toString(), schema);
+		return this._mongoConnection.model(modelName.toString(), schema);
 	}
 
 	/**
@@ -368,26 +368,26 @@ export default class DataModule extends BaseModule {
 	 *
 	 * @returns Promise
 	 */
-	private async loadModels() {
+	private async _loadModels() {
 		mongoose.SchemaTypes.String.set("trim", true);
 
-		this.models = {
-			abc: await this.loadModel("abc"),
-			news: await this.loadModel("news"),
-			session: await this.loadModel("session"),
-			station: await this.loadModel("station"),
-			user: await this.loadModel("user")
+		this._models = {
+			abc: await this._loadModel("abc"),
+			news: await this._loadModel("news"),
+			session: await this._loadModel("session"),
+			station: await this._loadModel("station"),
+			user: await this._loadModel("user")
 		};
 	}
 
 	/**
 	 * syncModelIndexes - Sync indexes for all models
 	 */
-	private async syncModelIndexes() {
-		if (!this.models) throw new Error("Models not loaded");
+	private async _syncModelIndexes() {
+		if (!this._models) throw new Error("Models not loaded");
 
 		await Promise.all(
-			Object.values(this.models).map(model => model.syncIndexes())
+			Object.values(this._models).map(model => model.syncIndexes())
 		);
 	}
 
@@ -400,18 +400,18 @@ export default class DataModule extends BaseModule {
 		jobContext: JobContext,
 		payload: ModelName | { name: ModelName }
 	) {
-		if (!this.models) throw new Error("Models not loaded");
+		if (!this._models) throw new Error("Models not loaded");
 
 		if (this.getStatus() !== ModuleStatus.STARTED)
 			throw new Error("Module not started");
 
 		const name = typeof payload === "object" ? payload.name : payload;
 
-		return this.models[name];
+		return this._models[name];
 	}
 
-	private async loadMigrations() {
-		if (!this.mongoConnection) throw new Error("Mongo is not available");
+	private async _loadMigrations() {
+		if (!this._mongoConnection) throw new Error("Mongo is not available");
 
 		const migrations = await readdir(
 			path.resolve(__dirname, "../schemas/migrations/")
@@ -421,13 +421,13 @@ export default class DataModule extends BaseModule {
 			migrations.map(async migrationFile => {
 				const { default: Migrate }: { default: typeof Migration } =
 					await import(`../schemas/migrations/${migrationFile}`);
-				return new Migrate(this.mongoConnection as Connection);
+				return new Migrate(this._mongoConnection as Connection);
 			})
 		);
 	}
 
-	private async runMigrations() {
-		const migrations = await this.loadMigrations();
+	private async _runMigrations() {
+		const migrations = await this._loadMigrations();
 
 		for (let i = 0; i < migrations.length; i += 1) {
 			const migration = migrations[i];
@@ -436,19 +436,22 @@ export default class DataModule extends BaseModule {
 		}
 	}
 
-	private async defineModelJobs() {
-		if (!this.models) throw new Error("Models not loaded");
+	private async _defineModelJobs() {
+		if (!this._models) throw new Error("Models not loaded");
 
 		await Promise.all(
-			Object.entries(this.models).map(async ([modelName, model]) => {
+			Object.entries(this._models).map(async ([modelName, model]) => {
 				await Promise.all(
 					["findById"].map(async method => {
 						this.jobConfig[`${modelName}.${method}`] = {
 							method: async (context, payload) =>
-								Object.getPrototypeOf(this)[method](context, {
-									...payload,
-									model: modelName
-								})
+								Object.getPrototypeOf(this)[`_${method}`](
+									context,
+									{
+										...payload,
+										model: modelName
+									}
+								)
 						};
 					})
 				);
@@ -464,7 +467,7 @@ export default class DataModule extends BaseModule {
 		);
 	}
 
-	private async findById(
+	private async _findById(
 		context: JobContext,
 		payload: { model: keyof Models; _id: Types.ObjectId }
 	) {

+ 63 - 63
backend/src/modules/EventsModule.ts

@@ -6,13 +6,13 @@ import { UniqueMethods } from "../types/Modules";
 import JobContext from "../JobContext";
 
 export default class EventsModule extends BaseModule {
-	private pubClient?: RedisClientType;
+	private _pubClient?: RedisClientType;
 
-	private subClient?: RedisClientType;
+	private _subClient?: RedisClientType;
 
-	private subscriptions: Record<string, ((message: any) => Promise<void>)[]>;
+	private _subscriptions: Record<string, ((message: any) => Promise<void>)[]>;
 
-	private scheduleCallbacks: Record<string, (() => Promise<void>)[]>;
+	private _scheduleCallbacks: Record<string, (() => Promise<void>)[]>;
 
 	/**
 	 * Events Module
@@ -20,8 +20,8 @@ export default class EventsModule extends BaseModule {
 	public constructor() {
 		super("events");
 
-		this.subscriptions = {};
-		this.scheduleCallbacks = {};
+		this._subscriptions = {};
+		this._scheduleCallbacks = {};
 		this.jobApiDefault = false;
 	}
 
@@ -31,8 +31,8 @@ export default class EventsModule extends BaseModule {
 	public override async startup() {
 		await super.startup();
 
-		await this.createPubClient();
-		await this.createSubClient();
+		await this._createPubClient();
+		await this._createSubClient();
 
 		await super.started();
 	}
@@ -40,12 +40,12 @@ export default class EventsModule extends BaseModule {
 	/**
 	 * createPubClient - Create redis client for publishing
 	 */
-	private async createPubClient() {
-		this.pubClient = createClient({ ...config.get("redis") });
+	private async _createPubClient() {
+		this._pubClient = createClient({ ...config.get("redis") });
 
-		await this.pubClient.connect();
+		await this._pubClient.connect();
 
-		const redisConfigResponse = await this.pubClient.sendCommand([
+		const redisConfigResponse = await this._pubClient.sendCommand([
 			"CONFIG",
 			"GET",
 			"notify-keyspace-events"
@@ -69,22 +69,22 @@ export default class EventsModule extends BaseModule {
 	/**
 	 * createSubClient - Create redis client for subscribing
 	 */
-	private async createSubClient() {
-		if (!this.pubClient) throw new Error("Redis pubClient unavailable.");
+	private async _createSubClient() {
+		if (!this._pubClient) throw new Error("Redis pubClient unavailable.");
 
-		this.subClient = this.pubClient?.duplicate();
+		this._subClient = this._pubClient?.duplicate();
 
-		await this.subClient.connect();
+		await this._subClient.connect();
 
-		const { database = 0 } = this.subClient.options ?? {};
+		const { database = 0 } = this._subClient.options ?? {};
 
-		await this.subClient.PSUBSCRIBE(
+		await this._subClient.PSUBSCRIBE(
 			`__keyevent@${database}__:expired`,
 			async message => {
-				if (!this.scheduleCallbacks[message]) return;
+				if (!this._scheduleCallbacks[message]) return;
 
 				await Promise.all(
-					this.scheduleCallbacks[message].map(callback => callback())
+					this._scheduleCallbacks[message].map(callback => callback())
 				);
 			}
 		);
@@ -93,7 +93,7 @@ export default class EventsModule extends BaseModule {
 	/**
 	 * createKey - Create hex key
 	 */
-	private createKey(type: "event" | "schedule", channel: string) {
+	private _createKey(type: "event" | "schedule", channel: string) {
 		if (!["event", "schedule"].includes(type))
 			throw new Error("Invalid type");
 
@@ -113,25 +113,25 @@ export default class EventsModule extends BaseModule {
 		context: JobContext,
 		payload: { channel: string; value: any }
 	) {
-		if (!this.pubClient) throw new Error("Redis pubClient unavailable.");
+		if (!this._pubClient) throw new Error("Redis pubClient unavailable.");
 
 		let { channel, value } = payload;
 
-		channel = this.createKey("event", channel);
+		channel = this._createKey("event", channel);
 
 		if (!value) throw new Error("Invalid value");
 
 		if (["object", "array"].includes(typeof value))
 			value = JSON.stringify(value);
 
-		await this.pubClient.publish(channel, value);
+		await this._pubClient.publish(channel, value);
 	}
 
 	/**
 	 * subscriptionListener - Listener for event subscriptions
 	 */
-	private async subscriptionListener(message: string, channel: string) {
-		if (!this.subscriptions || !this.subscriptions[channel]) return;
+	private async _subscriptionListener(message: string, channel: string) {
+		if (!this._subscriptions || !this._subscriptions[channel]) return;
 
 		if (message.startsWith("[") || message.startsWith("{"))
 			try {
@@ -142,7 +142,7 @@ export default class EventsModule extends BaseModule {
 		else if (message.startsWith('"') && message.endsWith('"'))
 			message = message.substring(1).substring(0, message.length - 2);
 
-		await Promise.all(this.subscriptions[channel].map(cb => cb(message)));
+		await Promise.all(this._subscriptions[channel].map(cb => cb(message)));
 	}
 
 	/**
@@ -157,44 +157,44 @@ export default class EventsModule extends BaseModule {
 			unique?: boolean;
 		}
 	) {
-		if (!this.subClient) throw new Error("Redis subClient unavailable.");
+		if (!this._subClient) throw new Error("Redis subClient unavailable.");
 
 		const { type = "event", callback, unique = false } = payload;
 
-		const channel = this.createKey(type, payload.channel);
+		const channel = this._createKey(type, payload.channel);
 
 		if (type === "schedule") {
 			if (
 				unique &&
-				this.scheduleCallbacks[channel] &&
-				this.scheduleCallbacks[channel].length > 0
+				this._scheduleCallbacks[channel] &&
+				this._scheduleCallbacks[channel].length > 0
 			)
 				return;
 
-			if (!this.scheduleCallbacks[channel])
-				this.scheduleCallbacks[channel] = [];
+			if (!this._scheduleCallbacks[channel])
+				this._scheduleCallbacks[channel] = [];
 
-			this.scheduleCallbacks[channel].push(() => callback());
+			this._scheduleCallbacks[channel].push(() => callback());
 
 			return;
 		}
 
 		if (
 			unique &&
-			this.subscriptions[channel] &&
-			this.subscriptions[channel].length > 0
+			this._subscriptions[channel] &&
+			this._subscriptions[channel].length > 0
 		)
 			return;
 
-		if (!this.subscriptions[channel]) {
-			this.subscriptions[channel] = [];
+		if (!this._subscriptions[channel]) {
+			this._subscriptions[channel] = [];
 
-			await this.subClient.subscribe(channel, (...args) =>
-				this.subscriptionListener(...args)
+			await this._subClient.subscribe(channel, (...args) =>
+				this._subscriptionListener(...args)
 			);
 		}
 
-		this.subscriptions[channel].push(callback);
+		this._subscriptions[channel].push(callback);
 	}
 
 	/**
@@ -208,33 +208,33 @@ export default class EventsModule extends BaseModule {
 			callback: (message?: any) => Promise<void>;
 		}
 	) {
-		if (!this.subClient) throw new Error("Redis subClient unavailable.");
+		if (!this._subClient) throw new Error("Redis subClient unavailable.");
 
 		const { type = "event", callback } = payload;
-		const channel = this.createKey(type, payload.channel);
+		const channel = this._createKey(type, payload.channel);
 
 		if (type === "schedule") {
-			if (!this.scheduleCallbacks[channel]) return;
+			if (!this._scheduleCallbacks[channel]) return;
 
-			const index = this.scheduleCallbacks[channel].indexOf(callback);
+			const index = this._scheduleCallbacks[channel].indexOf(callback);
 
-			if (index >= 0) this.scheduleCallbacks[channel].splice(index, 1);
+			if (index >= 0) this._scheduleCallbacks[channel].splice(index, 1);
 
 			return;
 		}
 
-		if (!this.subscriptions[channel]) return;
+		if (!this._subscriptions[channel]) return;
 
-		const index = this.subscriptions[channel].indexOf(callback);
+		const index = this._subscriptions[channel].indexOf(callback);
 
 		if (index < 0) return;
 
-		this.subscriptions[channel].splice(index, 1);
+		this._subscriptions[channel].splice(index, 1);
 
-		if (this.subscriptions[channel].length === 0) {
-			delete this.subscriptions[channel];
-			await this.subClient.unsubscribe(channel, (...args) =>
-				this.subscriptionListener(...args)
+		if (this._subscriptions[channel].length === 0) {
+			delete this._subscriptions[channel];
+			await this._subClient.unsubscribe(channel, (...args) =>
+				this._subscriptionListener(...args)
 			);
 		}
 	}
@@ -249,7 +249,7 @@ export default class EventsModule extends BaseModule {
 			time: number;
 		}
 	) {
-		if (!this.pubClient) throw new Error("Redis pubClient unavailable.");
+		if (!this._pubClient) throw new Error("Redis pubClient unavailable.");
 
 		let { time } = payload;
 
@@ -259,9 +259,9 @@ export default class EventsModule extends BaseModule {
 
 		if (time <= 0) throw new Error("Time must be greater than 0");
 
-		const channel = this.createKey("schedule", payload.channel);
+		const channel = this._createKey("schedule", payload.channel);
 
-		await this.pubClient.set(channel, "", { PX: time, NX: true });
+		await this._pubClient.set(channel, "", { PX: time, NX: true });
 	}
 
 	/**
@@ -273,11 +273,11 @@ export default class EventsModule extends BaseModule {
 			channel: string;
 		}
 	) {
-		if (!this.pubClient) throw new Error("Redis pubClient unavailable.");
+		if (!this._pubClient) throw new Error("Redis pubClient unavailable.");
 
-		const channel = this.createKey("schedule", payload.channel);
+		const channel = this._createKey("schedule", payload.channel);
 
-		await this.pubClient.del(channel);
+		await this._pubClient.del(channel);
 	}
 
 	/**
@@ -286,11 +286,11 @@ export default class EventsModule extends BaseModule {
 	public override async shutdown() {
 		await super.shutdown();
 
-		if (this.pubClient) await this.pubClient.quit();
-		if (this.subClient) await this.subClient.quit();
+		if (this._pubClient) await this._pubClient.quit();
+		if (this._subClient) await this._subClient.quit();
 
-		this.subscriptions = {};
-		this.scheduleCallbacks = {};
+		this._subscriptions = {};
+		this._scheduleCallbacks = {};
 
 		await this.stopped();
 	}

+ 22 - 22
backend/src/modules/WebSocketModule.ts

@@ -10,11 +10,11 @@ import JobContext from "../JobContext";
 import Job from "../Job";
 
 export default class WebSocketModule extends BaseModule {
-	private httpServer?: Server;
+	private _httpServer?: Server;
 
-	private wsServer?: WebSocketServer;
+	private _wsServer?: WebSocketServer;
 
-	private keepAliveInterval?: NodeJS.Timer;
+	private _keepAliveInterval?: NodeJS.Timer;
 
 	/**
 	 * WebSocket Module
@@ -31,26 +31,26 @@ export default class WebSocketModule extends BaseModule {
 	public override async startup() {
 		await super.startup();
 
-		this.httpServer = http
+		this._httpServer = http
 			.createServer(express())
 			.listen(config.get("port"));
 
-		this.wsServer = new WebSocketServer({
-			server: this.httpServer,
+		this._wsServer = new WebSocketServer({
+			server: this._httpServer,
 			path: "/ws",
 			WebSocket
 		});
 
-		this.wsServer.on(
+		this._wsServer.on(
 			"connection",
 			(socket: WebSocket, request: IncomingMessage) =>
-				this.handleConnection(socket, request)
+				this._handleConnection(socket, request)
 		);
 
-		this.keepAliveInterval = setInterval(() => this.keepAlive(), 45000);
+		this._keepAliveInterval = setInterval(() => this._keepAlive(), 45000);
 
-		this.wsServer.on("close", async () =>
-			clearInterval(this.keepAliveInterval)
+		this._wsServer.on("close", async () =>
+			clearInterval(this._keepAliveInterval)
 		);
 
 		await super.started();
@@ -59,10 +59,10 @@ export default class WebSocketModule extends BaseModule {
 	/**
 	 * keepAlive - Ping open clients and terminate closed
 	 */
-	private async keepAlive() {
-		if (!this.wsServer) return;
+	private async _keepAlive() {
+		if (!this._wsServer) return;
 
-		for await (const clients of this.wsServer.clients.entries()) {
+		for await (const clients of this._wsServer.clients.entries()) {
 			await Promise.all(
 				clients.map(async socket => {
 					switch (socket.readyState) {
@@ -83,7 +83,7 @@ export default class WebSocketModule extends BaseModule {
 	/**
 	 * handleConnection - Handle websocket connection
 	 */
-	private async handleConnection(
+	private async _handleConnection(
 		socket: WebSocket,
 		request: IncomingMessage
 	) {
@@ -119,13 +119,13 @@ export default class WebSocketModule extends BaseModule {
 
 		socket.dispatch("ready", readyData);
 
-		socket.on("message", message => this.handleMessage(socket, message));
+		socket.on("message", message => this._handleMessage(socket, message));
 	}
 
 	/**
 	 * handleMessage - Handle websocket message
 	 */
-	private async handleMessage(socket: WebSocket, message: RawData) {
+	private async _handleMessage(socket: WebSocket, message: RawData) {
 		if (this.jobQueue.getStatus().isPaused) {
 			socket.close();
 			return;
@@ -186,7 +186,7 @@ export default class WebSocketModule extends BaseModule {
 	 * getSockets - Get websocket clients
 	 */
 	public async getSockets(context: JobContext) {
-		return this.wsServer?.clients;
+		return this._wsServer?.clients;
 	}
 
 	/**
@@ -199,9 +199,9 @@ export default class WebSocketModule extends BaseModule {
 			sessionId
 		}: { socketId?: string; sessionId?: Types.ObjectId }
 	) {
-		if (!this.wsServer) return null;
+		if (!this._wsServer) return null;
 
-		for (const clients of this.wsServer.clients.entries() as IterableIterator<
+		for (const clients of this._wsServer.clients.entries() as IterableIterator<
 			[WebSocket, WebSocket]
 		>) {
 			const socket = clients.find(socket => {
@@ -242,8 +242,8 @@ export default class WebSocketModule extends BaseModule {
 	public override async shutdown() {
 		await super.shutdown();
 
-		if (this.httpServer) this.httpServer.close();
-		if (this.wsServer) this.wsServer.close();
+		if (this._httpServer) this._httpServer.close();
+		if (this._wsServer) this._wsServer.close();
 
 		await this.stopped();
 	}