mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-02 04:56:07 +00:00
feat: send attachments option by default
This commit is contained in:
parent
0b60586847
commit
006a9f390f
@ -386,7 +386,6 @@ export class ApiHandler {
|
||||
if (options.request.reason) {
|
||||
options.headers['X-Audit-Log-Reason'] = encodeURIComponent(options.request.reason);
|
||||
}
|
||||
|
||||
return { data, finalUrl } as { data: typeof data; finalUrl: `/${string}` };
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ export class BaseClient {
|
||||
options: BaseClientOptions;
|
||||
|
||||
/**@internal */
|
||||
static _seyferConfig?: InternalRuntimeConfigHTTP | InternalRuntimeConfig;
|
||||
static _seyfertConfig?: InternalRuntimeConfigHTTP | InternalRuntimeConfig;
|
||||
|
||||
constructor(options?: BaseClientOptions) {
|
||||
this.options = MergeOptions(
|
||||
@ -339,7 +339,7 @@ export class BaseClient {
|
||||
async getRC<
|
||||
T extends InternalRuntimeConfigHTTP | InternalRuntimeConfig = InternalRuntimeConfigHTTP | InternalRuntimeConfig,
|
||||
>() {
|
||||
const seyfertConfig = (BaseClient._seyferConfig ||
|
||||
const seyfertConfig = (BaseClient._seyfertConfig ||
|
||||
(await this.options.getRC?.()) ||
|
||||
(await magicImport(join(process.cwd(), 'seyfert.config.js')).then(x => x.default ?? x))) as T;
|
||||
|
||||
@ -358,7 +358,7 @@ export class BaseClient {
|
||||
output: join(process.cwd(), locations.output),
|
||||
};
|
||||
|
||||
BaseClient._seyferConfig = seyfertConfig;
|
||||
BaseClient._seyfertConfig = seyfertConfig;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -10,17 +10,19 @@ import type { BaseClientOptions, InternalRuntimeConfig, ServicesOptions, StartOp
|
||||
import { BaseClient } from './base';
|
||||
import { onInteractionCreate } from './oninteractioncreate';
|
||||
import { onMessageCreate } from './onmessagecreate';
|
||||
import { Collectors } from './collectors';
|
||||
|
||||
let parentPort: import('node:worker_threads').MessagePort;
|
||||
|
||||
export class Client<Ready extends boolean = boolean> extends BaseClient {
|
||||
private __handleGuilds?: Set<string> = new Set();
|
||||
gateway!: ShardManager;
|
||||
events? = new EventHandler(this.logger);
|
||||
me!: If<Ready, ClientUser>;
|
||||
declare options: ClientOptions;
|
||||
memberUpdateHandler = new MemberUpdateHandler();
|
||||
presenceUpdateHandler = new PresenceUpdateHandler();
|
||||
collectors = new Collectors();
|
||||
events? = new EventHandler(this.logger, this.collectors);
|
||||
|
||||
constructor(options?: ClientOptions) {
|
||||
super(options);
|
||||
@ -49,7 +51,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
|
||||
if (!rest.handlers.events) {
|
||||
this.events = undefined;
|
||||
} else if (typeof rest.handlers.events === 'function') {
|
||||
this.events = new EventHandler(this.logger);
|
||||
this.events = new EventHandler(this.logger, this.collectors);
|
||||
this.events.setHandlers({
|
||||
callback: rest.handlers.events,
|
||||
});
|
||||
|
97
src/client/collectors.ts
Normal file
97
src/client/collectors.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import type { Awaitable, CamelCase, SnakeCase } from '../common';
|
||||
import type { ClientNameEvents, GatewayEvents } from '../events';
|
||||
import type { ClientEvents } from '../events/hooks';
|
||||
|
||||
type SnakeCaseClientNameEvents = Uppercase<SnakeCase<ClientNameEvents>>;
|
||||
|
||||
type RunData<T extends SnakeCaseClientNameEvents> = {
|
||||
options: {
|
||||
event: T;
|
||||
idle?: number;
|
||||
timeout?: number;
|
||||
onStop?: (reason: string) => unknown;
|
||||
filter: (arg: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>) => Awaitable<boolean>;
|
||||
run: (arg: Awaited<ClientEvents[CamelCase<Lowercase<T>>]>) => unknown;
|
||||
};
|
||||
idle?: NodeJS.Timeout;
|
||||
timeout?: NodeJS.Timeout;
|
||||
nonce: string;
|
||||
};
|
||||
|
||||
export class Collectors {
|
||||
readonly values = new Map<SnakeCaseClientNameEvents, RunData<any>[]>();
|
||||
|
||||
private generateRandomUUID(name: SnakeCaseClientNameEvents) {
|
||||
const collectors = this.values.get(name);
|
||||
if (!collectors) return '*';
|
||||
|
||||
let nonce = randomUUID();
|
||||
|
||||
while (collectors.find(x => x.nonce === nonce)) {
|
||||
nonce = randomUUID();
|
||||
}
|
||||
|
||||
return nonce;
|
||||
}
|
||||
|
||||
create<T extends SnakeCaseClientNameEvents>(options: RunData<T>['options']) {
|
||||
if (!this.values.has(options.event)) {
|
||||
this.values.set(options.event, []);
|
||||
}
|
||||
|
||||
const nonce = this.generateRandomUUID(options.event);
|
||||
|
||||
this.values.get(options.event)!.push({
|
||||
options: {
|
||||
...options,
|
||||
name: options.event,
|
||||
} as RunData<any>['options'],
|
||||
idle:
|
||||
options.idle && options.idle > 0
|
||||
? setTimeout(() => {
|
||||
return this.delete(options.event, nonce, 'idle');
|
||||
}, options.idle)
|
||||
: undefined,
|
||||
timeout:
|
||||
options.timeout && options.timeout > 0
|
||||
? setTimeout(() => {
|
||||
return this.delete(options.event, nonce, 'timeout');
|
||||
}, options.timeout)
|
||||
: undefined,
|
||||
nonce,
|
||||
});
|
||||
return options;
|
||||
}
|
||||
|
||||
private delete(name: SnakeCaseClientNameEvents, nonce: string, reason = 'unknown') {
|
||||
const collectors = this.values.get(name);
|
||||
|
||||
if (!collectors?.length) {
|
||||
if (collectors) this.values.delete(name);
|
||||
return;
|
||||
}
|
||||
|
||||
const index = collectors.findIndex(x => x.nonce === nonce);
|
||||
if (index === -1) return;
|
||||
const collector = collectors[index];
|
||||
clearTimeout(collector.options.idle);
|
||||
clearTimeout(collector.options.timeout);
|
||||
collectors.splice(index, 1);
|
||||
return collector.options.onStop?.(reason);
|
||||
}
|
||||
|
||||
/**@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();
|
||||
await i.options.run(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ import { BaseClient } from './base';
|
||||
import type { Client } from './client';
|
||||
import { onInteractionCreate } from './oninteractioncreate';
|
||||
import { onMessageCreate } from './onmessagecreate';
|
||||
import { Collectors } from './collectors';
|
||||
|
||||
let workerData: WorkerData;
|
||||
let manager: import('node:worker_threads').MessagePort;
|
||||
@ -46,7 +47,8 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
|
||||
name: `[Worker #${workerData.workerId}]`,
|
||||
});
|
||||
|
||||
events? = new EventHandler(this.logger);
|
||||
collectors = new Collectors();
|
||||
events? = new EventHandler(this.logger, this.collectors);
|
||||
me!: When<Ready, ClientUser>;
|
||||
promises = new Map<string, { resolve: (value: any) => void; timeout: NodeJS.Timeout }>();
|
||||
|
||||
@ -117,7 +119,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
|
||||
if (!rest.handlers.events) {
|
||||
this.events = undefined;
|
||||
} else if (typeof rest.handlers.events === 'function') {
|
||||
this.events = new EventHandler(this.logger);
|
||||
this.events = new EventHandler(this.logger, this.collectors);
|
||||
this.events.setHandlers({
|
||||
callback: rest.handlers.events,
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BaseInteraction, type RawFile, WebhookMessage, resolveFiles, type ReplyInteractionBody, Modal } from '../..';
|
||||
import { BaseInteraction, WebhookMessage, resolveFiles, type ReplyInteractionBody, Modal } from '../..';
|
||||
import type { InteractionMessageUpdateBodyRequest, MessageWebhookCreateBodyRequest } from '../types/write';
|
||||
import { BaseShorter } from './base';
|
||||
|
||||
@ -8,6 +8,7 @@ export class InteractionShorter extends BaseShorter {
|
||||
const { files, ...rest } = body.data ?? {};
|
||||
//@ts-expect-error
|
||||
const data = body.data instanceof Modal ? body.data : rest;
|
||||
const parsedFiles = files ? await resolveFiles(files) : undefined;
|
||||
return this.client.proxy
|
||||
.interactions(id)(token)
|
||||
.callback.post({
|
||||
@ -16,9 +17,10 @@ export class InteractionShorter extends BaseShorter {
|
||||
type: body.type,
|
||||
data,
|
||||
},
|
||||
parsedFiles,
|
||||
this.client,
|
||||
),
|
||||
files: files ? await resolveFiles(files) : undefined,
|
||||
files: parsedFiles,
|
||||
});
|
||||
}
|
||||
|
||||
@ -32,12 +34,13 @@ export class InteractionShorter extends BaseShorter {
|
||||
|
||||
async editMessage(token: string, messageId: string, body: InteractionMessageUpdateBodyRequest) {
|
||||
const { files, ...data } = body;
|
||||
const parsedFiles = files ? await resolveFiles(files) : undefined;
|
||||
const apiMessage = await this.client.proxy
|
||||
.webhooks(this.client.applicationId)(token)
|
||||
.messages(messageId)
|
||||
.patch({
|
||||
body: BaseInteraction.transformBody(data, this.client),
|
||||
files: files ? await resolveFiles(files) : undefined,
|
||||
body: BaseInteraction.transformBody(data, parsedFiles, this.client),
|
||||
files: parsedFiles,
|
||||
});
|
||||
return new WebhookMessage(this.client, apiMessage, this.client.applicationId, token);
|
||||
}
|
||||
@ -59,12 +62,12 @@ export class InteractionShorter extends BaseShorter {
|
||||
}
|
||||
|
||||
async followup(token: string, { files, ...body }: MessageWebhookCreateBodyRequest) {
|
||||
files = files ? await resolveFiles(files) : undefined;
|
||||
const parsedFiles = files ? await resolveFiles(files) : undefined;
|
||||
const apiMessage = await this.client.proxy
|
||||
.webhooks(this.client.applicationId)(token)
|
||||
.post({
|
||||
body: BaseInteraction.transformBody(body, this.client),
|
||||
files: files as RawFile[] | undefined,
|
||||
body: BaseInteraction.transformBody(body, parsedFiles, this.client),
|
||||
files: parsedFiles,
|
||||
});
|
||||
return new WebhookMessage(this.client, apiMessage, this.client.applicationId, token);
|
||||
}
|
||||
|
@ -14,7 +14,11 @@ export class MessageShorter extends BaseShorter {
|
||||
async write(channelId: string, { files, ...body }: MessageCreateBodyRequest) {
|
||||
const parsedFiles = files ? await resolveFiles(files) : [];
|
||||
|
||||
const transformedBody = MessagesMethods.transformMessageBody<RESTPostAPIChannelMessageJSONBody>(body, this.client);
|
||||
const transformedBody = MessagesMethods.transformMessageBody<RESTPostAPIChannelMessageJSONBody>(
|
||||
body,
|
||||
parsedFiles,
|
||||
this.client,
|
||||
);
|
||||
return this.client.proxy
|
||||
.channels(channelId)
|
||||
.messages.post({
|
||||
@ -33,7 +37,7 @@ export class MessageShorter extends BaseShorter {
|
||||
.channels(channelId)
|
||||
.messages(messageId)
|
||||
.patch({
|
||||
body: MessagesMethods.transformMessageBody<RESTPatchAPIChannelMessageJSONBody>(body, this.client),
|
||||
body: MessagesMethods.transformMessageBody<RESTPatchAPIChannelMessageJSONBody>(body, parsedFiles, this.client),
|
||||
files: parsedFiles,
|
||||
})
|
||||
.then(async message => {
|
||||
|
@ -83,11 +83,12 @@ export class WebhookShorter extends BaseShorter {
|
||||
*/
|
||||
async writeMessage(webhookId: string, token: string, { body: data, ...payload }: MessageWebhookMethodWriteParams) {
|
||||
const { files, ...body } = data;
|
||||
const parsedFiles = files ? await resolveFiles(files) : [];
|
||||
const transformedBody = MessagesMethods.transformMessageBody<RESTPostAPIWebhookWithTokenJSONBody>(
|
||||
body,
|
||||
parsedFiles,
|
||||
this.client,
|
||||
);
|
||||
const parsedFiles = files ? await resolveFiles(files) : [];
|
||||
return this.client.proxy
|
||||
.webhooks(webhookId)(token)
|
||||
.post({ ...payload, files: parsedFiles, body: transformedBody })
|
||||
@ -108,11 +109,12 @@ export class WebhookShorter extends BaseShorter {
|
||||
{ messageId, body: data, ...json }: MessageWebhookMethodEditParams,
|
||||
) {
|
||||
const { files, ...body } = data;
|
||||
const parsedFiles = files ? await resolveFiles(files) : [];
|
||||
const transformedBody = MessagesMethods.transformMessageBody<RESTPostAPIWebhookWithTokenJSONBody>(
|
||||
body,
|
||||
parsedFiles,
|
||||
this.client,
|
||||
);
|
||||
const parsedFiles = files ? await resolveFiles(files) : [];
|
||||
return this.client.proxy
|
||||
.webhooks(webhookId)(token)
|
||||
.messages(messageId)
|
||||
|
@ -44,22 +44,24 @@ export class ComponentHandler extends BaseHandler {
|
||||
this.values.set(messageId, {
|
||||
components: [],
|
||||
options,
|
||||
idle: options.idle
|
||||
? setTimeout(() => {
|
||||
this.deleteValue(messageId);
|
||||
options.onStop?.('idle', () => {
|
||||
this.createComponentCollector(messageId, options);
|
||||
});
|
||||
}, options.idle)
|
||||
: undefined,
|
||||
timeout: options.timeout
|
||||
? setTimeout(() => {
|
||||
this.deleteValue(messageId);
|
||||
options.onStop?.('timeout', () => {
|
||||
this.createComponentCollector(messageId, options);
|
||||
});
|
||||
}, options.timeout)
|
||||
: undefined,
|
||||
idle:
|
||||
options.idle && options.idle > 0
|
||||
? setTimeout(() => {
|
||||
this.deleteValue(messageId);
|
||||
options.onStop?.('idle', () => {
|
||||
this.createComponentCollector(messageId, options);
|
||||
});
|
||||
}, options.idle)
|
||||
: undefined,
|
||||
timeout:
|
||||
options.timeout && options.timeout > 0
|
||||
? setTimeout(() => {
|
||||
this.deleteValue(messageId);
|
||||
options.onStop?.('timeout', () => {
|
||||
this.createComponentCollector(messageId, options);
|
||||
});
|
||||
}, options.timeout)
|
||||
: undefined,
|
||||
__run: (customId, callback) => {
|
||||
if (this.values.has(messageId)) {
|
||||
this.values.get(messageId)!.components.push({
|
||||
|
@ -5,16 +5,24 @@ import type {
|
||||
GatewayMessageDeleteDispatch,
|
||||
} from 'discord-api-types/v10';
|
||||
import type { Client, WorkerClient } from '../client';
|
||||
import { BaseHandler, ReplaceRegex, magicImport, type MakeRequired, type SnakeCase } from '../common';
|
||||
import { BaseHandler, type Logger, ReplaceRegex, magicImport, type MakeRequired, type SnakeCase } from '../common';
|
||||
import type { ClientEvents } from '../events/hooks';
|
||||
import * as RawEvents from '../events/hooks';
|
||||
import type { ClientEvent, ClientNameEvents } from './event';
|
||||
import type { Collectors } from '../client/collectors';
|
||||
|
||||
export type EventValue = MakeRequired<ClientEvent, '__filePath'> & { fired?: boolean };
|
||||
|
||||
export type GatewayEvents = Uppercase<SnakeCase<keyof ClientEvents>>;
|
||||
|
||||
export class EventHandler extends BaseHandler {
|
||||
constructor(
|
||||
logger: Logger,
|
||||
protected collectors: Collectors,
|
||||
) {
|
||||
super(logger);
|
||||
}
|
||||
|
||||
onFail = (event: GatewayEvents, err: unknown) => this.logger.warn('<Client>.events.onFail', err, event);
|
||||
protected filter = (path: string) => path.endsWith('.js') || (!path.endsWith('.d.ts') && path.endsWith('.ts'));
|
||||
|
||||
@ -69,6 +77,7 @@ export class EventHandler extends BaseHandler {
|
||||
break;
|
||||
}
|
||||
|
||||
await this.collectors.run(args[0].t, args[0].d);
|
||||
await this.runEvent(args[0].t, args[1], args[0].d, args[2]);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ export const config = {
|
||||
port: 8080,
|
||||
...data,
|
||||
} as InternalRuntimeConfigHTTP;
|
||||
if (isCloudfareWorker()) BaseClient._seyferConfig = obj;
|
||||
if (isCloudfareWorker()) BaseClient._seyfertConfig = obj;
|
||||
return obj;
|
||||
},
|
||||
};
|
||||
|
@ -35,6 +35,7 @@ import {
|
||||
InteractionType,
|
||||
type MessageFlags,
|
||||
type RESTPostAPIInteractionCallbackJSONBody,
|
||||
type RESTAPIAttachment,
|
||||
} from 'discord-api-types/v10';
|
||||
import { mix } from 'ts-mixer';
|
||||
import type { RawFile } from '../api';
|
||||
@ -114,7 +115,11 @@ export class BaseInteraction<
|
||||
this.user = this.member?.user ?? new User(client, interaction.user!);
|
||||
}
|
||||
|
||||
static transformBodyRequest(body: ReplyInteractionBody, self: UsingClient): APIInteractionResponse {
|
||||
static transformBodyRequest(
|
||||
body: ReplyInteractionBody,
|
||||
files: RawFile[] | undefined,
|
||||
self: UsingClient,
|
||||
): APIInteractionResponse {
|
||||
switch (body.type) {
|
||||
case InteractionResponseType.ApplicationCommandAutocompleteResult:
|
||||
case InteractionResponseType.DeferredMessageUpdate:
|
||||
@ -131,9 +136,15 @@ export class BaseInteraction<
|
||||
allowed_mentions: self.options?.allowedMentions,
|
||||
...(body.data ?? {}),
|
||||
//@ts-ignore
|
||||
components: body.data?.components?.map(x => (x instanceof ActionRow ? x.toJSON() : x)) ?? undefined,
|
||||
embeds: body.data?.embeds?.map(x => (x instanceof Embed ? x.toJSON() : x)) ?? undefined,
|
||||
attachments: body.data?.attachments?.map((x, i) => ({ id: i, ...resolveAttachment(x) })) ?? undefined,
|
||||
components: body.data?.components?.map(x => (x instanceof ActionRow ? x.toJSON() : x)),
|
||||
embeds: body.data?.embeds?.map(x => (x instanceof Embed ? x.toJSON() : x)),
|
||||
attachments:
|
||||
body.data && 'attachments' in body.data
|
||||
? body.data.attachments?.map((x, i) => ({ id: i, ...resolveAttachment(x) }))
|
||||
: (files?.map((x, id) => ({
|
||||
id,
|
||||
filename: x.name,
|
||||
})) as RESTAPIAttachment[]),
|
||||
poll: poll ? (poll instanceof PollBuilder ? poll.toJSON() : poll) : undefined,
|
||||
},
|
||||
};
|
||||
@ -166,14 +177,23 @@ export class BaseInteraction<
|
||||
| MessageUpdateBodyRequest
|
||||
| MessageCreateBodyRequest
|
||||
| MessageWebhookCreateBodyRequest,
|
||||
files: RawFile[] | undefined,
|
||||
self: UsingClient,
|
||||
) {
|
||||
const poll = (body as MessageWebhookCreateBodyRequest).poll;
|
||||
|
||||
return {
|
||||
allowed_mentions: self.options?.allowedMentions,
|
||||
attachments:
|
||||
'attachments' in body
|
||||
? body.attachments?.map((x, i) => ({ id: i, ...resolveAttachment(x) }))
|
||||
: (files?.map((x, id) => ({
|
||||
id,
|
||||
filename: x.name,
|
||||
})) as RESTAPIAttachment[]),
|
||||
...body,
|
||||
components: body.components?.map(x => (x instanceof ActionRow ? x.toJSON() : x)) ?? undefined,
|
||||
embeds: body?.embeds?.map(x => (x instanceof Embed ? x.toJSON() : x)) ?? undefined,
|
||||
components: body.components?.map(x => (x instanceof ActionRow ? x.toJSON() : x)),
|
||||
embeds: body?.embeds?.map(x => (x instanceof Embed ? x.toJSON() : x)),
|
||||
poll: poll ? (poll instanceof PollBuilder ? poll.toJSON() : poll) : undefined,
|
||||
} as T;
|
||||
}
|
||||
@ -184,9 +204,10 @@ export class BaseInteraction<
|
||||
const { files, ...rest } = body.data ?? {};
|
||||
//@ts-expect-error
|
||||
const data = body.data instanceof Modal ? body.data : rest;
|
||||
const parsedFiles = files ? await resolveFiles(files) : undefined;
|
||||
return (this.replied = this.__reply({
|
||||
body: BaseInteraction.transformBodyRequest({ data, type: body.type }, this.client),
|
||||
files: files ? await resolveFiles(files) : undefined,
|
||||
body: BaseInteraction.transformBodyRequest({ data, type: body.type }, parsedFiles, this.client),
|
||||
files: parsedFiles,
|
||||
}).then(() => (this.replied = true)));
|
||||
}
|
||||
return (this.replied = this.client.interactions.reply(this.id, this.token, body).then(() => (this.replied = true)));
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {
|
||||
ChannelFlags,
|
||||
ChannelType,
|
||||
type RESTAPIAttachment,
|
||||
VideoQualityMode,
|
||||
type APIChannelBase,
|
||||
type APIDMChannel,
|
||||
@ -40,6 +41,7 @@ import type { GuildMember } from './GuildMember';
|
||||
import type { GuildRole } from './GuildRole';
|
||||
import { DiscordBase } from './extra/DiscordBase';
|
||||
import { channelLink } from './extra/functions';
|
||||
import type { RawFile } from '..';
|
||||
|
||||
export class BaseChannel<T extends ChannelType> extends DiscordBase<APIChannelBase<ChannelType>> {
|
||||
declare type: T;
|
||||
@ -250,14 +252,24 @@ export class MessagesMethods extends DiscordBase {
|
||||
};
|
||||
}
|
||||
|
||||
static transformMessageBody<T>(body: MessageCreateBodyRequest | MessageUpdateBodyRequest, self: UsingClient) {
|
||||
static transformMessageBody<T>(
|
||||
body: MessageCreateBodyRequest | MessageUpdateBodyRequest,
|
||||
files: RawFile[] | undefined,
|
||||
self: UsingClient,
|
||||
) {
|
||||
const poll = (body as MessageCreateBodyRequest).poll;
|
||||
return {
|
||||
allowed_mentions: self.options?.allowedMentions,
|
||||
...body,
|
||||
components: body.components?.map(x => (x instanceof ActionRow ? x.toJSON() : x)) ?? undefined,
|
||||
embeds: body.embeds?.map(x => (x instanceof Embed ? x.toJSON() : x)) ?? undefined,
|
||||
attachments: body.attachments?.map((x, i) => ({ id: i, ...resolveAttachment(x) })) ?? undefined,
|
||||
attachments:
|
||||
'attachments' in body
|
||||
? body.attachments?.map((x, i) => ({ id: i, ...resolveAttachment(x) })) ?? undefined
|
||||
: (files?.map((x, id) => ({
|
||||
id,
|
||||
filename: x.name,
|
||||
})) as RESTAPIAttachment[]),
|
||||
poll: poll ? (poll instanceof PollBuilder ? poll.toJSON() : poll) : undefined,
|
||||
} as T;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user