Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat: Support new application properties and patch endpoint (#9709)
* feat: support new application endpoints

* chore: edit comment

* fix(ClientApplication): handle flags properly

* types: `readonly`

* chore: update route

* feat: add to core

* refactor(ClientApplication): add to user manager

* chore: remove comments

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
Jiralite and kodiakhq[bot] committed Oct 10, 2023
1 parent 44a3cbf commit 1fe7247
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 1 deletion.
21 changes: 20 additions & 1 deletion packages/core/src/api/applications.ts
@@ -1,7 +1,12 @@
/* eslint-disable jsdoc/check-param-names */

import type { RequestData, REST } from '@discordjs/rest';
import { type RESTGetCurrentApplicationResult, Routes } from 'discord-api-types/v10';
import {
type RESTGetCurrentApplicationResult,
type RESTPatchCurrentApplicationJSONBody,
type RESTPatchCurrentApplicationResult,
Routes,
} from 'discord-api-types/v10';

export class ApplicationsAPI {
public constructor(private readonly rest: REST) {}
Expand All @@ -15,4 +20,18 @@ export class ApplicationsAPI {
public async getCurrent({ signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.get(Routes.currentApplication(), { signal }) as Promise<RESTGetCurrentApplicationResult>;
}

/**
* Edits properties of the application associated with the requesting bot user.
*
* @see {@link https://discord.com/developers/docs/resources/application#edit-current-application}
* @param body - The new application data
* @param options - The options for editing the application
*/
public async editCurrent(body: RESTPatchCurrentApplicationJSONBody, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.patch(Routes.currentApplication(), {
body,
signal,
}) as Promise<RESTPatchCurrentApplicationResult>;
}
}
70 changes: 70 additions & 0 deletions packages/discord.js/src/structures/ClientApplication.js
Expand Up @@ -6,6 +6,7 @@ const Team = require('./Team');
const Application = require('./interfaces/Application');
const ApplicationCommandManager = require('../managers/ApplicationCommandManager');
const ApplicationFlagsBitField = require('../util/ApplicationFlagsBitField');
const DataResolver = require('../util/DataResolver');
const PermissionsBitField = require('../util/PermissionsBitField');

/**
Expand Down Expand Up @@ -119,6 +120,16 @@ class ClientApplication extends Application {
this.botRequireCodeGrant ??= null;
}

if ('bot' in data) {
/**
* The bot associated with this application.
* @type {?User}
*/
this.bot = this.client.users._add(data.bot);
} else {
this.bot ??= null;
}

if ('bot_public' in data) {
/**
* If this application's bot is public
Expand All @@ -129,6 +140,16 @@ class ClientApplication extends Application {
this.botPublic ??= null;
}

if ('interactions_endpoint_url' in data) {
/**
* This application's interaction endpoint URL.
* @type {?string}
*/
this.interactionsEndpointURL = data.interactions_endpoint_url;
} else {
this.interactionsEndpointURL ??= null;
}

if ('role_connections_verification_url' in data) {
/**
* This application's role connection verification entry point URL
Expand Down Expand Up @@ -168,6 +189,55 @@ class ClientApplication extends Application {
return !this.name;
}

/**
* Options used for editing an application.
* @typedef {Object} ClientApplicationEditOptions
* @property {string} [customInstallURL] The application's custom installation URL
* @property {string} [description] The application's description
* @property {string} [roleConnectionsVerificationURL] The application's role connection verification URL
* @property {ClientApplicationInstallParams} [installParams]
* Settings for the application's default in-app authorization
* @property {ApplicationFlagsResolvable} [flags] The flags for the application
* @property {?(BufferResolvable|Base64Resolvable)} [icon] The application's icon
* @property {?(BufferResolvable|Base64Resolvable)} [coverImage] The application's cover image
* @property {string} [interactionsEndpointURL] The application's interaction endpoint URL
* @property {string[]} [tags] The application's tags
*/

/**
* Edits this application.
* @param {ClientApplicationEditOptions} [options] The options for editing this application
* @returns {Promise<ClientApplication>}
*/
async edit({
customInstallURL,
description,
roleConnectionsVerificationURL,
installParams,
flags,
icon,
coverImage,
interactionsEndpointURL,
tags,
} = {}) {
const data = await this.client.rest.patch(Routes.currentApplication(), {
body: {
custom_install_url: customInstallURL,
description,
role_connections_verification_url: roleConnectionsVerificationURL,
install_params: installParams,
flags: flags === undefined ? undefined : ApplicationFlagsBitField.resolve(flags),
icon: icon && (await DataResolver.resolveImage(icon)),
cover_image: coverImage && (await DataResolver.resolveImage(coverImage)),
interactions_endpoint_url: interactionsEndpointURL,
tags,
},
});

this._patch(data);
return this;
}

/**
* Obtains this application from Discord.
* @returns {Promise<ClientApplication>}
Expand Down
15 changes: 15 additions & 0 deletions packages/discord.js/src/util/ApplicationFlagsBitField.js
Expand Up @@ -23,4 +23,19 @@ class ApplicationFlagsBitField extends BitField {
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/

/**
* Bitfield of the packed bits
* @type {number}
* @name ApplicationFlagsBitField#bitfield
*/

/**
* Data that can be resolved to give an application flag bit field. This can be:
* * A string (see {@link ApplicationFlagsBitField.Flags})
* * An application flag
* * An instance of ApplicationFlagsBitField
* * An Array of ApplicationFlagsResolvable
* @typedef {string|number|ApplicationFlagsBitField|ApplicationFlagsResolvable[]} ApplicationFlagsResolvable
*/

module.exports = ApplicationFlagsBitField;
17 changes: 17 additions & 0 deletions packages/discord.js/typings/index.d.ts
Expand Up @@ -496,6 +496,8 @@ export class ApplicationFlagsBitField extends BitField<ApplicationFlagsString> {
public static resolve(bit?: BitFieldResolvable<ApplicationFlagsString, number>): number;
}

export type ApplicationFlagsResolvable = BitFieldResolvable<ApplicationFlagsString, number>;

export type AutoModerationRuleResolvable = AutoModerationRule | Snowflake;

export abstract class Base {
Expand Down Expand Up @@ -1019,6 +1021,7 @@ export class ClientApplication extends Application {
private constructor(client: Client<true>, data: RawClientApplicationData);
public botPublic: boolean | null;
public botRequireCodeGrant: boolean | null;
public bot: User | null;
public commands: ApplicationCommandManager;
public guildId: Snowflake | null;
public get guild(): Guild | null;
Expand All @@ -1030,8 +1033,10 @@ export class ClientApplication extends Application {
public customInstallURL: string | null;
public owner: User | Team | null;
public get partial(): boolean;
public interactionsEndpointURL: string | null;
public roleConnectionsVerificationURL: string | null;
public rpcOrigins: string[];
public edit(optins: ClientApplicationEditOptions): Promise<ClientApplication>;
public fetch(): Promise<ClientApplication>;
public fetchRoleConnectionMetadataRecords(): Promise<ApplicationRoleConnectionMetadata[]>;
public editRoleConnectionMetadataRecords(
Expand Down Expand Up @@ -6518,6 +6523,18 @@ export interface WelcomeScreenEditOptions {
welcomeChannels?: WelcomeChannelData[];
}

export interface ClientApplicationEditOptions {
customInstallURL?: string;
description?: string;
roleConnectionsVerificationURL?: string;
installParams?: ClientApplicationInstallParams;
flags?: ApplicationFlagsResolvable;
icon?: BufferResolvable | Base64Resolvable | null;
coverImage?: BufferResolvable | Base64Resolvable | null;
interactionsEndpointURL?: string;
tags?: readonly string[];
}

export interface ClientApplicationInstallParams {
scopes: OAuth2Scopes[];
permissions: Readonly<PermissionsBitField>;
Expand Down

0 comments on commit 1fe7247

Please sign in to comment.