// 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
}