// Galactic - Discord moderation bot // Copyright (C) 2024 Navy.gif // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . import { LoggerClientOptions } from '@navy.gif/logger'; import { Partials, GatewayIntentBits, Snowflake, User, ApplicationCommandType, GuildMember, Role, BaseChannel, PermissionsString, Channel, APIEmbed, OverwriteType, Awaitable, Message, If, GuildBan, ThreadChannel, APIEmbedField, VoiceState, Invite, GuildTextBasedChannel, } from 'discord.js'; import { InvokerWrapper, MemberWrapper, UserWrapper } from '../src/client/components/wrappers/index.js'; import GuildWrapper from '../src/client/components/wrappers/GuildWrapper.js'; import DiscordClient from '../src/client/DiscordClient.js'; import { CommandOption, Inhibitor } from '../src/client/interfaces/index.js'; import { MuteType, TextCommandsSettings } from './Settings.js'; import { ClientEvents } from './Events.js'; import { FilterResult } from './Utils.js'; import { GuildSettingTypes } from './Guild.js'; import { StorageManagerOptions } from './Storage.js'; export type ManagerEvalOptions = { context?: object, debug?: boolean } export type DiscordStruct = { id: string } export type FormatParams = { [key: string]: string | number | boolean | undefined | null } export type FormatOpts = { code?: boolean, language?: string } export type ClientOptions = { rootDir: string, prefix?: string, developers?: string[], developmentMode?: boolean, invite: string, slashCommands?: { developerGuilds: string[] }, libraryOptions: { partials?: Partials[], intents: GatewayIntentBits[], invalidRequestWarningInterval?: number }, storage: StorageManagerOptions, logger: LoggerClientOptions, version: string } export type ComponentType = 'command' | 'module' | 'observer' | 'inhibitor' | 'setting' export type ComponentOptions = { id: string, type: ComponentType, moduleName?: string, guarded?: boolean, disabled?: boolean } export type ModuleOptions = { name: string } // type ComponentUpdate = (opts: { component: Component, type: 'ENABLE' | 'DISABLE' }) => void; // export type EventHook = (...args: ClientEvents[keyof ClientEvents]) => Promise | void // ((...args: unknown[]) => void) | ComponentUpdate; export type EventHook = (...args: ClientEvents[K]) => Awaitable; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type GenericEventHook = (...args: any[]) => Awaitable; export type Hooks = [keyof ClientEvents, GenericEventHook][]; export type ObserverOptions = { name?: string, priority?: number, hooks?: Hooks, } & Partial export type InhibitorOptions = { name?: string, guild?: boolean // Higher numbers come first priority?: number, silent?: boolean } & Partial export type InhibitorResponse = { error: T, inhibitor: Inhibitor, params: If, } export type InfractionType = | 'ADDROLE' | 'BAN' | 'KICK' | 'LOCKDOWN' | 'MUTE' | 'NICKNAME' | 'NOTE' | 'PRUNE' | 'REMOVEROLE' | 'SLOWMODE' | 'SOFTBAN' | 'UNBAN' | 'UNLOCKDOWN' | 'UNMUTE' | 'VCKICK' | 'VCMUTE' | 'VCUNMUTE' | 'VCBAN' | 'VCUNBAN' | 'WARN' | 'DELETE'; export enum CommandOptionType { SUB_COMMAND = 'SUB_COMMAND', SUB_COMMAND_GROUP = 'SUB_COMMAND_GROUP', ROLES = 'ROLES', // Note plurality, strings can parse users, roles, and channels. MEMBERS = 'MEMBERS', USERS = 'USERS', CHANNELS = 'CHANNELS', TEXT_CHANNELS = 'TEXT_CHANNELS', VOICE_CHANNELS = 'VOICE_CHANNELS', TIME = 'TIME', // timestring DATE = 'DATE', COMPONENT = 'COMPONENT', COMPONENTS = 'COMPONENTS', COMMAND = 'COMMAND', COMMANDS = 'COMMANDS', MODULE = 'MODULE', STRING = 'STRING', INTEGER = 'INTEGER', BOOLEAN = 'BOOLEAN', MEMBER = 'MEMBER', USER = 'USER', TEXT_CHANNEL = 'TEXT_CHANNEL', VOICE_CHANNEL = 'VOICE_CHANNEL', CHANNEL = 'CHANNEL', ROLE = 'ROLE', MENTIONABLE = 'MENTIONABLE', NUMBER = 'NUMBER', FLOAT = 'FLOAT', POINTS = 'POINTS' } export enum DiscordCommandOptionType { SUB_COMMAND = 1, SUB_COMMAND_GROUP = 2, ROLES = 3, // Note plurality, strings can parse users, roles, and channels. MEMBERS = 3, USERS = 3, CHANNELS = 3, TEXT_CHANNELS = 3, VOICE_CHANNELS = 3, TIME = 3, // timestring DATE = 3, COMPONENT = 3, COMPONENTS = 3, COMMAND = 3, COMMANDS = 3, MODULE = 3, STRING = 3, INTEGER = 4, BOOLEAN = 5, MEMBER = 6, USER = 6, TEXT_CHANNEL = 7, VOICE_CHANNEL = 7, CHANNEL = 7, ROLE = 8, MENTIONABLE = 9, NUMBER = 10, FLOAT = 10, POINTS = 4 } export enum ChannelTypes { TEXT_CHANNEL = 0, VOICE_CHANNEL = 3 } type CommandOptionChoice = { name: string, value: unknown } export type CommandOptionChoices = CommandOptionChoice[] export type DependsOnMode = 'OR' | 'AND' export type RawCommandOption = { name: string, type: CommandOptionType, options: RawCommandOption[] } export type CommandOptionShape = { name: string, description: string, type: number, required: boolean, choices: CommandOptionChoice[], options: CommandOptionShape[], min_value?: number, max_value?: number, channel_types: number[] | null, autocomplete: boolean } export type CommandOptionParams = { client?: DiscordClient, guild?: GuildWrapper | null, name: string | string[], aliases?: string[] description?: string | string[] type?: CommandOptionType | CommandOptionType[], required?: boolean, autocomplete?: boolean, strict?: boolean, showUsage?: boolean choices?: CommandOptionChoices, options?: CommandOptionParams[], dependsOn?: string[], dependsOnMode?: DependsOnMode, minimum?: number, maximum?: number, // min?: number, // max?: number, slashOption?: boolean, flag?: boolean, valueOptional?: boolean, valueAsAlias?: boolean, value?: unknown, defaultValue?: unknown, rawValue?: string | string[] | null, } export type CommandOptions = { name?: string, description?: string, tags?: string[], aliases?: string[], restricted?: boolean, showUsage?: boolean, guildOnly?: boolean, archivable?: boolean slash?: boolean, clientPermissions?: PermissionsString[], memberPermissions?: PermissionsString[], options?: CommandOptionParams[], moduleName?: string } & Partial export type CommandParams = { [key: string]: CommandOption | undefined } export type SettingActionType = InfractionType | '' export type SettingAction = { [key: string]: unknown type: SettingActionType, duration: number | null, points: number | null, expiration: number | null, force: boolean, prune: boolean, trigger: string | string[] | number } export type SettingMethod = 'add' | 'remove' | 'edit' | 'list' | 'reset' export type SettingTypeResolve = 'USER' | 'GUILD'; export type SettingEmojiOption = { // } export type SettingApiDefinitions = { // } export type BaseSetting = object export type SettingOptions = { name?: string, aliases?: string[], resolve?: If, description?: string, display?: string, emoji?: SettingEmojiOption, default?: GuildSettingTypes definitions?: SettingApiDefinitions, commandOptions?: CommandOptionParams[], commandType?: CommandOptionType, clientPermissions?: PermissionsString[], memberPermissions?: PermissionsString[], premium?: number } & Partial export type FilterSettingHelperResponse = { error: true, index?: string, content?: string, embeds?: APIEmbed[], params?: FormatParams } | { content: string, error?: false }; export type SlashCommandOptions = { commandType?: ApplicationCommandType } & CommandOptions; export type InfractionTargetType = 'USER' | 'CHANNEL'; export type InfractionArguments = { [key: string]: CommandOption | undefined } export type AdditionalInfractionData = { track?: boolean; muteType?: MuteType, roles?: Role[] roleIds?: Snowflake[], roleNames?: string[], oldPermissions?: { [key: string]: { type: OverwriteType, permissions: { SendMessages: boolean | null, AddReactions: boolean | null } } }, dehoist?: boolean, oldName?: string, name?: string, removedRoles?: Snowflake[] | null, muteRole?: Snowflake | null, amount?: number, message?: Snowflake, seconds?: number, } export type InfractionFlags = { // } export type InfractionChangeType = | 'UNRESOLVE' | 'RESOLVE' | 'DURATION' | 'EXPIRATION' | 'POINTS' | 'REASON' export type InfractionChange = { type: InfractionChangeType, staff: string, timestamp: number, duration?: number | null, reason?: string, expiration?: number | null, points?: number | null } export type BaseInfractionData = { _id?: string, type?: InfractionType, case?: number, arguments?: InfractionArguments, targetType?: InfractionTargetType, guild: GuildWrapper, channel?: GuildTextBasedChannel | null, invoker?: InvokerWrapper | null, target?: MemberWrapper | UserWrapper | GuildTextBasedChannel, executor?: MemberWrapper | UserWrapper duration?: number | null, reason?: string, silent?: boolean, points?: number, expiration?: number, data?: AdditionalInfractionData, hyperlink?: string | null, // _callbacked?: boolean, fetched?: boolean } export type InfractionJSON = { id: string, type: InfractionType, case: number, targetType: InfractionTargetType, guild: Snowflake, channel: Snowflake, channelName: string, target: Snowflake, targetTag: string, executor: Snowflake, executorTag: string, duration: number, reason: string, points: number, expiration: number, data: AdditionalInfractionData, callback: number | null, _callbacked?: boolean | null, timestamp: number, resolved: boolean, changes: InfractionChange[], flags: InfractionFlags, modLogMessage: Snowflake, modLogChannel: Snowflake dmLogMessage: Snowflake, message: Snowflake, } export type ModerationCallback = { infraction: InfractionJSON, timeout: NodeJS.Timeout } export type InfractionData = { // } & BaseInfractionData export type MemberResolveable = Snowflake | GuildMember | MemberWrapper | User | UserWrapper | string; export type UserResolveable = Snowflake | User | UserWrapper | MemberWrapper | GuildMember | string; export type RoleResolveable = Snowflake | Role | string; export type ChannelResolveable = Snowflake | BaseChannel | string; // type Resolveable = MemberResolveable | UserResolveable | RoleResolveable | ChannelResolveable export type MemberResolverFunction = (r: MemberResolveable, s: boolean, g: GuildWrapper | null) => Promise export type UserResolverFunction = (r: UserResolveable, s: boolean, g: GuildWrapper | null) => Promise export type RoleResolverFunction = (r: RoleResolveable, s: boolean, g: GuildWrapper | null) => Promise export type ChannelResolverFunction = (r: ChannelResolveable, s: boolean, g: GuildWrapper | null) => Promise export type ResolverFunction = | MemberResolverFunction | UserResolverFunction | RoleResolverFunction | ChannelResolverFunction export declare interface ExtendedMessage extends Message { guildWrapper: If; filtered?: FilterResult } export declare interface ExtendedGuildBan extends GuildBan { guildWrapper: GuildWrapper } export declare interface ExtendedGuildMember extends GuildMember { guildWrapper: GuildWrapper } export declare interface ExtendedThreadChannel extends ThreadChannel { guildWrapper: GuildWrapper } export declare interface ExtendedAPIEmbedField extends APIEmbedField { _attachment?: boolean; } export declare interface ExtendedAPIEmbed extends APIEmbed { fields: ExtendedAPIEmbedField[]; } export declare interface ExtendedVoiceState extends VoiceState { guildWrapper: GuildWrapper } export declare interface ExtendedInvite extends Invite { guildWrapper?: GuildWrapper } export type EntitySettings = { [key: string]: unknown, textcommands: TextCommandsSettings } export type EntityData = { id: Snowflake, banned?: boolean, settings?: EntitySettings }