mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-04 22:16:08 +00:00
feat: optimize code & implement onRunError and onStopError in collectors & use Promise.all
This commit is contained in:
parent
3850ef38a6
commit
d2157e7324
140
src/cache/resources/members.ts
vendored
140
src/cache/resources/members.ts
vendored
@ -1,70 +1,70 @@
|
|||||||
import type { APIGuildMember } from 'discord-api-types/v10';
|
import type { APIGuildMember } from 'discord-api-types/v10';
|
||||||
import type { ReturnCache } from '../..';
|
import type { ReturnCache } from '../..';
|
||||||
import { fakePromise } from '../../common';
|
import { fakePromise } from '../../common';
|
||||||
import { GuildMember } from '../../structures';
|
import { GuildMember } from '../../structures';
|
||||||
import { GuildBasedResource } from './default/guild-based';
|
import { GuildBasedResource } from './default/guild-based';
|
||||||
export class Members extends GuildBasedResource {
|
export class Members extends GuildBasedResource {
|
||||||
namespace = 'member';
|
namespace = 'member';
|
||||||
|
|
||||||
//@ts-expect-error
|
//@ts-expect-error
|
||||||
filter(data: APIGuildMember, id: string, guild_id: string) {
|
filter(data: APIGuildMember, id: string, guild_id: string) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
override parse(data: any, key: string, guild_id: string) {
|
override parse(data: any, key: string, guild_id: string) {
|
||||||
const { user, ...rest } = super.parse(data, data.user?.id ?? key, guild_id);
|
const { user, ...rest } = super.parse(data, data.user?.id ?? key, guild_id);
|
||||||
return rest;
|
return rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
override get(id: string, guild: string): ReturnCache<GuildMember | undefined> {
|
override get(id: string, guild: string): ReturnCache<GuildMember | undefined> {
|
||||||
return fakePromise(super.get(id, guild)).then(rawMember =>
|
return fakePromise(super.get(id, guild)).then(rawMember =>
|
||||||
fakePromise(this.client.cache.users?.get(id)).then(user =>
|
fakePromise(this.client.cache.users?.get(id)).then(user =>
|
||||||
rawMember && user ? new GuildMember(this.client, rawMember, user, guild) : undefined,
|
rawMember && user ? new GuildMember(this.client, rawMember, user, guild) : undefined,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override bulk(ids: string[], guild: string): ReturnCache<GuildMember[]> {
|
override bulk(ids: string[], guild: string): ReturnCache<GuildMember[]> {
|
||||||
return fakePromise(super.bulk(ids, guild)).then(members =>
|
return fakePromise(super.bulk(ids, guild)).then(members =>
|
||||||
fakePromise(this.client.cache.users?.bulk(ids) ?? []).then(
|
fakePromise(this.client.cache.users?.bulk(ids)).then(
|
||||||
users =>
|
users =>
|
||||||
members
|
members
|
||||||
.map(rawMember => {
|
.map(rawMember => {
|
||||||
const user = users.find(x => x.id === rawMember.id);
|
const user = users?.find(x => x.id === rawMember.id);
|
||||||
return user ? new GuildMember(this.client, rawMember, user, guild) : undefined;
|
return user ? new GuildMember(this.client, rawMember, user, guild) : undefined;
|
||||||
})
|
})
|
||||||
.filter(Boolean) as GuildMember[],
|
.filter(Boolean) as GuildMember[],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override values(guild: string): ReturnCache<GuildMember[]> {
|
override values(guild: string): ReturnCache<GuildMember[]> {
|
||||||
return fakePromise(super.values(guild)).then(members =>
|
return fakePromise(super.values(guild)).then(members =>
|
||||||
fakePromise(this.client.cache.users?.values() ?? []).then(
|
fakePromise(this.client.cache.users?.values()).then(
|
||||||
users =>
|
users =>
|
||||||
members
|
members
|
||||||
.map(rawMember => {
|
.map(rawMember => {
|
||||||
const user = users.find(x => x.id === rawMember.id);
|
const user = users?.find(x => x.id === rawMember.id);
|
||||||
return user ? new GuildMember(this.client, rawMember, user, rawMember.guild_id) : undefined;
|
return user ? new GuildMember(this.client, rawMember, user, rawMember.guild_id) : undefined;
|
||||||
})
|
})
|
||||||
.filter(Boolean) as GuildMember[],
|
.filter(Boolean) as GuildMember[],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async set(memberId: string, guildId: string, data: any): Promise<void>;
|
override async set(memberId: string, guildId: string, data: any): Promise<void>;
|
||||||
override async set(memberId_dataArray: [string, any][], guildId: string): Promise<void>;
|
override async set(memberId_dataArray: [string, any][], guildId: string): Promise<void>;
|
||||||
override async set(__keys: string | [string, any][], guild: string, data?: any) {
|
override async set(__keys: string | [string, any][], guild: string, data?: any) {
|
||||||
const keys: [string, any][] = Array.isArray(__keys) ? __keys : [[__keys, data]];
|
const keys: [string, any][] = Array.isArray(__keys) ? __keys : [[__keys, data]];
|
||||||
const bulkData: (['members', any, string, string] | ['users', any, string])[] = [];
|
const bulkData: (['members', any, string, string] | ['users', any, string])[] = [];
|
||||||
|
|
||||||
for (const [id, value] of keys) {
|
for (const [id, value] of keys) {
|
||||||
if (value.user) {
|
if (value.user) {
|
||||||
bulkData.push(['members', value, id, guild]);
|
bulkData.push(['members', value, id, guild]);
|
||||||
bulkData.push(['users', value.user, id]);
|
bulkData.push(['users', value.user, id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.cache.bulkSet(bulkData);
|
await this.cache.bulkSet(bulkData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,99 +1,115 @@
|
|||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import type { Awaitable, CamelCase, SnakeCase } from '../common';
|
import type { Awaitable, CamelCase, SnakeCase } from '../common';
|
||||||
import type { ClientNameEvents, GatewayEvents } from '../events';
|
import type { ClientNameEvents, GatewayEvents } from '../events';
|
||||||
import type { ClientEvents } from '../events/hooks';
|
import type { ClientEvents } from '../events/hooks';
|
||||||
|
import { error } from 'node:console';
|
||||||
type SnakeCaseClientNameEvents = Uppercase<SnakeCase<ClientNameEvents>>;
|
|
||||||
|
type SnakeCaseClientNameEvents = Uppercase<SnakeCase<ClientNameEvents>>;
|
||||||
type RunData<T extends SnakeCaseClientNameEvents> = {
|
|
||||||
options: {
|
type RunData<T extends SnakeCaseClientNameEvents> = {
|
||||||
event: T;
|
options: {
|
||||||
idle?: number;
|
event: T;
|
||||||
timeout?: number;
|
idle?: number;
|
||||||
onStop?: (reason: string) => unknown;
|
timeout?: number;
|
||||||
filter: (arg: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>) => Awaitable<boolean>;
|
onStop?: (reason: string) => unknown;
|
||||||
run: (arg: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>, stop: (reason?: string) => void) => unknown;
|
onStopError?: (reason: string, error: unknown) => unknown;
|
||||||
};
|
filter: (arg: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>) => Awaitable<boolean>;
|
||||||
idle?: NodeJS.Timeout;
|
run: (arg: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>, stop: (reason?: string) => void) => unknown;
|
||||||
timeout?: NodeJS.Timeout;
|
onRunError?: (
|
||||||
nonce: string;
|
arg: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>,
|
||||||
};
|
error: unknown,
|
||||||
|
stop: (reason?: string) => void,
|
||||||
export class Collectors {
|
) => unknown;
|
||||||
readonly values = new Map<SnakeCaseClientNameEvents, RunData<any>[]>();
|
};
|
||||||
|
idle?: NodeJS.Timeout;
|
||||||
private generateRandomUUID(name: SnakeCaseClientNameEvents) {
|
timeout?: NodeJS.Timeout;
|
||||||
const collectors = this.values.get(name);
|
nonce: string;
|
||||||
if (!collectors) return '*';
|
};
|
||||||
|
|
||||||
let nonce = randomUUID();
|
export class Collectors {
|
||||||
|
readonly values = new Map<SnakeCaseClientNameEvents, RunData<any>[]>();
|
||||||
while (collectors.find(x => x.nonce === nonce)) {
|
|
||||||
nonce = randomUUID();
|
private generateRandomUUID(name: SnakeCaseClientNameEvents) {
|
||||||
}
|
const collectors = this.values.get(name);
|
||||||
|
if (!collectors) return '*';
|
||||||
return nonce;
|
|
||||||
}
|
let nonce = randomUUID();
|
||||||
|
|
||||||
create<T extends SnakeCaseClientNameEvents>(options: RunData<T>['options']) {
|
while (collectors.find(x => x.nonce === nonce)) {
|
||||||
if (!this.values.has(options.event)) {
|
nonce = randomUUID();
|
||||||
this.values.set(options.event, []);
|
}
|
||||||
}
|
|
||||||
|
return nonce;
|
||||||
const nonce = this.generateRandomUUID(options.event);
|
}
|
||||||
|
|
||||||
this.values.get(options.event)!.push({
|
create<T extends SnakeCaseClientNameEvents>(options: RunData<T>['options']) {
|
||||||
options: {
|
if (!this.values.has(options.event)) {
|
||||||
...options,
|
this.values.set(options.event, []);
|
||||||
name: options.event,
|
}
|
||||||
} as RunData<any>['options'],
|
|
||||||
idle:
|
const nonce = this.generateRandomUUID(options.event);
|
||||||
options.idle && options.idle > 0
|
|
||||||
? setTimeout(() => {
|
this.values.get(options.event)!.push({
|
||||||
return this.delete(options.event, nonce, 'idle');
|
options: {
|
||||||
}, options.idle)
|
...options,
|
||||||
: undefined,
|
name: options.event,
|
||||||
timeout:
|
} as RunData<any>['options'],
|
||||||
options.timeout && options.timeout > 0
|
idle:
|
||||||
? setTimeout(() => {
|
options.idle && options.idle > 0
|
||||||
return this.delete(options.event, nonce, 'timeout');
|
? setTimeout(() => {
|
||||||
}, options.timeout)
|
return this.delete(options.event, nonce, 'idle');
|
||||||
: undefined,
|
}, options.idle)
|
||||||
nonce,
|
: undefined,
|
||||||
});
|
timeout:
|
||||||
return options;
|
options.timeout && options.timeout > 0
|
||||||
}
|
? setTimeout(() => {
|
||||||
|
return this.delete(options.event, nonce, 'timeout');
|
||||||
private delete(name: SnakeCaseClientNameEvents, nonce: string, reason = 'unknown') {
|
}, options.timeout)
|
||||||
const collectors = this.values.get(name);
|
: undefined,
|
||||||
|
nonce,
|
||||||
if (!collectors?.length) {
|
});
|
||||||
if (collectors) this.values.delete(name);
|
return options;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
private async delete(name: SnakeCaseClientNameEvents, nonce: string, reason = 'unknown') {
|
||||||
const index = collectors.findIndex(x => x.nonce === nonce);
|
const collectors = this.values.get(name);
|
||||||
if (index === -1) return;
|
|
||||||
const collector = collectors[index];
|
if (!collectors?.length) {
|
||||||
clearTimeout(collector.idle);
|
if (collectors) this.values.delete(name);
|
||||||
clearTimeout(collector.timeout);
|
return;
|
||||||
collectors.splice(index, 1);
|
}
|
||||||
return collector.options.onStop?.(reason);
|
|
||||||
}
|
const index = collectors.findIndex(x => x.nonce === nonce);
|
||||||
|
if (index === -1) return;
|
||||||
/**@internal */
|
const collector = collectors[index];
|
||||||
async run<T extends GatewayEvents>(name: T, data: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>) {
|
clearTimeout(collector.idle);
|
||||||
const collectors = this.values.get(name);
|
clearTimeout(collector.timeout);
|
||||||
if (!collectors) return;
|
collectors.splice(index, 1);
|
||||||
|
try {
|
||||||
for (const i of collectors) {
|
await collector.options.onStop?.(reason);
|
||||||
if (await i.options.filter(data)) {
|
} catch (e) {
|
||||||
i.idle?.refresh();
|
await collector.options.onStopError?.(reason, error);
|
||||||
await i.options.run(data, (reason = 'unknown') => {
|
}
|
||||||
return this.delete(i.options.event, i.nonce, reason);
|
}
|
||||||
});
|
|
||||||
break;
|
/**@internal */
|
||||||
}
|
async run<T extends GatewayEvents>(name: T, data: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>) {
|
||||||
}
|
const collectors = this.values.get(name);
|
||||||
}
|
if (!collectors) return;
|
||||||
}
|
|
||||||
|
for (const i of collectors) {
|
||||||
|
if (await i.options.filter(data)) {
|
||||||
|
i.idle?.refresh();
|
||||||
|
const stop = (reason = 'unknown') => {
|
||||||
|
return this.delete(i.options.event, i.nonce, reason);
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
await i.options.run(data, stop);
|
||||||
|
} catch (e) {
|
||||||
|
await i.options.onRunError?.(data, e, stop);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,362 +1,361 @@
|
|||||||
import {
|
import {
|
||||||
ApplicationCommandOptionType,
|
ApplicationCommandOptionType,
|
||||||
ApplicationCommandType,
|
ApplicationCommandType,
|
||||||
type ApplicationIntegrationType,
|
type ApplicationIntegrationType,
|
||||||
type InteractionContextType,
|
type InteractionContextType,
|
||||||
type APIApplicationCommandBasicOption,
|
type APIApplicationCommandBasicOption,
|
||||||
type APIApplicationCommandOption,
|
type APIApplicationCommandOption,
|
||||||
type APIApplicationCommandSubcommandGroupOption,
|
type APIApplicationCommandSubcommandGroupOption,
|
||||||
type LocaleString,
|
type LocaleString,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import type {
|
import type {
|
||||||
ComponentContext,
|
ComponentContext,
|
||||||
MenuCommandContext,
|
MenuCommandContext,
|
||||||
ModalContext,
|
ModalContext,
|
||||||
PermissionStrings,
|
PermissionStrings,
|
||||||
SeyfertNumberOption,
|
SeyfertNumberOption,
|
||||||
SeyfertStringOption,
|
SeyfertStringOption,
|
||||||
} from '../..';
|
} from '../..';
|
||||||
import type { Attachment } from '../../builders';
|
import type { Attachment } from '../../builders';
|
||||||
import { magicImport, type FlatObjectKeys } from '../../common';
|
import { magicImport, type FlatObjectKeys } from '../../common';
|
||||||
import type { AllChannels, AutocompleteInteraction, GuildRole, InteractionGuildMember, User } from '../../structures';
|
import type { AllChannels, AutocompleteInteraction, GuildRole, InteractionGuildMember, User } from '../../structures';
|
||||||
import type { Groups, RegisteredMiddlewares } from '../decorators';
|
import type { Groups, RegisteredMiddlewares } from '../decorators';
|
||||||
import type { OptionResolver } from '../optionresolver';
|
import type { OptionResolver } from '../optionresolver';
|
||||||
import type { CommandContext } from './chatcontext';
|
import type { CommandContext } from './chatcontext';
|
||||||
import type {
|
import type {
|
||||||
DefaultLocale,
|
DefaultLocale,
|
||||||
IgnoreCommand,
|
IgnoreCommand,
|
||||||
OKFunction,
|
OKFunction,
|
||||||
OnOptionsReturnObject,
|
OnOptionsReturnObject,
|
||||||
PassFunction,
|
PassFunction,
|
||||||
StopFunction,
|
StopFunction,
|
||||||
UsingClient,
|
UsingClient,
|
||||||
} from './shared';
|
} from './shared';
|
||||||
|
|
||||||
export interface ReturnOptionsTypes {
|
export interface ReturnOptionsTypes {
|
||||||
1: never; // subcommand
|
1: never; // subcommand
|
||||||
2: never; // subcommandgroup
|
2: never; // subcommandgroup
|
||||||
3: string;
|
3: string;
|
||||||
4: number; // integer
|
4: number; // integer
|
||||||
5: boolean;
|
5: boolean;
|
||||||
6: InteractionGuildMember | User;
|
6: InteractionGuildMember | User;
|
||||||
7: AllChannels;
|
7: AllChannels;
|
||||||
8: GuildRole;
|
8: GuildRole;
|
||||||
9: GuildRole | AllChannels | User;
|
9: GuildRole | AllChannels | User;
|
||||||
10: number; // number
|
10: number; // number
|
||||||
11: Attachment;
|
11: Attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Wrap<N extends ApplicationCommandOptionType> = N extends
|
type Wrap<N extends ApplicationCommandOptionType> = N extends
|
||||||
| ApplicationCommandOptionType.Subcommand
|
| ApplicationCommandOptionType.Subcommand
|
||||||
| ApplicationCommandOptionType.SubcommandGroup
|
| ApplicationCommandOptionType.SubcommandGroup
|
||||||
? never
|
? never
|
||||||
: {
|
: {
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
value?(
|
value?(
|
||||||
data: { context: CommandContext; value: ReturnOptionsTypes[N] },
|
data: { context: CommandContext; value: ReturnOptionsTypes[N] },
|
||||||
ok: OKFunction<any>,
|
ok: OKFunction<any>,
|
||||||
fail: StopFunction,
|
fail: StopFunction,
|
||||||
): void;
|
): void;
|
||||||
} & {
|
} & {
|
||||||
description: string;
|
description: string;
|
||||||
description_localizations?: APIApplicationCommandBasicOption['description_localizations'];
|
description_localizations?: APIApplicationCommandBasicOption['description_localizations'];
|
||||||
name_localizations?: APIApplicationCommandBasicOption['name_localizations'];
|
name_localizations?: APIApplicationCommandBasicOption['name_localizations'];
|
||||||
locales?: {
|
locales?: {
|
||||||
name?: FlatObjectKeys<DefaultLocale>;
|
name?: FlatObjectKeys<DefaultLocale>;
|
||||||
description?: FlatObjectKeys<DefaultLocale>;
|
description?: FlatObjectKeys<DefaultLocale>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type __TypeWrapper<T extends ApplicationCommandOptionType> = Wrap<T>;
|
export type __TypeWrapper<T extends ApplicationCommandOptionType> = Wrap<T>;
|
||||||
|
|
||||||
export type __TypesWrapper = {
|
export type __TypesWrapper = {
|
||||||
[P in keyof typeof ApplicationCommandOptionType]: `${(typeof ApplicationCommandOptionType)[P]}` extends `${infer D extends
|
[P in keyof typeof ApplicationCommandOptionType]: `${(typeof ApplicationCommandOptionType)[P]}` extends `${infer D extends
|
||||||
number}`
|
number}`
|
||||||
? Wrap<D>
|
? Wrap<D>
|
||||||
: never;
|
: never;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AutocompleteCallback = (interaction: AutocompleteInteraction) => any;
|
export type AutocompleteCallback = (interaction: AutocompleteInteraction) => any;
|
||||||
export type OnAutocompleteErrorCallback = (interaction: AutocompleteInteraction, error: unknown) => any;
|
export type OnAutocompleteErrorCallback = (interaction: AutocompleteInteraction, error: unknown) => any;
|
||||||
export type CommandBaseOption = __TypesWrapper[keyof __TypesWrapper];
|
export type CommandBaseOption = __TypesWrapper[keyof __TypesWrapper];
|
||||||
export type CommandBaseAutocompleteOption = __TypesWrapper[keyof __TypesWrapper] & {
|
export type CommandBaseAutocompleteOption = __TypesWrapper[keyof __TypesWrapper] & {
|
||||||
autocomplete: AutocompleteCallback;
|
autocomplete: AutocompleteCallback;
|
||||||
onAutocompleteError?: OnAutocompleteErrorCallback;
|
onAutocompleteError?: OnAutocompleteErrorCallback;
|
||||||
};
|
};
|
||||||
export type CommandAutocompleteOption = CommandBaseAutocompleteOption & { name: string };
|
export type CommandAutocompleteOption = CommandBaseAutocompleteOption & { name: string };
|
||||||
export type __CommandOption = CommandBaseOption; //| CommandBaseAutocompleteOption;
|
export type __CommandOption = CommandBaseOption; //| CommandBaseAutocompleteOption;
|
||||||
export type CommandOption = __CommandOption & { name: string };
|
export type CommandOption = __CommandOption & { name: string };
|
||||||
export type OptionsRecord = Record<string, __CommandOption & { type: ApplicationCommandOptionType }>;
|
export type OptionsRecord = Record<string, __CommandOption & { type: ApplicationCommandOptionType }>;
|
||||||
|
|
||||||
type KeysWithoutRequired<T extends OptionsRecord> = {
|
type KeysWithoutRequired<T extends OptionsRecord> = {
|
||||||
[K in keyof T]-?: T[K]['required'] extends true ? never : K;
|
[K in keyof T]-?: T[K]['required'] extends true ? never : K;
|
||||||
}[keyof T];
|
}[keyof T];
|
||||||
|
|
||||||
type ContextOptionsAux<T extends OptionsRecord> = {
|
type ContextOptionsAux<T extends OptionsRecord> = {
|
||||||
[K in Exclude<keyof T, KeysWithoutRequired<T>>]: T[K]['value'] extends (...args: any) => any
|
[K in Exclude<keyof T, KeysWithoutRequired<T>>]: T[K]['value'] extends (...args: any) => any
|
||||||
? Parameters<Parameters<T[K]['value']>[1]>[0]
|
? Parameters<Parameters<T[K]['value']>[1]>[0]
|
||||||
: T[K] extends SeyfertStringOption | SeyfertNumberOption
|
: T[K] extends SeyfertStringOption | SeyfertNumberOption
|
||||||
? T[K]['choices'] extends NonNullable<SeyfertStringOption['choices'] | SeyfertNumberOption['choices']>
|
? T[K]['choices'] extends NonNullable<SeyfertStringOption['choices'] | SeyfertNumberOption['choices']>
|
||||||
? T[K]['choices'][number]['value']
|
? T[K]['choices'][number]['value']
|
||||||
: ReturnOptionsTypes[T[K]['type']]
|
: ReturnOptionsTypes[T[K]['type']]
|
||||||
: ReturnOptionsTypes[T[K]['type']];
|
: ReturnOptionsTypes[T[K]['type']];
|
||||||
} & {
|
} & {
|
||||||
[K in KeysWithoutRequired<T>]?: T[K]['value'] extends (...args: any) => any
|
[K in KeysWithoutRequired<T>]?: T[K]['value'] extends (...args: any) => any
|
||||||
? Parameters<Parameters<T[K]['value']>[1]>[0]
|
? Parameters<Parameters<T[K]['value']>[1]>[0]
|
||||||
: T[K] extends SeyfertStringOption | SeyfertNumberOption
|
: T[K] extends SeyfertStringOption | SeyfertNumberOption
|
||||||
? T[K]['choices'] extends NonNullable<SeyfertStringOption['choices'] | SeyfertNumberOption['choices']>
|
? T[K]['choices'] extends NonNullable<SeyfertStringOption['choices'] | SeyfertNumberOption['choices']>
|
||||||
? T[K]['choices'][number]['value']
|
? T[K]['choices'][number]['value']
|
||||||
: ReturnOptionsTypes[T[K]['type']]
|
: ReturnOptionsTypes[T[K]['type']]
|
||||||
: ReturnOptionsTypes[T[K]['type']];
|
: ReturnOptionsTypes[T[K]['type']];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ContextOptions<T extends OptionsRecord> = ContextOptionsAux<T>;
|
export type ContextOptions<T extends OptionsRecord> = ContextOptionsAux<T>;
|
||||||
|
|
||||||
export class BaseCommand {
|
export class BaseCommand {
|
||||||
middlewares: (keyof RegisteredMiddlewares)[] = [];
|
middlewares: (keyof RegisteredMiddlewares)[] = [];
|
||||||
|
|
||||||
__filePath?: string;
|
__filePath?: string;
|
||||||
__t?: { name: string | undefined; description: string | undefined };
|
__t?: { name: string | undefined; description: string | undefined };
|
||||||
__autoload?: true;
|
__autoload?: true;
|
||||||
|
|
||||||
guildId?: string[];
|
guildId?: string[];
|
||||||
name!: string;
|
name!: string;
|
||||||
type!: number; // ApplicationCommandType.ChatInput | ApplicationCommandOptionType.Subcommand
|
type!: number; // ApplicationCommandType.ChatInput | ApplicationCommandOptionType.Subcommand
|
||||||
nsfw?: boolean;
|
nsfw?: boolean;
|
||||||
description!: string;
|
description!: string;
|
||||||
defaultMemberPermissions?: bigint;
|
defaultMemberPermissions?: bigint;
|
||||||
integrationTypes?: ApplicationIntegrationType[];
|
integrationTypes?: ApplicationIntegrationType[];
|
||||||
contexts?: InteractionContextType[];
|
contexts?: InteractionContextType[];
|
||||||
botPermissions?: bigint;
|
botPermissions?: bigint;
|
||||||
name_localizations?: Partial<Record<LocaleString, string>>;
|
name_localizations?: Partial<Record<LocaleString, string>>;
|
||||||
description_localizations?: Partial<Record<LocaleString, string>>;
|
description_localizations?: Partial<Record<LocaleString, string>>;
|
||||||
|
|
||||||
options?: CommandOption[] | SubCommand[];
|
options?: CommandOption[] | SubCommand[];
|
||||||
|
|
||||||
ignore?: IgnoreCommand;
|
ignore?: IgnoreCommand;
|
||||||
|
|
||||||
aliases?: string[];
|
aliases?: string[];
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
async __runOptions(
|
async __runOptions(
|
||||||
ctx: CommandContext<{}, never>,
|
ctx: CommandContext<{}, never>,
|
||||||
resolver: OptionResolver,
|
resolver: OptionResolver,
|
||||||
): Promise<[boolean, OnOptionsReturnObject]> {
|
): Promise<[boolean, OnOptionsReturnObject]> {
|
||||||
if (!this?.options?.length) {
|
if (!this?.options?.length) {
|
||||||
return [false, {}];
|
return [false, {}];
|
||||||
}
|
}
|
||||||
const data: OnOptionsReturnObject = {};
|
const data: OnOptionsReturnObject = {};
|
||||||
let errored = false;
|
let errored = false;
|
||||||
for (const i of this.options ?? []) {
|
for (const i of this.options ?? []) {
|
||||||
try {
|
try {
|
||||||
const option = this.options!.find(x => x.name === i.name) as __CommandOption;
|
const option = this.options!.find(x => x.name === i.name) as __CommandOption;
|
||||||
const value =
|
const value =
|
||||||
resolver.getHoisted(i.name)?.value !== undefined
|
resolver.getHoisted(i.name)?.value !== undefined
|
||||||
? await new Promise(
|
? await new Promise(
|
||||||
(res, rej) =>
|
(res, rej) =>
|
||||||
option.value?.({ context: ctx, value: resolver.getValue(i.name) } as never, res, rej) ||
|
option.value?.({ context: ctx, value: resolver.getValue(i.name) } as never, res, rej) ||
|
||||||
res(resolver.getValue(i.name)),
|
res(resolver.getValue(i.name)),
|
||||||
)
|
)
|
||||||
: undefined;
|
: undefined;
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
if (option.required) {
|
if (option.required) {
|
||||||
errored = true;
|
errored = true;
|
||||||
data[i.name] = {
|
data[i.name] = {
|
||||||
failed: true,
|
failed: true,
|
||||||
value: `${i.name} is required but returned no value`,
|
value: `${i.name} is required but returned no value`,
|
||||||
};
|
};
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
ctx.options[i.name] = value;
|
ctx.options[i.name] = value;
|
||||||
data[i.name] = {
|
data[i.name] = {
|
||||||
failed: false,
|
failed: false,
|
||||||
value,
|
value,
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errored = true;
|
errored = true;
|
||||||
data[i.name] = {
|
data[i.name] = {
|
||||||
failed: true,
|
failed: true,
|
||||||
value: e instanceof Error ? e.message : `${e}`,
|
value: e instanceof Error ? e.message : `${e}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [errored, data];
|
return [errored, data];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
static __runMiddlewares(
|
static __runMiddlewares(
|
||||||
context: CommandContext<{}, never> | ComponentContext | MenuCommandContext<any> | ModalContext,
|
context: CommandContext<{}, never> | ComponentContext | MenuCommandContext<any> | ModalContext,
|
||||||
middlewares: (keyof RegisteredMiddlewares)[],
|
middlewares: (keyof RegisteredMiddlewares)[],
|
||||||
global: boolean,
|
global: boolean,
|
||||||
): Promise<{ error?: string; pass?: boolean }> {
|
): Promise<{ error?: string; pass?: boolean }> {
|
||||||
if (!middlewares.length) {
|
if (!middlewares.length) {
|
||||||
return Promise.resolve({});
|
return Promise.resolve({});
|
||||||
}
|
}
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
||||||
return new Promise(res => {
|
return new Promise(res => {
|
||||||
let running = true;
|
let running = true;
|
||||||
const pass: PassFunction = () => {
|
const pass: PassFunction = () => {
|
||||||
if (!running) {
|
if (!running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
running = false;
|
running = false;
|
||||||
return res({ pass: true });
|
return res({ pass: true });
|
||||||
};
|
};
|
||||||
function next(obj: any) {
|
function next(obj: any) {
|
||||||
if (!running) {
|
if (!running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// biome-ignore lint/style/noArguments: yes
|
// biome-ignore lint/style/noArguments: yes
|
||||||
// biome-ignore lint/correctness/noUndeclaredVariables: xd
|
// biome-ignore lint/correctness/noUndeclaredVariables: xd
|
||||||
if (arguments.length) {
|
if (arguments.length) {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj;
|
context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj;
|
||||||
}
|
}
|
||||||
if (++index >= middlewares.length) {
|
if (++index >= middlewares.length) {
|
||||||
running = false;
|
running = false;
|
||||||
return res({});
|
return res({});
|
||||||
}
|
}
|
||||||
context.client.middlewares![middlewares[index]]({ context, next, stop, pass });
|
context.client.middlewares![middlewares[index]]({ context, next, stop, pass });
|
||||||
}
|
}
|
||||||
const stop: StopFunction = err => {
|
const stop: StopFunction = err => {
|
||||||
if (!running) {
|
if (!running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
running = false;
|
running = false;
|
||||||
return res({ error: err });
|
return res({ error: err });
|
||||||
};
|
};
|
||||||
context.client.middlewares![middlewares[0]]({ context, next, stop, pass });
|
context.client.middlewares![middlewares[0]]({ context, next, stop, pass });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
__runMiddlewares(context: CommandContext<{}, never>) {
|
__runMiddlewares(context: CommandContext<{}, never>) {
|
||||||
return BaseCommand.__runMiddlewares(context, this.middlewares as (keyof RegisteredMiddlewares)[], false);
|
return BaseCommand.__runMiddlewares(context, this.middlewares as (keyof RegisteredMiddlewares)[], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
__runGlobalMiddlewares(context: CommandContext<{}, never>) {
|
__runGlobalMiddlewares(context: CommandContext<{}, never>) {
|
||||||
return BaseCommand.__runMiddlewares(
|
return BaseCommand.__runMiddlewares(
|
||||||
context,
|
context,
|
||||||
(context.client.options?.globalMiddlewares ?? []) as (keyof RegisteredMiddlewares)[],
|
(context.client.options?.globalMiddlewares ?? []) as (keyof RegisteredMiddlewares)[],
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
const data = {
|
const data = {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
nsfw: !!this.nsfw,
|
nsfw: !!this.nsfw,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
name_localizations: this.name_localizations,
|
name_localizations: this.name_localizations,
|
||||||
description_localizations: this.description_localizations,
|
description_localizations: this.description_localizations,
|
||||||
guild_id: this.guildId,
|
guild_id: this.guildId,
|
||||||
default_member_permissions: this.defaultMemberPermissions ? this.defaultMemberPermissions.toString() : undefined,
|
default_member_permissions: this.defaultMemberPermissions ? this.defaultMemberPermissions.toString() : undefined,
|
||||||
contexts: this.contexts,
|
contexts: this.contexts,
|
||||||
integration_types: this.integrationTypes,
|
integration_types: this.integrationTypes,
|
||||||
} as {
|
} as {
|
||||||
name: BaseCommand['name'];
|
name: BaseCommand['name'];
|
||||||
type: BaseCommand['type'];
|
type: BaseCommand['type'];
|
||||||
nsfw: BaseCommand['nsfw'];
|
nsfw: BaseCommand['nsfw'];
|
||||||
description: BaseCommand['description'];
|
description: BaseCommand['description'];
|
||||||
name_localizations: BaseCommand['name_localizations'];
|
name_localizations: BaseCommand['name_localizations'];
|
||||||
description_localizations: BaseCommand['description_localizations'];
|
description_localizations: BaseCommand['description_localizations'];
|
||||||
guild_id: BaseCommand['guildId'];
|
guild_id: BaseCommand['guildId'];
|
||||||
default_member_permissions: string;
|
default_member_permissions: string;
|
||||||
contexts: BaseCommand['contexts'];
|
contexts: BaseCommand['contexts'];
|
||||||
integration_types: BaseCommand['integrationTypes'];
|
integration_types: BaseCommand['integrationTypes'];
|
||||||
};
|
};
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async reload() {
|
async reload() {
|
||||||
delete require.cache[this.__filePath!];
|
delete require.cache[this.__filePath!];
|
||||||
|
|
||||||
for (const i of this.options ?? []) {
|
for (const i of this.options ?? []) {
|
||||||
if (i instanceof SubCommand && i.__filePath) {
|
if (i instanceof SubCommand && i.__filePath) {
|
||||||
await i.reload();
|
await i.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const __tempCommand = await magicImport(this.__filePath!).then(x => x.default ?? x);
|
const __tempCommand = await magicImport(this.__filePath!).then(x => x.default ?? x);
|
||||||
|
|
||||||
Object.setPrototypeOf(this, __tempCommand.prototype);
|
Object.setPrototypeOf(this, __tempCommand.prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
run?(context: CommandContext): any;
|
run?(context: CommandContext): any;
|
||||||
onAfterRun?(context: CommandContext, error: unknown | undefined): any;
|
onAfterRun?(context: CommandContext, error: unknown | undefined): any;
|
||||||
onRunError?(context: CommandContext, error: unknown): any;
|
onRunError?(context: CommandContext, error: unknown): any;
|
||||||
onOptionsError?(context: CommandContext, metadata: OnOptionsReturnObject): any;
|
onOptionsError?(context: CommandContext, metadata: OnOptionsReturnObject): any;
|
||||||
onMiddlewaresError?(context: CommandContext, error: string): any;
|
onMiddlewaresError?(context: CommandContext, error: string): any;
|
||||||
onBotPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any;
|
onBotPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any;
|
||||||
onPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any;
|
onPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any;
|
||||||
onInternalError?(client: UsingClient, command: Command | SubCommand, error?: unknown): any;
|
onInternalError?(client: UsingClient, command: Command | SubCommand, error?: unknown): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Command extends BaseCommand {
|
export class Command extends BaseCommand {
|
||||||
type = ApplicationCommandType.ChatInput;
|
type = ApplicationCommandType.ChatInput;
|
||||||
|
|
||||||
groups?: Parameters<typeof Groups>[0];
|
groups?: Parameters<typeof Groups>[0];
|
||||||
groupsAliases?: Record<string, string>;
|
groupsAliases?: Record<string, string>;
|
||||||
__tGroups?: Record<
|
__tGroups?: Record<
|
||||||
string /* name for group*/,
|
string /* name for group*/,
|
||||||
{
|
{
|
||||||
name: string | undefined;
|
name: string | undefined;
|
||||||
description: string | undefined;
|
description: string | undefined;
|
||||||
defaultDescription: string;
|
defaultDescription: string;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
const options: APIApplicationCommandOption[] = [];
|
const options: APIApplicationCommandOption[] = [];
|
||||||
|
|
||||||
for (const i of this.options ?? []) {
|
for (const i of this.options ?? []) {
|
||||||
if (!(i instanceof SubCommand)) {
|
if (!(i instanceof SubCommand)) {
|
||||||
options.push({ ...i, autocomplete: 'autocomplete' in i } as APIApplicationCommandBasicOption);
|
options.push({ ...i, autocomplete: 'autocomplete' in i } as APIApplicationCommandBasicOption);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i.group) {
|
if (i.group) {
|
||||||
if (!options.find(x => x.name === i.group)) {
|
if (!options.find(x => x.name === i.group)) {
|
||||||
options.push({
|
options.push({
|
||||||
type: ApplicationCommandOptionType.SubcommandGroup,
|
type: ApplicationCommandOptionType.SubcommandGroup,
|
||||||
name: i.group,
|
name: i.group,
|
||||||
description: this.groups![i.group].defaultDescription,
|
description: this.groups![i.group].defaultDescription,
|
||||||
description_localizations: Object.fromEntries(this.groups?.[i.group].description ?? []),
|
description_localizations: Object.fromEntries(this.groups?.[i.group].description ?? []),
|
||||||
name_localizations: Object.fromEntries(this.groups?.[i.group].name ?? []),
|
name_localizations: Object.fromEntries(this.groups?.[i.group].name ?? []),
|
||||||
options: [],
|
options: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const group = options.find(x => x.name === i.group) as APIApplicationCommandSubcommandGroupOption;
|
const group = options.find(x => x.name === i.group) as APIApplicationCommandSubcommandGroupOption;
|
||||||
group.options?.push(i.toJSON());
|
group.options?.push(i.toJSON());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
options.push(i.toJSON());
|
options.push(i.toJSON());
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...super.toJSON(),
|
...super.toJSON(),
|
||||||
options,
|
options,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class SubCommand extends BaseCommand {
|
export abstract class SubCommand extends BaseCommand {
|
||||||
type = ApplicationCommandOptionType.Subcommand;
|
type = ApplicationCommandOptionType.Subcommand;
|
||||||
group?: string;
|
group?: string;
|
||||||
declare options?: CommandOption[];
|
declare options?: CommandOption[];
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
...super.toJSON(),
|
...super.toJSON(),
|
||||||
options: (this.options ?? []).map(
|
options:
|
||||||
x => ({ ...x, autocomplete: 'autocomplete' in x }) as APIApplicationCommandBasicOption,
|
this.options?.map(x => ({ ...x, autocomplete: 'autocomplete' in x }) as APIApplicationCommandBasicOption) ?? [],
|
||||||
),
|
};
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
abstract run(context: CommandContext<any>): any;
|
||||||
abstract run(context: CommandContext<any>): any;
|
}
|
||||||
}
|
|
||||||
|
@ -73,8 +73,10 @@ export class EventHandler extends BaseHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.runEvent(args[0].t, args[1], args[0].d, args[2]);
|
await Promise.all([
|
||||||
await this.client.collectors.run(args[0].t, args[0].d);
|
this.runEvent(args[0].t, args[1], args[0].d, args[2]),
|
||||||
|
this.client.collectors.run(args[0].t, args[0].d),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async runEvent(name: GatewayEvents, client: Client | WorkerClient, packet: any, shardId: number) {
|
async runEvent(name: GatewayEvents, client: Client | WorkerClient, packet: any, shardId: number) {
|
||||||
|
@ -1,271 +1,274 @@
|
|||||||
import type {
|
import type {
|
||||||
APIChannelMention,
|
APIChannelMention,
|
||||||
APIEmbed,
|
APIEmbed,
|
||||||
APIGuildMember,
|
APIGuildMember,
|
||||||
APIMessage,
|
APIMessage,
|
||||||
APIUser,
|
APIUser,
|
||||||
GatewayMessageCreateDispatchData,
|
GatewayMessageCreateDispatchData,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import type { ListenerOptions } from '../builders';
|
import type { ListenerOptions } from '../builders';
|
||||||
import type { UsingClient } from '../commands';
|
import type { UsingClient } from '../commands';
|
||||||
import { toCamelCase, type ObjectToLower } from '../common';
|
import { toCamelCase, type ObjectToLower } from '../common';
|
||||||
import type { EmojiResolvable } from '../common/types/resolvables';
|
import type { EmojiResolvable } from '../common/types/resolvables';
|
||||||
import type { MessageCreateBodyRequest, MessageUpdateBodyRequest } from '../common/types/write';
|
import type { MessageCreateBodyRequest, MessageUpdateBodyRequest } from '../common/types/write';
|
||||||
import type { ActionRowMessageComponents } from '../components';
|
import type { ActionRowMessageComponents } from '../components';
|
||||||
import { MessageActionRowComponent } from '../components/ActionRow';
|
import { MessageActionRowComponent } from '../components/ActionRow';
|
||||||
import { GuildMember } from './GuildMember';
|
import { GuildMember } from './GuildMember';
|
||||||
import { User } from './User';
|
import { User } from './User';
|
||||||
import type { MessageWebhookMethodEditParams, MessageWebhookMethodWriteParams } from './Webhook';
|
import type { MessageWebhookMethodEditParams, MessageWebhookMethodWriteParams } from './Webhook';
|
||||||
import { DiscordBase } from './extra/DiscordBase';
|
import { DiscordBase } from './extra/DiscordBase';
|
||||||
import { messageLink } from './extra/functions';
|
import { messageLink } from './extra/functions';
|
||||||
import { Embed, Poll } from '..';
|
import { Embed, Poll } from '..';
|
||||||
|
|
||||||
export type MessageData = APIMessage | GatewayMessageCreateDispatchData;
|
export type MessageData = APIMessage | GatewayMessageCreateDispatchData;
|
||||||
|
|
||||||
export interface BaseMessage
|
export interface BaseMessage
|
||||||
extends DiscordBase,
|
extends DiscordBase,
|
||||||
ObjectToLower<Omit<MessageData, 'timestamp' | 'author' | 'mentions' | 'components' | 'poll' | 'embeds'>> {}
|
ObjectToLower<Omit<MessageData, 'timestamp' | 'author' | 'mentions' | 'components' | 'poll' | 'embeds'>> {}
|
||||||
export class BaseMessage extends DiscordBase {
|
export class BaseMessage extends DiscordBase {
|
||||||
guildId: string | undefined;
|
guildId: string | undefined;
|
||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
author!: User;
|
author!: User;
|
||||||
member?: GuildMember;
|
member?: GuildMember;
|
||||||
components: MessageActionRowComponent<ActionRowMessageComponents>[];
|
components: MessageActionRowComponent<ActionRowMessageComponents>[];
|
||||||
poll?: Poll;
|
poll?: Poll;
|
||||||
mentions: {
|
mentions: {
|
||||||
roles: string[];
|
roles: string[];
|
||||||
channels: APIChannelMention[];
|
channels: APIChannelMention[];
|
||||||
users: (GuildMember | User)[];
|
users: (GuildMember | User)[];
|
||||||
};
|
};
|
||||||
embeds: InMessageEmbed[];
|
embeds: InMessageEmbed[];
|
||||||
|
|
||||||
constructor(client: UsingClient, data: MessageData) {
|
constructor(client: UsingClient, data: MessageData) {
|
||||||
super(client, data);
|
super(client, data);
|
||||||
this.mentions = {
|
this.mentions = {
|
||||||
roles: data.mention_roles ?? [],
|
roles: data.mention_roles ?? [],
|
||||||
channels: data.mention_channels ?? [],
|
channels: data.mention_channels ?? [],
|
||||||
users: [],
|
users: [],
|
||||||
};
|
};
|
||||||
this.components = (data.components ?? []).map(x => new MessageActionRowComponent(x));
|
this.components = data.components?.map(x => new MessageActionRowComponent(x)) ?? [];
|
||||||
this.embeds = data.embeds.map(embed => new InMessageEmbed(embed));
|
this.embeds = data.embeds.map(embed => new InMessageEmbed(embed));
|
||||||
this.patch(data);
|
this.patch(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
get user() {
|
get user() {
|
||||||
return this.author;
|
return this.author;
|
||||||
}
|
}
|
||||||
|
|
||||||
createComponentCollector(options?: ListenerOptions) {
|
createComponentCollector(options?: ListenerOptions) {
|
||||||
return this.client.components!.createComponentCollector(this.id, options);
|
return this.client.components!.createComponentCollector(this.id, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
get url() {
|
get url() {
|
||||||
return messageLink(this.channelId, this.id, this.guildId);
|
return messageLink(this.channelId, this.id, this.guildId);
|
||||||
}
|
}
|
||||||
|
|
||||||
guild(force = false) {
|
guild(force = false) {
|
||||||
if (!this.guildId) return;
|
if (!this.guildId) return;
|
||||||
return this.client.guilds.fetch(this.guildId, force);
|
return this.client.guilds.fetch(this.guildId, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
async channel(force = false) {
|
async channel(force = false) {
|
||||||
return this.client.channels.fetch(this.channelId, force);
|
return this.client.channels.fetch(this.channelId, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
react(emoji: EmojiResolvable) {
|
react(emoji: EmojiResolvable) {
|
||||||
return this.client.reactions.add(this.id, this.channelId, emoji);
|
return this.client.reactions.add(this.id, this.channelId, emoji);
|
||||||
}
|
}
|
||||||
|
|
||||||
private patch(data: MessageData) {
|
private patch(data: MessageData) {
|
||||||
if ('guild_id' in data) {
|
if ('guild_id' in data) {
|
||||||
this.guildId = data.guild_id;
|
this.guildId = data.guild_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.type !== undefined) {
|
if (data.type !== undefined) {
|
||||||
this.type = data.type;
|
this.type = data.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('timestamp' in data && data.timestamp) {
|
if ('timestamp' in data && data.timestamp) {
|
||||||
this.timestamp = Date.parse(data.timestamp);
|
this.timestamp = Date.parse(data.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('application_id' in data) {
|
if ('application_id' in data) {
|
||||||
this.applicationId = data.application_id;
|
this.applicationId = data.application_id;
|
||||||
}
|
}
|
||||||
if ('author' in data && data.author) {
|
if ('author' in data && data.author) {
|
||||||
this.author = new User(this.client, data.author);
|
this.author = new User(this.client, data.author);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('member' in data && data.member) {
|
if ('member' in data && data.member) {
|
||||||
this.member = new GuildMember(this.client, data.member, this.author, this.guildId!);
|
this.member = new GuildMember(this.client, data.member, this.author, this.guildId!);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.mentions?.length) {
|
if (data.mentions?.length) {
|
||||||
this.mentions.users = this.guildId
|
this.mentions.users = this.guildId
|
||||||
? data.mentions.map(
|
? data.mentions.map(
|
||||||
m =>
|
m =>
|
||||||
new GuildMember(
|
new GuildMember(
|
||||||
this.client,
|
this.client,
|
||||||
{
|
{
|
||||||
...(m as APIUser & { member?: Omit<APIGuildMember, 'user'> }).member!,
|
...(m as APIUser & { member?: Omit<APIGuildMember, 'user'> }).member!,
|
||||||
user: m,
|
user: m,
|
||||||
},
|
},
|
||||||
m,
|
m,
|
||||||
this.guildId!,
|
this.guildId!,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: data.mentions.map(u => new User(this.client, u));
|
: data.mentions.map(u => new User(this.client, u));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.poll) {
|
if (data.poll) {
|
||||||
this.poll = new Poll(this.client, data.poll, this.channelId, this.id);
|
this.poll = new Poll(this.client, data.poll, this.channelId, this.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Message
|
export interface Message
|
||||||
extends BaseMessage,
|
extends BaseMessage,
|
||||||
ObjectToLower<Omit<MessageData, 'timestamp' | 'author' | 'mentions' | 'components' | 'poll' | 'embeds'>> {}
|
ObjectToLower<Omit<MessageData, 'timestamp' | 'author' | 'mentions' | 'components' | 'poll' | 'embeds'>> {}
|
||||||
|
|
||||||
export class Message extends BaseMessage {
|
export class Message extends BaseMessage {
|
||||||
constructor(client: UsingClient, data: MessageData) {
|
constructor(client: UsingClient, data: MessageData) {
|
||||||
super(client, data);
|
super(client, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch() {
|
fetch() {
|
||||||
return this.client.messages.fetch(this.id, this.channelId);
|
return this.client.messages.fetch(this.id, this.channelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
reply(body: Omit<MessageCreateBodyRequest, 'message_reference'>, fail = true) {
|
reply(body: Omit<MessageCreateBodyRequest, 'message_reference'>, fail = true) {
|
||||||
return this.write({
|
return this.write({
|
||||||
...body,
|
...body,
|
||||||
message_reference: {
|
message_reference: {
|
||||||
message_id: this.id,
|
message_id: this.id,
|
||||||
channel_id: this.channelId,
|
channel_id: this.channelId,
|
||||||
guild_id: this.guildId,
|
guild_id: this.guildId,
|
||||||
fail_if_not_exists: fail,
|
fail_if_not_exists: fail,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
edit(body: MessageUpdateBodyRequest) {
|
edit(body: MessageUpdateBodyRequest) {
|
||||||
return this.client.messages.edit(this.id, this.channelId, body);
|
return this.client.messages.edit(this.id, this.channelId, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
write(body: MessageCreateBodyRequest) {
|
write(body: MessageCreateBodyRequest) {
|
||||||
return this.client.messages.write(this.channelId, body);
|
return this.client.messages.write(this.channelId, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(reason?: string) {
|
delete(reason?: string) {
|
||||||
return this.client.messages.delete(this.id, this.channelId, reason);
|
return this.client.messages.delete(this.id, this.channelId, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
crosspost(reason?: string) {
|
crosspost(reason?: string) {
|
||||||
return this.client.messages.crosspost(this.id, this.channelId, reason);
|
return this.client.messages.crosspost(this.id, this.channelId, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EditMessageWebhook = Omit<MessageWebhookMethodEditParams, 'messageId'>['body'] &
|
export type EditMessageWebhook = Omit<MessageWebhookMethodEditParams, 'messageId'>['body'] &
|
||||||
Pick<MessageWebhookMethodEditParams, 'query'>;
|
Pick<MessageWebhookMethodEditParams, 'query'>;
|
||||||
export type WriteMessageWebhook = MessageWebhookMethodWriteParams['body'] &
|
export type WriteMessageWebhook = MessageWebhookMethodWriteParams['body'] &
|
||||||
Pick<MessageWebhookMethodWriteParams, 'query'>;
|
Pick<MessageWebhookMethodWriteParams, 'query'>;
|
||||||
|
|
||||||
export class WebhookMessage extends BaseMessage {
|
export class WebhookMessage extends BaseMessage {
|
||||||
constructor(
|
constructor(
|
||||||
client: UsingClient,
|
client: UsingClient,
|
||||||
data: MessageData,
|
data: MessageData,
|
||||||
readonly webhookId: string,
|
readonly webhookId: string,
|
||||||
readonly webhookToken: string,
|
readonly webhookToken: string,
|
||||||
) {
|
) {
|
||||||
super(client, data);
|
super(client, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch() {
|
fetch() {
|
||||||
return this.api.webhooks(this.webhookId)(this.webhookToken).get({ query: this.thread?.id });
|
return this.api.webhooks(this.webhookId)(this.webhookToken).get({ query: this.thread?.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
edit(body: EditMessageWebhook) {
|
edit(body: EditMessageWebhook) {
|
||||||
const { query, ...rest } = body;
|
const { query, ...rest } = body;
|
||||||
return this.client.webhooks.editMessage(this.webhookId, this.webhookToken, {
|
return this.client.webhooks.editMessage(this.webhookId, this.webhookToken, {
|
||||||
body: rest,
|
body: rest,
|
||||||
query,
|
query,
|
||||||
messageId: this.id,
|
messageId: this.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
write(body: WriteMessageWebhook) {
|
write(body: WriteMessageWebhook) {
|
||||||
const { query, ...rest } = body;
|
const { query, ...rest } = body;
|
||||||
return this.client.webhooks.writeMessage(this.webhookId, this.webhookToken, {
|
return this.client.webhooks.writeMessage(this.webhookId, this.webhookToken, {
|
||||||
body: rest,
|
body: rest,
|
||||||
query,
|
query,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(reason?: string) {
|
delete(reason?: string) {
|
||||||
return this.client.webhooks.deleteMessage(this.webhookId, this.webhookToken, this.id, reason);
|
return this.client.webhooks.deleteMessage(this.webhookId, this.webhookToken, this.id, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InMessageEmbed {
|
export class InMessageEmbed {
|
||||||
constructor(public data: APIEmbed) {}
|
constructor(public data: APIEmbed) {}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
return this.data.title;
|
return this.data.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
get type() {
|
/**
|
||||||
return this.data.type;
|
* @deprecated
|
||||||
}
|
*/
|
||||||
|
get type() {
|
||||||
get description() {
|
return this.data.type;
|
||||||
return this.data.description;
|
}
|
||||||
}
|
|
||||||
|
get description() {
|
||||||
get url() {
|
return this.data.description;
|
||||||
return this.data.url;
|
}
|
||||||
}
|
|
||||||
|
get url() {
|
||||||
get timestamp() {
|
return this.data.url;
|
||||||
return this.data.timestamp;
|
}
|
||||||
}
|
|
||||||
|
get timestamp() {
|
||||||
get color() {
|
return this.data.timestamp;
|
||||||
return this.data.color;
|
}
|
||||||
}
|
|
||||||
|
get color() {
|
||||||
get footer() {
|
return this.data.color;
|
||||||
return toCamelCase(this.data.footer ?? {});
|
}
|
||||||
}
|
|
||||||
|
get footer() {
|
||||||
get image() {
|
return this.data.footer ? toCamelCase(this.data.footer) : undefined;
|
||||||
return toCamelCase(this.data.image ?? {});
|
}
|
||||||
}
|
|
||||||
|
get image() {
|
||||||
get thumbnail() {
|
return this.data.image ? toCamelCase(this.data.image) : undefined;
|
||||||
return toCamelCase(this.data.thumbnail ?? {});
|
}
|
||||||
}
|
|
||||||
|
get thumbnail() {
|
||||||
get video() {
|
return this.data.thumbnail ? toCamelCase(this.data.thumbnail) : undefined;
|
||||||
return toCamelCase(this.data.video ?? {});
|
}
|
||||||
}
|
|
||||||
|
get video() {
|
||||||
get provider() {
|
return this.data.video ? toCamelCase(this.data.video) : undefined;
|
||||||
return this.data.provider;
|
}
|
||||||
}
|
|
||||||
|
get provider() {
|
||||||
get author() {
|
return this.data.provider;
|
||||||
return toCamelCase(this.data.author ?? {});
|
}
|
||||||
}
|
|
||||||
|
get author() {
|
||||||
get fields() {
|
return this.data.author ? toCamelCase(this.data.author) : undefined;
|
||||||
return this.data.fields;
|
}
|
||||||
}
|
|
||||||
|
get fields() {
|
||||||
toBuilder() {
|
return this.data.fields;
|
||||||
return new Embed(this.data);
|
}
|
||||||
}
|
|
||||||
|
toBuilder() {
|
||||||
toJSON() {
|
return new Embed(this.data);
|
||||||
return { ...this.data };
|
}
|
||||||
}
|
|
||||||
}
|
toJSON() {
|
||||||
|
return { ...this.data };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user