UNPKG

db-discord

Version:

db-discord is a library that uses discord guilds and text channels as databases. db-discord relies on discord.js

184 lines (181 loc) 6.9 kB
import * as Discord from "db-discord-discord.js" import { Table } from "./Table"; import { LongTable } from "./LongTable"; import { FileTable } from "./FileTable"; import { ShortTable } from "./ShortTable"; import { KeyPairValue } from "./utilities"; export type TableType = "long" | "short" | "file" export interface MetaTableData { name: string; id: string; objectTypes: { [property: string]: string } | null type: TableType } export class discordDB { private guild: Discord.Guild; private channels: Discord.TextChannel[]; public metatable: ShortTable<MetaTableData>; public tables: KeyPairValue<MetaTableData, Table<any>>[]; private constructor(guild: Discord.Guild, channels: Discord.TextChannel[], metatable: ShortTable<MetaTableData>, tables: KeyPairValue<MetaTableData, Table<any>>[]) { this.guild = guild; this.channels = channels; this.metatable = metatable; this.tables = tables; } static async init(guild: Discord.Guild): Promise<discordDB> { let channels = guild.channels.array().filter(x => x.type == "text").filter(x => x.memberPermissions(guild.me)!.has("READ_MESSAGES")) as Discord.TextChannel[] let metatable = (() => { let metaChnnels = channels.filter(x => x.name === "metatable"); if (metaChnnels.length === 0) { return null; } return new ShortTable<MetaTableData>(metaChnnels[0]) })() || await (async () => { let channel = (await guild.createChannel("metatable", { type: "text" }) as Discord.TextChannel) channels[channels.length] = channel; return new ShortTable<MetaTableData>(channel); })() let metadata = await metatable.search({}) let tables = metadata.map<KeyPairValue<MetaTableData, Table<any>>>(meta => { let channel = channels.filter(x => x.id === meta.Value.id)[0]; let table: Table<any> = (() => { switch (meta.Value.type) { case "short": return new ShortTable<any>(channel) break; case "long": return new LongTable<any>(channel) break; case "file": return new FileTable(channel) break; default: throw new Error("table type not supported") break; } })() return { Key: meta.Value, Value: table } }); return new discordDB(guild, channels, metatable, tables); } getShortTableFromName<T>(name: string): ShortTable<T> | null { let channels = this.channels.filter(x => x.name === name); if (channels.length === 0) { return null; } return new ShortTable<T>(channels[0]) } getLongTableFromName<T>(name: string): LongTable<T> | null { let channels = this.channels.filter(x => x.name === name); if (channels.length === 0) { return null; } return new LongTable<T>(channels[0]) } getFileTableFromName(id: string) { let channels = this.channels.filter(x => x.id === id); if (channels.length === 0) { return null; } return new FileTable(channels[0]) } getShortTableFromID<T>(id: string) { let channels = this.channels.filter(x => x.id === id); if (channels.length === 0) { return null; } return new ShortTable<T>(channels[0]) } getLongTableFromID<T>(id: string) { let channels = this.channels.filter(x => x.id === id); if (channels.length === 0) { return null; } return new LongTable<T>(channels[0]) } getFileTableFromID(id: string) { let channels = this.channels.filter(x => x.id === id); if (channels.length === 0) { return null; } return new FileTable(channels[0]) } async createNewShortTable<T>(name: string) { let channel = (await this.guild.createChannel(name, { type: "text" }) as Discord.TextChannel) this.channels[this.channels.length] = channel; let table = new ShortTable<T>(channel); await this.addToMetatable(table) return table; } async createNewLongTable<T>(name: string) { let channel = (await this.guild.createChannel(name, { type: "text" }) as Discord.TextChannel) this.channels[this.channels.length] = channel; let table = new LongTable<T>(channel); await this.addToMetatable(table) return table; } async createNewFileTable(name: string) { let channel = (await this.guild.createChannel(name, { type: "text" }) as Discord.TextChannel) this.channels[this.channels.length] = channel; let table = new FileTable(channel); await this.addToMetatable(table) return table; } async getOrCreateShortTable<T>(name: string) { let table = this.getShortTableFromName<T>(name) if (table === null) { return await this.createNewShortTable<T>(name) } return table! } async getOrCreateLongTable<T>(name: string) { let table = this.getLongTableFromName<T>(name) if (table === null) { return await this.createNewLongTable<T>(name) } return table! } async getOrCreateFileTable(name: string) { let table = this.getFileTableFromName(name) if (table === null) { return await this.createNewFileTable(name) } return table! } async deleteTable(table: Table<any>): Promise<{}> { let channel = this.channels.filter(x => x.id === table.id)[0] let i = this.channels.indexOf(channel); this.channels.slice(i, i + 1) return await Promise.all([channel.delete(), await this.metatable.delete((await this.metatable.search({ searchObject: { id: table.id } }))[0].Key)]).then(x => ({})) } protected async addToMetatable(table: Table<any>) { let metadata: MetaTableData = { name: table.name, id: table.id, objectTypes: null, type: table.type, } this.tables[this.tables.length] = { Key: metadata, Value: table } return await this.metatable.write(metadata) } }