From 7e523b5df11056ad56284930ff5f590c94b0293b Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 17 Apr 2026 15:13:59 +0200 Subject: [PATCH] fix: ignore application command array order --- .../compute-differences/contexts.ts | 12 ++++--- .../compute-differences/integration_types.ts | 12 ++++--- .../computeDifferences.test.ts | 34 ++++++++++++++++++- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/lib/utils/application-commands/compute-differences/contexts.ts b/src/lib/utils/application-commands/compute-differences/contexts.ts index 31cd7a112..2825ef17d 100644 --- a/src/lib/utils/application-commands/compute-differences/contexts.ts +++ b/src/lib/utils/application-commands/compute-differences/contexts.ts @@ -23,24 +23,26 @@ export function* checkInteractionContextTypes( } // 2. Maybe changes in order or additions, log else if (newContexts?.length) { + const sortedExistingContexts = [...existingContexts!].sort((first, second) => first - second); + const sortedNewContexts = [...newContexts].sort((first, second) => first - second); let index = 0; - for (const newContext of newContexts) { + for (const newContext of sortedNewContexts) { const currentIndex = index++; - if (existingContexts![currentIndex] !== newContext) { + if (sortedExistingContexts[currentIndex] !== newContext) { yield { key: `contexts[${currentIndex}]`, - original: `contexts type ${existingContexts?.[currentIndex]}`, + original: `contexts type ${sortedExistingContexts[currentIndex]}`, expected: `contexts type ${newContext}` }; } } - if (index < existingContexts!.length) { + if (index < sortedExistingContexts.length) { let type: InteractionContextType; - while ((type = existingContexts![index]) !== undefined) { + while ((type = sortedExistingContexts[index]) !== undefined) { yield { key: `contexts[${index}]`, original: `context ${type} present`, diff --git a/src/lib/utils/application-commands/compute-differences/integration_types.ts b/src/lib/utils/application-commands/compute-differences/integration_types.ts index 675d29503..84a0e8427 100644 --- a/src/lib/utils/application-commands/compute-differences/integration_types.ts +++ b/src/lib/utils/application-commands/compute-differences/integration_types.ts @@ -23,24 +23,26 @@ export function* checkIntegrationTypes( } // 2. Maybe changes in order or additions, log else if (newIntegrationTypes?.length) { + const sortedExistingIntegrationTypes = [...existingIntegrationTypes!].sort((first, second) => first - second); + const sortedNewIntegrationTypes = [...newIntegrationTypes].sort((first, second) => first - second); let index = 0; - for (const newIntegrationType of newIntegrationTypes) { + for (const newIntegrationType of sortedNewIntegrationTypes) { const currentIndex = index++; - if (existingIntegrationTypes![currentIndex] !== newIntegrationType) { + if (sortedExistingIntegrationTypes[currentIndex] !== newIntegrationType) { yield { key: `integrationTypes[${currentIndex}]`, - original: `integration type ${existingIntegrationTypes?.[currentIndex]}`, + original: `integration type ${sortedExistingIntegrationTypes[currentIndex]}`, expected: `integration type ${newIntegrationType}` }; } } - if (index < existingIntegrationTypes!.length) { + if (index < sortedExistingIntegrationTypes.length) { let type: ApplicationIntegrationType; - while ((type = existingIntegrationTypes![index]) !== undefined) { + while ((type = sortedExistingIntegrationTypes[index]) !== undefined) { yield { key: `integrationTypes[${index}]`, original: `integration type ${type} present`, diff --git a/tests/application-commands/computeDifferences.test.ts b/tests/application-commands/computeDifferences.test.ts index 07ddf28fc..d86911913 100644 --- a/tests/application-commands/computeDifferences.test.ts +++ b/tests/application-commands/computeDifferences.test.ts @@ -1,5 +1,5 @@ import { ApplicationCommandOptionType, ApplicationCommandType, type RESTPostAPIChatInputApplicationCommandsJSONBody } from 'discord-api-types/v10'; -import { ChannelType } from 'discord.js'; +import { ApplicationIntegrationType, ChannelType, InteractionContextType } from 'discord.js'; import { getCommandDifferences as getCommandDifferencesRaw } from '../../src/lib/utils/application-commands/computeDifferences'; function getCommandDifferences(...args: Parameters) { @@ -59,6 +59,38 @@ describe('Compute differences for provided application commands', () => { expect(getCommandDifferences(command1, command2, false)).toEqual([]); }); + test('GIVEN two commands with the same integration types in a different order THEN do not return any difference', () => { + const command1: RESTPostAPIChatInputApplicationCommandsJSONBody = { + description: 'description 1', + name: 'command1', + integration_types: [ApplicationIntegrationType.UserInstall, ApplicationIntegrationType.GuildInstall] + }; + + const command2: RESTPostAPIChatInputApplicationCommandsJSONBody = { + description: 'description 1', + name: 'command1', + integration_types: [ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall] + }; + + expect(getCommandDifferences(command1, command2, false)).toEqual([]); + }); + + test('GIVEN two commands with the same contexts in a different order THEN do not return any difference', () => { + const command1: RESTPostAPIChatInputApplicationCommandsJSONBody = { + description: 'description 1', + name: 'command1', + contexts: [InteractionContextType.PrivateChannel, InteractionContextType.Guild] + }; + + const command2: RESTPostAPIChatInputApplicationCommandsJSONBody = { + description: 'description 1', + name: 'command1', + contexts: [InteractionContextType.Guild, InteractionContextType.PrivateChannel] + }; + + expect(getCommandDifferences(command1, command2, false)).toEqual([]); + }); + test('GIVEN 2 different descriptions THEN return the difference', () => { const command1: RESTPostAPIChatInputApplicationCommandsJSONBody = { description: 'description 1',