aXises/fortniteBot

View on GitHub
src/database/schemas/DBGuildPropertySchema.ts

Summary

Maintainability
A
2 hrs
Test Coverage
import * as winston from "winston";
import Logger from "log/Logger";
import { prop, Typegoose, ModelType, InstanceType, instanceMethod, staticMethod, arrayProp } from "typegoose";
import * as Mongoose from "mongoose";
import { GuildConfig } from "config/GuildBooleanConfig";
import { isUndefined } from "util";
import NikkuException from "exception/NikkuException";

export default class DBGuildPropertySchema extends Typegoose {
    private static readonly logger: winston.Logger = new Logger(DBGuildPropertySchema.constructor.name).getLogger();

    @prop({required: true, unique: true})
    public id: string;

    @arrayProp({default: [], items: String})
    public targets: string[];

    @prop({default: {}})
    public booleanConfig: any;

    @instanceMethod
    public async addTarget(this: InstanceType<any> & Mongoose.Document, target: string): Promise<void> {
        this.targets.push(target);
        try {
            return await this.save();
        } catch (err) {
            DBGuildPropertySchema.logger.error("Failed to save guild targets.");
            throw err;
        }
    }

    @instanceMethod
    public async removeTarget(this: InstanceType<any> & Mongoose.Document, target: string): Promise<void> {
        const index = this.targets.indexOf(target);
        if (index === -1) {
            DBGuildPropertySchema.logger.verbose("Target does not exist on current guild target list.");
            return Promise.reject();
        }
        this.targets.splice(index, 1);
        try {
            return await this.save();
        } catch (err) {
            DBGuildPropertySchema.logger.error("Remove target, failed to save document.");
            throw err;
        }
    }

    @instanceMethod
    public async addBooleanConfig(this: InstanceType<any> & Mongoose.Document, configName: string, initValue?: boolean): Promise<void> {
        try {
            await this.markModified("booleanConfig");
            if (!this.booleanConfig) {
                this.booleanConfig = {};
            }
            if (isUndefined(this.booleanConfig[configName])) {
                this.booleanConfig[configName] = initValue ? initValue : false;
            }
            return await this.save();
        } catch (err) {
            DBGuildPropertySchema.logger.error("Failed to add new configuration.");
            throw err;
        }
    }

    @instanceMethod
    public async booleanConfigExists(this: InstanceType<any> & Mongoose.Document, configName: string): Promise<boolean> {
        try {
            return !isUndefined(this.booleanConfig[configName]);
        } catch (err) {
            DBGuildPropertySchema.logger.error("Failed to retrieve configuration.");
            throw err;
        }
    }

    @instanceMethod
    public async getAllBooleanConfig(this: InstanceType<any> & Mongoose.Document): Promise<boolean> {
        return this.booleanConfig;
    }

    @instanceMethod
    public async getBooleanConfig(this: InstanceType<any> & Mongoose.Document,
            configName: GuildConfig.BooleanConfig.Options): Promise<boolean> {
        const enumOptions = GuildConfig.BooleanConfig.Options;
        try {
            if (isUndefined(this.booleanConfig[enumOptions[configName]])) {
                throw new NikkuException(undefined, "Undefined config name.");
            }
            return this.booleanConfig[enumOptions[configName]];
        } catch (err) {
            DBGuildPropertySchema.logger.error("Unable to retrieve configuration.");
            throw err;
        }
    }

    @instanceMethod
    public async setBooleanConfig(this: InstanceType<any> & Mongoose.Document, configName: string, value: boolean): Promise<boolean> {
        try {
            if (isUndefined(this.booleanConfig[configName])) {
                throw new NikkuException(undefined, "Undefined config name.");
            }
            await this.markModified("booleanConfig");
            this.booleanConfig[configName] = value;
            return await this.save();
        } catch (err) {
            DBGuildPropertySchema.logger.error("Unable to retrieve configuration.");
            throw err;
        }
    }

    public static async getGuildById(id: string): Promise<DBGuildPropertySchema> {
        return await (this.getModel().findOne({id}));
    }

    public static async getAllGuild(): Promise<DBGuildPropertySchema[]> {
        return await (this.getModel().find({}));
    }

    public static async registerGuild(id: string): Promise<void> {
        const Model = this.getModel();
        const model = new Model({
            id,
            targets: [],
            booleanConfig: {},
        });
        try {
            for (const key of GuildConfig.BooleanConfig.keys) {
                if (!(await model.booleanConfigExists(key))) {
                    await model.addBooleanConfig(key);
                }
            }
            await model.save();
            this.logger.info("Setup guild properties document.");
        } catch (err) {
            this.logger.error("Failed to setup guild properties document.");
            throw err;
        }
    }

    public static async registerGuildIfNotExist(id: string): Promise<void> {
        if (!(await this.getGuildById(id))) {
            await this.registerGuild(id);
        }
    }

    public static getModel(): Mongoose.Model<InstanceType<DBGuildPropertySchema>> & DBGuildPropertySchema & typeof DBGuildPropertySchema {
        return new DBGuildPropertySchema().getModelForClass(DBGuildPropertySchema);
    }
}