feat(ClientApplication): v13 add role connections

#9072 djs
This commit is contained in:
March 7th 2023-01-26 14:10:27 +07:00
parent 2c4df35bc1
commit 361352d773
10 changed files with 246 additions and 9 deletions

View File

@ -56,19 +56,19 @@
"@discordjs/collection": "^1.3.0", "@discordjs/collection": "^1.3.0",
"@discordjs/voice": "^0.14.0", "@discordjs/voice": "^0.14.0",
"@sapphire/async-queue": "^1.5.0", "@sapphire/async-queue": "^1.5.0",
"@sapphire/shapeshift": "^3.8.0", "@sapphire/shapeshift": "^3.8.1",
"@types/node-fetch": "^2.6.2", "@types/node-fetch": "^2.6.2",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.4",
"axios": "1.1", "axios": "1.1",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"discord-api-types": "^0.37.22", "discord-api-types": "^0.37.29",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"json-bigint": "^1.0.0", "json-bigint": "^1.0.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"safe-base64": "^2.0.1-0", "safe-base64": "^2.0.1-0",
"string_decoder": "^1.3.0", "string_decoder": "^1.3.0",
"string-similarity": "^4.0.4", "string-similarity": "^4.0.4",
"ws": "^8.11.0" "ws": "^8.12.0"
}, },
"engines": { "engines": {
"node": ">=16.6.0", "node": ">=16.6.0",
@ -82,15 +82,15 @@
"@types/node": "^16.11.12", "@types/node": "^16.11.12",
"conventional-changelog-cli": "^2.2.2", "conventional-changelog-cli": "^2.2.2",
"dtslint": "^4.2.1", "dtslint": "^4.2.1",
"eslint": "^8.29.0", "eslint": "^8.32.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.25.3", "eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"husky": "^7.0.4", "husky": "^7.0.4",
"is-ci": "^3.0.1", "is-ci": "^3.0.1",
"jest": "^28.1.3", "jest": "^28.1.3",
"lint-staged": "^12.1.4", "lint-staged": "^12.1.4",
"prettier": "^2.8.1", "prettier": "^2.8.3",
"tsd": "^0.25.0", "tsd": "^0.25.0",
"tslint": "^6.1.3", "tslint": "^6.1.3",
"typescript": "^4.9.4" "typescript": "^4.9.4"

View File

@ -76,6 +76,8 @@ exports.Activity = require('./structures/Presence').Activity;
exports.AnonymousGuild = require('./structures/AnonymousGuild'); exports.AnonymousGuild = require('./structures/AnonymousGuild');
exports.Application = require('./structures/interfaces/Application'); exports.Application = require('./structures/interfaces/Application');
exports.ApplicationCommand = require('./structures/ApplicationCommand'); exports.ApplicationCommand = require('./structures/ApplicationCommand');
exports.ApplicationRoleConnectionMetadata =
require('./structures/ApplicationRoleConnectionMetadata').ApplicationRoleConnectionMetadata;
exports.AutocompleteInteraction = require('./structures/AutocompleteInteraction'); exports.AutocompleteInteraction = require('./structures/AutocompleteInteraction');
exports.AutoModerationActionExecution = require('./structures/AutoModerationActionExecution'); exports.AutoModerationActionExecution = require('./structures/AutoModerationActionExecution');
exports.AutoModerationRule = require('./structures/AutoModerationRule'); exports.AutoModerationRule = require('./structures/AutoModerationRule');

View File

@ -0,0 +1,45 @@
'use strict';
const { ApplicationRoleConnectionMetadataTypes } = require('../util/Constants');
class ApplicationRoleConnectionMetadata {
constructor(data) {
/**
* The name of this metadata field
* @type {string}
*/
this.name = data.name;
/**
* The name localizations for this metadata field
* @type {?Object<Locale, string>}
*/
this.nameLocalizations = data.name_localizations ?? null;
/**
* The description of this metadata field
* @type {string}
*/
this.description = data.description;
/**
* The description localizations for this metadata field
* @type {?Object<Locale, string>}
*/
this.descriptionLocalizations = data.description_localizations ?? null;
/**
* The dictionary key for this metadata field
* @type {string}
*/
this.key = data.key;
/**
* The type of this metadata field
* @type {ApplicationRoleConnectionMetadataType}
*/
this.type = typeof data.type === 'number' ? ApplicationRoleConnectionMetadataTypes[data.type] : data.type;
}
}
exports.ApplicationRoleConnectionMetadata = ApplicationRoleConnectionMetadata;

View File

@ -1,10 +1,12 @@
'use strict'; 'use strict';
const { Collection } = require('@discordjs/collection'); const { Collection } = require('@discordjs/collection');
const { ApplicationRoleConnectionMetadata } = require('./ApplicationRoleConnectionMetadata');
const Team = require('./Team'); const Team = require('./Team');
const Application = require('./interfaces/Application'); const Application = require('./interfaces/Application');
const ApplicationCommandManager = require('../managers/ApplicationCommandManager'); const ApplicationCommandManager = require('../managers/ApplicationCommandManager');
const ApplicationFlags = require('../util/ApplicationFlags'); const ApplicationFlags = require('../util/ApplicationFlags');
const { ApplicationRoleConnectionMetadataTypes } = require('../util/Constants');
const Permissions = require('../util/Permissions'); const Permissions = require('../util/Permissions');
/** /**
@ -155,6 +157,48 @@ class ClientApplication extends Application {
this._patch(app.application); this._patch(app.application);
return this; return this;
} }
/**
* Gets this application's role connection metadata records
* @returns {Promise<ApplicationRoleConnectionMetadata[]>}
*/
async fetchRoleConnectionMetadataRecords() {
const metadata = await this.client.api.applications(this.id)('role-connections').metadata.get();
return metadata.map(data => new ApplicationRoleConnectionMetadata(data));
}
/**
* Data for creating or editing an application role connection metadata.
* @typedef {Object} ApplicationRoleConnectionMetadataEditOptions
* @property {string} name The name of the metadata field
* @property {?Object<Locale, string>} [nameLocalizations] The name localizations for the metadata field
* @property {string} description The description of the metadata field
* @property {?Object<Locale, string>} [descriptionLocalizations] The description localizations for the metadata field
* @property {string} key The dictionary key of the metadata field
* @property {ApplicationRoleConnectionMetadataType} type The type of the metadata field
*/
/**
* Updates this application's role connection metadata records
* @param {ApplicationRoleConnectionMetadataEditOptions[]} records The new role connection metadata records
* @returns {Promise<ApplicationRoleConnectionMetadata[]>}
*/
async editRoleConnectionMetadataRecords(records) {
const newRecords = await this.client.api
.applications(this.client.user.id)('role-connections')
.metadata.put({
data: records.map(record => ({
type: typeof record.type === 'string' ? ApplicationRoleConnectionMetadataTypes[record.type] : record.type,
key: record.key,
name: record.name,
name_localizations: record.nameLocalizations,
description: record.description,
description_localizations: record.descriptionLocalizations,
})),
});
return newRecords.map(data => new ApplicationRoleConnectionMetadata(data));
}
} }
module.exports = ClientApplication; module.exports = ClientApplication;

View File

@ -1,8 +1,9 @@
'use strict'; 'use strict';
const { Collection } = require('@discordjs/collection'); const { Collection } = require('@discordjs/collection');
const { ApplicationRoleConnectionMetadata } = require('./ApplicationRoleConnectionMetadata');
const Base = require('./Base'); const Base = require('./Base');
const ApplicationFlags = require('../util/ApplicationFlags'); const ApplicationFlags = require('../util/ApplicationFlags');
const { ClientApplicationAssetTypes, Endpoints } = require('../util/Constants'); const { ClientApplicationAssetTypes, Endpoints, ApplicationRoleConnectionMetadataTypes } = require('../util/Constants');
const DataResolver = require('../util/DataResolver'); const DataResolver = require('../util/DataResolver');
const Permissions = require('../util/Permissions'); const Permissions = require('../util/Permissions');
const SnowflakeUtil = require('../util/SnowflakeUtil'); const SnowflakeUtil = require('../util/SnowflakeUtil');
@ -192,6 +193,16 @@ class DeveloperPortalApplication extends Base {
* @type {?string} * @type {?string}
*/ */
this.PrivacyPolicy = data.privacy_policy_url ?? null; this.PrivacyPolicy = data.privacy_policy_url ?? null;
if ('role_connections_verification_url' in data) {
/**
* This application's role connection verification entry point URL
* @type {?string}
*/
this.roleConnectionsVerificationURL = data.role_connections_verification_url;
} else {
this.roleConnectionsVerificationURL ??= null;
}
} }
/** /**
* The timestamp the application was created at * The timestamp the application was created at
@ -447,6 +458,48 @@ class DeveloperPortalApplication extends Base {
return undefined; return undefined;
} }
/**
* Gets this application's role connection metadata records
* @returns {Promise<ApplicationRoleConnectionMetadata[]>}
*/
async fetchRoleConnectionMetadataRecords() {
const metadata = await this.client.api.applications(this.id)('role-connections').metadata.get();
return metadata.map(data => new ApplicationRoleConnectionMetadata(data));
}
/**
* Data for creating or editing an application role connection metadata.
* @typedef {Object} ApplicationRoleConnectionMetadataEditOptions
* @property {string} name The name of the metadata field
* @property {?Object<Locale, string>} [nameLocalizations] The name localizations for the metadata field
* @property {string} description The description of the metadata field
* @property {?Object<Locale, string>} [descriptionLocalizations] The description localizations for the metadata field
* @property {string} key The dictionary key of the metadata field
* @property {ApplicationRoleConnectionMetadataType} type The type of the metadata field
*/
/**
* Updates this application's role connection metadata records
* @param {ApplicationRoleConnectionMetadataEditOptions[]} records The new role connection metadata records
* @returns {Promise<ApplicationRoleConnectionMetadata[]>}
*/
async editRoleConnectionMetadataRecords(records) {
const newRecords = await this.client.api
.applications(this.client.user.id)('role-connections')
.metadata.put({
data: records.map(record => ({
type: typeof record.type === 'string' ? ApplicationRoleConnectionMetadataTypes[record.type] : record.type,
key: record.key,
name: record.name,
name_localizations: record.nameLocalizations,
description: record.description,
description_localizations: record.descriptionLocalizations,
})),
});
return newRecords.map(data => new ApplicationRoleConnectionMetadata(data));
}
/** /**
* When concatenated with a string, this automatically returns the application's name instead of the * When concatenated with a string, this automatically returns the application's name instead of the
* Application object. * Application object.

View File

@ -57,6 +57,16 @@ class Application extends Base {
} else { } else {
this.icon ??= null; this.icon ??= null;
} }
if ('role_connections_verification_url' in data) {
/**
* This application's role connection verification entry point URL
* @type {?string}
*/
this.roleConnectionsVerificationURL = data.role_connections_verification_url;
} else {
this.roleConnectionsVerificationURL ??= null;
}
} }
/** /**

View File

@ -1483,6 +1483,35 @@ exports.ApplicationCommandOptionTypes = createEnum([
*/ */
exports.ApplicationCommandPermissionTypes = createEnum([null, 'ROLE', 'USER']); exports.ApplicationCommandPermissionTypes = createEnum([null, 'ROLE', 'USER']);
/**
* Each metadata type offers a comparison operation that allows
* guilds to configure role requirements based on metadata values stored by the bot.
* Bots specify a metadata value for each user and guilds specify
* the required guild's configured value within the guild role settings.
* All available channel types:
* * INTEGER_LESS_THAN_OR_EQUAL
* * INTEGER_GREATER_THAN_OR_EQUAL
* * INTEGER_EQUAL
* * INTEGER_NOT_EQUAL
* * DATATIME_LESS_THAN_OR_EQUAL
* * DATATIME_GREATER_THAN_OR_EQUAL
* * BOOLEAN_EQUAL
* * BOOLEAN_NOT_EQUAL
* @typedef {string} ApplicationRoleConnectionMetadataType
* @see{@link https://discord.com/developers/docs/resources/application-role-connection-metadata#application-role-connection-metadata-object-application-role-connection-metadata-type}
*/
exports.ApplicationRoleConnectionMetadataTypes = createEnum(
null,
'INTEGER_LESS_THAN_OR_EQUAL',
'INTEGER_GREATER_THAN_OR_EQUAL',
'INTEGER_EQUAL',
'INTEGER_NOT_EQUAL',
'DATATIME_LESS_THAN_OR_EQUAL',
'DATATIME_GREATER_THAN_OR_EQUAL',
'BOOLEAN_EQUAL',
'BOOLEAN_NOT_EQUAL',
);
/** /**
* The type of an {@link AutoModerationRuleTriggerTypes} object: * The type of an {@link AutoModerationRuleTriggerTypes} object:
* * KEYWORD * * KEYWORD
@ -1780,6 +1809,7 @@ function createEnum(keys) {
* The type of an {@link ApplicationCommandPermissions} object. * The type of an {@link ApplicationCommandPermissions} object.
* @property {Object<ApplicationCommandType, number>} ApplicationCommandTypes * @property {Object<ApplicationCommandType, number>} ApplicationCommandTypes
* The type of an {@link ApplicationCommand} object. * The type of an {@link ApplicationCommand} object.
* @property {Object{ApplicationRoleConnectionMetadataType, number}} ApplicationRoleConnectionMetadataTypes
* @property {Object<AutoModerationRuleTriggerType, number>} AutoModerationRuleTriggerTypes Characterizes the type * @property {Object<AutoModerationRuleTriggerType, number>} AutoModerationRuleTriggerTypes Characterizes the type
* of content which can trigger the rule. * of content which can trigger the rule.
* @property {Object<AutoModerationActionType, number>} AutoModerationActionTypes * @property {Object<AutoModerationActionType, number>} AutoModerationActionTypes

11
typings/enums.d.ts vendored
View File

@ -333,3 +333,14 @@ export const enum WebhookTypes {
'Channel Follower' = 2, 'Channel Follower' = 2,
Application = 3, Application = 3,
} }
export enum ApplicationRoleConnectionMetadataTypes {
INTEGER_LESS_THAN_OR_EQUAL = 1,
INTEGER_GREATER_THAN_OR_EQUAL,
INTEGER_EQUAL,
INTEGER_NOT_EQUAL,
DATATIME_LESS_THAN_OR_EQUAL,
DATATIME_GREATER_THAN_OR_EQUAL,
BOOLEAN_EQUAL,
BOOLEAN_NOT_EQUAL,
}

31
typings/index.d.ts vendored
View File

@ -106,8 +106,10 @@ import {
SortOrderType, SortOrderType,
SelectMenuComponentTypes, SelectMenuComponentTypes,
ForumLayoutType, ForumLayoutType,
ApplicationRoleConnectionMetadataTypes,
} from './enums'; } from './enums';
import { import {
APIApplicationRoleConnectionMetadata,
APIAutoModerationRule, APIAutoModerationRule,
GatewayAutoModerationActionExecutionDispatchData, GatewayAutoModerationActionExecutionDispatchData,
RawActivityData, RawActivityData,
@ -411,6 +413,7 @@ export abstract class Application extends Base {
public icon: string | null; public icon: string | null;
public id: Snowflake; public id: Snowflake;
public name: string | null; public name: string | null;
public roleConnectionsVerificationURL: string | null;
public coverURL(options?: StaticImageURLOptions): string | null; public coverURL(options?: StaticImageURLOptions): string | null;
/** @deprecated This method is deprecated as it is unsupported and will be removed in the next major version. */ /** @deprecated This method is deprecated as it is unsupported and will be removed in the next major version. */
public fetchAssets(): Promise<ApplicationAsset[]>; public fetchAssets(): Promise<ApplicationAsset[]>;
@ -463,6 +466,7 @@ export class DeveloperPortalApplication extends Base {
public testers: Collection<Snowflake, Tester>; public testers: Collection<Snowflake, Tester>;
public TermsOfService: string | null; public TermsOfService: string | null;
public PrivacyPolicy: string | null; public PrivacyPolicy: string | null;
public roleConnectionsVerificationURL: string | null;
public fetch(): Promise<ClientApplication>; public fetch(): Promise<ClientApplication>;
public coverURL(options?: StaticImageURLOptions): string | null; public coverURL(options?: StaticImageURLOptions): string | null;
/** @deprecated This method is deprecated as it is unsupported and will be removed in the next major version. */ /** @deprecated This method is deprecated as it is unsupported and will be removed in the next major version. */
@ -480,6 +484,10 @@ export class DeveloperPortalApplication extends Base {
public delete(MFACode?: number): Promise<undefined>; public delete(MFACode?: number): Promise<undefined>;
public addAsset(image: BufferResolvable | Base64Resolvable, name: string): Promise<ApplicationAsset>; public addAsset(image: BufferResolvable | Base64Resolvable, name: string): Promise<ApplicationAsset>;
public deleteAsset(id: string): Promise<undefined>; public deleteAsset(id: string): Promise<undefined>;
public fetchRoleConnectionMetadataRecords(): Promise<ApplicationRoleConnectionMetadata[]>;
public editRoleConnectionMetadataRecords(
records: ApplicationRoleConnectionMetadataEditOptions[],
): Promise<ApplicationRoleConnectionMetadata[]>;
} }
export class DeveloperPortalManager extends BaseManager { export class DeveloperPortalManager extends BaseManager {
@ -560,6 +568,16 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public static sendContextMenu(message: Message): Promise<InteractionResponse>; public static sendContextMenu(message: Message): Promise<InteractionResponse>;
} }
export class ApplicationRoleConnectionMetadata {
private constructor(data: APIApplicationRoleConnectionMetadata);
public name: string;
public nameLocalizations: LocalizationMap | null;
public description: string;
public descriptionLocalizations: LocalizationMap | null;
public key: string;
public type: ApplicationRoleConnectionMetadataTypes;
}
export type ApplicationResolvable = Application | Activity | Snowflake; export type ApplicationResolvable = Application | Activity | Snowflake;
export type AutoModerationRuleResolvable = AutoModerationRule | Snowflake; export type AutoModerationRuleResolvable = AutoModerationRule | Snowflake;
@ -968,6 +986,10 @@ export class ClientApplication extends Application {
public readonly partial: boolean; public readonly partial: boolean;
public rpcOrigins: string[]; public rpcOrigins: string[];
public fetch(): Promise<ClientApplication>; public fetch(): Promise<ClientApplication>;
public fetchRoleConnectionMetadataRecords(): Promise<ApplicationRoleConnectionMetadata[]>;
public editRoleConnectionMetadataRecords(
records: ApplicationRoleConnectionMetadataEditOptions[],
): Promise<ApplicationRoleConnectionMetadata[]>;
} }
export class ClientPresence extends Presence { export class ClientPresence extends Presence {
@ -5178,6 +5200,15 @@ export type ApplicationFlagsString =
| 'EMBEDDED_FIRST_PARTY' | 'EMBEDDED_FIRST_PARTY'
| 'APPLICATION_COMMAND_BADGE'; | 'APPLICATION_COMMAND_BADGE';
export interface ApplicationRoleConnectionMetadataEditOptions {
name: string;
nameLocalizations?: LocalizationMap | null;
description: string;
descriptionLocalizations?: LocalizationMap | null;
key: string;
type: ApplicationRoleConnectionMetadataTypes;
}
export interface AutoModerationAction { export interface AutoModerationAction {
type: AutoModerationActionType | AutoModerationActionTypes; type: AutoModerationActionType | AutoModerationActionTypes;
metadata: AutoModerationActionMetadata; metadata: AutoModerationActionMetadata;

View File

@ -80,6 +80,7 @@ import {
APITextInputComponent, APITextInputComponent,
APIModalActionRowComponent, APIModalActionRowComponent,
APIModalSubmitInteraction, APIModalSubmitInteraction,
LocalizationMap,
} from 'discord-api-types/v9'; } from 'discord-api-types/v9';
import { GuildChannel, Guild, PermissionOverwrites, InteractionType } from '.'; import { GuildChannel, Guild, PermissionOverwrites, InteractionType } from '.';
@ -90,6 +91,7 @@ import type {
AutoModerationRuleTriggerTypes, AutoModerationRuleTriggerTypes,
InteractionTypes, InteractionTypes,
MessageComponentTypes, MessageComponentTypes,
ApplicationRoleConnectionMetadataTypes,
} from './enums'; } from './enums';
export type RawActivityData = GatewayActivity; export type RawActivityData = GatewayActivity;
@ -269,3 +271,12 @@ export interface APIAutoModerationRuleTriggerMetadata {
regex_patterns?: string[]; regex_patterns?: string[];
mention_total_limit?: number; mention_total_limit?: number;
} }
export interface APIApplicationRoleConnectionMetadata {
type: ApplicationRoleConnectionMetadataTypes;
key: string;
name: string;
name_localizations?: LocalizationMap;
description: string;
description_localizations?: LocalizationMap;
}