Compare commits

...

10 Commits

Author SHA1 Message Date
Jiralite
52a9e213c2 fix(GuildMemberManager): Allow setting own nickname (#8066) 2022-07-17 21:47:02 +02:00
Almeida
b7e62380f2 test(builders): improve coverage (#8274) 2022-07-17 21:20:26 +02:00
Lo
cafde77d73 refactor(Util)!: rename fetchRecommendedShards (#8298) 2022-07-17 21:17:49 +02:00
Rodry
b7d4e55419 types(GuildFeature): allow feature strings to be passed (#8264)
Co-authored-by: Synbulat Biishev <syjalo.dev@gmail.com>
2022-07-17 21:14:54 +02:00
Almeida
5aeed99350 docs: align webhook method return types with implementation (#8253) 2022-07-17 21:14:25 +02:00
Jiralite
452dec57ca docs: Remove @private constructor documentation (#8255) 2022-07-17 21:13:54 +02:00
Jiralite
64f814066c refactor(Embed): Add all the types (#8254) 2022-07-17 21:13:40 +02:00
Rodry
33a7a5cbdc types(CategoryChannelChildManager): fix Holds type (#8288) 2022-07-17 21:12:22 +02:00
iCrawl
edf83f02ea chore: bump dev versions 2022-07-17 21:05:21 +02:00
iCrawl
25bd771559 chore(voice): release @discordjs/voice@0.11.0 2022-07-17 21:04:18 +02:00
22 changed files with 388 additions and 153 deletions

View File

@@ -0,0 +1,73 @@
import {
APIActionRowComponent,
APIButtonComponent,
APIMessageActionRowComponent,
APISelectMenuComponent,
APITextInputComponent,
ButtonStyle,
ComponentType,
TextInputStyle,
} from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
import {
ActionRowBuilder,
ButtonBuilder,
createComponentBuilder,
SelectMenuBuilder,
TextInputBuilder,
} from '../../src/index';
describe('createComponentBuilder', () => {
test.each([ButtonBuilder, SelectMenuBuilder, TextInputBuilder])(
'passing an instance of %j should return itself',
(Builder) => {
const builder = new Builder();
expect(createComponentBuilder(builder)).toBe(builder);
},
);
test('GIVEN an action row component THEN returns a ActionRowBuilder', () => {
const actionRow: APIActionRowComponent<APIMessageActionRowComponent> = {
components: [],
type: ComponentType.ActionRow,
};
expect(createComponentBuilder(actionRow)).toBeInstanceOf(ActionRowBuilder);
});
test('GIVEN a button component THEN returns a ButtonBuilder', () => {
const button: APIButtonComponent = {
custom_id: 'abc',
style: ButtonStyle.Primary,
type: ComponentType.Button,
};
expect(createComponentBuilder(button)).toBeInstanceOf(ButtonBuilder);
});
test('GIVEN a select menu component THEN returns a SelectMenuBuilder', () => {
const selectMenu: APISelectMenuComponent = {
custom_id: 'abc',
options: [],
type: ComponentType.SelectMenu,
};
expect(createComponentBuilder(selectMenu)).toBeInstanceOf(SelectMenuBuilder);
});
test('GIVEN a text input component THEN returns a TextInputBuilder', () => {
const textInput: APITextInputComponent = {
custom_id: 'abc',
label: 'abc',
style: TextInputStyle.Short,
type: ComponentType.TextInput,
};
expect(createComponentBuilder(textInput)).toBeInstanceOf(TextInputBuilder);
});
test('GIVEN an unknown component type THEN throws error', () => {
// @ts-expect-error
expect(() => createComponentBuilder({ type: 'invalid' })).toThrowError();
});
});

View File

@@ -86,6 +86,10 @@ describe('Context Menu Commands', () => {
test('GIVEN valid builder with defaultPermission false THEN does not throw error', () => {
expect(() => getBuilder().setName('foo').setDefaultPermission(false)).not.toThrowError();
});
test('GIVEN valid builder with dmPermission false THEN does not throw error', () => {
expect(() => getBuilder().setName('foo').setDMPermission(false)).not.toThrowError();
});
});
describe('Context menu command localizations', () => {

View File

@@ -1,4 +1,5 @@
import {
APIApplicationCommandAttachmentOption,
APIApplicationCommandBooleanOption,
APIApplicationCommandChannelOption,
APIApplicationCommandIntegerOption,
@@ -12,6 +13,7 @@ import {
} from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
import {
SlashCommandAttachmentOption,
SlashCommandBooleanOption,
SlashCommandChannelOption,
SlashCommandIntegerOption,
@@ -58,6 +60,9 @@ const getRoleOption = () => new SlashCommandRoleOption().setName('owo').setDescr
const getMentionableOption = () =>
new SlashCommandMentionableOption().setName('owo').setDescription('Testing 123').setRequired(true);
const getAttachmentOption = () =>
new SlashCommandAttachmentOption().setName('attachment').setDescription('attachment').setRequired(true);
describe('Application Command toJSON() results', () => {
test('GIVEN a boolean option THEN calling toJSON should return a valid JSON', () => {
expect(getBooleanOption().toJSON()).toEqual<APIApplicationCommandBooleanOption>({
@@ -205,4 +210,13 @@ describe('Application Command toJSON() results', () => {
required: true,
});
});
test('GIVEN an attachment option THEN calling toJSON should return a valid JSON', () => {
expect(getAttachmentOption().toJSON()).toEqual<APIApplicationCommandAttachmentOption>({
name: 'attachment',
description: 'attachment',
type: ApplicationCommandOptionType.Attachment,
required: true,
});
});
});

View File

@@ -93,6 +93,7 @@ describe('Slash Commands', () => {
test('GIVEN valid array of options or choices THEN does not throw error', () => {
expect(() => SlashCommandAssertions.validateMaxOptionsLength([])).not.toThrowError();
expect(() => SlashCommandAssertions.validateChoicesLength(25)).not.toThrowError();
expect(() => SlashCommandAssertions.validateChoicesLength(25, [])).not.toThrowError();
});
@@ -133,6 +134,7 @@ describe('Slash Commands', () => {
getBuilder()
.setName('example')
.setDescription('Example command')
.setDMPermission(false)
.addBooleanOption((boolean) =>
boolean.setName('iscool').setDescription('Are we cool or what?').setRequired(true),
)

View File

@@ -1,4 +1,9 @@
import { APIModalInteractionResponseCallbackData, ComponentType, TextInputStyle } from 'discord-api-types/v10';
import {
APIModalInteractionResponseCallbackData,
APITextInputComponent,
ComponentType,
TextInputStyle,
} from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
import {
ActionRowBuilder,
@@ -49,16 +54,18 @@ describe('Modals', () => {
test('GIVEN valid fields THEN builder does not throw', () => {
expect(() =>
modal()
.setTitle('test')
.setCustomId('foobar')
.setComponents(new ActionRowBuilder())
.addComponents([new ActionRowBuilder()]),
modal().setTitle('test').setCustomId('foobar').setComponents(new ActionRowBuilder()),
).not.toThrowError();
expect(() =>
// @ts-expect-error: You can pass a TextInputBuilder and it will add it to an action row
modal().setTitle('test').setCustomId('foobar').addComponents(new TextInputBuilder()),
).not.toThrowError();
});
test('GIVEN invalid fields THEN builder does throw', () => {
expect(() => modal().setTitle('test').setCustomId('foobar').toJSON()).toThrowError();
// @ts-expect-error
expect(() => modal().setTitle('test').setCustomId(42).toJSON()).toThrowError();
});
@@ -112,4 +119,55 @@ describe('Modals', () => {
.toJSON(),
).toEqual(modalData);
});
describe('equals()', () => {
const textInput1 = new TextInputBuilder()
.setCustomId('custom id')
.setLabel('label')
.setStyle(TextInputStyle.Paragraph);
const textInput2: APITextInputComponent = {
type: ComponentType.TextInput,
custom_id: 'custom id',
label: 'label',
style: TextInputStyle.Paragraph,
};
test('GIVEN equal builders THEN returns true', () => {
const equalTextInput = new TextInputBuilder()
.setCustomId('custom id')
.setLabel('label')
.setStyle(TextInputStyle.Paragraph);
expect(textInput1.equals(equalTextInput)).toBeTruthy();
});
test('GIVEN the same builder THEN returns true', () => {
expect(textInput1.equals(textInput1)).toBeTruthy();
});
test('GIVEN equal builder and data THEN returns true', () => {
expect(textInput1.equals(textInput2)).toBeTruthy();
});
test('GIVEN different builders THEN returns false', () => {
const diffTextInput = new TextInputBuilder()
.setCustomId('custom id')
.setLabel('label 2')
.setStyle(TextInputStyle.Paragraph);
expect(textInput1.equals(diffTextInput)).toBeFalsy();
});
test('GIVEN different text input builder and data THEN returns false', () => {
const diffTextInputData: APITextInputComponent = {
type: ComponentType.TextInput,
custom_id: 'custom id',
label: 'label 2',
style: TextInputStyle.Short,
};
expect(textInput1.equals(diffTextInputData)).toBeFalsy();
});
});
});

View File

@@ -0,0 +1,42 @@
import { describe, test, expect } from 'vitest';
import {
isJSONEncodable,
isEquatable,
ActionRowBuilder,
enableValidators,
disableValidators,
isValidationEnabled,
} from '../src/index';
describe('isEquatable', () => {
test('returns true if the object is equatable', () => {
expect(isEquatable({ equals: () => true })).toBeTruthy();
});
test('returns false if the object is not equatable', () => {
expect(isEquatable({})).toBeFalsy();
});
});
describe('isJSONEncodable', () => {
test('returns true if the object is JSON encodable', () => {
expect(isJSONEncodable({ toJSON: () => ({}) })).toBeTruthy();
expect(isJSONEncodable(new ActionRowBuilder())).toBeTruthy();
});
test('returns false if the object is not JSON encodable', () => {
expect(isJSONEncodable({})).toBeFalsy();
});
});
describe('validation', () => {
test('enables validation', () => {
enableValidators();
expect(isValidationEnabled()).toBeTruthy();
});
test('disables validation', () => {
disableValidators();
expect(isValidationEnabled()).toBeFalsy();
});
});

View File

@@ -1,6 +1,6 @@
{
"name": "@discordjs/collection",
"version": "0.8.0",
"version": "0.9.0-dev",
"description": "Utility data structure used in discord.js",
"scripts": {
"test": "vitest run",

View File

@@ -42,12 +42,32 @@ class WebhookClient extends BaseClient {
}
// These are here only for documentation purposes - they are implemented by Webhook
/* eslint-disable no-empty-function */
/* eslint-disable no-empty-function, valid-jsdoc */
/**
* Sends a message with this webhook.
* @param {string|MessagePayload|WebhookMessageOptions} options The content for the reply
* @returns {Promise<APIMessage>}
*/
send() {}
sendSlackMessage() {}
/**
* Gets a message that was sent by this webhook.
* @param {Snowflake} message The id of the message to fetch
* @param {WebhookFetchMessageOptions} [options={}] The options to provide to fetch the message.
* @returns {Promise<APIMessage>} Returns the message sent by this webhook
*/
fetchMessage() {}
edit() {}
/**
* Edits a message that was sent by this webhook.
* @param {MessageResolvable} message The message to edit
* @param {string|MessagePayload|WebhookEditMessageOptions} options The options to provide
* @returns {Promise<APIMessage>} Returns the message edited by this webhook
*/
editMessage() {}
sendSlackMessage() {}
edit() {}
delete() {}
deleteMessage() {}
get createdTimestamp() {}

View File

@@ -299,11 +299,13 @@ class GuildMemberManager extends CachedManager {
}
data.roles &&= data.roles.map(role => (role instanceof Role ? role.id : role));
data.communication_disabled_until =
// eslint-disable-next-line eqeqeq
data.communicationDisabledUntil != null
? new Date(data.communicationDisabledUntil).toISOString()
: data.communicationDisabledUntil;
if (typeof data.communicationDisabledUntil !== 'undefined') {
data.communication_disabled_until =
// eslint-disable-next-line eqeqeq
data.communicationDisabledUntil != null
? new Date(data.communicationDisabledUntil).toISOString()
: data.communicationDisabledUntil;
}
let endpoint;
if (id === this.client.user.id) {

View File

@@ -8,7 +8,7 @@ const { setTimeout: sleep } = require('node:timers/promises');
const { Collection } = require('@discordjs/collection');
const Shard = require('./Shard');
const { Error, TypeError, RangeError, ErrorCodes } = require('../errors');
const { mergeDefault, fetchRecommendedShards } = require('../util/Util');
const { mergeDefault, fetchRecommendedShardCount } = require('../util/Util');
/**
* This is a utility class that makes multi-process sharding of a bot an easy and painless experience.
@@ -187,7 +187,7 @@ class ShardingManager extends EventEmitter {
async spawn({ amount = this.totalShards, delay = 5500, timeout = 30_000 } = {}) {
// Obtain/verify the number of shards to spawn
if (amount === 'auto') {
amount = await fetchRecommendedShards(this.token);
amount = await fetchRecommendedShardCount(this.token);
} else {
if (typeof amount !== 'number' || isNaN(amount)) {
throw new TypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.');

View File

@@ -6,11 +6,6 @@ const isEqual = require('fast-deep-equal');
* Represents a component
*/
class Component {
/**
* Creates a new component from API data
* @param {APIMessageComponent} data The API component data
* @private
*/
constructor(data) {
/**
* The API data associated with this component

View File

@@ -6,14 +6,9 @@ const isEqual = require('fast-deep-equal');
* Represents an embed.
*/
class Embed {
/**
* Creates a new embed object
* @param {APIEmbed} data API embed data
* @private
*/
constructor(data) {
/**
* The API embed data
* The API embed data.
* @type {APIEmbed}
* @readonly
*/
@@ -21,16 +16,16 @@ class Embed {
}
/**
* An array of fields of this embed
* @type {?Array<APIEmbedField>}
* An array of fields of this embed.
* @type {Array<APIEmbedField>}
* @readonly
*/
get fields() {
return this.data.fields ?? null;
return this.data.fields ?? [];
}
/**
* The embed title
* The title of this embed.
* @type {?string}
* @readonly
*/
@@ -39,7 +34,7 @@ class Embed {
}
/**
* The embed description
* The description of this embed.
* @type {?string}
* @readonly
*/
@@ -48,7 +43,7 @@ class Embed {
}
/**
* The embed URL
* The URL of this embed.
* @type {?string}
* @readonly
*/
@@ -57,7 +52,7 @@ class Embed {
}
/**
* The embed color
* The color of this embed.
* @type {?number}
* @readonly
*/
@@ -66,7 +61,7 @@ class Embed {
}
/**
* The timestamp of the embed in an ISO 8601 format
* The timestamp of this embed. This is in an ISO 8601 format.
* @type {?string}
* @readonly
*/
@@ -75,8 +70,16 @@ class Embed {
}
/**
* The embed thumbnail data
* @type {?EmbedImageData}
* @typedef {Object} EmbedAssetData
* @property {?string} url The URL of the image
* @property {?string} proxyURL The proxy URL of the image
* @property {?string} height The height of the image
* @property {?string} width The width of the image
*/
/**
* The thumbnail of this embed.
* @type {?EmbedAssetData}
* @readonly
*/
get thumbnail() {
@@ -90,8 +93,8 @@ class Embed {
}
/**
* The embed image data
* @type {?EmbedImageData}
* The image of this embed.
* @type {?EmbedAssetData}
* @readonly
*/
get image() {
@@ -105,16 +108,30 @@ class Embed {
}
/**
* Received video data
* @type {?EmbedVideoData}
* The video of this embed.
* @type {?EmbedAssetData}
* @readonly
*/
get video() {
return this.data.video ?? null;
if (!this.data.video) return null;
return {
url: this.data.image.url,
proxyURL: this.data.image.proxy_url,
height: this.data.image.height,
width: this.data.image.width,
};
}
/**
* The embed author data
* @typedef {Object} EmbedAuthorData
* @property {string} name The name of the author
* @property {?string} url The URL of the author
* @property {?string} iconURL The icon URL of the author
* @property {?string} proxyIconURL The proxy icon URL of the author
*/
/**
* The author of this embed.
* @type {?EmbedAuthorData}
* @readonly
*/
@@ -129,8 +146,8 @@ class Embed {
}
/**
* Received data about the embed provider
* @type {?EmbedProvider}
* The provider of this embed.
* @type {?APIEmbedProvider}
* @readonly
*/
get provider() {
@@ -138,7 +155,14 @@ class Embed {
}
/**
* The embed footer data
* @typedef {Object} EmbedFooterData
* @property {string} text The text of the footer
* @property {?string} iconURL The URL of the icon
* @property {?string} proxyIconURL The proxy URL of the icon
*/
/**
* The footer of this embed.
* @type {?EmbedFooterData}
* @readonly
*/
@@ -152,7 +176,7 @@ class Embed {
}
/**
* The accumulated length for the embed title, description, fields, footer text, and author name
* The accumulated length for the embed title, description, fields, footer text, and author name.
* @type {number}
* @readonly
*/
@@ -167,7 +191,7 @@ class Embed {
}
/**
* The hex color of the current color of the embed
* The hex color of this embed.
* @type {?string}
* @readonly
*/
@@ -178,7 +202,7 @@ class Embed {
}
/**
* Returns the API-compatible JSON for this embed
* Returns the API-compatible JSON for this embed.
* @returns {APIEmbed}
*/
toJSON() {
@@ -186,7 +210,7 @@ class Embed {
}
/**
* Whether or not the given embeds are equal
* Whether the given embeds are equal.
* @param {Embed|APIEmbed} other The embed to compare against
* @returns {boolean}
*/

View File

@@ -7,11 +7,6 @@ const { ErrorCodes } = require('../errors');
* Represents an interaction's response
*/
class InteractionResponse {
/**
* @param {BaseInteraction} interaction The interaction associated with this response
* @param {Snowflake?} id The interaction id associated with the original response
* @private
*/
constructor(interaction, id) {
/**
* The interaction associated with the interaction response

View File

@@ -148,7 +148,7 @@ class Webhook {
/**
* Sends a message with this webhook.
* @param {string|MessagePayload|WebhookMessageOptions} options The options to provide
* @returns {Promise<APIMessage>}
* @returns {Promise<Message>}
* @example
* // Send a basic message
* webhook.send('hello!')
@@ -288,7 +288,7 @@ class Webhook {
* Gets a message that was sent by this webhook.
* @param {Snowflake|'@original'} message The id of the message to fetch
* @param {WebhookFetchMessageOptions} [options={}] The options to provide to fetch the message.
* @returns {Promise<APIMessage>} Returns the message sent by this webhook
* @returns {Promise<Message>} Returns the message sent by this webhook
*/
async fetchMessage(message, { threadId } = {}) {
if (!this.token) throw new Error(ErrorCodes.WebhookTokenUnavailable);
@@ -309,7 +309,7 @@ class Webhook {
* Edits a message that was sent by this webhook.
* @param {MessageResolvable|'@original'} message The message to edit
* @param {string|MessagePayload|WebhookEditMessageOptions} options The options to provide
* @returns {Promise<APIMessage>} Returns the message edited by this webhook
* @returns {Promise<Message>} Returns the message edited by this webhook
*/
async editMessage(message, options) {
if (!this.token) throw new Error(ErrorCodes.WebhookTokenUnavailable);

View File

@@ -48,6 +48,11 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIEmbedField}
*/
/**
* @external APIEmbedProvider
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIEmbedProvider}
*/
/**
* @external APIEmoji
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIEmoji}

View File

@@ -1,48 +0,0 @@
'use strict';
/**
* @typedef {Object} EmbedData
* @property {?string} title The title of the embed
* @property {?EmbedType} type The type of the embed
* @property {?string} description The description of the embed
* @property {?string} url The URL of the embed
* @property {?string} timestamp The timestamp on the embed
* @property {?number} color The color of the embed
* @property {?EmbedFooterData} footer The footer of the embed
* @property {?EmbedImageData} image The image of the embed
* @property {?EmbedImageData} thumbnail The thumbnail of the embed
* @property {?EmbedProviderData} provider The provider of the embed
* @property {?EmbedAuthorData} author The author in the embed
* @property {?EmbedFieldData[]} fields The fields in this embed
*/
/**
* @typedef {Object} EmbedFooterData
* @property {string} text The text of the footer
* @property {?string} iconURL The URL of the icon
*/
/**
* @typedef {Object} EmbedImageData
* @property {?string} url The URL of the image
*/
/**
* @typedef {Object} EmbedProviderData
* @property {?string} name The name of the provider
* @property {?string} url The URL of the provider
*/
/**
* @typedef {Object} EmbedAuthorData
* @property {string} name The name of the author
* @property {?string} url The URL of the author
* @property {?string} iconURL The icon URL of the author
*/
/**
* @typedef {Object} EmbedFieldData
* @property {string} name The name of the field
* @property {string} value The value of the field
* @property {?boolean} inline Whether to inline this field
*/

View File

@@ -211,7 +211,7 @@ function escapeSpoiler(text) {
}
/**
* @typedef {Object} FetchRecommendedShardsOptions
* @typedef {Object} FetchRecommendedShardCountOptions
* @property {number} [guildsPerShard=1000] Number of guilds assigned per shard
* @property {number} [multipleOf=1] The multiple the shard count should round up to. (16 for large bot sharding)
*/
@@ -219,10 +219,10 @@ function escapeSpoiler(text) {
/**
* Gets the recommended shard count from Discord.
* @param {string} token Discord auth token
* @param {FetchRecommendedShardsOptions} [options] Options for fetching the recommended shard count
* @param {FetchRecommendedShardCountOptions} [options] Options for fetching the recommended shard count
* @returns {Promise<number>} The recommended number of shards
*/
async function fetchRecommendedShards(token, { guildsPerShard = 1_000, multipleOf = 1 } = {}) {
async function fetchRecommendedShardCount(token, { guildsPerShard = 1_000, multipleOf = 1 } = {}) {
if (!token) throw new DiscordError(ErrorCodes.TokenMissing);
const response = await fetch(RouteBases.api + Routes.gatewayBot(), {
method: 'GET',
@@ -555,7 +555,7 @@ module.exports = {
escapeUnderline,
escapeStrikethrough,
escapeSpoiler,
fetchRecommendedShards,
fetchRecommendedShardCount,
parseEmoji,
resolvePartialEmoji,
mergeDefault,

View File

@@ -113,7 +113,6 @@ import {
APIEmbedAuthor,
APIEmbedFooter,
APIEmbedImage,
APIEmbedVideo,
VideoQualityMode,
LocalizationMap,
LocaleString,
@@ -122,6 +121,7 @@ import {
APIChannel,
ThreadAutoArchiveDuration,
FormattingPatterns,
APIEmbedProvider,
} from 'discord-api-types/v10';
import { ChildProcess } from 'node:child_process';
import { EventEmitter } from 'node:events';
@@ -494,7 +494,7 @@ export abstract class BaseGuild extends Base {
protected constructor(client: Client, data: RawBaseGuildData);
public get createdAt(): Date;
public get createdTimestamp(): number;
public features: GuildFeature[];
public features: `${GuildFeature}`[];
public icon: string | null;
public id: Snowflake;
public name: string;
@@ -667,12 +667,12 @@ export interface EmbedData {
timestamp?: string | number | Date;
color?: number;
footer?: EmbedFooterData;
image?: EmbedImageData;
thumbnail?: EmbedImageData;
provider?: EmbedProviderData;
image?: EmbedAssetData;
thumbnail?: EmbedAssetData;
provider?: APIEmbedProvider;
author?: EmbedAuthorData;
fields?: EmbedFieldData[];
video?: EmbedVideoData;
fields?: APIEmbedField[];
video?: EmbedAssetData;
}
export interface IconData {
@@ -684,16 +684,7 @@ export type EmbedAuthorData = Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'
export type EmbedFooterData = Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'> & IconData;
export interface EmbedProviderData {
name?: string;
url?: string;
}
export interface EmbedImageData extends Omit<APIEmbedImage, 'proxy_url'> {
proxyURL?: string;
}
export interface EmbedVideoData extends Omit<APIEmbedVideo, 'proxy_url'> {
export interface EmbedAssetData extends Omit<APIEmbedImage, 'proxy_url'> {
proxyURL?: string;
}
@@ -706,7 +697,7 @@ export class EmbedBuilder extends BuildersEmbed {
export class Embed {
private constructor(data: APIEmbed);
public readonly data: Readonly<APIEmbed>;
public get fields(): APIEmbedField[] | null;
public get fields(): APIEmbedField[];
public get footer(): EmbedFooterData | null;
public get title(): string | null;
public get description(): string | null;
@@ -714,11 +705,11 @@ export class Embed {
public get color(): number | null;
public get hexColor(): string | null;
public get timestamp(): string | null;
public get thumbnail(): EmbedImageData | null;
public get image(): EmbedImageData | null;
public get thumbnail(): EmbedAssetData | null;
public get image(): EmbedAssetData | null;
public get author(): EmbedAuthorData | null;
public get provider(): EmbedProviderData | null;
public get video(): EmbedVideoData | null;
public get provider(): APIEmbedProvider | null;
public get video(): EmbedAssetData | null;
public get length(): number;
public equals(other: Embed | APIEmbed): boolean;
public toJSON(): APIEmbed;
@@ -1344,7 +1335,7 @@ export class GuildPreview extends Base {
public discoverySplash: string | null;
public emojis: Collection<Snowflake, GuildPreviewEmoji>;
public stickers: Collection<Snowflake, Sticker>;
public features: GuildFeature[];
public features: `${GuildFeature}`[];
public icon: string | null;
public id: Snowflake;
public name: string;
@@ -1579,10 +1570,10 @@ export class InteractionWebhook extends PartialWebhookMixin() {
public token: string;
public send(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
public editMessage(
message: MessageResolvable,
message: MessageResolvable | '@original',
options: string | MessagePayload | WebhookEditMessageOptions,
): Promise<Message>;
public fetchMessage(message: string): Promise<Message>;
public fetchMessage(message: Snowflake | '@original'): Promise<Message>;
}
export class Invite extends Base {
@@ -2299,7 +2290,7 @@ export class ShardingManager extends EventEmitter {
public once(event: 'shardCreate', listener: (shard: Shard) => Awaitable<void>): this;
}
export interface FetchRecommendedShardsOptions {
export interface FetchRecommendedShardCountOptions {
guildsPerShard?: number;
multipleOf?: number;
}
@@ -2649,7 +2640,7 @@ export function escapeUnderline(text: string): string;
export function escapeStrikethrough(text: string): string;
export function escapeSpoiler(text: string): string;
export function cleanCodeBlockContent(text: string): string;
export function fetchRecommendedShards(token: string, options?: FetchRecommendedShardsOptions): Promise<number>;
export function fetchRecommendedShardCount(token: string, options?: FetchRecommendedShardCountOptions): Promise<number>;
export function flatten(obj: unknown, ...props: Record<string, boolean | string>[]): unknown;
export function makeError(obj: MakeErrorOptions): Error;
export function makePlainError(err: Error): MakeErrorOptions;
@@ -2813,6 +2804,13 @@ export class Webhook extends WebhookMixin() {
applicationId: null;
owner: User | APIUser;
};
public editMessage(
message: MessageResolvable,
options: string | MessagePayload | WebhookEditMessageOptions,
): Promise<Message>;
public fetchMessage(message: Snowflake, options?: WebhookFetchMessageOptions): Promise<Message>;
public send(options: string | MessagePayload | Omit<WebhookMessageOptions, 'flags'>): Promise<Message>;
}
export class WebhookClient extends WebhookMixin(BaseClient) {
@@ -3284,11 +3282,7 @@ export class BaseGuildEmojiManager extends CachedManager<Snowflake, GuildEmoji,
public resolveIdentifier(emoji: EmojiIdentifierResolvable): string | null;
}
export class CategoryChannelChildManager extends DataManager<
Snowflake,
NonCategoryGuildBasedChannel,
GuildChannelResolvable
> {
export class CategoryChannelChildManager extends DataManager<Snowflake, CategoryChildChannel, GuildChannelResolvable> {
private constructor(channel: CategoryChannel);
public channel: CategoryChannel;
@@ -4417,12 +4411,6 @@ export interface EmbedField {
inline: boolean;
}
export interface EmbedFieldData {
name: string;
value: string;
inline?: boolean;
}
export type EmojiIdentifierResolvable = string | EmojiResolvable;
export type EmojiResolvable = Snowflake | GuildEmoji | ReactionEmoji;
@@ -4759,7 +4747,7 @@ export interface GuildEditData {
preferredLocale?: Locale | null;
premiumProgressBarEnabled?: boolean;
description?: string | null;
features?: GuildFeature[];
features?: `${GuildFeature}`[];
reason?: string;
}
@@ -5436,7 +5424,7 @@ export type VoiceBasedChannel = Extract<Channel, { bitrate: number }>;
export type GuildBasedChannel = Extract<Channel, { guild: Guild }>;
export type NonCategoryGuildBasedChannel = Exclude<GuildBasedChannel, CategoryChannel>;
export type CategoryChildChannel = Exclude<Extract<Channel, { parent: CategoryChannel | null }>, CategoryChannel>;
export type NonThreadGuildBasedChannel = Exclude<GuildBasedChannel, AnyThreadChannel>;

View File

@@ -23,6 +23,7 @@ import {
APITextInputComponent,
APIEmbed,
ApplicationCommandType,
APIMessage,
} from 'discord-api-types/v10';
import {
ApplicationCommand,
@@ -130,6 +131,9 @@ import {
ThreadMemberManager,
CollectedMessageInteraction,
ShardEvents,
Webhook,
WebhookClient,
InteractionWebhook,
} from '.';
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
@@ -1691,3 +1695,20 @@ expectType<ChannelMention>(partialGroupDMChannel.toString());
expectType<UserMention>(dmChannel.toString());
expectType<UserMention>(user.toString());
expectType<UserMention>(guildMember.toString());
declare const webhook: Webhook;
declare const webhookClient: WebhookClient;
declare const interactionWebhook: InteractionWebhook;
declare const snowflake: Snowflake;
expectType<Promise<Message>>(webhook.send('content'));
expectType<Promise<Message>>(webhook.editMessage(snowflake, 'content'));
expectType<Promise<Message>>(webhook.fetchMessage(snowflake));
expectType<Promise<APIMessage>>(webhookClient.send('content'));
expectType<Promise<APIMessage>>(webhookClient.editMessage(snowflake, 'content'));
expectType<Promise<APIMessage>>(webhookClient.fetchMessage(snowflake));
expectType<Promise<Message>>(interactionWebhook.send('content'));
expectType<Promise<Message>>(interactionWebhook.editMessage(snowflake, 'content'));
expectType<Promise<Message>>(interactionWebhook.fetchMessage(snowflake));

View File

@@ -1,6 +1,6 @@
{
"name": "@discordjs/rest",
"version": "0.6.0",
"version": "0.7.0-dev",
"description": "The REST API for discord.js",
"scripts": {
"test": "vitest run",

View File

@@ -2,6 +2,46 @@
All notable changes to this project will be documented in this file.
# [@discordjs/voice@0.11.0](https://github.com/discordjs/discord.js/compare/@discordjs/voice@0.10.0...@discordjs/voice@0.11.0) - (2022-07-17)
## Bug Fixes
- **VoiceReceiver:** ParsePacket correctly (#8277) ([1a6ddbb](https://github.com/discordjs/discord.js/commit/1a6ddbbe7b99b5eff4617b99399965740c38490b))
- **recorder-example:** Bump dependencies (#8123) ([10ba008](https://github.com/discordjs/discord.js/commit/10ba0080cc20c44389779416b6a8215603eca6ca))
- **SpeakingMap:** Allow docgen to detect event name (#8236) ([c271e05](https://github.com/discordjs/discord.js/commit/c271e05223d84f643314be649344a2cfe514923f))
- **codecov:** Use cobertura (#8235) ([fd1c240](https://github.com/discordjs/discord.js/commit/fd1c24036f3c1835b918a12be8760d46f80460ac))
- **voice:** Re-add accidental removal of postbuild script ([f8739bd](https://github.com/discordjs/discord.js/commit/f8739bd9c0c691c9593761237189dc529ed0b0a3))
## Documentation
- Add codecov coverage badge to readmes (#8226) ([f6db285](https://github.com/discordjs/discord.js/commit/f6db285c073898a749fe4591cbd4463d1896daf5))
- Remove Music bot in voice examples (#8203) ([741b3c8](https://github.com/discordjs/discord.js/commit/741b3c8e279c1cc6ba862bc83299d369bc6c1bc6))
## Features
- **builder:** Add max min length in string option (#8214) ([96c8d21](https://github.com/discordjs/discord.js/commit/96c8d21f95eb366c46ae23505ba9054f44821b25))
- Add website documentation early mvp (#8183) ([d95197c](https://github.com/discordjs/discord.js/commit/d95197cc78593df4d0a8d1cc492b0e41b4ab58b8))
- **docgen:** Proper event parsing for typescript ([d4b41dd](https://github.com/discordjs/discord.js/commit/d4b41dd0815b493b599d4f4d1b6dd18cd99f91ea))
- **docgen:** Update typedoc ([b3346f4](https://github.com/discordjs/discord.js/commit/b3346f4b9b3d4f96443506643d4631dc1c6d7b21))
- Website (#8043) ([127931d](https://github.com/discordjs/discord.js/commit/127931d1df7a2a5c27923c2f2151dbf3824e50cc))
- **docgen:** Typescript support ([3279b40](https://github.com/discordjs/discord.js/commit/3279b40912e6aa61507bedb7db15a2b8668de44b))
- Docgen package (#8029) ([8b979c0](https://github.com/discordjs/discord.js/commit/8b979c0245c42fd824d8e98745ee869f5360fc86))
- Add scripts package for locally used scripts ([f2ae1f9](https://github.com/discordjs/discord.js/commit/f2ae1f9348bfd893332a9060f71a8a5f272a1b8b))
## Refactor
- Move all the config files to root (#8033) ([769ea0b](https://github.com/discordjs/discord.js/commit/769ea0bfe78c4f1d413c6b397c604ffe91e39c6a))
## Typings
- **voice:** Bring back typed events (#8109) ([70b42bb](https://github.com/discordjs/discord.js/commit/70b42bb64a4f83da0da242569b9c7921c8d1e26f))
# [@discordjs/voice@0.10.0](https://github.com/discordjs/discord.js/compare/@discordjs/voice@0.9.0...@discordjs/voice@0.10.0) - (2022-06-04)
## Styling
- Cleanup tests and tsup configs ([6b8ef20](https://github.com/discordjs/discord.js/commit/6b8ef20cb3af5b5cfd176dd0aa0a1a1e98551629))
# [@discordjs/voice@0.10.0](https://github.com/discordjs/discord.js/compare/@discordjs/voice@0.9.0...@discordjs/voice@0.10.0) - (2022-06-04)
## Styling

View File

@@ -1,6 +1,6 @@
{
"name": "@discordjs/voice",
"version": "0.11.0-dev",
"version": "0.12.0-dev",
"description": "Implementation of the Discord Voice API for node.js",
"scripts": {
"build": "tsup && node scripts/postbuild.mjs",