mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
feat: better support for applications and their resources (#328)
* feat: stuff * fix: :b * chore: apply formatting * fix: lol --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
7849ad1235
commit
a677ec795c
@ -14,12 +14,15 @@ import type {
|
||||
RESTGetAPIEntitlementsResult,
|
||||
RESTGetAPIGuildApplicationCommandsPermissionsResult,
|
||||
RESTGetAPISKUsResult,
|
||||
RESTGetCurrentApplicationResult,
|
||||
RESTPatchAPIApplicationCommandJSONBody,
|
||||
RESTPatchAPIApplicationCommandResult,
|
||||
RESTPatchAPIApplicationEmojiJSONBody,
|
||||
RESTPatchAPIApplicationEmojiResult,
|
||||
RESTPatchAPIApplicationGuildCommandJSONBody,
|
||||
RESTPatchAPIApplicationGuildCommandResult,
|
||||
RESTPatchCurrentApplicationJSONBody,
|
||||
RESTPatchCurrentApplicationResult,
|
||||
RESTPostAPIApplicationCommandsJSONBody,
|
||||
RESTPostAPIApplicationCommandsResult,
|
||||
RESTPostAPIApplicationEmojiJSONBody,
|
||||
@ -36,11 +39,17 @@ import type {
|
||||
RESTPutAPIApplicationRoleConnectionMetadataJSONBody,
|
||||
RESTPutAPIApplicationRoleConnectionMetadataResult,
|
||||
RESTPutAPIGuildApplicationCommandsPermissionsResult,
|
||||
RestGetAPIApplicationActivityInstanceResult,
|
||||
} from '../../types';
|
||||
import type { RestArguments, RestArgumentsNoBody } from '../api';
|
||||
|
||||
export interface ApplicationRoutes {
|
||||
applications: (id: string) => {
|
||||
get(args?: RestArgumentsNoBody): Promise<RESTGetCurrentApplicationResult>;
|
||||
patch(args: RestArguments<RESTPatchCurrentApplicationJSONBody>): Promise<RESTPatchCurrentApplicationResult>;
|
||||
'activity-instances': (id: string) => {
|
||||
get(args?: RestArgumentsNoBody): Promise<RestGetAPIApplicationActivityInstanceResult>;
|
||||
};
|
||||
guilds: (id: string) => {
|
||||
commands: {
|
||||
get(
|
||||
|
36
src/cache/resources/emojis.ts
vendored
36
src/cache/resources/emojis.ts
vendored
@ -1,10 +1,10 @@
|
||||
import type { CacheFrom, ReturnCache } from '../..';
|
||||
import type { ApplicationEmojiStructure, CacheFrom, ReturnCache } from '../..';
|
||||
import { type GuildEmojiStructure, Transformers } from '../../client/transformers';
|
||||
import { fakePromise } from '../../common';
|
||||
import type { APIEmoji } from '../../types';
|
||||
import type { APIApplicationEmoji, APIEmoji } from '../../types';
|
||||
import { GuildRelatedResource } from './default/guild-related';
|
||||
|
||||
export class Emojis extends GuildRelatedResource<any, APIEmoji> {
|
||||
export class Emojis extends GuildRelatedResource<any, APIEmoji | APIApplicationEmoji> {
|
||||
namespace = 'emoji';
|
||||
|
||||
//@ts-expect-error
|
||||
@ -12,19 +12,25 @@ export class Emojis extends GuildRelatedResource<any, APIEmoji> {
|
||||
return true;
|
||||
}
|
||||
|
||||
override get(id: string): ReturnCache<GuildEmojiStructure | undefined> {
|
||||
return fakePromise(super.get(id)).then(rawEmoji =>
|
||||
rawEmoji ? Transformers.GuildEmoji(this.client, rawEmoji, rawEmoji.guild_id) : undefined,
|
||||
);
|
||||
override get(id: string): ReturnCache<GuildEmojiStructure | ApplicationEmojiStructure | undefined> {
|
||||
return fakePromise(super.get(id)).then(rawEmoji => {
|
||||
if (!rawEmoji) return undefined;
|
||||
if (rawEmoji.guild_id === this.client.applicationId) return Transformers.ApplicationEmoji(this.client, rawEmoji);
|
||||
return Transformers.GuildEmoji(this.client, rawEmoji, rawEmoji.guild_id);
|
||||
});
|
||||
}
|
||||
|
||||
raw(id: string): ReturnCache<APIEmoji | undefined> {
|
||||
return super.get(id);
|
||||
}
|
||||
|
||||
override bulk(ids: string[]): ReturnCache<GuildEmojiStructure[]> {
|
||||
override bulk(ids: string[]): ReturnCache<(GuildEmojiStructure | ApplicationEmojiStructure)[]> {
|
||||
return fakePromise(super.bulk(ids) as (APIEmoji & { id: string; guild_id: string })[]).then(emojis =>
|
||||
emojis.map(rawEmoji => Transformers.GuildEmoji(this.client, rawEmoji, rawEmoji.guild_id)),
|
||||
emojis.map(rawEmoji => {
|
||||
if (rawEmoji.guild_id === this.client.applicationId)
|
||||
return Transformers.ApplicationEmoji(this.client, rawEmoji as APIApplicationEmoji);
|
||||
return Transformers.GuildEmoji(this.client, rawEmoji, rawEmoji.guild_id);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@ -32,13 +38,19 @@ export class Emojis extends GuildRelatedResource<any, APIEmoji> {
|
||||
return super.bulk(ids);
|
||||
}
|
||||
|
||||
override values(guild: string): ReturnCache<GuildEmojiStructure[]> {
|
||||
override values(guild: string): ReturnCache<(GuildEmojiStructure | ApplicationEmojiStructure)[]> {
|
||||
return fakePromise(super.values(guild) as (APIEmoji & { id: string; guild_id: string })[]).then(emojis =>
|
||||
emojis.map(rawEmoji => Transformers.GuildEmoji(this.client, rawEmoji, rawEmoji.guild_id)),
|
||||
emojis.map(rawEmoji => {
|
||||
if (rawEmoji.guild_id === this.client.applicationId)
|
||||
return Transformers.ApplicationEmoji(this.client, rawEmoji as APIApplicationEmoji);
|
||||
return Transformers.GuildEmoji(this.client, rawEmoji, rawEmoji.guild_id);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
valuesRaw(guild: string): ReturnCache<(APIEmoji & { id: string; guild_id: string })[]> {
|
||||
valuesRaw(
|
||||
guild: string,
|
||||
): ReturnCache<(((APIEmoji & { id: string }) | APIApplicationEmoji) & { guild_id: string })[]> {
|
||||
return super.values(guild);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,14 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
|
||||
super(options);
|
||||
}
|
||||
|
||||
get applicationId() {
|
||||
return this.me?.application.id ?? super.applicationId;
|
||||
}
|
||||
|
||||
set applicationId(id: string) {
|
||||
super.applicationId = id;
|
||||
}
|
||||
|
||||
setServices({
|
||||
gateway,
|
||||
...rest
|
||||
|
@ -2,6 +2,7 @@ import { type CustomStructures, OptionResolver } from '../commands';
|
||||
import type { StructStates } from '../common/';
|
||||
import {
|
||||
AnonymousGuild,
|
||||
ApplicationEmoji,
|
||||
AutoModerationRule,
|
||||
BaseChannel,
|
||||
BaseGuildChannel,
|
||||
@ -9,6 +10,7 @@ import {
|
||||
ClientUser,
|
||||
DMChannel,
|
||||
DirectoryChannel,
|
||||
Emoji,
|
||||
Entitlement,
|
||||
ForumChannel,
|
||||
Guild,
|
||||
@ -32,10 +34,13 @@ import {
|
||||
Webhook,
|
||||
WebhookMessage,
|
||||
} from '../structures';
|
||||
import { Application } from '../structures/Application';
|
||||
import type { ChannelType } from '../types';
|
||||
|
||||
export type PollStructure = InferCustomStructure<Poll, 'Poll'>;
|
||||
export type ClientUserStructure = InferCustomStructure<ClientUser, 'ClientUser'>;
|
||||
export type ApplicationStructure = InferCustomStructure<Application, 'Application'>;
|
||||
export type ApplicationEmojiStructure = InferCustomStructure<ApplicationEmoji, 'ApplicationEmoji'>;
|
||||
export type AnonymousGuildStructure = InferCustomStructure<AnonymousGuild, 'AnonymousGuild'>;
|
||||
export type AutoModerationRuleStructure = InferCustomStructure<AutoModerationRule, 'AutoModerationRule'>;
|
||||
export type BaseChannelStructure = InferCustomStructure<BaseChannel<ChannelType>, 'BaseChannel'>;
|
||||
@ -52,6 +57,7 @@ export type NewsChannelStructure = InferCustomStructure<NewsChannel, 'NewsChanne
|
||||
export type DirectoryChannelStructure = InferCustomStructure<DirectoryChannel, 'DirectoryChannel'>;
|
||||
export type GuildStructure<State extends StructStates = 'api'> = InferCustomStructure<Guild<State>, 'Guild'>;
|
||||
export type GuildBanStructure = InferCustomStructure<GuildBan, 'GuildBan'>;
|
||||
export type EmojiStructure = InferCustomStructure<Emoji, 'Emoji'>;
|
||||
export type GuildEmojiStructure = InferCustomStructure<GuildEmoji, 'GuildEmoji'>;
|
||||
export type GuildMemberStructure = InferCustomStructure<GuildMember, 'GuildMember'>;
|
||||
export type InteractionGuildMemberStructure = InferCustomStructure<InteractionGuildMember, 'InteractionGuildMember'>;
|
||||
@ -67,6 +73,12 @@ export type OptionResolverStructure = InferCustomStructure<OptionResolver, 'Opti
|
||||
export type EntitlementStructure = InferCustomStructure<Entitlement, 'Entitlement'>;
|
||||
|
||||
export const Transformers = {
|
||||
Application(...args: ConstructorParameters<typeof Application>): ApplicationStructure {
|
||||
return new Application(...args);
|
||||
},
|
||||
ApplicationEmoji(...args: ConstructorParameters<typeof ApplicationEmoji>): ApplicationEmojiStructure {
|
||||
return new ApplicationEmoji(...args);
|
||||
},
|
||||
AnonymousGuild(...args: ConstructorParameters<typeof AnonymousGuild>): AnonymousGuildStructure {
|
||||
return new AnonymousGuild(...args);
|
||||
},
|
||||
@ -118,6 +130,9 @@ export const Transformers = {
|
||||
GuildBan(...args: ConstructorParameters<typeof GuildBan>): GuildBanStructure {
|
||||
return new GuildBan(...args);
|
||||
},
|
||||
Emoji(...args: ConstructorParameters<typeof Emoji>): EmojiStructure {
|
||||
return new Emoji(...args);
|
||||
},
|
||||
GuildEmoji(...args: ConstructorParameters<typeof GuildEmoji>): GuildEmojiStructure {
|
||||
return new GuildEmoji(...args);
|
||||
},
|
||||
|
@ -96,6 +96,14 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
|
||||
return acc / this.shards.size;
|
||||
}
|
||||
|
||||
get applicationId() {
|
||||
return this.me?.application.id ?? super.applicationId;
|
||||
}
|
||||
|
||||
set applicationId(id: string) {
|
||||
super.applicationId = id;
|
||||
}
|
||||
|
||||
setServices(rest: ServicesOptions) {
|
||||
super.setServices(rest);
|
||||
if (this.options.postMessage && rest.cache?.adapter instanceof WorkerAdapter) {
|
||||
|
@ -1,90 +1,141 @@
|
||||
import { type EntitlementStructure, Transformers } from '../../client';
|
||||
import { CacheFrom, resolveImage } from '../..';
|
||||
import { type ApplicationEmojiStructure, type EntitlementStructure, Transformers } from '../../client';
|
||||
import type {
|
||||
APIEntitlement,
|
||||
RESTGetAPIEntitlementsQuery,
|
||||
RESTPostAPIApplicationEmojiJSONBody,
|
||||
RESTPatchAPIApplicationEmojiJSONBody,
|
||||
RESTPatchCurrentApplicationJSONBody,
|
||||
RESTPostAPIEntitlementBody,
|
||||
} from '../../types';
|
||||
import type { ApplicationEmojiResolvable } from '../types/resolvables';
|
||||
import { BaseShorter } from './base';
|
||||
|
||||
export class ApplicationShorter extends BaseShorter {
|
||||
/**
|
||||
* Lists the emojis for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @returns The emojis.
|
||||
*/
|
||||
listEmojis(applicationId: string) {
|
||||
return this.client.proxy.applications(applicationId).emojis.get();
|
||||
async listEmojis(force = false): Promise<ApplicationEmojiStructure[]> {
|
||||
if (!force) {
|
||||
const cached = (await this.client.cache.emojis?.values(this.client.applicationId)) as
|
||||
| ApplicationEmojiStructure[]
|
||||
| undefined;
|
||||
if (cached?.length) return cached;
|
||||
}
|
||||
const data = await this.client.proxy.applications(this.client.applicationId).emojis.get();
|
||||
this.client.cache.emojis?.set(
|
||||
CacheFrom.Rest,
|
||||
data.items.map(e => [e.id, e]),
|
||||
this.client.applicationId,
|
||||
);
|
||||
return data.items.map(e => Transformers.ApplicationEmoji(this.client, e));
|
||||
}
|
||||
/**
|
||||
* Gets an emoji for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @param emojiId The ID of the emoji.
|
||||
* @returns The emoji.
|
||||
*/
|
||||
getEmoji(applicationId: string, emojiId: string) {
|
||||
return this.client.proxy.applications(applicationId).emojis(emojiId).get();
|
||||
async getEmoji(emojiId: string, force = false): Promise<ApplicationEmojiStructure> {
|
||||
if (!force) {
|
||||
const cached = (await this.client.cache.emojis?.get(emojiId)) as ApplicationEmojiStructure;
|
||||
if (cached) return cached;
|
||||
}
|
||||
const data = await this.client.proxy.applications(this.client.applicationId).emojis(emojiId).get();
|
||||
this.client.cache.emojis?.set(CacheFrom.Rest, data.id, this.client.applicationId, data);
|
||||
return Transformers.ApplicationEmoji(this.client, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new emoji for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @param body.name The name of the emoji.
|
||||
* @param body.image The [image data string](https://discord.com/developers/docs/reference#image-data) of the emoji.
|
||||
* @returns The created emoji.
|
||||
*/
|
||||
createEmoji(applicationId: string, body: RESTPostAPIApplicationEmojiJSONBody) {
|
||||
return this.client.proxy.applications(applicationId).emojis.post({ body });
|
||||
async createEmoji(raw: ApplicationEmojiResolvable) {
|
||||
const data = await this.client.proxy
|
||||
.applications(this.client.applicationId)
|
||||
.emojis.post({ body: { ...raw, image: await resolveImage(raw.image) } });
|
||||
this.client.cache.emojis?.set(CacheFrom.Rest, data.id, this.client.applicationId, data);
|
||||
return Transformers.ApplicationEmoji(this.client, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits an emoji for the application.
|
||||
* @param emojiId The ID of the emoji.
|
||||
* @param body.name The new name of the emoji.
|
||||
* @returns The edited emoji.
|
||||
*/
|
||||
async editEmoji(emojiId: string, body: RESTPatchAPIApplicationEmojiJSONBody) {
|
||||
const data = await this.client.proxy.applications(this.client.applicationId).emojis(emojiId).patch({ body });
|
||||
this.client.cache.emojis?.patch(CacheFrom.Rest, emojiId, this.client.applicationId, data);
|
||||
return Transformers.ApplicationEmoji(this.client, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an emoji for the application.
|
||||
* @param emojiId The ID of the emoji.
|
||||
*/
|
||||
deleteEmoji(emojiId: string) {
|
||||
return this.client.proxy.applications(this.client.applicationId).emojis(emojiId).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the entitlements for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @param [query] The query parameters.
|
||||
*/
|
||||
listEntitlements(applicationId: string, query?: RESTGetAPIEntitlementsQuery): Promise<EntitlementStructure[]> {
|
||||
listEntitlements(query?: RESTGetAPIEntitlementsQuery): Promise<EntitlementStructure[]> {
|
||||
return this.client.proxy
|
||||
.applications(applicationId)
|
||||
.applications(this.client.applicationId)
|
||||
.entitlements.get({ query })
|
||||
.then(et => et.map(e => Transformers.Entitlement(this.client, e)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes an entitlement for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @param entitlementId The ID of the entitlement.
|
||||
*/
|
||||
consumeEntitlement(applicationId: string, entitlementId: string) {
|
||||
return this.client.proxy.applications(applicationId).entitlements(entitlementId).consume.post();
|
||||
consumeEntitlement(entitlementId: string) {
|
||||
return this.client.proxy.applications(this.client.applicationId).entitlements(entitlementId).consume.post();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a test entitlement for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @param body The body of the request.
|
||||
*/
|
||||
createTestEntitlement(applicationId: string, body: RESTPostAPIEntitlementBody): Promise<EntitlementStructure> {
|
||||
createTestEntitlement(body: RESTPostAPIEntitlementBody): Promise<EntitlementStructure> {
|
||||
return this.client.proxy
|
||||
.applications(applicationId)
|
||||
.applications(this.client.applicationId)
|
||||
.entitlements.post({ body })
|
||||
.then(et => Transformers.Entitlement(this.client, et as APIEntitlement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a test entitlement for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @param entitlementId The ID of the entitlement.
|
||||
*/
|
||||
deleteTestEntitlement(applicationId: string, entitlementId: string) {
|
||||
return this.client.proxy.applications(applicationId).entitlements(entitlementId).delete();
|
||||
deleteTestEntitlement(entitlementId: string) {
|
||||
return this.client.proxy.applications(this.client.applicationId).entitlements(entitlementId).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the SKUs for the application.
|
||||
* @param applicationId The ID of the application.
|
||||
* @returns The SKUs.
|
||||
*/
|
||||
listSKUs(applicationId: string) {
|
||||
return this.client.proxy.applications(applicationId).skus.get();
|
||||
listSKUs() {
|
||||
return this.client.proxy.applications(this.client.applicationId).skus.get();
|
||||
}
|
||||
|
||||
async fetch() {
|
||||
const data = await this.client.proxy.applications('@me').get();
|
||||
return Transformers.Application(this.client, data);
|
||||
}
|
||||
|
||||
async edit(body: RESTPatchCurrentApplicationJSONBody) {
|
||||
const data = await this.client.proxy.applications('@me').patch({ body });
|
||||
return Transformers.Application(this.client, data);
|
||||
}
|
||||
|
||||
getActivityInstance(instanceId: string) {
|
||||
return this.client.proxy.applications(this.client.applicationId)['activity-instances'](instanceId).get();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ export class BanShorter extends BaseShorter {
|
||||
*/
|
||||
async bulkCreate(guildId: string, body: RESTPostAPIGuildBulkBanJSONBody, reason?: string) {
|
||||
const bans = await this.client.proxy.guilds(guildId)['bulk-bans'].post({ reason, body });
|
||||
for (const id of bans.banned_users) this.client.cache.members?.removeIfNI('GuildModeration', id, guildId);
|
||||
await Promise.all(
|
||||
bans.banned_users.map(id => this.client.cache.members?.removeIfNI('GuildModeration', id, guildId)),
|
||||
);
|
||||
return bans;
|
||||
}
|
||||
|
||||
@ -70,12 +72,11 @@ export class BanShorter extends BaseShorter {
|
||||
* @returns A Promise that resolves to an array of listed bans.
|
||||
*/
|
||||
async list(guildId: string, query?: RESTGetAPIGuildBansQuery, force = false): Promise<GuildBanStructure[]> {
|
||||
let bans: APIBan[] | GuildBanStructure[];
|
||||
if (!force) {
|
||||
bans = (await this.client.cache.bans?.values(guildId)) ?? [];
|
||||
if (bans.length) return bans;
|
||||
const bans = await this.client.cache.bans?.values(guildId);
|
||||
if (bans?.length) return bans;
|
||||
}
|
||||
bans = await this.client.proxy.guilds(guildId).bans.get({
|
||||
const bans = await this.client.proxy.guilds(guildId).bans.get({
|
||||
query,
|
||||
});
|
||||
await this.client.cache.bans?.set(
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { CacheFrom } from '../../cache';
|
||||
import type { Channels } from '../../cache/resources/channels';
|
||||
import type { Overwrites } from '../../cache/resources/overwrites';
|
||||
import { type MessageStructure, type ThreadChannelStructure, Transformers } from '../../client/transformers';
|
||||
import { type AllChannels, BaseChannel, type GuildMember, type GuildRole, channelFrom } from '../../structures';
|
||||
@ -29,9 +28,8 @@ export class ChannelShorter extends BaseShorter {
|
||||
}
|
||||
|
||||
async raw(id: string, force?: boolean): Promise<APIChannel> {
|
||||
let channel: APIChannel | ReturnType<Channels['raw']>;
|
||||
if (!force) {
|
||||
channel = await this.client.cache.channels?.raw(id);
|
||||
const channel = await this.client.cache.channels?.raw(id);
|
||||
const overwrites = await this.client.cache.overwrites?.raw(id);
|
||||
if (channel) {
|
||||
if (overwrites) (channel as APIGuildChannel<ChannelType>).permission_overwrites = overwrites;
|
||||
@ -39,7 +37,7 @@ export class ChannelShorter extends BaseShorter {
|
||||
}
|
||||
}
|
||||
|
||||
channel = await this.client.proxy.channels(id).get();
|
||||
const channel = await this.client.proxy.channels(id).get();
|
||||
await this.client.cache.channels?.patch(
|
||||
CacheFrom.Rest,
|
||||
id,
|
||||
@ -198,11 +196,11 @@ export class ChannelShorter extends BaseShorter {
|
||||
if (checkAdmin && role.permissions.has([PermissionFlagsBits.Administrator])) {
|
||||
return new PermissionsBitField(PermissionsBitField.All);
|
||||
}
|
||||
const channelOverwrites = (await this.client.cache.overwrites?.get(channelId)) ?? [];
|
||||
|
||||
const permissions = new PermissionsBitField(role.permissions.bits);
|
||||
const channelOverwrites = await this.client.cache.overwrites?.get(channelId);
|
||||
if (!channelOverwrites) return permissions;
|
||||
const everyoneOverwrites = channelOverwrites.find(x => x.id === role.guildId);
|
||||
const roleOverwrites = channelOverwrites.find(x => x.id === role.id);
|
||||
const permissions = new PermissionsBitField(role.permissions.bits);
|
||||
|
||||
permissions.remove([everyoneOverwrites?.deny.bits ?? 0n]);
|
||||
permissions.add([everyoneOverwrites?.allow.bits ?? 0n]);
|
||||
|
@ -14,14 +14,11 @@ export class EmojiShorter extends BaseShorter {
|
||||
* @returns A Promise that resolves to an array of emojis.
|
||||
*/
|
||||
async list(guildId: string, force = false): Promise<GuildEmojiStructure[]> {
|
||||
let emojis: APIEmoji[] | GuildEmojiStructure[];
|
||||
if (!force) {
|
||||
emojis = (await this.client.cache.emojis?.values(guildId)) ?? [];
|
||||
if (emojis.length) {
|
||||
return emojis;
|
||||
}
|
||||
const cached = (await this.client.cache.emojis?.values(guildId)) as GuildEmojiStructure[] | undefined;
|
||||
if (cached?.length) return cached;
|
||||
}
|
||||
emojis = await this.client.proxy.guilds(guildId).emojis.get();
|
||||
const emojis = await this.client.proxy.guilds(guildId).emojis.get();
|
||||
await this.client.cache.emojis?.set(
|
||||
CacheFrom.Rest,
|
||||
emojis.map<[string, APIEmoji]>(x => [x.id!, x]),
|
||||
@ -58,12 +55,11 @@ export class EmojiShorter extends BaseShorter {
|
||||
* @returns A Promise that resolves to the fetched emoji.
|
||||
*/
|
||||
async fetch(guildId: string, emojiId: string, force = false): Promise<GuildEmojiStructure> {
|
||||
let emoji: APIEmoji | GuildEmojiStructure | undefined;
|
||||
if (!force) {
|
||||
emoji = await this.client.cache.emojis?.get(emojiId);
|
||||
const emoji = (await this.client.cache.emojis?.get(emojiId)) as GuildEmojiStructure | undefined;
|
||||
if (emoji) return emoji;
|
||||
}
|
||||
emoji = await this.client.proxy.guilds(guildId).emojis(emojiId).get();
|
||||
const emoji = await this.client.proxy.guilds(guildId).emojis(emojiId).get();
|
||||
return Transformers.GuildEmoji(this.client, emoji, guildId);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,14 @@
|
||||
import type { EmbedColors } from '..';
|
||||
import type { EmbedColors, OmitInsert } from '..';
|
||||
import type { Attachment, AttachmentDataType, AttachmentResolvable } from '../../builders';
|
||||
import type { GuildMember } from '../../structures';
|
||||
import type { APIGuildMember, APIPartialEmoji } from '../../types';
|
||||
import type { APIGuildMember, APIPartialEmoji, RESTPostAPIApplicationEmojiJSONBody } from '../../types';
|
||||
|
||||
export type EmojiResolvable = string | Partial<APIPartialEmoji> | `<${string | undefined}:${string}:${string}>`;
|
||||
export type GuildMemberResolvable = string | Partial<GuildMember> | APIGuildMember;
|
||||
export type ColorResolvable = `#${string}` | number | keyof typeof EmbedColors | 'Random' | [number, number, number];
|
||||
export type ImageResolvable = { data: AttachmentResolvable; type: AttachmentDataType } | Attachment;
|
||||
export type ApplicationEmojiResolvable = OmitInsert<
|
||||
RESTPostAPIApplicationEmojiJSONBody,
|
||||
'image',
|
||||
{ image: ImageResolvable }
|
||||
>;
|
||||
|
61
src/structures/Application.ts
Normal file
61
src/structures/Application.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import type { UsingClient } from '..';
|
||||
import type { ApplicationEmojiResolvable, ObjectToLower } from '../common';
|
||||
import type {
|
||||
APIApplication,
|
||||
RESTPatchAPIApplicationEmojiJSONBody,
|
||||
RESTPatchCurrentApplicationJSONBody,
|
||||
} from '../types';
|
||||
import { DiscordBase } from './extra/DiscordBase';
|
||||
|
||||
export interface Application extends ObjectToLower<APIApplication> {}
|
||||
|
||||
/**
|
||||
* Due to current limitations, this is exclusively for the current application.
|
||||
*/
|
||||
export class Application extends DiscordBase<APIApplication> {
|
||||
constructor(client: UsingClient, data: APIApplication) {
|
||||
// override any id for safety
|
||||
data.id = client.applicationId;
|
||||
super(client, data);
|
||||
}
|
||||
/**
|
||||
* Fetch the current application.
|
||||
*/
|
||||
fetch() {
|
||||
return this.client.applications.fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the current application.
|
||||
*/
|
||||
edit(data: RESTPatchCurrentApplicationJSONBody) {
|
||||
return this.client.applications.edit(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an activity instance.
|
||||
*/
|
||||
getActivityInstance(instanceId: string) {
|
||||
return this.client.applications.getActivityInstance(instanceId);
|
||||
}
|
||||
|
||||
emojis = {
|
||||
/**
|
||||
* Get an application emoji.
|
||||
*/
|
||||
fetch: (id: string) => this.client.applications.getEmoji(id),
|
||||
/**
|
||||
* Get the application emojis.
|
||||
*/
|
||||
list: () => this.client.applications.listEmojis(),
|
||||
/**
|
||||
* Create an application emoji.
|
||||
*/
|
||||
create: (data: ApplicationEmojiResolvable) => this.client.applications.createEmoji(data),
|
||||
/**
|
||||
* Edit an application emoji.
|
||||
*/
|
||||
edit: (emojiId: string, body: RESTPatchAPIApplicationEmojiJSONBody) =>
|
||||
this.client.applications.editEmoji(emojiId, body),
|
||||
};
|
||||
}
|
@ -1,25 +1,54 @@
|
||||
import { type ClientUserStructure, Transformers } from '../client';
|
||||
import type { ClientUserStructure } from '../client';
|
||||
import type { UsingClient } from '../commands';
|
||||
import type { GatewayReadyDispatchData, RESTPatchAPICurrentUserJSONBody } from '../types';
|
||||
import { User } from './User';
|
||||
|
||||
/**
|
||||
* Represents a client user that extends the base User class.
|
||||
* This class is used to interact with the authenticated user.
|
||||
*
|
||||
* @extends User
|
||||
*/
|
||||
export class ClientUser extends User {
|
||||
/**
|
||||
* Indicates if the user is a bot.
|
||||
* @type {true}
|
||||
*/
|
||||
bot = true;
|
||||
|
||||
/**
|
||||
* Creates an instance of ClientUser.
|
||||
*
|
||||
* @param client - The client instance used for making API requests.
|
||||
* @param data - The user data received from the gateway.
|
||||
* @param application - The application data received from the gateway.
|
||||
*/
|
||||
constructor(
|
||||
client: UsingClient,
|
||||
data: GatewayReadyDispatchData['user'],
|
||||
public application: GatewayReadyDispatchData['application'],
|
||||
readonly application: GatewayReadyDispatchData['application'],
|
||||
) {
|
||||
super(client, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the current user data from the API.
|
||||
*
|
||||
* @returns A promise that resolves to the ClientUserStructure.
|
||||
*/
|
||||
async fetch(): Promise<ClientUserStructure> {
|
||||
const data = await this.api.users('@me').get();
|
||||
return Transformers.ClientUser(this.client, data, this.application);
|
||||
return this.__patchThis(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the current user data.
|
||||
*
|
||||
* @param body - The data to update the user with.
|
||||
* @returns A promise that resolves to the updated ClientUserStructure.
|
||||
*/
|
||||
async edit(body: RESTPatchAPICurrentUserJSONBody): Promise<ClientUserStructure> {
|
||||
const data = await this.api.users('@me').patch({ body });
|
||||
return Transformers.ClientUser(this.client, data, this.application);
|
||||
return this.__patchThis(data);
|
||||
}
|
||||
}
|
||||
|
@ -2,45 +2,23 @@ import type { BaseCDNUrlOptions } from '../api';
|
||||
import type { ReturnCache } from '../cache';
|
||||
import type { GuildEmojiStructure, GuildStructure } from '../client';
|
||||
import type { UsingClient } from '../commands';
|
||||
import { type EmojiShorter, Formatter, type MethodContext, type ObjectToLower } from '../common';
|
||||
import type { APIEmoji, RESTPatchAPIChannelJSONBody, RESTPatchAPIGuildEmojiJSONBody } from '../types';
|
||||
import { type EmojiShorter, Formatter, type MethodContext, type ObjectToLower, type When } from '../common';
|
||||
import type {
|
||||
APIApplicationEmoji,
|
||||
APIEmoji,
|
||||
RESTPatchAPIApplicationEmojiJSONBody,
|
||||
RESTPatchAPIGuildEmojiJSONBody,
|
||||
} from '../types';
|
||||
import { User } from './User';
|
||||
import { DiscordBase } from './extra/DiscordBase';
|
||||
|
||||
export interface GuildEmoji extends DiscordBase, ObjectToLower<Omit<APIEmoji, 'id'>> {}
|
||||
export interface Emoji extends DiscordBase, ObjectToLower<Omit<APIEmoji, 'id' | 'user'>> {}
|
||||
|
||||
export class GuildEmoji extends DiscordBase {
|
||||
constructor(
|
||||
client: UsingClient,
|
||||
data: APIEmoji,
|
||||
readonly guildId: string,
|
||||
) {
|
||||
export class Emoji<T extends boolean = false> extends DiscordBase {
|
||||
user: When<T, User>;
|
||||
constructor(client: UsingClient, data: APIEmoji) {
|
||||
super(client, { ...data, id: data.id! });
|
||||
}
|
||||
|
||||
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
||||
guild(mode: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
||||
guild(mode: 'cache' | 'rest' | 'flow' = 'flow'): unknown {
|
||||
switch (mode) {
|
||||
case 'cache':
|
||||
return (
|
||||
this.client.cache.guilds?.get(this.guildId) ||
|
||||
(this.client.cache.adapter.isAsync ? (Promise.resolve() as any) : undefined)
|
||||
);
|
||||
default:
|
||||
return this.client.guilds.fetch(this.guildId, mode === 'rest');
|
||||
}
|
||||
}
|
||||
|
||||
edit(body: RESTPatchAPIChannelJSONBody, reason?: string): Promise<GuildEmojiStructure> {
|
||||
return this.client.emojis.edit(this.guildId, this.id, body, reason);
|
||||
}
|
||||
|
||||
delete(reason?: string) {
|
||||
return this.client.emojis.delete(this.guildId, this.id, reason);
|
||||
}
|
||||
|
||||
fetch(force = false): Promise<GuildEmojiStructure> {
|
||||
return this.client.emojis.fetch(this.guildId, this.id, force);
|
||||
this.user = (data.user && new User(client, data.user)) as never;
|
||||
}
|
||||
|
||||
url(options?: BaseCDNUrlOptions) {
|
||||
@ -58,6 +36,44 @@ export class GuildEmoji extends DiscordBase {
|
||||
animated: !!this.animated,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface GuildEmoji extends Emoji {}
|
||||
|
||||
export class GuildEmoji extends Emoji {
|
||||
constructor(
|
||||
client: UsingClient,
|
||||
data: APIEmoji,
|
||||
readonly guildId: string,
|
||||
) {
|
||||
super(client, data);
|
||||
}
|
||||
|
||||
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
||||
guild(mode: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
||||
guild(mode: 'cache' | 'rest' | 'flow' = 'flow'): unknown {
|
||||
switch (mode) {
|
||||
case 'cache':
|
||||
return (
|
||||
this.client.cache.guilds?.get(this.guildId) ||
|
||||
(this.client.cache.adapter.isAsync ? (Promise.resolve() as any) : undefined)
|
||||
);
|
||||
default:
|
||||
return this.client.guilds.fetch(this.guildId, mode === 'rest');
|
||||
}
|
||||
}
|
||||
|
||||
edit(body: RESTPatchAPIGuildEmojiJSONBody, reason?: string): Promise<GuildEmojiStructure> {
|
||||
return this.client.emojis.edit(this.guildId, this.id, body, reason);
|
||||
}
|
||||
|
||||
delete(reason?: string) {
|
||||
return this.client.emojis.delete(this.guildId, this.id, reason);
|
||||
}
|
||||
|
||||
fetch(force = false): Promise<GuildEmojiStructure> {
|
||||
return this.client.emojis.fetch(this.guildId, this.id, force);
|
||||
}
|
||||
|
||||
static methods({ client, guildId }: MethodContext<{ guildId: string }>) {
|
||||
return {
|
||||
@ -71,3 +87,21 @@ export class GuildEmoji extends DiscordBase {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class ApplicationEmoji extends Emoji<true> {
|
||||
constructor(client: UsingClient, data: APIApplicationEmoji) {
|
||||
super(client, data);
|
||||
}
|
||||
|
||||
fetch() {
|
||||
return this.client.applications.getEmoji(this.id);
|
||||
}
|
||||
|
||||
edit(body: RESTPatchAPIApplicationEmojiJSONBody) {
|
||||
return this.client.applications.editEmoji(this.id, body);
|
||||
}
|
||||
|
||||
delete() {
|
||||
return this.client.applications.deleteEmoji(this.id);
|
||||
}
|
||||
}
|
@ -14,6 +14,6 @@ export class Entitlement extends DiscordBase<APIEntitlement> {
|
||||
}
|
||||
|
||||
consume() {
|
||||
return this.client.applications.consumeEntitlement(this.applicationId, this.id);
|
||||
return this.client.applications.consumeEntitlement(this.id);
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ import type { UsingClient } from '../commands';
|
||||
import type { ObjectToLower, StructPropState, StructStates, ToClass } from '../common/types/util';
|
||||
import type { APIGuild, APIPartialGuild, GatewayGuildCreateDispatchData, RESTPatchAPIGuildJSONBody } from '../types';
|
||||
import { AutoModerationRule } from './AutoModerationRule';
|
||||
import { GuildEmoji } from './Emoji';
|
||||
import { GuildBan } from './GuildBan';
|
||||
import { GuildEmoji } from './GuildEmoji';
|
||||
import { GuildMember } from './GuildMember';
|
||||
import { GuildRole } from './GuildRole';
|
||||
import { GuildTemplate } from './GuildTemplate';
|
||||
|
@ -46,14 +46,20 @@ export class BaseGuild extends DiscordBase<APIPartialGuild> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave the guild.
|
||||
*/
|
||||
leave() {
|
||||
return this.client.guilds.leave(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* iconURL gets the current guild icon.
|
||||
* @link https://discord.com/developers/docs/reference#image-formatting
|
||||
*/
|
||||
iconURL(options?: ImageOptions): string | undefined {
|
||||
if (!this.icon) {
|
||||
return;
|
||||
}
|
||||
if (!this.icon) return;
|
||||
|
||||
return this.rest.cdn.icons(this.id).get(this.icon, options);
|
||||
}
|
||||
|
||||
@ -64,9 +70,8 @@ export class BaseGuild extends DiscordBase<APIPartialGuild> {
|
||||
* @returns Splash url or void.
|
||||
*/
|
||||
splashURL(options?: ImageOptions): string | undefined {
|
||||
if (!this.splash) {
|
||||
return;
|
||||
}
|
||||
if (!this.splash) return;
|
||||
|
||||
return this.rest.cdn['discovery-splashes'](this.id).get(this.splash, options);
|
||||
}
|
||||
|
||||
@ -77,9 +82,8 @@ export class BaseGuild extends DiscordBase<APIPartialGuild> {
|
||||
* @returns Banner url or void
|
||||
*/
|
||||
bannerURL(options?: ImageOptions): string | undefined {
|
||||
if (!this.banner) {
|
||||
return;
|
||||
}
|
||||
if (!this.banner) return;
|
||||
|
||||
return this.rest.cdn.banners(this.id).get(this.banner, options);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ export * from './AnonymousGuild';
|
||||
export * from './AutoModerationRule';
|
||||
export * from './ClientUser';
|
||||
export * from './Guild';
|
||||
export * from './GuildEmoji';
|
||||
export * from './Emoji';
|
||||
export * from './GuildMember';
|
||||
export * from './GuildPreview';
|
||||
export * from './GuildRole';
|
||||
|
@ -2,8 +2,9 @@
|
||||
* Types extracted from https://discord.com/developers/docs/resources/application
|
||||
*/
|
||||
|
||||
import type { LocalizationMap } from '.';
|
||||
import type { APIEmoji, LocalizationMap } from '.';
|
||||
import type { Permissions, Snowflake } from '..';
|
||||
import type { MakeRequired } from '../../common';
|
||||
import type { APIPartialGuild } from './guild';
|
||||
import type { ApplicationIntegrationType } from './interactions';
|
||||
import type { OAuth2Scopes } from './oauth2';
|
||||
@ -292,3 +293,35 @@ export enum ApplicationRoleConnectionMetadataType {
|
||||
*/
|
||||
BooleanNotEqual,
|
||||
}
|
||||
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-instance-object
|
||||
*/
|
||||
export interface APIActivityInstance {
|
||||
application_id: string;
|
||||
instance_id: string;
|
||||
launch_id: string;
|
||||
/** Location the instance is runnning in */
|
||||
location: APIActivityLocation;
|
||||
users: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-location-object
|
||||
*/
|
||||
export interface APIActivityLocation {
|
||||
id: string;
|
||||
/** Enum describing kind of location */
|
||||
kind: ActivityLocation;
|
||||
channel_id: string;
|
||||
guild_id?: string | null;
|
||||
}
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-location-kind-enum
|
||||
*/
|
||||
export enum ActivityLocation {
|
||||
GuildChannel = 'gc',
|
||||
PrivateChannel = 'pc',
|
||||
}
|
||||
|
||||
export type APIApplicationEmoji = MakeRequired<APIEmoji, 'id' | 'user'>;
|
||||
|
@ -1,4 +1,9 @@
|
||||
import type { APIApplication, APIApplicationRoleConnectionMetadata, APIEmoji } from '../payloads';
|
||||
import type {
|
||||
APIActivityInstance,
|
||||
APIApplication,
|
||||
APIApplicationEmoji,
|
||||
APIApplicationRoleConnectionMetadata,
|
||||
} from '../payloads';
|
||||
import type { Nullable, StrictPartial } from '../utils';
|
||||
import type { RESTPatchAPIGuildEmojiJSONBody, RESTPostAPIGuildEmojiJSONBody } from './emoji';
|
||||
|
||||
@ -49,13 +54,13 @@ export type RESTPatchCurrentApplicationResult = APIApplication;
|
||||
* https://discord.com/developers/docs/resources/emoji#list-application-emojis
|
||||
*/
|
||||
export interface RESTGetAPIApplicationEmojisResult {
|
||||
emojis: APIEmoji[];
|
||||
items: APIApplicationEmoji[];
|
||||
}
|
||||
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/emoji#get-application-emoji
|
||||
*/
|
||||
export type RESTGetAPIApplicationEmojiResult = APIEmoji;
|
||||
export type RESTGetAPIApplicationEmojiResult = APIApplicationEmoji;
|
||||
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/emoji#create-application-emoji-json-params
|
||||
@ -65,7 +70,7 @@ export type RESTPostAPIApplicationEmojiJSONBody = Pick<RESTPostAPIGuildEmojiJSON
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/emoji#create-application-emoji
|
||||
*/
|
||||
export type RESTPostAPIApplicationEmojiResult = APIEmoji;
|
||||
export type RESTPostAPIApplicationEmojiResult = APIApplicationEmoji;
|
||||
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/emoji#modify-application-emoji
|
||||
@ -75,9 +80,14 @@ export type RESTPatchAPIApplicationEmojiJSONBody = Pick<RESTPatchAPIGuildEmojiJS
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/emoji#modify-application-emoji
|
||||
*/
|
||||
export type RESTPatchAPIApplicationEmojiResult = APIEmoji;
|
||||
export type RESTPatchAPIApplicationEmojiResult = APIApplicationEmoji;
|
||||
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/emoji#delete-application-emoji
|
||||
*/
|
||||
export type RESTDeleteAPIApplicationEmojiResult = never;
|
||||
|
||||
/**
|
||||
* https://discord.com/developers/docs/resources/application#get-application-activity-instance
|
||||
*/
|
||||
export type RestGetAPIApplicationActivityInstanceResult = APIActivityInstance | undefined;
|
||||
|
Loading…
x
Reference in New Issue
Block a user