| import { Collection, Db, MongoClient } from 'mongodb'; |
| import structuredClone from '@ungap/structured-clone'; |
| |
| |
| export const Entry = data => { |
| data = data ?? {}; |
| data.getKey = key => data[key] |
| return { |
| get(target, prop, receiver) { |
| let dataToReturn = data[prop] |
| if (dataToReturn === null ) return Reflect.get(target, prop, receiver); |
| if (typeof dataToReturn === "object" && !Array.isArray(dataToReturn)) dataToReturn = new Proxy( |
| Reflect.get(target, prop, receiver), |
| Entry(dataToReturn), |
| ) |
| return dataToReturn ?? Reflect.get(target, prop, receiver); |
| } |
| } |
| } |
| |
| |
| export default class Database { |
| mongoClient: MongoClient; |
| database: Db; |
| guilds: Collection<GuildConfig>; |
| defaultData: GuildConfig; |
| |
| constructor(url) { |
| this.mongoClient = new MongoClient(url); |
| } |
| |
| async connect() { |
| await this.mongoClient.connect() |
| this.database = this.mongoClient.db("Nucleus"); |
| this.guilds = this.database.collection<GuildConfig>("guilds"); |
| await this.guilds.createIndex({ id: "text" }, { unique: true }); |
| this.defaultData = (await import("../config/default.json", { assert: { type: "json" }})).default as unknown as GuildConfig; |
| return this; |
| } |
| |
| async read(guild: string) { |
| let entry = await this.guilds.findOne({ id: guild }); |
| return new Proxy(structuredClone(this.defaultData), Entry(entry)) as unknown as GuildConfig |
| } |
| |
| async write(guild: string, set: object = {}, unset: string[] = []) { |
| let uo = {} |
| for (let key of unset) { |
| uo[key] = ""; |
| } |
| await this.guilds.updateOne({ id: guild }, { |
| $unset: uo, |
| $set: set |
| }, { upsert: true }); |
| } |
| |
| async append(guild: string, key: string, value: any) { |
| if (Array.isArray(value)) { |
| await this.guilds.updateOne({ id: guild }, { |
| $addToSet: { [key]: { $each: value } } |
| }, { upsert: true }); |
| } else { |
| await this.guilds.updateOne({ id: guild }, { |
| $addToSet: { [key]: value } |
| }, { upsert: true }); |
| } |
| } |
| |
| async remove(guild: string, key: string, value: any) { |
| if (Array.isArray(value)) { |
| await this.guilds.updateOne({ id: guild }, { |
| $pullAll: { [key]: value } |
| }, { upsert: true }); |
| } else { |
| await this.guilds.updateOne({ id: guild }, { |
| $pullAll: { [key]: [value] } |
| }, { upsert: true }); |
| } |
| } |
| } |
| |
| export interface GuildConfig { |
| id: string, |
| version: number, |
| singleEventNotifications: { |
| statsChannelDeleted: boolean |
| } |
| filters: { |
| images: { |
| NSFW: boolean, |
| size: boolean |
| }, |
| malware: boolean, |
| wordFilter: { |
| enabled: boolean, |
| words: { |
| strict: string[], |
| loose: string[] |
| }, |
| allowed: { |
| users: string[], |
| roles: string[], |
| channels: string[] |
| } |
| }, |
| invite: { |
| enabled: boolean, |
| allowed: { |
| users: string[], |
| channels: string[], |
| roles: string[] |
| } |
| }, |
| pings: { |
| mass: number, |
| everyone: boolean, |
| roles: boolean, |
| allowed: { |
| roles: string[], |
| rolesToMention: string[], |
| users: string[], |
| channels: string[] |
| } |
| } |
| } |
| welcome: { |
| enabled: boolean, |
| verificationRequired: { |
| message: boolean, |
| role: string | null |
| }, |
| welcomeRole: string | null, |
| channel: string | null, |
| message: string | null, |
| } |
| stats: { |
| enabled: boolean, |
| channel: string | null, |
| text: string | null, |
| }[] |
| logging: { |
| logs: { |
| enabled: boolean, |
| channel: string | null, |
| toLog: string | null, |
| }, |
| staff: { |
| channel: string | null, |
| } |
| } |
| verify: { |
| enabled: boolean, |
| role: string | null, |
| } |
| tickets: { |
| enabled: boolean, |
| category: string | null, |
| types: string | null, |
| customTypes: string[], |
| useCustom: boolean, |
| supportRole: string | null, |
| maxTickets: number |
| } |
| moderation: { |
| mute: { |
| timeout: boolean, |
| role: string | null, |
| text: string | null, |
| link: string | null |
| }, |
| kick: { |
| text: string | null, |
| link: string | null |
| }, |
| ban: { |
| text: string | null, |
| link: string | null |
| }, |
| softban: { |
| text: string | null, |
| link: string | null |
| }, |
| warn: { |
| text: string | null, |
| link: string | null |
| }, |
| role: { |
| role: string | null, |
| } |
| } |
| tracks: { |
| name: string, |
| retainPrevious: boolean, |
| nullable: boolean, |
| track: string[], |
| manageableBy: string[] |
| }[] |
| roleMenu: { |
| enabled: boolean, |
| allowWebUI: boolean, |
| options: { |
| name: string, |
| description: string, |
| min: number, |
| max: number, |
| options: { |
| name: string, |
| description: string, |
| role: string |
| }[] |
| }[] |
| } |
| tags: {} |
| }; |