UNPKG

@sapphire/framework

Version:

Discord bot framework built for advanced and amazing bots.

179 lines (177 loc) • 6.91 kB
import { hasChannelTypesSupport, hasChoicesAndAutocompleteSupport, hasMinMaxLengthSupport, hasMinMaxValueSupport, optionTypeToPrettyName, subcommandTypes } from "./_shared.mjs"; import { checkDescription } from "./description.mjs"; import { checkLocalizations } from "./localizations.mjs"; import { checkName } from "./name.mjs"; import { handleAutocomplete } from "./option/autocomplete.mjs"; import { checkChannelTypes } from "./option/channelTypes.mjs"; import { handleMinMaxLengthOptions } from "./option/minMaxLength.mjs"; import { handleMinMaxValueOptions } from "./option/minMaxValue.mjs"; import { checkOptionRequired } from "./option/required.mjs"; import { checkOptionType } from "./option/type.mjs"; import { ApplicationCommandOptionType } from "discord-api-types/v10"; //#region src/lib/utils/application-commands/compute-differences/options.ts function* checkOptions(existingOptions, newOptions) { if (!existingOptions?.length && newOptions?.length) yield { key: "options", original: "no options present", expected: "options present" }; else if (existingOptions?.length && !newOptions?.length) yield { key: "options", original: "options present", expected: "no options present" }; else if (newOptions?.length) { let index = 0; for (const option of newOptions) { const currentIndex = index++; const existingOption = existingOptions[currentIndex]; yield* reportOptionDifferences({ currentIndex, option, existingOption }); } if (index < existingOptions.length) { let option; while ((option = existingOptions[index]) !== void 0) { const expectedType = optionTypeToPrettyName.get(option.type) ?? `unknown (${option.type}); please contact Sapphire developers about this!`; yield { key: `existing command option at index ${index}`, expected: "no option present", original: `${expectedType} with name ${option.name}` }; index++; } } } } function* reportOptionDifferences({ option, existingOption, currentIndex, keyPath = (index) => `options[${index}]` }) { if (!existingOption) { const expectedType = optionTypeToPrettyName.get(option.type) ?? `unknown (${option.type}); please contact Sapphire developers about this!`; yield { key: keyPath(currentIndex), expected: `${expectedType} with name ${option.name}`, original: "no option present" }; return; } yield* checkOptionType({ key: `${keyPath(currentIndex)}.type`, originalType: existingOption.type, expectedType: option.type }); yield* checkName({ key: `${keyPath(currentIndex)}.name`, oldName: existingOption.name, newName: option.name }); const originalLocalizedNames = existingOption.name_localizations; const expectedLocalizedNames = option.name_localizations; yield* checkLocalizations({ localeMapName: `${keyPath(currentIndex)}.nameLocalizations`, localePresentMessage: "localized names", localeMissingMessage: "no localized names", originalLocalizedDescriptions: originalLocalizedNames, expectedLocalizedDescriptions: expectedLocalizedNames }); yield* checkDescription({ key: `${keyPath(currentIndex)}.description`, oldDescription: existingOption.description, newDescription: option.description }); const originalLocalizedDescriptions = existingOption.description_localizations; const expectedLocalizedDescriptions = option.description_localizations; yield* checkLocalizations({ localeMapName: `${keyPath(currentIndex)}.descriptionLocalizations`, localePresentMessage: "localized descriptions", localeMissingMessage: "no localized descriptions", originalLocalizedDescriptions, expectedLocalizedDescriptions }); yield* checkOptionRequired({ key: `${keyPath(currentIndex)}.required`, oldRequired: existingOption.required, newRequired: option.required }); if (subcommandTypes.includes(existingOption.type) && subcommandTypes.includes(option.type)) { const castedExisting = existingOption; const castedExpected = option; if (castedExisting.type === ApplicationCommandOptionType.SubcommandGroup && castedExpected.type === ApplicationCommandOptionType.SubcommandGroup) for (const [subcommandIndex, subcommandOption] of castedExpected.options.entries()) yield* reportOptionDifferences({ currentIndex: subcommandIndex, option: subcommandOption, existingOption: castedExisting.options?.[subcommandIndex], keyPath: (index) => `${keyPath(currentIndex)}.options[${index}]` }); else if (castedExisting.type === ApplicationCommandOptionType.Subcommand && castedExpected.type === ApplicationCommandOptionType.Subcommand) yield* handleSubcommandOptions({ expectedOptions: castedExpected.options, existingOptions: castedExisting.options, currentIndex, keyPath }); } if (hasMinMaxValueSupport(option)) yield* handleMinMaxValueOptions({ currentIndex, existingOption, expectedOption: option, keyPath }); if (hasChoicesAndAutocompleteSupport(option)) yield* handleAutocomplete({ expectedOption: option, existingOption, currentIndex, keyPath }); if (hasMinMaxLengthSupport(option)) yield* handleMinMaxLengthOptions({ currentIndex, existingOption, expectedOption: option, keyPath }); if (hasChannelTypesSupport(option)) yield* checkChannelTypes({ currentIndex, existingChannelTypes: existingOption.channel_types, keyPath, newChannelTypes: option.channel_types }); } function* handleSubcommandOptions({ expectedOptions, existingOptions, currentIndex, keyPath }) { if (!existingOptions?.length && expectedOptions?.length) yield { key: `${keyPath(currentIndex)}.options`, expected: "options present", original: "no options present" }; else if (existingOptions?.length && !expectedOptions?.length) yield { key: `${keyPath(currentIndex)}.options`, expected: "no options present", original: "options present" }; else if (expectedOptions?.length) { let processedIndex = 0; for (const subcommandOption of expectedOptions) { const currentSubCommandOptionIndex = processedIndex++; const existingSubcommandOption = existingOptions[currentSubCommandOptionIndex]; yield* reportOptionDifferences({ currentIndex: currentSubCommandOptionIndex, option: subcommandOption, existingOption: existingSubcommandOption, keyPath: (index) => `${keyPath(currentIndex)}.options[${index}]` }); } if (processedIndex < existingOptions.length) { let option; while ((option = existingOptions[processedIndex]) !== void 0) { const expectedType = optionTypeToPrettyName.get(option.type) ?? `unknown (${option.type}); please contact Sapphire developers about this!`; yield { key: `existing command option at path ${keyPath(currentIndex)}.options[${processedIndex}]`, expected: "no option present", original: `${expectedType} with name ${option.name}` }; processedIndex++; } } } } //#endregion export { checkOptions }; //# sourceMappingURL=options.mjs.map