diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/common/Sentry.ts | 10 | ||||
-rw-r--r-- | src/lib/common/util/Arg.ts | 119 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts | 2 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushClient.ts | 9 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushClientUtil.ts | 2 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushCommand.ts | 51 | ||||
-rw-r--r-- | src/lib/extensions/discord.js/BushStoreChannel.ts | 1 | ||||
-rw-r--r-- | src/lib/extensions/global.d.ts | 1 |
8 files changed, 139 insertions, 56 deletions
diff --git a/src/lib/common/Sentry.ts b/src/lib/common/Sentry.ts index 1de09ac..119e205 100644 --- a/src/lib/common/Sentry.ts +++ b/src/lib/common/Sentry.ts @@ -1,12 +1,18 @@ +import { RewriteFrames } from '@sentry/integrations'; import * as SentryNode from '@sentry/node'; import config from './../../config/options.js'; export class Sentry { - public constructor() { + public constructor(rootdir: string) { SentryNode.init({ dsn: config.credentials.sentryDsn, environment: config.environment, - tracesSampleRate: 1.0 + tracesSampleRate: 1.0, + integrations: [ + new RewriteFrames({ + root: rootdir + }) + ] }); } } diff --git a/src/lib/common/util/Arg.ts b/src/lib/common/util/Arg.ts index 1982f4a..9ce8b54 100644 --- a/src/lib/common/util/Arg.ts +++ b/src/lib/common/util/Arg.ts @@ -1,4 +1,4 @@ -import { type BushArgumentType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BaseBushArgumentType, BushArgumentTypeCaster, BushSlashMessage, type BushArgumentType } from '#lib'; import { Argument, type ArgumentTypeCaster, type Flag, type ParsedValuePredicate } from 'discord-akairo'; import { type Message } from 'discord.js'; @@ -9,12 +9,16 @@ export class Arg { * @param message - Message that called the command. * @param phrase - Phrase to process. */ - public static cast( - type: BushArgumentType | ArgumentTypeCaster, - message: BushMessage | BushSlashMessage, - phrase: string - ): Promise<any> { - return Argument.cast(type, client.commandHandler.resolver, message as Message, phrase); + public static async cast<T extends ATC>(type: T, message: Message | BushSlashMessage, phrase: string): Promise<ATCR<T>>; + public static async cast<T extends KBAT>(type: T, message: Message | BushSlashMessage, phrase: string): Promise<BAT[T]>; + public static async cast<T extends AT | ATC>(type: T, message: Message | BushSlashMessage, phrase: string): Promise<any>; + public static async cast(type: ATC | AT, message: Message | BushSlashMessage, phrase: string): Promise<any> { + return Argument.cast( + type as ArgumentTypeCaster | keyof BushArgumentType, + client.commandHandler.resolver, + message as Message, + phrase + ); } /** @@ -22,8 +26,11 @@ export class Arg { * If any of the types fails, the entire composition fails. * @param types - Types to use. */ - public static compose(...types: BushArgumentType[]): ArgumentTypeCaster { - return Argument.compose(...types); + public static compose<T extends ATC>(...types: T[]): ATCATCR<T>; + public static compose<T extends KBAT>(...types: T[]): ATCBAT<T>; + public static compose<T extends AT | ATC>(...types: T[]): ATC; + public static compose(...types: (AT | ATC)[]): ATC { + return Argument.compose(...(types as any)); } /** @@ -31,8 +38,11 @@ export class Arg { * If any of the types fails, the composition still continues with the failure passed on. * @param types - Types to use. */ - public static composeWithFailure(...types: BushArgumentType[]): ArgumentTypeCaster { - return Argument.composeWithFailure(...types); + public static composeWithFailure<T extends ATC>(...types: T[]): ATCATCR<T>; + public static composeWithFailure<T extends KBAT>(...types: T[]): ATCBAT<T>; + public static composeWithFailure<T extends AT | ATC>(...types: T[]): ATC; + public static composeWithFailure(...types: (AT | ATC)[]): ATC { + return Argument.composeWithFailure(...(types as any)); } /** @@ -48,8 +58,11 @@ export class Arg { * Only inputs where each type resolves with a non-void value are valid. * @param types - Types to use. */ - public static product(...types: BushArgumentType[]): ArgumentTypeCaster { - return Argument.product(...types); + public static product<T extends ATC>(...types: T[]): ATCATCR<T>; + public static product<T extends KBAT>(...types: T[]): ATCBAT<T>; + public static product<T extends AT | ATC>(...types: T[]): ATC; + public static product(...types: (AT | ATC)[]): ATC { + return Argument.product(...(types as any)); } /** @@ -59,8 +72,11 @@ export class Arg { * @param max - Maximum value. * @param inclusive - Whether or not to be inclusive on the upper bound. */ - public static range(type: BushArgumentType, min: number, max: number, inclusive?: boolean): ArgumentTypeCaster { - return Argument.range(type, min, max, inclusive); + public static range<T extends ATC>(type: T, min: number, max: number, inclusive?: boolean): ATCATCR<T>; + public static range<T extends KBAT>(type: T, min: number, max: number, inclusive?: boolean): ATCBAT<T>; + public static range<T extends AT | ATC>(type: T, min: number, max: number, inclusive?: boolean): ATC; + public static range(type: AT | ATC, min: number, max: number, inclusive?: boolean): ATC { + return Argument.range(type as any, min, max, inclusive); } /** @@ -69,8 +85,11 @@ export class Arg { * @param type - The type to use. * @param tag - Tag to add. Defaults to the `type` argument, so useful if it is a string. */ - public static tagged(type: BushArgumentType, tag?: any): ArgumentTypeCaster { - return Argument.tagged(type, tag); + public static tagged<T extends ATC>(type: T, tag?: any): ATCATCR<T>; + public static tagged<T extends KBAT>(type: T, tag?: any): ATCBAT<T>; + public static tagged<T extends AT | ATC>(type: T, tag?: any): ATC; + public static tagged(type: AT | ATC, tag?: any): ATC { + return Argument.tagged(type as any, tag); } /** @@ -79,8 +98,11 @@ export class Arg { * Each type will also be tagged using `tagged` with themselves. * @param types - Types to use. */ - public static taggedUnion(...types: BushArgumentType[]): ArgumentTypeCaster { - return Argument.taggedUnion(...types); + public static taggedUnion<T extends ATC>(...types: T[]): ATCATCR<T>; + public static taggedUnion<T extends KBAT>(...types: T[]): ATCBAT<T>; + public static taggedUnion<T extends AT | ATC>(...types: T[]): ATC; + public static taggedUnion(...types: (AT | ATC)[]): ATC { + return Argument.taggedUnion(...(types as any)); } /** @@ -89,8 +111,11 @@ export class Arg { * @param type - The type to use. * @param tag - Tag to add. Defaults to the `type` argument, so useful if it is a string. */ - public static taggedWithInput(type: BushArgumentType, tag?: any): ArgumentTypeCaster { - return Argument.taggedWithInput(type, tag); + public static taggedWithInput<T extends ATC>(type: T, tag?: any): ATCATCR<T>; + public static taggedWithInput<T extends KBAT>(type: T, tag?: any): ATCBAT<T>; + public static taggedWithInput<T extends AT | ATC>(type: T, tag?: any): ATC; + public static taggedWithInput(type: AT | ATC, tag?: any): ATC { + return Argument.taggedWithInput(type as any, tag); } /** @@ -98,8 +123,11 @@ export class Arg { * The first type that resolves to a non-void value is used. * @param types - Types to use. */ - public static union(...types: BushArgumentType[]): ArgumentTypeCaster { - return Argument.union(...types); + public static union<T extends ATC>(...types: T[]): ATCATCR<T>; + public static union<T extends KBAT>(...types: T[]): ATCBAT<T>; + public static union<T extends AT | ATC>(...types: T[]): ATC; + public static union(...types: (AT | ATC)[]): ATC { + return Argument.union(...(types as any)); } /** @@ -108,8 +136,11 @@ export class Arg { * @param type - The type to use. * @param predicate - The predicate function. */ - public static validate(type: BushArgumentType, predicate: ParsedValuePredicate): ArgumentTypeCaster { - return Argument.validate(type, predicate); + public static validate<T extends ATC>(type: T, predicate: ParsedValuePredicate): ATCATCR<T>; + public static validate<T extends KBAT>(type: T, predicate: ParsedValuePredicate): ATCBAT<T>; + public static validate<T extends AT | ATC>(type: T, predicate: ParsedValuePredicate): ATC; + public static validate(type: AT | ATC, predicate: ParsedValuePredicate): ATC { + return Argument.validate(type as any, predicate); } /** @@ -117,7 +148,41 @@ export class Arg { * Result is in an object `{ input, value }` and wrapped in `Flag.fail` when failed. * @param type - The type to use. */ - public static withInput(type: BushArgumentType): ArgumentTypeCaster { - return Argument.withInput(type); + public static withInput<T extends ATC>(type: T): ATC<ATCR<T>>; + public static withInput<T extends KBAT>(type: T): ATCBAT<T>; + public static withInput<T extends AT | ATC>(type: T): ATC; + public static withInput(type: AT | ATC): ATC { + return Argument.withInput(type as any); } } + +type ArgumentTypeCasterReturn<R> = R extends BushArgumentTypeCaster<infer S> ? S : R; +/** ```ts + * <R = unknown> = ArgumentTypeCaster<R> + * ``` */ +type ATC<R = unknown> = BushArgumentTypeCaster<R>; +/** ```ts + * keyof BaseArgumentType + * ``` */ +type KBAT = keyof BaseBushArgumentType; +/** ```ts + * <R> = ArgumentTypeCasterReturn<R> + * ``` */ +type ATCR<R> = ArgumentTypeCasterReturn<R>; +/** ```ts + * keyof BaseBushArgumentType | string + * ``` */ +type AT = BushArgumentTypeCaster | keyof BaseBushArgumentType | string; +/** ```ts + * BaseArgumentType + * ``` */ +type BAT = BaseBushArgumentType; + +/** ```ts + * <T extends ArgumentTypeCaster> = ArgumentTypeCaster<ArgumentTypeCasterReturn<T>> + * ``` */ +type ATCATCR<T extends BushArgumentTypeCaster> = BushArgumentTypeCaster<ArgumentTypeCasterReturn<T>>; +/** ```ts + * <T extends keyof BaseArgumentType> = ArgumentTypeCaster<BaseArgumentType[T]> + * ``` */ +type ATCBAT<T extends keyof BaseBushArgumentType> = BushArgumentTypeCaster<BaseBushArgumentType[T]>; diff --git a/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts b/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts index f27fb89..7a9a3db 100644 --- a/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts +++ b/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts @@ -1,3 +1,3 @@ import { type BushMessage } from '#lib'; -export type BushArgumentTypeCaster = (message: BushMessage, phrase: string) => any; +export type BushArgumentTypeCaster<R = unknown> = (message: BushMessage, phrase: string) => R; diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts index e5ce7be..a9e172a 100644 --- a/src/lib/extensions/discord-akairo/BushClient.ts +++ b/src/lib/extensions/discord-akairo/BushClient.ts @@ -187,8 +187,8 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re prefix: async ({ guild }: Message) => { if (this.config.isDevelopment) return 'dev '; if (!guild) return this.config.prefix; - const row = await GuildModel.findByPk(guild.id); - return (row?.prefix ?? this.config.prefix) as string; + const prefix = await (guild as BushGuild).getSetting('prefix'); + return (prefix ?? this.config.prefix) as string; }, allowMention: true, handleEdits: true, @@ -348,7 +348,10 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re * Starts the bot */ public async start() { - void this.logger.success('version', process.version, false); + if (!process.version.startsWith('v17.')) { + void (await this.console.error('version', `Please use node <<v17.x.x>>, not <<${process.version}>>.`, false)); + process.exit(2); + } this.intercept('ready', async (arg, done) => { await this.guilds.fetch(); const promises = this.guilds.cache.map((guild) => { diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts index cded096..ab1f3ed 100644 --- a/src/lib/extensions/discord-akairo/BushClientUtil.ts +++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts @@ -112,7 +112,7 @@ export class BushClientUtil extends ClientUtil { void this.handleError('haste', new Error(`content over 400,000 characters (${content.length.toLocaleString()})`)); return { error: 'content too long' }; } else if (content.length > 400_000) { - content = content.substr(0, 400_000); + content = content.substring(0, 400_000); isSubstr = true; } for (const url of this.#hasteURLs) { diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts index d8f0d38..5111c19 100644 --- a/src/lib/extensions/discord-akairo/BushCommand.ts +++ b/src/lib/extensions/discord-akairo/BushCommand.ts @@ -1,4 +1,12 @@ -import { type BushClient, type BushCommandHandler, type BushMessage, type BushSlashMessage } from '#lib'; +import { + BushArgumentTypeCaster, + BushUser, + ParsedDuration, + type BushClient, + type BushCommandHandler, + type BushMessage, + type BushSlashMessage +} from '#lib'; import { AkairoApplicationCommandAutocompleteOption, AkairoApplicationCommandChannelOptionData, @@ -13,25 +21,26 @@ import { SlashOption, SlashResolveTypes, type ArgumentOptions, - type ArgumentTypeCaster, type CommandOptions } from 'discord-akairo'; -import { BaseArgumentType } from 'discord-akairo/dist/src/struct/commands/arguments/Argument'; -import { ApplicationCommandOptionChoice, type PermissionResolvable, type Snowflake } from 'discord.js'; - -export type BaseBushArgumentType = - | BaseArgumentType - | 'duration' - | 'contentWithDuration' - | 'permission' - | 'snowflake' - | 'discordEmoji' - | 'roleWithDuration' - | 'abbreviatedNumber' - | 'globalUser' - | 'messageLink'; - -export type BushArgumentType = BaseBushArgumentType | RegExp; +import { ArgumentType, ArgumentTypeCaster, BaseArgumentType } from 'discord-akairo/dist/src/struct/commands/arguments/Argument'; +import { ApplicationCommandOptionChoice, PermissionString, type PermissionResolvable, type Snowflake } from 'discord.js'; +import { DiscordEmojiInfo } from '../../../arguments/discordEmoji'; +import { RoleWithDuration } from '../../../arguments/roleWithDuration'; + +export interface BaseBushArgumentType extends BaseArgumentType { + duration: number | null; + contentWithDuration: ParsedDuration; + permission: PermissionString | null; + snowflake: Snowflake | null; + discordEmoji: DiscordEmojiInfo | null; + roleWithDuration: RoleWithDuration | null; + abbreviatedNumber: number | null; + globalUser: BushUser | null; + messageLink: BushMessage | null; +} + +export type BushArgumentType = keyof BaseBushArgumentType | RegExp; interface BaseBushArgumentOptions extends Omit<ArgumentOptions, 'type' | 'prompt'> { id: string; @@ -149,7 +158,7 @@ export interface BushArgumentOptions extends BaseBushArgumentOptions { * - `contentWithDuration` tries to parse duration in milliseconds and returns the remaining content with the duration * removed */ - type?: BushArgumentType | BaseBushArgumentType[]; + type?: BushArgumentType | (keyof BaseBushArgumentType)[] | BushArgumentTypeCaster; } export interface CustomBushArgumentOptions extends BaseBushArgumentOptions { /** @@ -160,7 +169,7 @@ export interface CustomBushArgumentOptions extends BaseBushArgumentOptions { * A regular expression can also be used. * The evaluated argument will be an object containing the `match` and `matches` if global. */ - customType?: ArgumentTypeCaster | (string | string[])[] | RegExp | string | null; + customType?: (string | string[])[] | RegExp | string | null; } export type BushMissingPermissionSupplier = (message: BushMessage | BushSlashMessage) => Promise<any> | any; @@ -344,7 +353,7 @@ export class BushCommand extends Command { if ('retry' in arg) newArg.prompt.retry = arg.retry; if ('optional' in arg) newArg.prompt.optional = arg.optional; } - if ('type' in arg) newArg.type = arg.type; + if ('type' in arg) newArg.type = arg.type as ArgumentType | ArgumentTypeCaster; if ('unordered' in arg) newArg.unordered = arg.unordered; newTextArgs.push(newArg); } diff --git a/src/lib/extensions/discord.js/BushStoreChannel.ts b/src/lib/extensions/discord.js/BushStoreChannel.ts index 8540936..918c27b 100644 --- a/src/lib/extensions/discord.js/BushStoreChannel.ts +++ b/src/lib/extensions/discord.js/BushStoreChannel.ts @@ -2,6 +2,7 @@ import type { BushCategoryChannel, BushClient, BushGuild, BushGuildMember } from import { StoreChannel, type Collection, type Snowflake } from 'discord.js'; import type { RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; +// eslint-disable-next-line deprecation/deprecation export class BushStoreChannel extends StoreChannel { public declare guild: BushGuild; public declare readonly members: Collection<Snowflake, BushGuildMember>; diff --git a/src/lib/extensions/global.d.ts b/src/lib/extensions/global.d.ts index 8427873..1df86bb 100644 --- a/src/lib/extensions/global.d.ts +++ b/src/lib/extensions/global.d.ts @@ -3,7 +3,6 @@ import type { BushClient, BushClientUtil } from '#lib'; declare global { var client: BushClient; var util: BushClientUtil; - var __rootdir__: string; // eslint-disable-next-line @typescript-eslint/no-unused-vars interface ReadonlyArray<T> { |