import { GuildMember } from "discord.js"; import { getRepository, In } from "typeorm"; import { KnownUser } from "@shared/db/entity/KnownUser"; import { HTTPError } from "got/dist/source"; const VALID_EXTENSIONS = new Set([ "png", "jpg", "jpeg", "bmp", ]); export type EsModuleClass = { prototype: T; new(...params: unknown[]): T; }; export function isModuleClass(obj: unknown) : obj is EsModuleClass { return Object.prototype.hasOwnProperty.call(obj, "prototype"); } export function isDevelopment(): boolean { return process.env.NODE_ENV == "dev"; } export function isValidImage(fileName?: string): boolean { if (!fileName) return false; const extPosition = fileName.lastIndexOf("."); if (extPosition < 0) return false; const ext = fileName.substring(extPosition + 1).toLowerCase(); return VALID_EXTENSIONS.has(ext); } export async function isAuthorisedAsync(member: GuildMember | null | undefined): Promise { if (!member) return false; const repo = getRepository(KnownUser); const user = await repo.findOne({ where: { userID: member.id }, select: ["canModerate"] }); if (user && user.canModerate) return true; const role = await repo.findOne({ select: ["userID"], where: { userID: In(member.roles.cache.keyArray()), canModerate: true } }); if (role) return true; return false; } export function compareNumbers(prop: (o: T) => number) { return (a: T, b: T): -1 | 0 | 1 => { const ap = prop(a); const bp = prop(b); if (ap < bp) return 1; else if (ap > bp) return -1; return 0; }; } export type Dict = { [key: string]: TVal }; export function getNumberEnums(e : Record) : number[] { return Object.keys(e).filter(k => typeof e[k as keyof E] === "number").map(k => e[k as keyof E]); } export function formatString(str: string, vars: Record): string { return Object.keys(vars).filter(s => Object.prototype.hasOwnProperty.call(vars, s)).reduce((s, cur) => s.replace(`{${cur}}`, vars[cur]), str); } export async function tryDo(promise: Promise) : Promise<{ok: boolean, result?: TResult, error?: unknown}> { try { return {ok: true, result: await promise}; } catch(err) { return {ok: false, error: err}; } } export async function assertOk(promise: Promise): Promise { try { return await promise; } catch (err) { if (hasStackTrace(err)) { const trace: {stack?: string} = {}; Error.captureStackTrace(trace); err.stack = `${err.stack}\nCaused by: ${trace.stack}`; } throw err; } } export function isHttpError(err?: unknown): err is HTTPError { return err && Object.prototype.hasOwnProperty.call(err, "response"); } export function hasStackTrace(reason?: unknown): reason is {stack: unknown} { return reason && Object.prototype.hasOwnProperty.call(reason, "stack"); }