vimcord 1.0.35 → 1.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as discord_js from 'discord.js';
2
- import { SlashCommandBuilder as SlashCommandBuilder$1, SlashCommandOptionsOnlyBuilder, SlashCommandSubcommandBuilder, SlashCommandSubcommandsOnlyBuilder, SlashCommandSubcommandGroupBuilder, PermissionResolvable, ActivityType, ContextMenuCommandBuilder, ChatInputCommandInteraction, ClientEvents, CommandInteraction, RepliableInteraction, TextBasedChannel, Message, GuildMember, User, EmbedBuilder, DMChannel, TextChannel, NewsChannel, ThreadChannel, ColorResolvable, ButtonComponentData, APIThumbnailComponent, ActionRowBuilder, MessageActionRowComponentBuilder, ContainerBuilder, BaseMessageOptions, StickerResolvable, PollData, InteractionReplyOptions, MessageMentionOptions, ReplyOptions, ForwardOptions, Client, APIEmbedField, APIEmbed, ClientOptions, Guild, ContextMenuCommandInteraction, MessageComponentType, UserResolvable as UserResolvable$1, MappedInteractionTypes, InteractionCollector, APITextInputComponent, APIStringSelectComponent, APIChannelSelectComponent, APIUserSelectComponent, APIRoleSelectComponent, APIMentionableSelectComponent, APIFileUploadComponent, AwaitModalSubmitOptions, ModalSubmitInteraction, InteractionDeferUpdateOptions, InteractionResponse, APIModalInteractionResponseCallbackData, ModalBuilder, Interaction, AttachmentBuilder, SelectMenuComponentOptionData, StringSelectMenuOptionBuilder, StringSelectMenuInteraction, ButtonInteraction, MessageReaction, StringSelectMenuBuilder, ButtonBuilder, ReactionCollector, APIButtonComponent, ChannelType, PartialGroupDMChannel, PartialDMChannel, GuildBasedChannel, AnyThreadChannel, VoiceBasedChannel, CategoryChannel, Channel, Role, GuildTextBasedChannel } from 'discord.js';
3
- import { DotenvConfigOptions } from 'dotenv';
4
- import * as mongoose from 'mongoose';
5
- import mongoose__default, { ClientSessionOptions, Connection, Schema, Model, SchemaDefinition, mongo, ClientSession, Require_id, RootFilterQuery, MongooseBaseQueryOptions, CreateOptions, QueryOptions, ProjectionType, HydratedDocument, UpdateQuery, MongooseUpdateQueryOptions, PipelineStage, AggregateOptions } from 'mongoose';
2
+ import { SlashCommandBuilder as SlashCommandBuilder$1, SlashCommandOptionsOnlyBuilder, SlashCommandSubcommandBuilder, SlashCommandSubcommandsOnlyBuilder, SlashCommandSubcommandGroupBuilder, PermissionResolvable, ChatInputCommandInteraction, Message, ContextMenuCommandInteraction, ContextMenuCommandBuilder, ClientEvents, ActivityType, Guild, CommandInteraction, ColorResolvable, ButtonComponentData, APIThumbnailComponent, ActionRowBuilder, MessageActionRowComponentBuilder, ContainerBuilder, BaseMessageOptions, StickerResolvable, PollData, InteractionReplyOptions, MessageMentionOptions, ReplyOptions, ForwardOptions, Client, TextBasedChannel, GuildMember, User, APIEmbedField, APIEmbed, EmbedBuilder, RepliableInteraction, DMChannel, TextChannel, NewsChannel, ThreadChannel, ClientOptions, MessageComponentType, InteractionCollector, MappedInteractionTypes, UserResolvable as UserResolvable$1, AwaitModalSubmitOptions, ModalSubmitInteraction, APIChannelSelectComponent, APIFileUploadComponent, APIMentionableSelectComponent, APITextInputComponent, APIStringSelectComponent, APIUserSelectComponent, APIRoleSelectComponent, APIModalInteractionResponseCallbackData, ModalBuilder, Interaction, InteractionDeferUpdateOptions, InteractionResponse, MessagePayload, AttachmentBuilder, SelectMenuComponentOptionData, StringSelectMenuOptionBuilder, StringSelectMenuInteraction, ButtonInteraction, MessageReaction, ButtonBuilder, StringSelectMenuBuilder, ReactionCollector, APIButtonComponent, ChannelType, PartialGroupDMChannel, PartialDMChannel, GuildBasedChannel, AnyThreadChannel, VoiceBasedChannel, CategoryChannel, Channel, Role, GuildTextBasedChannel } from 'discord.js';
6
3
  import { PartialDeep } from 'type-fest';
7
4
  import EventEmitter from 'node:events';
8
5
  import { Loop } from 'qznt';
6
+ import * as mongoose from 'mongoose';
7
+ import mongoose__default, { ClientSessionOptions, Connection, QueryOptions, HydratedDocument, Require_id, Schema, Model, SchemaDefinition, mongo, ClientSession, RootFilterQuery, MongooseBaseQueryOptions, CreateOptions, Document, ProjectionType, UpdateQuery, MongooseUpdateQueryOptions, PipelineStage, AggregateOptions, AnyBulkWriteOperation, MongooseBulkWriteOptions } from 'mongoose';
8
+ import { DotenvConfigOptions } from 'dotenv';
9
9
  import { Interface } from 'node:readline';
10
10
 
11
11
  type AnySlashCommandBuilder = SlashCommandBuilder$1 | SlashCommandOptionsOnlyBuilder | SlashCommandSubcommandBuilder | SlashCommandSubcommandsOnlyBuilder | SlashCommandSubcommandGroupBuilder;
@@ -77,258 +77,92 @@ interface CommandPermissionResults {
77
77
  blacklistedRole?: string;
78
78
  }
79
79
 
80
- interface MongoConnectionOptions {
81
- /** The maximum number of attempts to connect to MongoDB @defaultValue `3` */
82
- maxRetries?: number;
83
- }
84
- declare class MongoDatabase {
85
- private static instances;
86
- private static emitter;
87
- readonly moduleName = "MongoDatabase";
88
- readonly clientId: number;
89
- readonly client: Vimcord;
90
- readonly mongoose: mongoose__default.Mongoose;
91
- private isConnecting;
92
- /**
93
- * Returns an instance of MongoDatabase.
94
- * @param clientId [default: 0]
95
- */
96
- static getInstance(clientId?: number | Vimcord): MongoDatabase | undefined;
97
- /**
98
- * Waits for a MongoDatabase instance to be ready. First waiting for the instance to initialize if it doesn't exist.
99
- * @param clientId [default: 0]
100
- * @param timeoutMs [default: 60000]
101
- */
102
- static getReadyInstance(clientId?: number | Vimcord, timeoutMs?: number): Promise<MongoDatabase>;
103
- /**
104
- * Starts a new Mongo client session.
105
- * @param options Options for the new session
106
- * @param clientId [default: 0]
107
- */
108
- static startSession(options?: ClientSessionOptions, clientId?: number | Vimcord): Promise<mongoose__default.mongo.ClientSession>;
109
- constructor(client: Vimcord, options?: mongoose__default.MongooseOptions);
110
- get connection(): Connection;
111
- get isReady(): boolean;
112
- waitForReady(): Promise<this>;
113
- connect(uri?: string, connectionOptions?: mongoose__default.ConnectOptions, options?: MongoConnectionOptions): Promise<boolean>;
114
- disconnect(): Promise<void>;
115
- startSession(options?: ClientSessionOptions): Promise<mongoose__default.mongo.ClientSession>;
116
- useTransaction(fn: (session: mongoose__default.ClientSession) => Promise<void>): Promise<void>;
117
- }
118
-
119
- type DatabaseManager = MongoDatabase;
120
-
121
- interface VimcordAppConfig {
122
- devMode: boolean;
123
- name: string;
124
- appVersion: string;
125
- /** Enable verbose console logs?
126
- * @defaultValue false */
127
- verbose: boolean;
128
- /** Disable the vimcord client banner on startup
129
- * @defaultValue false */
130
- disableBanner: boolean;
131
- /** Only auto import modules that end with these suffixes */
132
- moduleSuffixes: {
133
- /** @defaultValue slash */
134
- slashCommand: "slash";
135
- /** @defaultValue ctx */
136
- contextCommand: "ctx";
137
- /** @defaultValue prefix */
138
- prefixCommand: "prefix";
139
- /** @defaultValue event */
140
- event: "event";
141
- };
142
- }
143
- declare function createVimcordAppConfig(options?: PartialDeep<VimcordAppConfig>): VimcordAppConfig;
144
-
145
- interface VimcordStaffConfig {
146
- ownerId: string | null;
147
- superUsers: string[];
148
- superUserRoles: string[];
149
- bypassers: {
150
- commandName: string;
151
- userIds: string[];
152
- }[];
153
- bypassesGuildAdmin: {
154
- allBotStaff: boolean;
155
- botOwner: boolean;
156
- superUsers: boolean;
157
- bypassers: boolean;
158
- };
159
- guild: {
160
- id: string | null;
161
- inviteUrl: string | null;
162
- channels: Record<string, string>;
163
- };
164
- }
165
- declare function createVimcordStaffConfig(options?: PartialDeep<VimcordStaffConfig>): VimcordStaffConfig;
166
-
167
- interface VimcordSlashCommandConfig extends BaseCommandConfig<CommandType.Slash> {
168
- }
169
- declare function createVimcordSlashCommandConfig(options?: PartialDeep<VimcordSlashCommandConfig>): VimcordSlashCommandConfig;
170
-
171
- interface VimcordPrefixCommandConfig extends BaseCommandConfig<CommandType.Prefix> {
172
- /** @defaultValue ! */
173
- defaultPrefix: string;
174
- /** @defaultValue true */
175
- allowMentionAsPrefix: boolean;
176
- /** @defaultValue true */
177
- allowCaseInsensitiveCommandNames: boolean;
178
- /**
179
- * A custom resolver to fetch a guild-specific prefix.
180
- * Returns a string (the prefix) or null/undefined to fallback to default.
181
- */
182
- guildPrefixResolver?: (client: Vimcord, guildId: string) => Promise<string | null | undefined> | string | null | undefined;
183
- }
184
- declare function createVimcordPrefixCommandConfig(options?: PartialDeep<VimcordPrefixCommandConfig>): VimcordPrefixCommandConfig;
185
-
186
- interface VimcordContextCommandConfig extends BaseCommandConfig<CommandType.Context> {
187
- }
188
- declare function createVimcordContextCommandConfig(options?: PartialDeep<VimcordContextCommandConfig>): VimcordContextCommandConfig;
189
-
190
- interface LoggerOptions {
191
- colors?: Partial<typeof LOGGER_COLORS>;
192
- prefix?: string | null;
193
- prefixEmoji?: string | null;
194
- minLevel?: LogLevel;
195
- /** @defaultValue `true` */
196
- showTimestamp?: boolean;
197
- }
198
- declare enum LogLevel {
199
- DEBUG = 0,
200
- INFO = 1,
201
- SUCCESS = 2,
202
- WARN = 3,
203
- ERROR = 4
204
- }
205
- declare const LOGGER_COLORS: {
206
- primary: string;
207
- success: string;
208
- warn: string;
209
- danger: string;
210
- muted: string;
211
- text: string;
212
- };
213
- /** Reusable functions for using `console.log()`, but in 4k ultra HD retrocolor */
214
- declare class Logger {
215
- private logPrefixEmoji;
216
- private logPrefix;
217
- private minLevel;
218
- private showTimestamp;
219
- private colorScheme;
220
- constructor(options?: LoggerOptions);
221
- protected formatTimestamp(): string;
222
- protected formatPrefix(): string;
223
- protected shouldLog(level: LogLevel): boolean;
224
- get prefixEmoji(): string | null;
225
- get prefix(): string | null;
226
- get colors(): {
227
- primary: string;
228
- success: string;
229
- warn: string;
230
- danger: string;
231
- muted: string;
232
- text: string;
233
- };
234
- extend<Extra extends Record<string, (...args: any) => void>>(extras: Extra & ThisType<Logger>): Logger & Extra;
235
- setPrefix(prefix: string | null): this;
236
- setPrefixEmoji(prefixEmoji: string | null): this;
237
- setMinLevel(minLevel: LogLevel): this;
238
- setShowTimestamp(show: boolean): this;
239
- setColors(colors: Partial<typeof LOGGER_COLORS>): this;
240
- log(message: string, ...args: any[]): void;
241
- debug(message: string, ...args: any[]): void;
242
- info(message: string, ...args: any[]): void;
243
- success(message: string, ...args: any[]): void;
244
- warn(message: string, ...args: any[]): void;
245
- error(message: string, error?: Error, ...args: any[]): void;
246
- loader(message: string): (newMessage?: string) => void;
247
- table(title: string, data: Record<string, any>): void;
248
- section(title: string): void;
80
+ declare enum CommandType {
81
+ Slash = 0,
82
+ Prefix = 1,
83
+ Context = 2
249
84
  }
250
- declare const logger: Logger;
251
-
252
- declare enum StatusType {
253
- DND = "dnd",
254
- Idle = "idle",
255
- Online = "online",
256
- Invisible = "invisible"
85
+ declare enum MissingPermissionReason {
86
+ User = 0,
87
+ Bot = 1,
88
+ Role = 2,
89
+ UserBlacklisted = 3,
90
+ RoleBlacklisted = 4,
91
+ NotInGuild = 5,
92
+ NotGuildOwner = 6,
93
+ NotBotOwner = 7,
94
+ NotBotStaff = 8
257
95
  }
258
- interface ClientActivity {
259
- /** Mappings:
260
- * - `$USER_COUNT` - this.client.users.cache.size
261
- * - `$GUILD_COUNT` - this.client.guilds.cache.size
262
- * - `$STAFF_GUILD_MEMBER_COUNT` - self explanatory
263
- */
264
- name: string;
265
- type: ActivityType;
266
- status: StatusType;
267
- streamUrl?: string;
96
+ declare enum RateLimitScope {
97
+ User = 0,
98
+ Guild = 1,
99
+ Channel = 2,
100
+ Global = 3
268
101
  }
269
- interface ClientStatus {
270
- /** In seconds */
271
- interval?: number;
272
- randomize?: boolean;
273
- activity: ClientActivity | ClientActivity[];
102
+ type BaseCommandParameters<T extends CommandType> = T extends CommandType.Slash ? [client: Vimcord<true>, interaction: ChatInputCommandInteraction] : T extends CommandType.Prefix ? [client: Vimcord<true>, message: Message] : T extends CommandType.Context ? [client: Vimcord<true>, interaction: ContextMenuCommandInteraction] : never;
103
+ interface BaseCommandConfig<T extends CommandType> {
104
+ /** Is this command enabled? @defaultValue true */
105
+ enabled?: boolean;
106
+ /** Custom conditions that must be met for this command to execute */
107
+ conditions?: Array<(...args: BaseCommandParameters<T>) => boolean | Promise<boolean>>;
108
+ /** Command permission requirements */
109
+ permissions?: CommandPermissions;
110
+ /** Command metadata configuration */
111
+ metadata?: CommandMetadata;
112
+ /** Rate limiting options */
113
+ rateLimit?: CommandRateLimitOptions<(...args: BaseCommandParameters<T>) => any>;
114
+ /** Log whenever a command is executed? @defaultValue true */
115
+ logExecution?: boolean;
116
+ /** Executed before the main command logic */
117
+ beforeExecute?: (...args: BaseCommandParameters<T>) => any;
118
+ /** The main command function that will be executed */
119
+ execute?: (...args: BaseCommandParameters<T>) => any;
120
+ /** Executed after successful execution */
121
+ afterExecute?: (result: any, ...args: BaseCommandParameters<T>) => any;
122
+ /** Executed when the required permissions are not met */
123
+ onMissingPermissions?: (results: CommandPermissionResults, ...args: BaseCommandParameters<T>) => any;
124
+ /** Executed when the required conditions are not met */
125
+ onConditionsNotMet?: (...args: BaseCommandParameters<T>) => any;
126
+ /** Executed when this command is used when its disabled */
127
+ onUsedWhenDisabled?: (...args: BaseCommandParameters<T>) => any;
128
+ /** Executed when the rate limit is hit */
129
+ onRateLimit?: (...args: BaseCommandParameters<T>) => any;
130
+ /** Custom error handler */
131
+ onError?: (error: Error, ...args: BaseCommandParameters<T>) => any;
274
132
  }
275
- interface VimcordClientStatus {
276
- production: ClientStatus;
277
- development: ClientStatus;
133
+ interface BaseAppCommandConfig {
134
+ /** Command deployment configuration */
135
+ deployment?: AppCommandDeployment;
278
136
  }
279
- declare function createVimcordStatusConfig(options?: PartialDeep<VimcordClientStatus>): VimcordClientStatus;
280
-
281
- type StatusManagerEvents = {
282
- changed: [ClientActivity];
283
- cleared: [];
284
- rotation: [ClientActivity];
285
- paused: [Loop];
286
- started: [Loop];
287
- destroyed: [];
288
- };
289
- declare class StatusManager {
290
- client: Vimcord;
291
- logger: Logger;
292
- emitter: EventEmitter<StatusManagerEvents>;
293
- lastActivity: ClientActivity | null;
294
- lastActivityIndex: number;
295
- private task;
296
- constructor(client: Vimcord);
297
- private clearData;
298
- private getReadyClient;
299
- private formatActivityName;
300
- private setActivity;
301
- private statusRotationTask;
302
- private scheduleStatusRotation;
303
- start(): this;
304
- pause(): this;
305
- set(status: PartialDeep<VimcordClientStatus>): Promise<this>;
306
- destroy(): Promise<this>;
307
- clear(): Promise<this>;
137
+ interface CommandInternalRateLimitData {
138
+ /** Number of times executed */
139
+ executions: number;
140
+ /** Timestamp of latest execution */
141
+ timestamp: number;
308
142
  }
309
143
 
310
- interface ContextCommandConfig extends BaseCommandConfig<CommandType.Context>, BaseAppCommandConfig {
144
+ interface _ContextCommandConfig extends BaseCommandConfig<CommandType.Context>, BaseAppCommandConfig {
311
145
  builder: ContextMenuCommandBuilder | ((builder: ContextMenuCommandBuilder) => ContextMenuCommandBuilder);
312
146
  deferReply?: boolean | {
313
147
  ephemeral?: boolean;
314
148
  };
315
149
  }
316
- declare class ContextCommandBuilder extends BaseCommandBuilder<CommandType.Context, ContextCommandConfig> {
150
+ declare class ContextCommandBuilder extends BaseCommandBuilder<CommandType.Context, _ContextCommandConfig> {
317
151
  builder: ContextMenuCommandBuilder;
318
- constructor(config: ContextCommandConfig);
152
+ constructor(config: _ContextCommandConfig);
319
153
  private handleExecution;
320
154
  private validateBuilder;
321
- setBuilder(builder: ContextCommandConfig["builder"]): this;
322
- setDeferReply(defer: ContextCommandConfig["deferReply"]): this;
155
+ setBuilder(builder: _ContextCommandConfig["builder"]): this;
156
+ setDeferReply(defer: _ContextCommandConfig["deferReply"]): this;
323
157
  setDeployment(deployment: AppCommandDeployment): this;
324
- setExecute(fn: ContextCommandConfig["execute"]): this;
325
- toConfig(): ContextCommandConfig;
158
+ setExecute(fn: _ContextCommandConfig["execute"]): this;
159
+ toConfig(): _ContextCommandConfig;
326
160
  }
327
161
 
328
162
  /**
329
163
  * Configuration specific to Prefix-based commands
330
164
  */
331
- interface PrefixCommandConfig extends BaseCommandConfig<CommandType.Prefix> {
165
+ interface _PrefixCommandConfig extends BaseCommandConfig<CommandType.Prefix> {
332
166
  /** The primary name of the command */
333
167
  name: string;
334
168
  /** Alternative triggers for this command */
@@ -336,9 +170,9 @@ interface PrefixCommandConfig extends BaseCommandConfig<CommandType.Prefix> {
336
170
  /** A brief explanation of what the command does */
337
171
  description?: string;
338
172
  }
339
- declare class PrefixCommandBuilder extends BaseCommandBuilder<CommandType.Prefix, PrefixCommandConfig> {
340
- options: PrefixCommandConfig;
341
- constructor(options: PrefixCommandConfig);
173
+ declare class PrefixCommandBuilder extends BaseCommandBuilder<CommandType.Prefix, _PrefixCommandConfig> {
174
+ options: _PrefixCommandConfig;
175
+ constructor(options: _PrefixCommandConfig);
342
176
  /**
343
177
  * Specialized execution logic for Prefix Commands.
344
178
  */
@@ -364,14 +198,14 @@ declare class PrefixCommandBuilder extends BaseCommandBuilder<CommandType.Prefix
364
198
  * Override setExecute to ensure handleExecution remains the entry point.
365
199
  * This is the only base method we need to redefine.
366
200
  */
367
- setExecute(fn: PrefixCommandConfig["execute"]): this;
201
+ setExecute(fn: _PrefixCommandConfig["execute"]): this;
368
202
  /**
369
203
  * Converts the current builder state back into a config object.
370
204
  */
371
- toConfig(): PrefixCommandConfig;
205
+ toConfig(): _PrefixCommandConfig;
372
206
  }
373
207
 
374
- interface SlashCommandConfig extends BaseCommandConfig<CommandType.Slash>, BaseAppCommandConfig {
208
+ interface _SlashCommandConfig extends BaseCommandConfig<CommandType.Slash>, BaseAppCommandConfig {
375
209
  builder: AnySlashCommandBuilder | ((builder: SlashCommandBuilder$1) => AnySlashCommandBuilder);
376
210
  deferReply?: boolean | {
377
211
  ephemeral?: boolean;
@@ -382,24 +216,34 @@ interface SlashCommandConfig extends BaseCommandConfig<CommandType.Slash>, BaseA
382
216
  }>;
383
217
  onUnknownRouteHandler?: (client: Vimcord<true>, interaction: ChatInputCommandInteraction) => any;
384
218
  }
385
- declare class SlashCommandBuilder extends BaseCommandBuilder<CommandType.Slash, SlashCommandConfig> {
219
+ declare class SlashCommandBuilder extends BaseCommandBuilder<CommandType.Slash, _SlashCommandConfig> {
386
220
  builder: AnySlashCommandBuilder;
387
221
  readonly routes: Map<string, (client: Vimcord<true>, interaction: ChatInputCommandInteraction) => any>;
388
- constructor(config: SlashCommandConfig);
222
+ constructor(config: _SlashCommandConfig);
389
223
  private handleExecution;
390
224
  private validateBuilder;
391
- setBuilder(builder: SlashCommandConfig["builder"]): this;
392
- setDeferReply(defer: SlashCommandConfig["deferReply"]): this;
225
+ setBuilder(builder: _SlashCommandConfig["builder"]): this;
226
+ setDeferReply(defer: _SlashCommandConfig["deferReply"]): this;
393
227
  setDeployment(deployment: AppCommandDeployment): this;
394
- setRoutes(...routes: NonNullable<SlashCommandConfig["routes"]>): this;
395
- addRoutes(...routes: NonNullable<SlashCommandConfig["routes"]>): this;
396
- setUnknownRouteHandler(handler: SlashCommandConfig["onUnknownRouteHandler"]): this;
397
- setExecute(fn: SlashCommandConfig["execute"]): this;
398
- toConfig(): SlashCommandConfig;
228
+ setRoutes(...routes: NonNullable<_SlashCommandConfig["routes"]>): this;
229
+ addRoutes(...routes: NonNullable<_SlashCommandConfig["routes"]>): this;
230
+ setUnknownRouteHandler(handler: _SlashCommandConfig["onUnknownRouteHandler"]): this;
231
+ setExecute(fn: _SlashCommandConfig["execute"]): this;
232
+ toConfig(): _SlashCommandConfig;
399
233
  }
400
234
 
401
235
  type VimcordCommandBuilderByType<T extends CommandType> = T extends CommandType.Slash ? SlashCommandBuilder : T extends CommandType.Context ? ContextCommandBuilder : T extends CommandType.Prefix ? PrefixCommandBuilder : never;
402
236
 
237
+ declare abstract class ModuleImporter<T> {
238
+ readonly client: Vimcord;
239
+ abstract readonly items: Map<string, T>;
240
+ abstract readonly itemSuffix: string | undefined;
241
+ abstract readonly itemName: string;
242
+ constructor(client: Vimcord);
243
+ importFrom(dir: string | string[], set?: boolean, suffix?: string | string[] | null): Promise<Map<string, T>>;
244
+ protected abstract getName(module: T): string;
245
+ }
246
+
403
247
  interface CommandFilter {
404
248
  names?: string[];
405
249
  fuzzyNames?: string[];
@@ -411,12 +255,14 @@ interface CommandByCategory<T extends CommandType> {
411
255
  emoji: string | undefined;
412
256
  commands: VimcordCommandBuilderByType<T>[];
413
257
  }
414
- declare class BaseCommandManager<T extends CommandType> {
258
+ declare class BaseCommandManager<T extends CommandType> extends ModuleImporter<VimcordCommandBuilderByType<T>> {
415
259
  readonly type: T;
416
- readonly client: Vimcord;
417
- readonly commands: Map<string, VimcordCommandBuilderByType<T>>;
418
- readonly moduleSuffix?: string;
419
- constructor(client: Vimcord, type: T, moduleSuffix?: string);
260
+ readonly items: Map<string, VimcordCommandBuilderByType<T>>;
261
+ readonly itemSuffix: string | undefined;
262
+ constructor(client: Vimcord, type: T, itemSuffix?: string);
263
+ get commands(): Map<string, VimcordCommandBuilderByType<T>>;
264
+ get itemName(): string;
265
+ protected getName(module: VimcordCommandBuilderByType<T>): string;
420
266
  /**
421
267
  * Gets a command by name.
422
268
  */
@@ -429,12 +275,6 @@ declare class BaseCommandManager<T extends CommandType> {
429
275
  * Groups commands by category alphabetically.
430
276
  */
431
277
  sortByCategory(): CommandByCategory<T>[];
432
- /**
433
- * Imports command modules from a directory.
434
- * @param dir Path of one or more folders.
435
- * @param set Replaces imported command modules with the ones found.
436
- */
437
- importFrom(dir: string | string[], set?: boolean): Promise<Map<string, VimcordCommandBuilderByType<T>>>;
438
278
  }
439
279
  declare class SlashCommandManager extends BaseCommandManager<CommandType.Slash> {
440
280
  constructor(client: Vimcord);
@@ -451,7 +291,7 @@ declare class CommandManager {
451
291
  readonly prefix: PrefixCommandManager;
452
292
  readonly context: ContextCommandManager;
453
293
  constructor(client: Vimcord);
454
- getAllAppCommands(options?: CommandFilter): (SlashCommandBuilder | ContextCommandBuilder)[];
294
+ getAllAppCommands(options?: CommandFilter): (ContextCommandBuilder | SlashCommandBuilder)[];
455
295
  registerGlobal(options?: CommandFilter): Promise<void>;
456
296
  unregisterGlobal(): Promise<void>;
457
297
  registerGuild(options?: CommandFilter & {
@@ -462,6 +302,68 @@ declare class CommandManager {
462
302
  }): Promise<void>;
463
303
  }
464
304
 
305
+ interface LoggerOptions {
306
+ colors?: Partial<typeof LOGGER_COLORS>;
307
+ prefix?: string | null;
308
+ prefixEmoji?: string | null;
309
+ minLevel?: LogLevel;
310
+ /** @defaultValue `true` */
311
+ showTimestamp?: boolean;
312
+ }
313
+ declare enum LogLevel {
314
+ DEBUG = 0,
315
+ INFO = 1,
316
+ SUCCESS = 2,
317
+ WARN = 3,
318
+ ERROR = 4
319
+ }
320
+ declare const LOGGER_COLORS: {
321
+ primary: string;
322
+ success: string;
323
+ warn: string;
324
+ danger: string;
325
+ muted: string;
326
+ text: string;
327
+ };
328
+ /** Reusable functions for using `console.log()`, but in 4k ultra HD retrocolor */
329
+ declare class Logger {
330
+ private logPrefixEmoji;
331
+ private logPrefix;
332
+ private minLevel;
333
+ private showTimestamp;
334
+ private colorScheme;
335
+ constructor(options?: LoggerOptions);
336
+ protected formatTimestamp(): string;
337
+ protected formatPrefix(): string;
338
+ protected shouldLog(level: LogLevel): boolean;
339
+ get prefixEmoji(): string | null;
340
+ get prefix(): string | null;
341
+ get colors(): {
342
+ primary: string;
343
+ success: string;
344
+ warn: string;
345
+ danger: string;
346
+ muted: string;
347
+ text: string;
348
+ };
349
+ extend<Extra extends Record<string, (...args: any) => void>>(extras: Extra & ThisType<Logger>): Logger & Extra;
350
+ setPrefix(prefix: string | null): this;
351
+ setPrefixEmoji(prefixEmoji: string | null): this;
352
+ setMinLevel(minLevel: LogLevel): this;
353
+ setShowTimestamp(show: boolean): this;
354
+ setColors(colors: Partial<typeof LOGGER_COLORS>): this;
355
+ log(message: string, ...args: any[]): void;
356
+ debug(message: string, ...args: any[]): void;
357
+ info(message: string, ...args: any[]): void;
358
+ success(message: string, ...args: any[]): void;
359
+ warn(message: string, ...args: any[]): void;
360
+ error(message: string, error?: Error, ...args: any[]): void;
361
+ loader(message: string): (newMessage?: string) => void;
362
+ table(title: string, data: Record<string, any>): void;
363
+ section(title: string): void;
364
+ }
365
+ declare const logger: Logger;
366
+
465
367
  type EventParameters<T extends keyof ClientEvents> = [client: Vimcord<true>, ...args: ClientEvents[T]];
466
368
 
467
369
  interface EventMetadata {
@@ -560,11 +462,13 @@ declare class EventBuilder<T extends keyof ClientEvents = keyof ClientEvents> im
560
462
  executeEvent(...args: EventParameters<T>): Promise<any>;
561
463
  }
562
464
 
563
- declare class EventManager {
564
- client: Vimcord;
565
- events: Map<string, EventBuilder<any>>;
465
+ declare class EventManager extends ModuleImporter<EventBuilder<any>> {
466
+ readonly items: Map<string, EventBuilder<any>>;
467
+ readonly itemSuffix = "event";
468
+ readonly itemName = "Event Handlers";
566
469
  logger: Logger;
567
470
  constructor(client: Vimcord);
471
+ protected getName(module: EventBuilder<any>): string;
568
472
  register<T extends keyof ClientEvents>(...events: EventBuilder<T>[]): void;
569
473
  unregister(...names: string[]): void;
570
474
  clear(): void;
@@ -573,27 +477,362 @@ declare class EventManager {
573
477
  getByCategory(category: string): EventBuilder[];
574
478
  getByEvent<T extends keyof ClientEvents>(eventType: T): EventBuilder<T>[];
575
479
  executeEvents<T extends keyof ClientEvents>(eventType: T, ...args: ClientEvents[T]): Promise<void>;
576
- /** Import event modules that end with `.event` */
577
- importFrom(dir: string | string[], replaceAll?: boolean): Promise<Map<string, EventBuilder<any>>>;
578
480
  }
579
481
 
580
- declare enum SendMethod {
581
- Reply = 0,
582
- EditReply = 1,
583
- FollowUp = 2,
584
- Channel = 3,
585
- MessageReply = 4,
586
- MessageEdit = 5,
587
- User = 6
482
+ declare enum StatusType {
483
+ DND = "dnd",
484
+ Idle = "idle",
485
+ Online = "online",
486
+ Invisible = "invisible"
487
+ }
488
+ interface ClientActivity {
489
+ /** Mappings:
490
+ * - `$USER_COUNT` - this.client.users.cache.size
491
+ * - `$GUILD_COUNT` - this.client.guilds.cache.size
492
+ * - `$STAFF_GUILD_MEMBER_COUNT` - self explanatory
493
+ */
494
+ name: string;
495
+ type: ActivityType;
496
+ status: StatusType;
497
+ streamUrl?: string;
498
+ }
499
+ interface ClientStatus {
500
+ /** In seconds */
501
+ interval?: number;
502
+ randomize?: boolean;
503
+ activity: ClientActivity | ClientActivity[];
504
+ }
505
+ interface VimcordClientStatus {
506
+ production: ClientStatus;
507
+ development: ClientStatus;
508
+ }
509
+ declare function createVimcordStatusConfig(options?: PartialDeep<VimcordClientStatus>): VimcordClientStatus;
510
+
511
+ type StatusManagerEvents = {
512
+ changed: [ClientActivity];
513
+ cleared: [];
514
+ rotation: [ClientActivity];
515
+ paused: [Loop];
516
+ started: [Loop];
517
+ destroyed: [];
518
+ };
519
+ declare class StatusManager {
520
+ client: Vimcord;
521
+ logger: Logger;
522
+ emitter: EventEmitter<StatusManagerEvents>;
523
+ lastActivity: ClientActivity | null;
524
+ lastActivityIndex: number;
525
+ private task;
526
+ constructor(client: Vimcord);
527
+ private clearData;
528
+ private getReadyClient;
529
+ private formatActivityName;
530
+ private setActivity;
531
+ private statusRotationTask;
532
+ private scheduleStatusRotation;
533
+ start(): this;
534
+ pause(): this;
535
+ set(status: PartialDeep<VimcordClientStatus>): Promise<this>;
536
+ destroy(): Promise<this>;
537
+ clear(): Promise<this>;
538
+ }
539
+
540
+ interface MongoConnectionOptions {
541
+ /** The maximum number of attempts to connect to MongoDB @defaultValue `3` */
542
+ maxRetries?: number;
543
+ }
544
+ declare class MongoDatabase {
545
+ private static instances;
546
+ private static emitter;
547
+ readonly moduleName = "MongoDatabase";
548
+ readonly clientId: number;
549
+ readonly client: Vimcord;
550
+ readonly mongoose: mongoose__default.Mongoose;
551
+ private isConnecting;
552
+ /**
553
+ * Returns an instance of MongoDatabase.
554
+ * @param clientId [default: 0]
555
+ */
556
+ static getInstance(clientId?: number | Vimcord): MongoDatabase | undefined;
557
+ /**
558
+ * Waits for a MongoDatabase instance to be ready. First waiting for the instance to initialize if it doesn't exist.
559
+ * @param clientId [default: 0]
560
+ * @param timeoutMs [default: 60000]
561
+ */
562
+ static getReadyInstance(clientId?: number | Vimcord, timeoutMs?: number): Promise<MongoDatabase>;
563
+ /**
564
+ * Starts a new Mongo client session.
565
+ * @param options Options for the new session
566
+ * @param clientId [default: 0]
567
+ */
568
+ static startSession(options?: ClientSessionOptions, clientId?: number | Vimcord): Promise<mongoose__default.mongo.ClientSession>;
569
+ constructor(client: Vimcord, options?: mongoose__default.MongooseOptions);
570
+ get connection(): Connection;
571
+ get isReady(): boolean;
572
+ waitForReady(): Promise<this>;
573
+ connect(uri?: string, connectionOptions?: mongoose__default.ConnectOptions, options?: MongoConnectionOptions): Promise<boolean>;
574
+ disconnect(): Promise<void>;
575
+ startSession(options?: ClientSessionOptions): Promise<mongoose__default.mongo.ClientSession>;
576
+ useTransaction(fn: (session: mongoose__default.ClientSession) => Promise<void>): Promise<void>;
577
+ }
578
+
579
+ type DatabaseManager = MongoDatabase;
580
+
581
+ declare class ErrorHandler {
582
+ readonly client: Vimcord;
583
+ constructor(client: Vimcord);
584
+ /** Handles command errors - sends error embed to user, then rethrows. */
585
+ handleCommandError(error: Error, guild: Guild | null, messageOrInteraction: Message | CommandInteraction): Promise<void>;
586
+ /** Handles internal Vimcord errors - logs with [Vimcord] prefix. */
587
+ handleVimcordError(error: Error, context: string): void;
588
+ /** Sets up global process error handlers. */
589
+ setupGlobalHandlers(): void;
590
+ }
591
+
592
+ interface AppConfig {
593
+ /** The name of the bot displayed in logs and startup banner.
594
+ * @accessible via `client.$name` for use in embeds, error messages, etc.
595
+ */
596
+ name: string;
597
+ /** The current version of the bot displayed in logs and startup banner.
598
+ * @accessible via `client.$version` for version commands or update notifications.
599
+ * @defaultValue Extracted from your `package.json` version field. If not found, defaults to `1.0.0`.
600
+ */
601
+ version: string;
602
+ /** Enables development mode for testing and debugging.
603
+ *
604
+ * **The way it works:**
605
+ * - If the bot is ran with the `--dev` flag it will automatically be enabled
606
+ * - Can be changed during runtime using the `client.$devMode` setter
607
+ *
608
+ * **What this does by default:**
609
+ * - Automatically switches to `TOKEN_DEV` and `MONGO_URI_DEV` environment variables
610
+ *
611
+ * **Common use cases:**
612
+ * - Use a separate Discord server, bot account, or database for testing
613
+ * - Skip production-only behaviors like analytics tracking or email notifications
614
+ * - Enable additional debug commands or verbose logging
615
+ * - Switch between development and production API endpoints for your other services
616
+ *
617
+ * @accessible via `client.$devMode` to conditionally enable/disable your own features.
618
+ *
619
+ * @example
620
+ * ```ts
621
+ * // Use different API endpoints for your own services
622
+ * const baseAPIUrl = client.$devMode
623
+ * ? 'http://localhost:3000'
624
+ * : 'https://api.production.com';
625
+ * ```
626
+ */
627
+ devMode: boolean;
628
+ /** Enables verbose console logging with additional debug information.
629
+ * @accessible via `client.$verboseMode`
630
+ * @defaultValue false
631
+ */
632
+ verbose: boolean;
633
+ /** Enables the Vimcord CLI.
634
+ * @defaultValue false
635
+ */
636
+ enableCLI: boolean;
637
+ /** Disables the Vimcord ASCII art banner on startup.
638
+ * @defaultValue false
639
+ */
640
+ disableBanner: boolean;
641
+ }
642
+ declare const createAppConfig: (options?: {
643
+ name?: string | undefined;
644
+ version?: string | undefined;
645
+ devMode?: boolean | undefined;
646
+ verbose?: boolean | undefined;
647
+ enableCLI?: boolean | undefined;
648
+ disableBanner?: boolean | undefined;
649
+ }, existing?: AppConfig | undefined) => AppConfig;
650
+
651
+ interface ContextCommandConfig extends BaseCommandConfig<CommandType.Context> {
652
+ }
653
+ declare const createContextCommandConfig: (options?: {
654
+ enabled?: boolean | undefined;
655
+ conditions?: ((client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => boolean | Promise<boolean>)[] | undefined;
656
+ permissions?: {
657
+ user?: discord_js.PermissionResolvable[] | undefined;
658
+ bot?: discord_js.PermissionResolvable[] | undefined;
659
+ roles?: string[] | undefined;
660
+ userWhitelist?: string[] | undefined;
661
+ userBlacklist?: string[] | undefined;
662
+ roleBlacklist?: string[] | undefined;
663
+ guildOnly?: boolean | undefined;
664
+ guildOwnerOnly?: boolean | undefined;
665
+ botOwnerOnly?: boolean | undefined;
666
+ botStaffOnly?: boolean | undefined;
667
+ } | undefined;
668
+ metadata?: {
669
+ category?: string | undefined;
670
+ categoryEmoji?: string | undefined;
671
+ tags?: string[] | undefined;
672
+ examples?: string[] | undefined;
673
+ emoji?: string | undefined;
674
+ hidden?: boolean | undefined;
675
+ } | undefined;
676
+ rateLimit?: {
677
+ max?: number | undefined;
678
+ interval?: number | undefined;
679
+ scope?: RateLimitScope | undefined;
680
+ onRateLimit?: ((client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
681
+ } | undefined;
682
+ logExecution?: boolean | undefined;
683
+ beforeExecute?: ((client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
684
+ execute?: ((client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
685
+ afterExecute?: ((result: any, client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
686
+ onMissingPermissions?: ((results: CommandPermissionResults, client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
687
+ onConditionsNotMet?: ((client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
688
+ onUsedWhenDisabled?: ((client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
689
+ onRateLimit?: ((client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
690
+ onError?: ((error: Error, client: Vimcord<true>, interaction: discord_js.ContextMenuCommandInteraction<discord_js.CacheType>) => any) | undefined;
691
+ }, existing?: ContextCommandConfig | undefined) => ContextCommandConfig;
692
+
693
+ interface PrefixCommandConfig extends BaseCommandConfig<CommandType.Prefix> {
694
+ /** @defaultValue ! */
695
+ defaultPrefix: string;
696
+ /** @defaultValue true */
697
+ allowMentionAsPrefix: boolean;
698
+ /** @defaultValue true */
699
+ allowCaseInsensitiveCommandNames: boolean;
700
+ /**
701
+ * A custom resolver to fetch a guild-specific prefix.
702
+ * Returns a string (the prefix) or null/undefined to fallback to default.
703
+ */
704
+ guildPrefixResolver?: (client: Vimcord, guildId: string) => Promise<string | null | undefined> | string | null | undefined;
705
+ }
706
+ declare const createPrefixCommandConfig: (options?: {
707
+ defaultPrefix?: string | undefined;
708
+ allowMentionAsPrefix?: boolean | undefined;
709
+ allowCaseInsensitiveCommandNames?: boolean | undefined;
710
+ guildPrefixResolver?: ((client: Vimcord, guildId: string) => Promise<string | null | undefined> | string | null | undefined) | undefined;
711
+ enabled?: boolean | undefined;
712
+ conditions?: ((client: Vimcord<true>, message: discord_js.Message<boolean>) => boolean | Promise<boolean>)[] | undefined;
713
+ permissions?: {
714
+ user?: discord_js.PermissionResolvable[] | undefined;
715
+ bot?: discord_js.PermissionResolvable[] | undefined;
716
+ roles?: string[] | undefined;
717
+ userWhitelist?: string[] | undefined;
718
+ userBlacklist?: string[] | undefined;
719
+ roleBlacklist?: string[] | undefined;
720
+ guildOnly?: boolean | undefined;
721
+ guildOwnerOnly?: boolean | undefined;
722
+ botOwnerOnly?: boolean | undefined;
723
+ botStaffOnly?: boolean | undefined;
724
+ } | undefined;
725
+ metadata?: {
726
+ category?: string | undefined;
727
+ categoryEmoji?: string | undefined;
728
+ tags?: string[] | undefined;
729
+ examples?: string[] | undefined;
730
+ emoji?: string | undefined;
731
+ hidden?: boolean | undefined;
732
+ } | undefined;
733
+ rateLimit?: {
734
+ max?: number | undefined;
735
+ interval?: number | undefined;
736
+ scope?: RateLimitScope | undefined;
737
+ onRateLimit?: ((client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
738
+ } | undefined;
739
+ logExecution?: boolean | undefined;
740
+ beforeExecute?: ((client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
741
+ execute?: ((client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
742
+ afterExecute?: ((result: any, client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
743
+ onMissingPermissions?: ((results: CommandPermissionResults, client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
744
+ onConditionsNotMet?: ((client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
745
+ onUsedWhenDisabled?: ((client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
746
+ onRateLimit?: ((client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
747
+ onError?: ((error: Error, client: Vimcord<true>, message: discord_js.Message<boolean>) => any) | undefined;
748
+ }, existing?: PrefixCommandConfig | undefined) => PrefixCommandConfig;
749
+
750
+ interface SlashCommandConfig extends BaseCommandConfig<CommandType.Slash> {
751
+ }
752
+ declare const createSlashCommandConfig: (options?: {
753
+ enabled?: boolean | undefined;
754
+ conditions?: ((client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => boolean | Promise<boolean>)[] | undefined;
755
+ permissions?: {
756
+ user?: discord_js.PermissionResolvable[] | undefined;
757
+ bot?: discord_js.PermissionResolvable[] | undefined;
758
+ roles?: string[] | undefined;
759
+ userWhitelist?: string[] | undefined;
760
+ userBlacklist?: string[] | undefined;
761
+ roleBlacklist?: string[] | undefined;
762
+ guildOnly?: boolean | undefined;
763
+ guildOwnerOnly?: boolean | undefined;
764
+ botOwnerOnly?: boolean | undefined;
765
+ botStaffOnly?: boolean | undefined;
766
+ } | undefined;
767
+ metadata?: {
768
+ category?: string | undefined;
769
+ categoryEmoji?: string | undefined;
770
+ tags?: string[] | undefined;
771
+ examples?: string[] | undefined;
772
+ emoji?: string | undefined;
773
+ hidden?: boolean | undefined;
774
+ } | undefined;
775
+ rateLimit?: {
776
+ max?: number | undefined;
777
+ interval?: number | undefined;
778
+ scope?: RateLimitScope | undefined;
779
+ onRateLimit?: ((client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
780
+ } | undefined;
781
+ logExecution?: boolean | undefined;
782
+ beforeExecute?: ((client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
783
+ execute?: ((client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
784
+ afterExecute?: ((result: any, client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
785
+ onMissingPermissions?: ((results: CommandPermissionResults, client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
786
+ onConditionsNotMet?: ((client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
787
+ onUsedWhenDisabled?: ((client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
788
+ onRateLimit?: ((client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
789
+ onError?: ((error: Error, client: Vimcord<true>, interaction: discord_js.ChatInputCommandInteraction<discord_js.CacheType>) => any) | undefined;
790
+ }, existing?: SlashCommandConfig | undefined) => SlashCommandConfig;
791
+
792
+ interface StaffConfig {
793
+ ownerId: string | null;
794
+ superUsers: string[];
795
+ superUserRoles: string[];
796
+ bypassers: {
797
+ commandName: string;
798
+ userIds: string[];
799
+ }[];
800
+ bypassesGuildAdmin: {
801
+ allBotStaff: boolean;
802
+ botOwner: boolean;
803
+ superUsers: boolean;
804
+ bypassers: boolean;
805
+ };
806
+ guild: {
807
+ id: string | null;
808
+ inviteUrl: string | null;
809
+ channels: Record<string, string>;
810
+ };
588
811
  }
589
- type SendHandler = CommandInteraction | RepliableInteraction | TextBasedChannel | Message | GuildMember | User;
590
- type InteractionBasedSendHandler = CommandInteraction | RepliableInteraction;
591
- type EmbedResolvable = EmbedBuilder | BetterEmbed;
592
- type InteractionResolveable = CommandInteraction | RepliableInteraction;
593
- type UserResolvable = GuildMember | User | string;
594
- type SendableTextChannel = DMChannel | TextChannel | NewsChannel | ThreadChannel;
812
+ declare const createStaffConfig: (options?: {
813
+ ownerId?: string | null | undefined;
814
+ superUsers?: string[] | undefined;
815
+ superUserRoles?: string[] | undefined;
816
+ bypassers?: {
817
+ commandName: string;
818
+ userIds: string[];
819
+ }[] | undefined;
820
+ bypassesGuildAdmin?: {
821
+ allBotStaff?: boolean | undefined;
822
+ botOwner?: boolean | undefined;
823
+ superUsers?: boolean | undefined;
824
+ bypassers?: boolean | undefined;
825
+ } | undefined;
826
+ guild?: {
827
+ id?: string | null | undefined;
828
+ inviteUrl?: string | null | undefined;
829
+ channels?: {
830
+ [x: string]: string | undefined;
831
+ } | undefined;
832
+ } | undefined;
833
+ }, existing?: StaffConfig | undefined) => StaffConfig;
595
834
 
596
- interface VimcordToolsConfig {
835
+ interface ToolsConfig {
597
836
  devMode: boolean;
598
837
  embedColor: ColorResolvable[];
599
838
  embedColorDev: ColorResolvable[];
@@ -629,9 +868,8 @@ interface VimcordToolsConfig {
629
868
  rejectLabel: string;
630
869
  };
631
870
  }
632
- declare const globalVimcordToolsConfig: VimcordToolsConfig;
633
- declare function defineGlobalToolsConfig(options: PartialDeep<VimcordToolsConfig>): void;
634
- declare function createToolsConfig(options?: PartialDeep<VimcordToolsConfig>): VimcordToolsConfig & {
871
+ declare const globalToolsConfig: ToolsConfig;
872
+ declare const createToolsConfig: (options?: {
635
873
  devMode?: boolean | undefined;
636
874
  embedColor?: ColorResolvable[] | undefined;
637
875
  embedColorDev?: ColorResolvable[] | undefined;
@@ -660,7 +898,7 @@ declare function createToolsConfig(options?: PartialDeep<VimcordToolsConfig>): V
660
898
  id?: string | undefined;
661
899
  } | undefined;
662
900
  } | undefined;
663
- back?: {
901
+ last?: {
664
902
  label?: string | undefined;
665
903
  emoji?: {
666
904
  animated?: boolean | undefined;
@@ -668,7 +906,7 @@ declare function createToolsConfig(options?: PartialDeep<VimcordToolsConfig>): V
668
906
  id?: string | undefined;
669
907
  } | undefined;
670
908
  } | undefined;
671
- jump?: {
909
+ back?: {
672
910
  label?: string | undefined;
673
911
  emoji?: {
674
912
  animated?: boolean | undefined;
@@ -676,7 +914,7 @@ declare function createToolsConfig(options?: PartialDeep<VimcordToolsConfig>): V
676
914
  id?: string | undefined;
677
915
  } | undefined;
678
916
  } | undefined;
679
- next?: {
917
+ jump?: {
680
918
  label?: string | undefined;
681
919
  emoji?: {
682
920
  animated?: boolean | undefined;
@@ -684,7 +922,7 @@ declare function createToolsConfig(options?: PartialDeep<VimcordToolsConfig>): V
684
922
  id?: string | undefined;
685
923
  } | undefined;
686
924
  } | undefined;
687
- last?: {
925
+ next?: {
688
926
  label?: string | undefined;
689
927
  emoji?: {
690
928
  animated?: boolean | undefined;
@@ -700,11 +938,12 @@ declare function createToolsConfig(options?: PartialDeep<VimcordToolsConfig>): V
700
938
  confirmLabel?: string | undefined;
701
939
  rejectLabel?: string | undefined;
702
940
  } | undefined;
703
- };
941
+ }, existing?: ToolsConfig | undefined) => ToolsConfig;
942
+ declare const defineGlobalToolsConfig: (options: PartialDeep<ToolsConfig>) => void;
704
943
 
705
944
  interface BetterContainerData {
706
- color?: string | string[] | null;
707
- config?: VimcordToolsConfig;
945
+ color?: ColorResolvable | ColorResolvable[] | null;
946
+ config?: PartialDeep<ToolsConfig>;
708
947
  }
709
948
  declare class BetterContainer {
710
949
  private container;
@@ -713,6 +952,8 @@ declare class BetterContainer {
713
952
  constructor(data?: BetterContainerData);
714
953
  private configure;
715
954
  build(): void;
955
+ setColor(color: ColorResolvable | ColorResolvable[]): this;
956
+ clearColor(): this;
716
957
  addSeparator(options?: {
717
958
  divider?: boolean;
718
959
  spacing?: number;
@@ -827,7 +1068,7 @@ interface BetterEmbedData {
827
1068
  color?: ColorResolvable | ColorResolvable[] | null;
828
1069
  timestamp?: number | boolean | Date | null;
829
1070
  acf?: boolean;
830
- config?: VimcordToolsConfig;
1071
+ config?: PartialDeep<ToolsConfig>;
831
1072
  }
832
1073
  declare class BetterEmbed {
833
1074
  private embed;
@@ -881,30 +1122,82 @@ declare class BetterEmbed {
881
1122
  send(handler: SendHandler, options?: DynaSendOptions, overrides?: Partial<BetterEmbedData>): Promise<Message | null>;
882
1123
  }
883
1124
 
884
- interface CommandErrorMessageConfig {
885
- /** Use a custom embed */
886
- embed?: (embed: BetterEmbed, error: Error, guild: Guild | null | undefined) => BetterEmbed;
887
- /** @defaultValue config.staff.mainServer.inviteUrl */
888
- inviteUrl?: string;
889
- /** The support server invite button label @defaultValue "Support Server" */
890
- inviteButtonLabel?: string;
891
- /** The error details button label @defaultValue "Details" */
892
- detailButtonLabel?: string;
893
- /** @defaultValue 30_000 // 30 seconds */
894
- detailButtonIdleTimeout?: number;
895
- /** Should the message be ephemeral? */
896
- ephemeral?: boolean;
897
- /** Should the message be deleted after a certain amount of time? */
898
- deleteAfter?: number;
1125
+ declare enum SendMethod {
1126
+ Reply = 0,
1127
+ EditReply = 1,
1128
+ FollowUp = 2,
1129
+ Channel = 3,
1130
+ MessageReply = 4,
1131
+ MessageEdit = 5,
1132
+ User = 6
1133
+ }
1134
+ type SendHandler = CommandInteraction | RepliableInteraction | TextBasedChannel | Message | GuildMember | User;
1135
+ type InteractionBasedSendHandler = CommandInteraction | RepliableInteraction;
1136
+ type EmbedResolvable = EmbedBuilder | BetterEmbed;
1137
+ type InteractionResolveable = CommandInteraction | RepliableInteraction;
1138
+ type UserResolvable = GuildMember | User | string;
1139
+ type SendableTextChannel = DMChannel | TextChannel | NewsChannel | ThreadChannel;
1140
+
1141
+ interface ModuleImportOptions {
1142
+ /** The directories to import from. */
1143
+ dir: string | string[];
1144
+ /** Recursively imports modules from subdirectories.
1145
+ * @defaultValue true
1146
+ **/
1147
+ recursive?: boolean;
1148
+ /** Only import modules that end with these suffixes.
1149
+ *
1150
+ * If set to `null` all files in the directory will be imported, which may lead to import errors if you have modules not related to commands in the same directory.
1151
+ *
1152
+ * Respectively, the default suffixes are `.slash`, `.ctx`, `.prefix`, and `.event`.
1153
+ *
1154
+ * @example
1155
+ * // Example module filenames using the default suffixes
1156
+ * "ping.slash.ts"
1157
+ * "avatar.ctx.ts"
1158
+ * "help.prefix.ts"
1159
+ * "ready.event.ts"
1160
+ */
1161
+ suffix?: string | string[] | null;
1162
+ }
1163
+ interface AppModuleImports {
1164
+ /** Default suffix: slash
1165
+ * @example
1166
+ * // Example module filename
1167
+ * "ping.slash.ts"
1168
+ */
1169
+ slashCommands?: string | string[] | ModuleImportOptions;
1170
+ /** Default suffix: ctx
1171
+ * @example
1172
+ * // Example module filename
1173
+ * "avatar.ctx.ts"
1174
+ */
1175
+ contextCommands?: string | string[] | ModuleImportOptions;
1176
+ /** Default suffix: prefix
1177
+ * @example
1178
+ * // Example module filename
1179
+ * "help.prefix.ts"
1180
+ */
1181
+ prefixCommands?: string | string[] | ModuleImportOptions;
1182
+ /** Default suffix: event
1183
+ * @example
1184
+ * // Example module filename
1185
+ * "ready.event.ts"
1186
+ */
1187
+ events?: string | string[] | ModuleImportOptions;
899
1188
  }
900
1189
  interface VimcordFeatures {
901
- /** Use global process error handlers @defaultValue `false` */
1190
+ /** Use global process error handlers.
1191
+ * @defaultValue true */
902
1192
  useGlobalErrorHandlers?: boolean;
903
- /** Use our default prefix command handler @defaultValue `true` */
1193
+ /** Use our default prefix command handler.
1194
+ * @defaultValue true */
904
1195
  useDefaultPrefixCommandHandler?: boolean;
905
- /** Use our default slash command handler @defaultValue `true` */
1196
+ /** Use our default slash command handler.
1197
+ * @defaultValue true */
906
1198
  useDefaultSlashCommandHandler?: boolean;
907
- /** Use our default context command handler @defaultValue `true` */
1199
+ /** Use our default context command handler.
1200
+ * @defaultValue true */
908
1201
  useDefaultContextCommandHandler?: boolean;
909
1202
  /** Reply to the user with an Uh-oh! embed when a command fails. If not using our default command handlers, you will have to implement this yourself using {@link sendCommandErrorEmbed}
910
1203
  * @example
@@ -920,29 +1213,57 @@ interface VimcordFeatures {
920
1213
  * }
921
1214
  * ``` */
922
1215
  enableCommandErrorMessage?: boolean | CommandErrorMessageConfig;
923
- /** Update the state of {@link globalVimcordToolsConfig.devMode} whenever {@link VimcordAppConfig.devMode} is updated in the client. This is mainly useful for {@link BetterEmbed} to switch between devMode and production colors during runtime without having to update the global config manually @defaultValue `false` */
924
- hookToolsDevMode?: boolean;
925
- /** Setup and configure `dotenv` @defaultValue `false` */
926
- useEnv?: boolean | DotenvConfigOptions;
927
1216
  /** The maximum number of attempts to log into Discord @defaultValue `3` */
928
- loginAttempts?: number;
929
- /** Import modules from directories */
930
- importModules?: {
931
- events?: string | string[];
932
- slashCommands?: string | string[];
933
- prefixCommands?: string | string[];
934
- contextCommands?: string | string[];
935
- };
1217
+ maxLoginAttempts?: number;
1218
+ /** Automatically imports modules from these directories. */
1219
+ importModules?: AppModuleImports;
936
1220
  }
937
1221
  interface VimcordConfig {
938
- app: VimcordAppConfig;
939
- staff: VimcordStaffConfig;
940
- slashCommands: VimcordSlashCommandConfig;
941
- prefixCommands: VimcordPrefixCommandConfig;
942
- contextCommands: VimcordContextCommandConfig;
1222
+ app: AppConfig;
1223
+ staff: StaffConfig;
1224
+ slashCommands: SlashCommandConfig;
1225
+ prefixCommands: PrefixCommandConfig;
1226
+ contextCommands: ContextCommandConfig;
1227
+ }
1228
+ interface VimcordCreateConfig {
1229
+ options: ClientOptions;
1230
+ features?: VimcordFeatures;
1231
+ config?: PartialDeep<VimcordConfig>;
1232
+ }
1233
+ interface CommandErrorMessageConfig {
1234
+ /** Use a custom embed */
1235
+ embed?: (embed: EmbedResolvable, error: Error, guild: Guild | null | undefined) => EmbedResolvable;
1236
+ /** @defaultValue config.staff.mainServer.inviteUrl */
1237
+ inviteUrl?: string;
1238
+ /** The support server invite button label @defaultValue "Support Server" */
1239
+ inviteButtonLabel?: string;
1240
+ /** The error details button label @defaultValue "Details" */
1241
+ detailButtonLabel?: string;
1242
+ /** @defaultValue 30_000 // 30 seconds */
1243
+ detailButtonIdleTimeout?: number;
1244
+ /** Should the message be ephemeral? */
1245
+ ephemeral?: boolean;
1246
+ /** Should the message be deleted after a certain amount of time? */
1247
+ deleteAfter?: number;
943
1248
  }
1249
+
944
1250
  declare class Vimcord<Ready extends boolean = boolean> extends Client<Ready> {
945
1251
  static instances: Map<number, Vimcord<boolean>>;
1252
+ private static emitter;
1253
+ private clientStartingPromise;
1254
+ static create(options: ClientOptions, features?: VimcordFeatures, config?: PartialDeep<VimcordConfig>): Vimcord;
1255
+ static create(config: VimcordCreateConfig): Vimcord;
1256
+ /**
1257
+ * Returns an instance of Vimcord.
1258
+ * @param clientId [default: 0]
1259
+ */
1260
+ static getInstance(clientId?: number): Vimcord | undefined;
1261
+ /**
1262
+ * Waits for a Vimcord instance to be ready.
1263
+ * @param clientId [default: 0]
1264
+ * @param timeoutMs [default: 60000]
1265
+ */
1266
+ static getReadyInstance(clientId?: number, timeoutMs?: number): Promise<Vimcord<true>>;
946
1267
  readonly uuid: string;
947
1268
  readonly clientId: number;
948
1269
  readonly clientOptions: ClientOptions;
@@ -952,15 +1273,27 @@ declare class Vimcord<Ready extends boolean = boolean> extends Client<Ready> {
952
1273
  readonly events: EventManager;
953
1274
  readonly commands: CommandManager;
954
1275
  db?: DatabaseManager;
955
- logger: Logger & {
1276
+ readonly logger: Logger & {
956
1277
  clientBanner(client: Vimcord): void;
957
1278
  clientReady(clientTag: string, guildCount: number): void;
958
1279
  moduleLoaded(moduleName: string, count?: number, ignoredCount?: number): void;
959
1280
  commandExecuted(commandName: string, username: string, guildName?: string): void;
960
1281
  database(action: string, details?: string): void;
961
1282
  };
962
- private clientStartingPromise;
1283
+ readonly error: ErrorHandler;
963
1284
  constructor(options: ClientOptions, features?: VimcordFeatures, config?: PartialDeep<VimcordConfig>);
1285
+ /** Current app name */
1286
+ get $name(): string;
1287
+ set $name(name: string);
1288
+ /** Current app version */
1289
+ get $version(): string;
1290
+ set $version(version: string);
1291
+ /** Current dev mode state */
1292
+ get $devMode(): boolean;
1293
+ set $devMode(mode: boolean);
1294
+ /** Current verbose mode state */
1295
+ get $verboseMode(): boolean;
1296
+ set $verboseMode(mode: boolean);
964
1297
  /** Returns the options, features, and config of this client. */
965
1298
  toJSON(): {
966
1299
  options: ClientOptions;
@@ -968,93 +1301,90 @@ declare class Vimcord<Ready extends boolean = boolean> extends Client<Ready> {
968
1301
  config: VimcordConfig;
969
1302
  };
970
1303
  /** Makes a clone of this client. */
971
- clone(): Vimcord<boolean>;
972
- configureApp(options?: PartialDeep<VimcordAppConfig>): this;
973
- configureStaff(options?: PartialDeep<VimcordStaffConfig>): this;
974
- configureSlashCommands(options?: PartialDeep<VimcordSlashCommandConfig>): this;
975
- configurePrefixCommands(options?: PartialDeep<VimcordPrefixCommandConfig>): this;
976
- configureContextCommands(options?: PartialDeep<VimcordContextCommandConfig>): this;
977
- importEventModules(dir: string | string[], replaceAll?: boolean): Promise<this>;
978
- importSlashCommandModules(dir: string | string[], replaceAll?: boolean): Promise<this>;
979
- importPrefixCommandModules(dir: string | string[], replaceAll?: boolean): Promise<this>;
980
- importContextCommandModules(dir: string | string[], replaceAll?: boolean): Promise<this>;
981
- useDatabase(db: DatabaseManager): Promise<boolean>;
982
- waitForReady(): Promise<Vimcord<true>>;
1304
+ clone(): Vimcord;
1305
+ /**
1306
+ * Modifies a client config.
1307
+ * @param type The type of config to modify.
1308
+ * @param options The options to set for the config.
1309
+ */
1310
+ configure<T extends keyof VimcordConfig>(type: T, options?: PartialDeep<VimcordConfig[T]>): this;
1311
+ /** Builds the client by importing modules and registering builtin handlers. */
983
1312
  build(): Promise<this>;
984
- /** Automatically uses `process.env.TOKEN` or `process.env.TOKEN_DEV` if token isn't provided */
1313
+ /**
1314
+ * Imports modules into the client.
1315
+ * @param type The type of modules to import.
1316
+ * @param options The options to import the module with.
1317
+ * @param set Replaces already imported modules with the ones found.
1318
+ */
1319
+ importModules<T extends keyof AppModuleImports>(type: T, options: AppModuleImports[T], set?: boolean): Promise<this>;
1320
+ /**
1321
+ * Allows Vimcord to handle environment variables using [dotenv](https://www.npmjs.com/package/dotenv).
1322
+ * @param options Options for dotenv
1323
+ * @see https://www.npmjs.com/package/dotenv
1324
+ */
1325
+ useEnv(options?: DotenvConfigOptions): this;
1326
+ /**
1327
+ * Connects to a database.
1328
+ * @param db The database manager to use.
1329
+ */
1330
+ useDatabase(db: DatabaseManager): Promise<boolean>;
1331
+ /**
1332
+ * Fetches a user from the client, checking the cache first.
1333
+ * @param userId The ID of the user to fetch.
1334
+ */
1335
+ fetchUser(userId: string | undefined | null): Promise<discord_js.User | null>;
1336
+ /**
1337
+ * Fetches a guild from the client, checking the cache first.
1338
+ * @param guildId The ID of the guild to fetch.
1339
+ */
1340
+ fetchGuild(guildId: string | undefined | null): Promise<discord_js.Guild | null>;
1341
+ /**
1342
+ * Starts the client and connects to Discord.
1343
+ * Automatically uses `process.env.TOKEN` or `process.env.TOKEN_DEV` if token isn't provided.
1344
+ * @param token The Discord bot token.
1345
+ * @param callback Runs after logging in.
1346
+ */
985
1347
  start(token?: string): Promise<string | null>;
986
- start(preHook?: (client: Vimcord) => any): Promise<string | null>;
987
- start(token?: string, preHook?: (client: Vimcord) => any): Promise<string | null>;
1348
+ start(callback?: (client: Vimcord) => unknown): Promise<string | null>;
1349
+ start(token?: string, callback?: (client: Vimcord) => unknown): Promise<string | null>;
1350
+ /** Destroys the client and disconnects from Discord. */
988
1351
  kill(): Promise<void>;
989
- /** Shortcut for {@link fetchUser tools.fetchUser} */
990
- fetchUser(id: string | undefined | null): Promise<User | null>;
991
- /** Shortcut for {@link fetchGuild tools.fetchGuild} */
992
- fetchGuild(id: string | undefined | null): Promise<Guild | null>;
993
1352
  }
994
1353
 
995
- declare enum CommandType {
996
- Slash = 0,
997
- Prefix = 1,
998
- Context = 2
999
- }
1000
- declare enum MissingPermissionReason {
1001
- User = 0,
1002
- Bot = 1,
1003
- Role = 2,
1004
- UserBlacklisted = 3,
1005
- RoleBlacklisted = 4,
1006
- NotInGuild = 5,
1007
- NotGuildOwner = 6,
1008
- NotBotOwner = 7,
1009
- NotBotStaff = 8
1010
- }
1011
- declare enum RateLimitScope {
1012
- User = 0,
1013
- Guild = 1,
1014
- Channel = 2,
1015
- Global = 3
1016
- }
1017
- type BaseCommandParameters<T extends CommandType> = T extends CommandType.Slash ? [client: Vimcord<true>, interaction: ChatInputCommandInteraction] : T extends CommandType.Prefix ? [client: Vimcord<true>, message: Message] : T extends CommandType.Context ? [client: Vimcord<true>, interaction: ContextMenuCommandInteraction] : never;
1018
- interface BaseCommandConfig<T extends CommandType> {
1019
- /** Is this command enabled? @defaultValue true */
1020
- enabled?: boolean;
1021
- /** Custom conditions that must be met for this command to execute */
1022
- conditions?: Array<(...args: BaseCommandParameters<T>) => boolean | Promise<boolean>>;
1023
- /** Command permission requirements */
1024
- permissions?: CommandPermissions;
1025
- /** Command metadata configuration */
1026
- metadata?: CommandMetadata;
1027
- /** Rate limiting options */
1028
- rateLimit?: CommandRateLimitOptions<(...args: BaseCommandParameters<T>) => any>;
1029
- /** Log whenever a command is executed? @defaultValue true */
1030
- logExecution?: boolean;
1031
- /** Executed before the main command logic */
1032
- beforeExecute?: (...args: BaseCommandParameters<T>) => any;
1033
- /** The main command function that will be executed */
1034
- execute?: (...args: BaseCommandParameters<T>) => any;
1035
- /** Executed after successful execution */
1036
- afterExecute?: (result: any, ...args: BaseCommandParameters<T>) => any;
1037
- /** Executed when the required permissions are not met */
1038
- onMissingPermissions?: (results: CommandPermissionResults, ...args: BaseCommandParameters<T>) => any;
1039
- /** Executed when the required conditions are not met */
1040
- onConditionsNotMet?: (...args: BaseCommandParameters<T>) => any;
1041
- /** Executed when this command is used when its disabled */
1042
- onUsedWhenDisabled?: (...args: BaseCommandParameters<T>) => any;
1043
- /** Executed when the rate limit is hit */
1044
- onRateLimit?: (...args: BaseCommandParameters<T>) => any;
1045
- /** Custom error handler */
1046
- onError?: (error: Error, ...args: BaseCommandParameters<T>) => any;
1047
- }
1048
- interface BaseAppCommandConfig {
1049
- /** Command deployment configuration */
1050
- deployment?: AppCommandDeployment;
1051
- }
1052
- interface CommandInternalRateLimitData {
1053
- /** Number of times executed */
1054
- executions: number;
1055
- /** Timestamp of latest execution */
1056
- timestamp: number;
1057
- }
1354
+ declare const clientLoggerFactory: (client: Vimcord) => Logger & {
1355
+ clientBanner(client: Vimcord): void;
1356
+ clientReady(clientTag: string, guildCount: number): void;
1357
+ moduleLoaded(moduleName: string, count?: number, ignoredCount?: number): void;
1358
+ commandExecuted(commandName: string, username: string, guildName?: string): void;
1359
+ database(action: string, details?: string): void;
1360
+ };
1361
+
1362
+ declare const DEFAULT_MODULE_SUFFIXES: {
1363
+ readonly slashCommands: ".slash";
1364
+ readonly contextCommands: ".ctx";
1365
+ readonly prefixCommands: ".prefix";
1366
+ readonly events: ".event";
1367
+ };
1368
+ declare const configSetters: Record<keyof VimcordConfig, (options: PartialDeep<VimcordConfig[keyof VimcordConfig]>, existing?: VimcordConfig[keyof VimcordConfig]) => VimcordConfig[keyof VimcordConfig]>;
1369
+ declare const moduleImporters: Record<keyof AppModuleImports, (client: Vimcord, options: AppModuleImports[keyof AppModuleImports], set?: boolean) => any>;
1370
+ declare function defineClientOptions(options: ClientOptions): ClientOptions;
1371
+ declare function defineVimcordFeatures(features: VimcordFeatures): VimcordFeatures;
1372
+ declare function defineVimcordConfig(config: PartialDeep<VimcordConfig>): VimcordConfig;
1373
+ /**
1374
+ * Returns an instance of Vimcord.
1375
+ * @param clientId [default: 0]
1376
+ */
1377
+ declare const useClient: typeof Vimcord.getInstance;
1378
+ /**
1379
+ * Waits for a Vimcord instance to be ready.
1380
+ * @param clientId [default: 0]
1381
+ * @param timeoutMs [default: 60000]
1382
+ */
1383
+ declare const useReadyClient: typeof Vimcord.getReadyInstance;
1384
+ /**
1385
+ * Creates a new instance of Vimcord.
1386
+ */
1387
+ declare const createClient: typeof Vimcord.create;
1058
1388
 
1059
1389
  declare abstract class BaseCommandBuilder<T extends CommandType, O extends BaseCommandConfig<T> = BaseCommandConfig<T>> {
1060
1390
  readonly uuid: string;
@@ -1148,12 +1478,6 @@ declare abstract class BaseCommandBuilder<T extends CommandType, O extends BaseC
1148
1478
  setOnError(callback: (error: Error, ...args: BaseCommandParameters<T>) => any): this;
1149
1479
  }
1150
1480
 
1151
- declare const BUILTIN_ContextCommandHandler: EventBuilder<"interactionCreate">;
1152
-
1153
- declare const BUILTIN_PrefixCommandHandler: EventBuilder<"messageCreate">;
1154
-
1155
- declare const BUILTIN_SlashCommandHandler: EventBuilder<"interactionCreate">;
1156
-
1157
1481
  type MongoPlugin<Definition extends object> = (builder: MongoSchemaBuilder<Definition>) => void;
1158
1482
  type ExtractReturn<T> = T extends (this: any, ...args: any) => infer R ? Awaited<R> : never;
1159
1483
  type LeanOrHydratedDocument<T, O extends QueryOptions<T>> = O["lean"] extends false ? HydratedDocument<T> : Require_id<T>;
@@ -1249,12 +1573,12 @@ declare class MongoSchemaBuilder<Definition extends object = any> {
1249
1573
  createHexId(bytes: number, path: keyof Require_id<Definition>, maxRetries?: number): Promise<string>;
1250
1574
  count(filter?: RootFilterQuery<Definition>, options?: mongo.CountOptions & MongooseBaseQueryOptions<Definition> & mongo.Abortable): Promise<number>;
1251
1575
  exists(filter: RootFilterQuery<Definition>): Promise<boolean>;
1252
- create(query: Partial<Require_id<Definition>>[], options?: CreateOptions): Promise<(mongoose.Document<unknown, {}, Definition, {}, {}> & (Require_id<Definition> extends infer T ? T extends Require_id<Definition> ? T extends {
1576
+ create(query: Partial<Require_id<Definition>>[], options?: CreateOptions): Promise<(Document<unknown, {}, Definition, {}, {}> & (Require_id<Definition> extends infer T ? T extends Require_id<Definition> ? T extends {
1253
1577
  __v?: infer U;
1254
1578
  } ? T : T & {
1255
1579
  __v: number;
1256
1580
  } : never : never))[]>;
1257
- upsert(filter: RootFilterQuery<Definition>, query: Partial<Require_id<Definition>>, options?: QueryOptions<Definition>): Promise<mongoose.Document<unknown, {}, Definition, {}, {}> & (Require_id<Definition> extends infer T ? T extends Require_id<Definition> ? T extends {
1581
+ upsert(filter: RootFilterQuery<Definition>, query: Partial<Require_id<Definition>>, options?: QueryOptions<Definition>): Promise<Document<unknown, {}, Definition, {}, {}> & (Require_id<Definition> extends infer T ? T extends Require_id<Definition> ? T extends {
1258
1582
  __v?: infer U;
1259
1583
  } ? T : T & {
1260
1584
  __v: number;
@@ -1267,8 +1591,23 @@ declare class MongoSchemaBuilder<Definition extends object = any> {
1267
1591
  update<Options extends QueryOptions<Definition>>(filter: RootFilterQuery<Definition>, update: UpdateQuery<Definition>, options?: Options): Promise<LeanOrHydratedDocument<Definition, Options> | null | undefined>;
1268
1592
  updateAll(filter: RootFilterQuery<Definition>, update: UpdateQuery<Definition>, options?: mongo.UpdateOptions & MongooseUpdateQueryOptions<Definition>): Promise<mongoose.UpdateWriteOpResult>;
1269
1593
  aggregate<T extends any>(pipeline: PipelineStage[], options?: AggregateOptions): Promise<T[]>;
1594
+ bulkWrite(ops: AnyBulkWriteOperation[], options?: MongooseBulkWriteOptions): Promise<mongo.BulkWriteResult>;
1595
+ bulkSave(docs: Document[], options?: MongooseBulkWriteOptions): Promise<mongo.BulkWriteResult & {
1596
+ mongoose?: {
1597
+ validationErrors: mongoose.Error[];
1598
+ results: Array<mongoose.Error | mongo.WriteError | null>;
1599
+ };
1600
+ }>;
1270
1601
  }
1271
1602
 
1603
+ declare const contextCommandHandler: EventBuilder<"interactionCreate">;
1604
+
1605
+ declare const prefixCommandHandler: EventBuilder<"messageCreate">;
1606
+
1607
+ declare const slashCommandHandler: EventBuilder<"interactionCreate">;
1608
+
1609
+ declare function validateCommandPermissions(permissions: CommandPermissions, client: Vimcord<true>, user: GuildMember | User, command: CommandInteraction | string): CommandPermissionResults;
1610
+
1272
1611
  interface BetterCollectorOptions<T extends MessageComponentType> {
1273
1612
  type?: T;
1274
1613
  participants?: UserResolvable$1[];
@@ -1282,7 +1621,7 @@ interface BetterCollectorOptions<T extends MessageComponentType> {
1282
1621
  maxComponents?: number;
1283
1622
  maxUsers?: number;
1284
1623
  onTimeout?: CollectorTimeoutType;
1285
- config?: VimcordToolsConfig;
1624
+ config?: PartialDeep<ToolsConfig>;
1286
1625
  }
1287
1626
  interface ListenerOptions<ComponentType extends MessageComponentType = MessageComponentType, InGuild extends boolean = boolean> {
1288
1627
  participants?: UserResolvable$1[];
@@ -1361,7 +1700,7 @@ interface BetterModalOptions {
1361
1700
  /** Max 5 components. */
1362
1701
  components?: BetterModalComponent[];
1363
1702
  /** A custom Vimcord config. */
1364
- config?: VimcordToolsConfig;
1703
+ config?: ToolsConfig;
1365
1704
  }
1366
1705
  interface AwaitSubmitOptions extends Omit<AwaitModalSubmitOptions<ModalSubmitInteraction>, "filter" | "time"> {
1367
1706
  /** The time to wait for the modal to be submitted in milliseconds. */
@@ -1381,6 +1720,8 @@ interface ModalSubmitResult<T extends any = any> {
1381
1720
  reply: (options: RequiredDynaSendOptions) => Promise<Message | null>;
1382
1721
  /** Defers the interaction, closing the modal. */
1383
1722
  deferUpdate: (options?: InteractionDeferUpdateOptions) => Promise<InteractionResponse>;
1723
+ /** Follow up the interaction. */
1724
+ followUp: (options: string | MessagePayload | InteractionReplyOptions) => Promise<Message | null>;
1384
1725
  }
1385
1726
  declare class BetterModal {
1386
1727
  readonly id: string;
@@ -1460,7 +1801,7 @@ interface PaginatorOptions {
1460
1801
  dynamic?: boolean;
1461
1802
  timeout?: number;
1462
1803
  onTimeout?: PaginationTimeoutType;
1463
- config?: VimcordToolsConfig;
1804
+ config?: PartialDeep<ToolsConfig>;
1464
1805
  }
1465
1806
  interface PaginatorData {
1466
1807
  message: Message | null;
@@ -1489,7 +1830,7 @@ interface PaginatorData {
1489
1830
  };
1490
1831
  components: {
1491
1832
  chapterSelect: StringSelectMenuBuilder;
1492
- navigation: Record<keyof VimcordToolsConfig["paginator"]["buttons"], ButtonBuilder>;
1833
+ navigation: Record<keyof ToolsConfig["paginator"]["buttons"], ButtonBuilder>;
1493
1834
  actionRows: {
1494
1835
  chapterSelect: ActionRowBuilder<StringSelectMenuBuilder>;
1495
1836
  navigation: ActionRowBuilder<ButtonBuilder>;
@@ -1571,7 +1912,7 @@ interface PromptOptions {
1571
1912
  /** @defaultValue [PromptResolveType.DeleteOnConfirm, PromptResolveType.DeleteOnReject] */
1572
1913
  onResolve?: PromptResolveType[];
1573
1914
  timeout?: number;
1574
- config?: VimcordToolsConfig;
1915
+ config?: PartialDeep<ToolsConfig>;
1575
1916
  }
1576
1917
  interface PromptResult {
1577
1918
  message: Message | null;
@@ -1596,7 +1937,7 @@ declare class Prompt {
1596
1937
  }>;
1597
1938
  readonly onResolve: PromptResolveType[];
1598
1939
  readonly timeout: number;
1599
- readonly config: VimcordToolsConfig;
1940
+ readonly config: ToolsConfig;
1600
1941
  private message;
1601
1942
  constructor(options?: PromptOptions);
1602
1943
  private createDefaultForm;
@@ -1642,7 +1983,7 @@ declare function cleanMention(str: string | undefined): string | undefined;
1642
1983
  * @param content - The message's clean content to parse. Will be used if message.mentions isn't populated.
1643
1984
  * @param type - The type of mention.
1644
1985
  * @param index - The argument index in the content. Default is `0`
1645
- * @param idOnly - Whether to return the ID instead of the fecthed object. */
1986
+ * @param idOnly - Whether to return the ID instead of the fetched object. */
1646
1987
  declare function getMessageMention<M extends Message, T extends MentionType>(message: M, content: string | undefined | null, type: T, index: number, idOnly: true): Promise<string | null>;
1647
1988
  declare function getMessageMention<M extends Message, T extends MentionType>(message: M, content: string | undefined | null, type: T, index?: number, idOnly?: false): Promise<FetchedMessageMention<T, M extends Message<true> ? true : false> | null>;
1648
1989
  /** Get the ID of the first mention of a specified type from a message or message content.
@@ -1671,19 +2012,37 @@ declare function fetchMember(guild: Guild, memberId: string | undefined | null):
1671
2012
  * @param channelId - The ID of the channel to fetch.
1672
2013
  * @param type - The type of channel to fetch. */
1673
2014
  declare function fetchChannel<T extends ChannelType>(guild: Guild, channelId: string | undefined | null, type?: T): Promise<FetchedChannel<T> | null>;
1674
- /** Fetch a role from a guild, checking the cache first.
1675
- * @param guild - The guild to fetch the role from.
1676
- * @param roleId - The ID of the role to fetch. */
1677
- declare function fetchRole(guild: Guild, roleId: string | undefined | null): Promise<Role | null>;
1678
2015
  /** Fetch a message from a channel, checking the cache first.
1679
2016
  * @param channel - The channel to fetch the message from.
1680
2017
  * @param messageId - The ID of the message to fetch. */
1681
2018
  declare function fetchMessage(channel: GuildTextBasedChannel | VoiceBasedChannel, messageId: string | undefined | null): Promise<Message | null>;
2019
+ /** Fetch a role from a guild, checking the cache first.
2020
+ * @param guild - The guild to fetch the role from.
2021
+ * @param roleId - The ID of the role to fetch. */
2022
+ declare function fetchRole(guild: Guild, roleId: string | undefined | null): Promise<Role | null>;
2023
+
2024
+ declare function sendCommandErrorEmbed(client: Vimcord, error: Error, guild: Guild | null | undefined, messageOrInteraction: Message | CommandInteraction): Promise<Message<boolean> | null>;
2025
+
2026
+ declare function createConfigFactory<T>(defaultConfig: T, validate?: (config: T) => void): (options?: PartialDeep<T>, existing?: T) => T;
2027
+
2028
+ declare function getProcessDir(): string;
2029
+ declare function importModulesFromDir<T extends any>(dir: string, suffix?: string): Promise<{
2030
+ module: T;
2031
+ path: string;
2032
+ }[]>;
1682
2033
 
2034
+ /** Reads the `package.json` file from the current working directory. */
2035
+ declare function getPackageJson(): any;
2036
+ /** Checks if the process was ran using the `--dev` flag. */
2037
+ declare function getDevMode(): boolean;
2038
+
2039
+ type VimcordCLIMode = "on" | "off";
1683
2040
  interface VimcordCLIOptions {
1684
2041
  prefix: string;
1685
2042
  }
1686
2043
  declare class VimcordCLI {
2044
+ static mode: VimcordCLIMode;
2045
+ static setMode(mode: VimcordCLIMode): void;
1687
2046
  rl: Interface;
1688
2047
  options: VimcordCLIOptions;
1689
2048
  commands: Map<string, {
@@ -1697,24 +2056,6 @@ declare class VimcordCLI {
1697
2056
  addCommand(commandName: string, description: string, fn: (args: string[], content: string) => void): void;
1698
2057
  removeCommand(commandName: string): boolean;
1699
2058
  }
1700
- declare const CLI: VimcordCLI;
1701
- /** One-time function to be called during client creation */
1702
- declare function initCLI(): void;
1703
-
1704
- type VimcordConfigOptions = PartialDeep<VimcordConfig>;
1705
- declare function useClient(clientId?: number): Vimcord<boolean> | undefined;
1706
- declare function useReadyClient(clientId?: number): Promise<Vimcord<true> | undefined>;
1707
- declare function createClient(options: ClientOptions, features?: VimcordFeatures, config?: VimcordConfigOptions): Vimcord<boolean>;
1708
-
1709
- declare function getCallerFileName(): string | undefined;
1710
- declare function getProcessDir(): string;
1711
- declare function importModulesFromDir<T extends any>(dir: string, suffix?: string): Promise<{
1712
- module: T;
1713
- path: string;
1714
- }[]>;
1715
-
1716
- declare function sendCommandErrorEmbed(client: Vimcord, error: Error, guild: Guild | null | undefined, messageOrInteraction: Message | CommandInteraction): Promise<Message<boolean> | null>;
1717
-
1718
- declare function validateCommandPermissions(permissions: CommandPermissions, client: Vimcord<true>, user: GuildMember | User, command: CommandInteraction | string): CommandPermissionResults;
2059
+ declare let CLI: VimcordCLI;
1719
2060
 
1720
- export { type AnySlashCommandBuilder, type AppCommandDeployment, type AwaitSubmitOptions, BUILTIN_ContextCommandHandler, BUILTIN_PrefixCommandHandler, BUILTIN_SlashCommandHandler, type BaseAppCommandConfig, BaseCommandBuilder, type BaseCommandConfig, BaseCommandManager, type BaseCommandParameters, type BetterChannelSelectComponent, BetterCollector, type BetterCollectorOptions, BetterContainer, type BetterContainerData, BetterEmbed, type BetterEmbedAuthor, type BetterEmbedContext, type BetterEmbedData, type BetterEmbedFooter, type BetterEmbedTitle, type BetterFileUploadSelectComponent, type BetterMentionableSelectComponent, BetterModal, type BetterModalComponent, type BetterModalOptions, type BetterRoleSelectComponent, type BetterStringSelectComponent, type BetterTextInputComponent, type BetterUserSelectComponent, type ButtonHandler, CLI, type Chapter, type ChapterData, type ClientActivity, type ClientStatus, CollectorTimeoutType, type CommandByCategory, type CommandErrorMessageConfig, type CommandFilter, type CommandInternalRateLimitData, CommandManager, type CommandMetadata, type CommandPermissionResults, type CommandPermissions, type CommandRateLimitOptions, CommandType, ContextCommandBuilder, type ContextCommandConfig, ContextCommandManager, type CustomButton, type DatabaseManager, DynaSend, type DynaSendOptions, type EmbedResolvable, EventBuilder, type EventConfig, type EventDeployment, EventManager, type EventMetadata, type EventParameters, type EventRateLimitOptions, type ExtractReturn, type FetchedChannel, type FetchedMessageMention, type GetMessageMentionOptions, type InteractionBasedSendHandler, type InteractionResolveable, LOGGER_COLORS, type LeanOrHydratedDocument, type ListenerOptions, LogLevel, Logger, type LoggerOptions, type MentionType, MissingPermissionReason, type ModalSubmitResult, MongoDatabase, type MongoPlugin, MongoSchemaBuilder, type MongoSchemaOptions, type PageIndex, type PageResolvable, type PaginationEvent, PaginationTimeoutType, PaginationType, Paginator, type PaginatorData, type PaginatorOptions, PrefixCommandBuilder, type PrefixCommandConfig, PrefixCommandManager, Prompt, type PromptOptions, PromptResolveType, type PromptResult, RateLimitScope, type RequiredDynaSendOptions, type SendHandler, SendMethod, type SendableComponent, type SendableTextChannel, type SinglePageResolvable, SlashCommandBuilder, type SlashCommandConfig, SlashCommandManager, StatusManager, StatusType, type UserResolvable, Vimcord, type VimcordAppConfig, VimcordCLI, type VimcordCLIOptions, type VimcordClientStatus, type VimcordCommandBuilderByType, type VimcordConfig, type VimcordConfigOptions, type VimcordContextCommandConfig, type VimcordFeatures, type VimcordPrefixCommandConfig, type VimcordSlashCommandConfig, type VimcordStaffConfig, type VimcordToolsConfig, __zero, cleanMention, createClient, createMongoPlugin, createMongoSchema, createToolsConfig, createVimcordAppConfig, createVimcordContextCommandConfig, createVimcordPrefixCommandConfig, createVimcordSlashCommandConfig, createVimcordStaffConfig, createVimcordStatusConfig, defineGlobalToolsConfig, dynaSend, fetchChannel, fetchGuild, fetchMember, fetchMessage, fetchRole, fetchUser, getCallerFileName, getFirstMentionId, getMessageMention, getProcessDir, globalVimcordToolsConfig, importModulesFromDir, initCLI, isMentionOrSnowflake, logger, prompt, sendCommandErrorEmbed, useClient, useReadyClient, validateCommandPermissions };
2061
+ export { type AnySlashCommandBuilder, type AppCommandDeployment, type AppConfig, type AppModuleImports, type AwaitSubmitOptions, type BaseAppCommandConfig, BaseCommandBuilder, type BaseCommandConfig, BaseCommandManager, type BaseCommandParameters, type BetterChannelSelectComponent, BetterCollector, type BetterCollectorOptions, BetterContainer, type BetterContainerData, BetterEmbed, type BetterEmbedAuthor, type BetterEmbedContext, type BetterEmbedData, type BetterEmbedFooter, type BetterEmbedTitle, type BetterFileUploadSelectComponent, type BetterMentionableSelectComponent, BetterModal, type BetterModalComponent, type BetterModalOptions, type BetterRoleSelectComponent, type BetterStringSelectComponent, type BetterTextInputComponent, type BetterUserSelectComponent, type ButtonHandler, CLI, type Chapter, type ChapterData, type ClientActivity, type ClientStatus, CollectorTimeoutType, type CommandByCategory, type CommandErrorMessageConfig, type CommandFilter, type CommandInternalRateLimitData, CommandManager, type CommandMetadata, type CommandPermissionResults, type CommandPermissions, type CommandRateLimitOptions, CommandType, ContextCommandBuilder, type ContextCommandConfig, ContextCommandManager, type CustomButton, DEFAULT_MODULE_SUFFIXES, type DatabaseManager, DynaSend, type DynaSendOptions, type EmbedResolvable, ErrorHandler, EventBuilder, type EventConfig, type EventDeployment, EventManager, type EventMetadata, type EventParameters, type EventRateLimitOptions, type ExtractReturn, type FetchedChannel, type FetchedMessageMention, type GetMessageMentionOptions, type InteractionBasedSendHandler, type InteractionResolveable, LOGGER_COLORS, type LeanOrHydratedDocument, type ListenerOptions, LogLevel, Logger, type LoggerOptions, type MentionType, MissingPermissionReason, type ModalSubmitResult, type ModuleImportOptions, ModuleImporter, MongoDatabase, type MongoPlugin, MongoSchemaBuilder, type MongoSchemaOptions, type PageIndex, type PageResolvable, type PaginationEvent, PaginationTimeoutType, PaginationType, Paginator, type PaginatorData, type PaginatorOptions, PrefixCommandBuilder, type PrefixCommandConfig, PrefixCommandManager, Prompt, type PromptOptions, PromptResolveType, type PromptResult, RateLimitScope, type RequiredDynaSendOptions, type SendHandler, SendMethod, type SendableComponent, type SendableTextChannel, type SinglePageResolvable, SlashCommandBuilder, type SlashCommandConfig, SlashCommandManager, type StaffConfig, StatusManager, StatusType, type ToolsConfig, type UserResolvable, Vimcord, VimcordCLI, type VimcordCLIMode, type VimcordCLIOptions, type VimcordClientStatus, type VimcordCommandBuilderByType, type VimcordConfig, type VimcordCreateConfig, type VimcordFeatures, __zero, cleanMention, clientLoggerFactory, configSetters, contextCommandHandler, createAppConfig, createClient, createConfigFactory, createContextCommandConfig, createMongoPlugin, createMongoSchema, createPrefixCommandConfig, createSlashCommandConfig, createStaffConfig, createToolsConfig, createVimcordStatusConfig, defineClientOptions, defineGlobalToolsConfig, defineVimcordConfig, defineVimcordFeatures, dynaSend, fetchChannel, fetchGuild, fetchMember, fetchMessage, fetchRole, fetchUser, getDevMode, getFirstMentionId, getMessageMention, getPackageJson, getProcessDir, globalToolsConfig, importModulesFromDir, isMentionOrSnowflake, logger, moduleImporters, prefixCommandHandler, prompt, sendCommandErrorEmbed, slashCommandHandler, useClient, useReadyClient, validateCommandPermissions };