mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 12:03:31 +01:00
fix: use case converter for json component serialization (#7464)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
This commit is contained in:
@@ -53,6 +53,7 @@
|
|||||||
"@sapphire/snowflake": "^3.1.0",
|
"@sapphire/snowflake": "^3.1.0",
|
||||||
"@types/ws": "^8.2.2",
|
"@types/ws": "^8.2.2",
|
||||||
"discord-api-types": "^0.27.0",
|
"discord-api-types": "^0.27.0",
|
||||||
|
"lodash.snakecase": "^4.1.1",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
"ws": "^8.5.0"
|
"ws": "^8.5.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { ActionRow: BuildersActionRow } = require('@discordjs/builders');
|
const { ActionRow: BuildersActionRow } = require('@discordjs/builders');
|
||||||
const Components = require('../util/Components');
|
const Transformers = require('../util/Transformers');
|
||||||
|
|
||||||
class ActionRow extends BuildersActionRow {
|
class ActionRow extends BuildersActionRow {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
// TODO: Simplify when getters PR is merged.
|
super(Transformers.toSnakeCase(data));
|
||||||
const initData = Components.transformJSON(data);
|
|
||||||
super({ ...initData, components: initData.components ?? [] });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { ButtonComponent: BuildersButtonComponent } = require('@discordjs/builders');
|
const { ButtonComponent: BuildersButtonComponent } = require('@discordjs/builders');
|
||||||
const Components = require('../util/Components');
|
const Transformers = require('../util/Transformers');
|
||||||
|
|
||||||
class ButtonComponent extends BuildersButtonComponent {
|
class ButtonComponent extends BuildersButtonComponent {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
super(Components.transformJSON(data));
|
super(Transformers.toSnakeCase(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Embed: BuildersEmbed } = require('@discordjs/builders');
|
const { Embed: BuildersEmbed } = require('@discordjs/builders');
|
||||||
const Embeds = require('../util/Embeds');
|
const Transformers = require('../util/Transformers');
|
||||||
|
|
||||||
class Embed extends BuildersEmbed {
|
class Embed extends BuildersEmbed {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
super({ ...Embeds.transformJSON(data) });
|
super(Transformers.toSnakeCase(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ const { Buffer } = require('node:buffer');
|
|||||||
const { Embed, isJSONEncodable } = require('@discordjs/builders');
|
const { Embed, isJSONEncodable } = require('@discordjs/builders');
|
||||||
const { MessageFlags } = require('discord-api-types/v9');
|
const { MessageFlags } = require('discord-api-types/v9');
|
||||||
const { RangeError } = require('../errors');
|
const { RangeError } = require('../errors');
|
||||||
const Components = require('../util/Components');
|
|
||||||
const DataResolver = require('../util/DataResolver');
|
const DataResolver = require('../util/DataResolver');
|
||||||
const Embeds = require('../util/Embeds');
|
|
||||||
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
||||||
|
const Transformers = require('../util/Transformers');
|
||||||
const Util = require('../util/Util');
|
const Util = require('../util/Util');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,7 +133,7 @@ class MessagePayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const components = this.options.components?.map(c =>
|
const components = this.options.components?.map(c =>
|
||||||
isJSONEncodable(c) ? c.toJSON() : Components.transformJSON(c),
|
isJSONEncodable(c) ? c.toJSON() : Transformers.toSnakeCase(c),
|
||||||
);
|
);
|
||||||
|
|
||||||
let username;
|
let username;
|
||||||
@@ -195,7 +194,7 @@ class MessagePayload {
|
|||||||
tts,
|
tts,
|
||||||
nonce,
|
nonce,
|
||||||
embeds: this.options.embeds?.map(embed =>
|
embeds: this.options.embeds?.map(embed =>
|
||||||
embed instanceof Embed ? embed.toJSON() : Embeds.transformJSON(embed),
|
embed instanceof Embed ? embed.toJSON() : Transformers.toSnakeCase(embed),
|
||||||
),
|
),
|
||||||
components,
|
components,
|
||||||
username,
|
username,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { SelectMenuComponent: BuildersSelectMenuComponent } = require('@discordjs/builders');
|
const { SelectMenuComponent: BuildersSelectMenuComponent } = require('@discordjs/builders');
|
||||||
const Components = require('../util/Components');
|
const Transformers = require('../util/Transformers');
|
||||||
|
|
||||||
class SelectMenuComponent extends BuildersSelectMenuComponent {
|
class SelectMenuComponent extends BuildersSelectMenuComponent {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
super(Components.transformJSON(data));
|
super(Transformers.toSnakeCase(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,29 +42,3 @@
|
|||||||
/**
|
/**
|
||||||
* @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} ComponentData
|
* @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;
|
|
||||||
|
|||||||
@@ -46,36 +46,3 @@
|
|||||||
* @property {string} value
|
* @property {string} value
|
||||||
* @property {?boolean} inline
|
* @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;
|
|
||||||
|
|||||||
20
packages/discord.js/src/util/Transformers.js
Normal file
20
packages/discord.js/src/util/Transformers.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const snakeCase = require('lodash.snakecase');
|
||||||
|
|
||||||
|
class Transformers extends null {
|
||||||
|
/**
|
||||||
|
* Transforms camel-cased keys into snake cased keys
|
||||||
|
* @param {*} obj The object to transform
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
static toSnakeCase(obj = {}) {
|
||||||
|
if (typeof obj !== 'object' || !obj) return obj;
|
||||||
|
if (Array.isArray(obj)) return obj.map(Transformers.toSnakeCase);
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(obj).map(([key, value]) => [snakeCase(key), Transformers.toSnakeCase(value)]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Transformers;
|
||||||
10
packages/discord.js/typings/index.d.ts
vendored
10
packages/discord.js/typings/index.d.ts
vendored
@@ -2411,16 +2411,6 @@ export class Formatters extends null {
|
|||||||
|
|
||||||
export type ComponentData = ActionRowComponentData | ButtonComponentData | SelectMenuComponentData;
|
export type ComponentData = ActionRowComponentData | ButtonComponentData | SelectMenuComponentData;
|
||||||
|
|
||||||
export class Components extends null {
|
|
||||||
private constructor();
|
|
||||||
public static transformJSON(data: ComponentData | APIMessageComponent): APIMessageComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Embeds extends null {
|
|
||||||
private constructor();
|
|
||||||
public static transformJSON(data: EmbedData | APIEmbed): APIEmbed;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class VoiceChannel extends BaseGuildVoiceChannel {
|
export class VoiceChannel extends BaseGuildVoiceChannel {
|
||||||
public readonly speakable: boolean;
|
public readonly speakable: boolean;
|
||||||
public type: ChannelType.GuildVoice;
|
public type: ChannelType.GuildVoice;
|
||||||
|
|||||||
@@ -4441,6 +4441,7 @@ __metadata:
|
|||||||
husky: ^7.0.4
|
husky: ^7.0.4
|
||||||
is-ci: ^3.0.1
|
is-ci: ^3.0.1
|
||||||
jest: ^27.5.1
|
jest: ^27.5.1
|
||||||
|
lodash.snakecase: ^4.1.1
|
||||||
node-fetch: ^2.6.7
|
node-fetch: ^2.6.7
|
||||||
prettier: ^2.5.1
|
prettier: ^2.5.1
|
||||||
tsd: ^0.19.1
|
tsd: ^0.19.1
|
||||||
@@ -7610,6 +7611,13 @@ dts-critic@latest:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"lodash.snakecase@npm:^4.1.1":
|
||||||
|
version: 4.1.1
|
||||||
|
resolution: "lodash.snakecase@npm:4.1.1"
|
||||||
|
checksum: 1685ed3e83dda6eae5a4dcaee161a51cd210aabb3e1c09c57150e7dd8feda19e4ca0d27d0631eabe8d0f4eaa51e376da64e8c018ae5415417c5890d42feb72a8
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.7.0":
|
"lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.7.0":
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
resolution: "lodash@npm:4.17.21"
|
resolution: "lodash@npm:4.17.21"
|
||||||
|
|||||||
Reference in New Issue
Block a user