Skip to content

Commit

Permalink
refactor: allow discord.js builders to accept camelCase (#7424)
Browse files Browse the repository at this point in the history
  • Loading branch information
suneettipirneni authored Feb 13, 2022
1 parent f495364 commit 94bf727
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 43 deletions.
8 changes: 4 additions & 4 deletions packages/discord.js/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ exports.WebSocketManager = require('./client/websocket/WebSocketManager');
exports.WebSocketShard = require('./client/websocket/WebSocketShard');

// Structures
exports.ActionRow = require('./structures/ActionRow');
exports.Activity = require('./structures/Presence').Activity;
exports.AnonymousGuild = require('./structures/AnonymousGuild');
exports.Application = require('./structures/interfaces/Application');
Expand All @@ -80,6 +81,7 @@ exports.BaseGuild = require('./structures/BaseGuild');
exports.BaseGuildEmoji = require('./structures/BaseGuildEmoji');
exports.BaseGuildTextChannel = require('./structures/BaseGuildTextChannel');
exports.BaseGuildVoiceChannel = require('./structures/BaseGuildVoiceChannel');
exports.ButtonComponent = require('./structures/ButtonComponent');
exports.ButtonInteraction = require('./structures/ButtonInteraction');
exports.CategoryChannel = require('./structures/CategoryChannel');
exports.Channel = require('./structures/Channel').Channel;
Expand All @@ -92,7 +94,7 @@ exports.Collector = require('./structures/interfaces/Collector');
exports.CommandInteractionOptionResolver = require('./structures/CommandInteractionOptionResolver');
exports.ContextMenuCommandInteraction = require('./structures/ContextMenuCommandInteraction');
exports.DMChannel = require('./structures/DMChannel');
exports.Embed = require('@discordjs/builders').Embed;
exports.Embed = require('./structures/Embed');
exports.UnsafeEmbed = require('@discordjs/builders').UnsafeEmbed;
exports.Emoji = require('./structures/Emoji').Emoji;
exports.Guild = require('./structures/Guild').Guild;
Expand Down Expand Up @@ -131,6 +133,7 @@ exports.ReactionCollector = require('./structures/ReactionCollector');
exports.ReactionEmoji = require('./structures/ReactionEmoji');
exports.RichPresenceAssets = require('./structures/Presence').RichPresenceAssets;
exports.Role = require('./structures/Role').Role;
exports.SelectMenuComponent = require('./structures/SelectMenuComponent');
exports.SelectMenuInteraction = require('./structures/SelectMenuInteraction');
exports.StageChannel = require('./structures/StageChannel');
exports.StageInstance = require('./structures/StageInstance').StageInstance;
Expand Down Expand Up @@ -190,10 +193,7 @@ exports.StickerType = require('discord-api-types/v9').StickerType;
exports.StickerFormatType = require('discord-api-types/v9').StickerFormatType;
exports.UserFlags = require('discord-api-types/v9').UserFlags;
exports.WebhookType = require('discord-api-types/v9').WebhookType;
exports.ActionRow = require('@discordjs/builders').ActionRow;
exports.ButtonComponent = require('@discordjs/builders').ButtonComponent;
exports.UnsafeButtonComponent = require('@discordjs/builders').UnsafeButtonComponent;
exports.SelectMenuComponent = require('@discordjs/builders').SelectMenuComponent;
exports.UnsafeSelectMenuComponent = require('@discordjs/builders').UnsafeSelectMenuComponent;
exports.SelectMenuOption = require('@discordjs/builders').SelectMenuOption;
exports.UnsafeSelectMenuOption = require('@discordjs/builders').UnsafeSelectMenuOption;
Expand Down
14 changes: 14 additions & 0 deletions packages/discord.js/src/structures/ActionRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

const { ActionRow: BuildersActionRow } = require('@discordjs/builders');
const Components = require('../util/Components');

class ActionRow extends BuildersActionRow {
constructor(data) {
// TODO: Simplify when getters PR is merged.
const initData = Components.transformJSON(data);
super({ ...initData, components: initData.components ?? [] });
}
}

module.exports = ActionRow;
12 changes: 12 additions & 0 deletions packages/discord.js/src/structures/ButtonComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const { ButtonComponent: BuildersButtonComponent } = require('@discordjs/builders');
const Components = require('../util/Components');

class ButtonComponent extends BuildersButtonComponent {
constructor(data) {
super(Components.transformJSON(data));
}
}

module.exports = ButtonComponent;
12 changes: 12 additions & 0 deletions packages/discord.js/src/structures/Embed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const { Embed: BuildersEmbed } = require('@discordjs/builders');
const Embeds = require('../util/Embeds');

class Embed extends BuildersEmbed {
constructor(data) {
super({ ...Embeds.transformJSON(data) });
}
}

module.exports = Embed;
12 changes: 9 additions & 3 deletions packages/discord.js/src/structures/MessagePayload.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use strict';

const { Buffer } = require('node:buffer');
const { createComponent, Embed } = require('@discordjs/builders');
const { Embed, isJSONEncodable } = require('@discordjs/builders');
const { MessageFlags } = require('discord-api-types/v9');
const { RangeError } = require('../errors');
const Components = require('../util/Components');
const DataResolver = require('../util/DataResolver');
const Embeds = require('../util/Embeds');
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
const Util = require('../util/Util');

Expand Down Expand Up @@ -131,7 +133,9 @@ class MessagePayload {
}
}

const components = this.options.components?.map(c => createComponent(c).toJSON());
const components = this.options.components?.map(c =>
isJSONEncodable(c) ? c.toJSON() : Components.transformJSON(c),
);

let username;
let avatarURL;
Expand Down Expand Up @@ -190,7 +194,9 @@ class MessagePayload {
content,
tts,
nonce,
embeds: this.options.embeds?.map(embed => (embed instanceof Embed ? embed : new Embed(embed)).toJSON()),
embeds: this.options.embeds?.map(embed =>
embed instanceof Embed ? embed.toJSON() : Embeds.transformJSON(embed),
),
components,
username,
avatar_url: avatarURL,
Expand Down
12 changes: 12 additions & 0 deletions packages/discord.js/src/structures/SelectMenuComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const { SelectMenuComponent: BuildersSelectMenuComponent } = require('@discordjs/builders');
const Components = require('../util/Components');

class SelectMenuComponent extends BuildersSelectMenuComponent {
constructor(data) {
super(Components.transformJSON(data));
}
}

module.exports = SelectMenuComponent;
70 changes: 70 additions & 0 deletions packages/discord.js/src/util/Components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use strict';

/**
* @typedef {Object} BaseComponentData
* @property {ComponentType} type
*/

/**
* @typedef {BaseComponentData} ActionRowData
* @property {ComponentData[]} components
*/

/**
* @typedef {BaseComponentData} ButtonComponentData
* @property {ButtonStyle} style
* @property {?boolean} disabled
* @property {string} label
* @property {?APIComponentEmoji} emoji
* @property {?string} customId
* @property {?string} url
*/

/**
* @typedef {object} SelectMenuComponentOptionData
* @property {string} label
* @property {string} value
* @property {?string} description
* @property {?APIComponentEmoji} emoji
* @property {?boolean} default
*/

/**
* @typedef {BaseComponentData} SelectMenuComponentData
* @property {string} customId
* @property {?boolean} disabled
* @property {?number} maxValues
* @property {?number} minValues
* @property {?SelectMenuComponentOptionData[]} options
* @property {?string} placeholder
*/

/**
* @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} ComponentData
*/

class Components extends null {
/**
* Transforms json data into api-compatible json data.
* @param {ComponentData|APIMessageComponent} data The data to transform.
* @returns {APIMessageComponentData}
*/
static transformJSON(data) {
return {
type: data?.type,
custom_id: data?.customId ?? data?.custom_id,
disabled: data?.disabled,
style: data?.style,
label: data?.label,
emoji: data?.emoji,
url: data?.url,
options: data?.options,
placeholder: data?.placeholder,
min_values: data?.minValues ?? data?.min_values,
max_values: data?.maxValues ?? data?.max_values,
components: data?.components?.map(c => Components.transformJSON(c)),
};
}
}

module.exports = Components;
81 changes: 81 additions & 0 deletions packages/discord.js/src/util/Embeds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use strict';

/**
* @typedef {Object} EmbedData
* @property {?string} title
* @property {?EmbedType} type
* @property {?string} description
* @property {?string} url
* @property {?string} timestamp
* @property {?number} color
* @property {?EmbedFooterData} footer
* @property {?EmbedImageData} image
* @property {?EmbedImageData} thumbnail
* @property {?EmbedProviderData} provider
* @property {?EmbedAuthorData} author
* @property {?EmbedFieldData[]} fields
*/

/**
* @typedef {Object} EmbedFooterData
* @property {string} text
* @property {?string} iconURL
*/

/**
* @typedef {Object} EmbedImageData
* @property {?string} url
*/

/**
* @typedef {Object} EmbedProviderData
* @property {?string} name
* @property {?string} url
*/

/**
* @typedef {Object} EmbedAuthorData
* @property {string} name
* @property {?string} url
* @property {?string} iconURL
*/

/**
* @typedef {Object} EmbedFieldData
* @property {string} name
* @property {string} value
* @property {?boolean} inline
*/

class Embeds extends null {
/**
* Transforms json data into api-compatible json data.
* @param {EmbedData|APIEmbed} data The data to transform.
* @returns {APIEmbed}
*/
static transformJSON(data) {
return {
title: data?.title,
type: data?.type,
description: data?.description,
url: data?.url,
timestamp: data?.timestamp,
color: data?.color,
footer: {
test: data?.footer?.text,
icon_url: data?.footer?.iconURL ?? data?.footer?.icon_url,
},
image: data?.image,
thumbnail: data?.thumbnail,
provider: data?.provider,
author: {
name: data?.author?.name,
text: data?.author?.text,
icon_url: data?.author?.iconURL ?? data?.author?.icon_url,
},
fields: data?.fields,
};
}
}

module.exports = Embeds;
Loading

0 comments on commit 94bf727

Please sign in to comment.