diff --git a/packages/discord.js/.lintstagedrc.json b/packages/discord.js/.lintstagedrc.json index e4e385774d7f..e27848430be3 100644 --- a/packages/discord.js/.lintstagedrc.json +++ b/packages/discord.js/.lintstagedrc.json @@ -1,5 +1,5 @@ { "$schema": "https://json.schemastore.org/lintstagedrc.schema.json", "*": "prettier --ignore-unknown --write", - "{src/**,test/**,typings/**,scripts/**}.{mjs,js,ts}": "cross-env ESLINT_USE_FLAT_CONFIG=false eslint --ext mjs,js,ts --fix" + "{src/**,typings/**,scripts/**}.{mjs,js,ts}": "cross-env ESLINT_USE_FLAT_CONFIG=false eslint --ext mjs,js,ts --fix" } diff --git a/packages/discord.js/src/structures/MessagePayload.js b/packages/discord.js/src/structures/MessagePayload.js index e46b48f83446..3046fc84dee7 100644 --- a/packages/discord.js/src/structures/MessagePayload.js +++ b/packages/discord.js/src/structures/MessagePayload.js @@ -249,7 +249,9 @@ class MessagePayload { username, avatar_url: avatarURL, allowed_mentions: - this.isMessage && this.target.author.id !== this.target.client.user.id ? undefined : allowedMentions, + this.isMessage && message_reference === undefined && this.target.author.id !== this.target.client.user.id + ? undefined + : allowedMentions, flags, message_reference, attachments: this.options.attachments, diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index d63f2113b213..2fc71ad4c36e 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -152,7 +152,7 @@ /** * @external APIMediaGalleryItem - * @se {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMediaGalleryItem} + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMediaGalleryItem} */ /** diff --git a/packages/discord.js/test/messages.js b/packages/discord.js/test/messages.js new file mode 100644 index 000000000000..bb9eb771366e --- /dev/null +++ b/packages/discord.js/test/messages.js @@ -0,0 +1,148 @@ +'use strict'; + +const { readFile } = require('node:fs/promises'); +const { createReadStream } = require('node:fs'); +const path = require('node:path'); +const { setTimeout: sleep } = require('node:timers/promises'); +const util = require('node:util'); +const { fetch } = require('undici'); +const { Client, GatewayIntentBits, AttachmentBuilder, EmbedBuilder, MessageFlags, ComponentType } = require('../src'); + +const client = new Client({ + intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent], +}); + +const buffer = l => + fetch(l) + .then(res => res.arrayBuffer()) + .then(Buffer.from); + +const linkA = 'https://discord.js.org/static/logo.svg'; +const fileA = path.join(__dirname, 'blobReach.png'); + +const embed = () => new EmbedBuilder(); +const attach = (attachment, name) => new AttachmentBuilder(attachment, { name }); + +const tests = [ + m => m.channel.send('x'), + + m => m.channel.send({ content: 'x', embeds: [{ description: 'a' }] }), + m => m.channel.send({ embeds: [{ description: 'a' }] }), + m => m.channel.send({ files: [{ attachment: fileA }] }), + m => + m.channel.send({ + embeds: [{ description: 'a' }], + files: [{ attachment: fileA, name: 'xyz.png' }], + }), + + m => m.channel.send({ content: 'x', embeds: [embed().setDescription('a')] }), + m => m.channel.send({ embeds: [embed().setDescription('a')] }), + m => m.channel.send({ embeds: [embed().setDescription('a'), embed().setDescription('b')] }), + + m => m.channel.send({ content: 'x', files: [attach(fileA)] }), + m => m.channel.send({ files: [fileA] }), + m => m.channel.send({ files: [attach(fileA)] }), + async m => m.channel.send({ files: [await buffer(linkA)] }), + async m => m.channel.send({ files: [{ attachment: await buffer(linkA) }] }), + m => m.channel.send({ files: [attach(fileA), attach(fileA)] }), + + m => m.channel.send({ embeds: [{ description: 'a' }] }).then(m2 => m2.edit('x')), + m => m.channel.send({ embeds: [embed().setDescription('a')] }).then(m2 => m2.edit('x')), + + m => m.channel.send('x').then(m2 => m2.edit({ embeds: [{ description: 'a' }] })), + m => m.channel.send('x').then(m2 => m2.edit({ embeds: [embed().setDescription('a')] })), + + m => m.channel.send({ embeds: [{ description: 'a' }] }).then(m2 => m2.edit({ content: 'x', embeds: [] })), + m => m.channel.send({ embeds: [embed().setDescription('a')] }).then(m2 => m2.edit({ content: 'x', embeds: [] })), + + m => m.channel.send({ content: 'x', embeds: [embed().setDescription('a')], files: [attach(fileA)] }), + m => m.channel.send({ content: 'x', files: [attach(fileA), attach(fileA)] }), + + m => m.channel.send({ embeds: [embed().setDescription('a')], files: [attach(fileA)] }), + m => + m.channel.send({ + embeds: [embed().setImage('attachment://two.png')], + files: [attach(fileA, 'two.png')], + }), + m => m.channel.send({ content: 'x', files: [attach(fileA)] }), + m => m.channel.send({ files: [fileA] }), + m => m.channel.send({ files: [attach(fileA)] }), + async m => m.channel.send({ files: [await readFile(fileA)] }), + + m => m.channel.send({ content: 'x', files: [attach(createReadStream(fileA))] }), + m => m.channel.send({ files: [createReadStream(fileA)] }), + m => m.channel.send({ files: [{ attachment: createReadStream(fileA) }] }), + + m => m.reply({ content: 'x', allowedMentions: { repliedUser: false } }), + m => m.reply({ content: 'x', allowedMentions: { repliedUser: true } }), + m => m.reply({ content: 'x' }), + m => m.reply({ content: `${m.author}`, allowedMentions: { repliedUser: false } }), + m => m.reply({ content: `${m.author}`, allowedMentions: { parse: ['users'], repliedUser: false } }), + m => m.reply({ content: `${m.author}`, allowedMentions: { parse: ['users'], repliedUser: true } }), + m => m.reply({ content: `${m.author}` }), + + m => m.edit({ flags: MessageFlags.SuppressEmbeds }), + m => m.edit({ flags: MessageFlags.SuppressEmbeds, allowedMentions: { repliedUser: false } }), + + m => + m + .reply({ content: 'x', allowedMentions: { repliedUser: false } }) + .then(msg => msg.edit({ content: 'a', allowedMentions: { repliedUser: true } })), + + m => + m.channel.send({ + components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }], + flags: MessageFlags.IsComponentsV2, + }), + m => + m.channel.send({ + components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }], + flags: MessageFlags.IsComponentsV2, + allowedMentions: { parse: ['users'] }, + }), + m => + m.channel.send({ + components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }], + flags: MessageFlags.IsComponentsV2, + allowedMentions: { parse: [] }, + }), + m => + m.reply({ + components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }], + flags: MessageFlags.IsComponentsV2, + allowedMentions: { parse: [], repliedUser: true }, + }), + m => + m.reply({ + components: [{ type: ComponentType.TextDisplay, content: `${m.author}` }], + flags: MessageFlags.IsComponentsV2, + allowedMentions: { parse: [], repliedUser: false }, + }), + + m => m.channel.send('Done!'), +]; + +client.on('messageCreate', async message => { + if (message.author.id !== process.env.OWNER) return; + const match = message.content.match(/^do (.+)$/); + if (match?.[1] === 'it') { + /* eslint-disable no-await-in-loop */ + for (const [i, test] of tests.entries()) { + await message.channel.send(`**#${i}**\n\`\`\`js\n${test.toString()}\`\`\``); + await test(message).catch(e => message.channel.send(`Error!\n\`\`\`\n${e}\`\`\``)); + await sleep(1_000); + } + /* eslint-enable no-await-in-loop */ + } else if (match) { + const n = parseInt(match[1]) || 0; + const test = tests.slice(n)[0]; + const i = tests.indexOf(test); + await message.channel.send(`**#${i}**\n\`\`\`js\n${test.toString()}\`\`\``); + await test(message).catch(e => message.channel.send(`Error!\n\`\`\`\n${e}\`\`\``)); + } +}); + +client.login(); + +// eslint-disable-next-line no-console +process.on('unhandledRejection', console.error); diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index c28cfb7f55ee..f1370585991f 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3219,7 +3219,7 @@ export type SelectMenuType = APISelectMenuComponent['type']; export interface SeparatorComponentData extends BaseComponentData { spacing?: SeparatorSpacingSize; - dividier?: boolean; + divider?: boolean; } export class SeparatorComponent extends Component { private constructor(data: APISeparatorComponent); diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 6fe3b823fec8..c3f97a035b14 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -687,7 +687,7 @@ client.on('messageCreate', async message => { const rawSeparator: SeparatorComponentData = { type: ComponentType.Separator, spacing: 1, - dividier: false, + divider: false, }; const rawFile: FileComponentData = { diff --git a/packages/ws/package.json b/packages/ws/package.json index c4bc21c45f06..6b2974627426 100644 --- a/packages/ws/package.json +++ b/packages/ws/package.json @@ -102,7 +102,7 @@ "typescript": "~5.5.4", "undici": "6.21.1", "vitest": "^2.0.5", - "zlib-sync": "^0.1.9" + "zlib-sync": "^0.1.10" }, "engines": { "node": ">=20" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a6112fca75f..475504e580cb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1780,8 +1780,8 @@ importers: specifier: ^2.0.5 version: 2.0.5(@edge-runtime/vm@3.2.0)(@types/node@18.19.45)(happy-dom@14.12.3)(terser@5.39.0) zlib-sync: - specifier: ^0.1.9 - version: 0.1.9 + specifier: ^0.1.10 + version: 0.1.10 packages: @@ -14625,8 +14625,8 @@ packages: engines: {node: '>=8.0.0'} hasBin: true - zlib-sync@0.1.9: - resolution: {integrity: sha512-DinB43xCjVwIBDpaIvQqHbmDsnYnSt6HJ/yiB2MZQGTqgPcwBSZqLkimXwK8BvdjQ/MaZysb5uEenImncqvCqQ==} + zlib-sync@0.1.10: + resolution: {integrity: sha512-t7/pYg5tLBznL1RuhmbAt8rNp5tbhr+TSrJFnMkRtrGIaPJZ6Dc0uR4u3OoQI2d6cGlVI62E3Gy6gwkxyIqr/w==} zod-validation-error@2.1.0: resolution: {integrity: sha512-VJh93e2wb4c3tWtGgTa0OF/dTt/zoPCPzXq4V11ZjxmEAFaPi/Zss1xIZdEB5RD8GD00U0/iVXgqkF77RV7pdQ==} @@ -24515,7 +24515,7 @@ snapshots: espree: 10.1.0 esquery: 1.6.0 parse-imports: 2.1.1 - semver: 7.6.3 + semver: 7.7.1 spdx-expression-parse: 4.0.0 synckit: 0.9.1 transitivePeerDependencies: @@ -24729,7 +24729,7 @@ snapshots: natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 - semver: 7.6.3 + semver: 7.7.1 vue-eslint-parser: 9.4.3(eslint@8.57.0) xml-name-validator: 4.0.0 transitivePeerDependencies: @@ -32503,7 +32503,7 @@ snapshots: optionalDependencies: commander: 9.5.0 - zlib-sync@0.1.9: + zlib-sync@0.1.10: dependencies: nan: 2.20.0