Compare commits

...

746 Commits

Author SHA1 Message Date
iCrawl
9ef7ffdc6d ci: use proper regex escapes 2022-04-17 20:07:19 +02:00
iCrawl
9fa92ac0f9 ci: extract package and semver from tag 2022-04-17 19:55:59 +02:00
iCrawl
2c2f88cd43 ci: change logic to parse version 2022-04-17 19:08:02 +02:00
iCrawl
93defeccce ci: move logic for replacing tag name 2022-04-17 18:49:31 +02:00
iCrawl
443533ba99 ci: fix env vars 2022-04-17 18:35:31 +02:00
iCrawl
3cc96d7940 ci: replace branch name for documentation 2022-04-17 18:31:28 +02:00
iCrawl
b94a8761f8 chore: update dev versions 2022-04-17 13:40:46 +02:00
iCrawl
9bf2a0d5cb chore: release new versions 2022-04-17 13:32:57 +02:00
iCrawl
9917981f24 chore: update ts-docgen 2022-04-17 11:53:45 +02:00
iCrawl
ab8b946276 chore: update docgen 2022-04-17 11:45:03 +02:00
iCrawl
bcf7f1cfad chore: deps 2022-04-17 11:27:36 +02:00
Suneet Tipirneni
a58556adc0 feat: allow createMessageComponentCollector without using fetchReply (#7623)
* feat: allow creation of message component collectors without fetchReply

* chore: attempt at requested changes

* fix: collector bug

* refactor: use better names

* feat: add update() support

* feat: add defer support

* refactor: InteractionReply -> InteractionResponse

* fix: remove log

* chore: make requested changes

* Update packages/discord.js/src/structures/InteractionResponse.js

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>

* chore: make requested changes

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-04-17 10:59:36 +02:00
Suneet Tipirneni
40b9a1d67d feat: Slash command localization for builders (#7683)
* feat: add slash command localizations

* chore: make requested changes

* chore: make requested changes

* fix: prevent unnecessary spread

* chore: make requested changes

* chore: don't allow maps
2022-04-17 10:58:20 +02:00
MateoDeveloper
ab4c608b97 refactor(MessageAttachment): use Attachment instead (#7691)
* fix: TOKEN_INVALID error not thrown at login with invalid token

* refactor(MessageAttachment): Use Attachment instead

* Delete a mistake

* Add WebSocketManager file, deleted by error

* add a new line on WebSocketManager file

* fix: imports

* fix: conflict with typings

* chore: update reference on GuildStickerManager
2022-04-17 10:57:38 +02:00
Jiralite
1b2d8decb6 fix(MessageManager): Allow caching option of an unspecified limit (#7763)
* refactor: merge parameters

* refactor: remove default
2022-04-17 10:55:17 +02:00
Suneet Tipirneni
a674f64e1d chore: reexport all builders in discord.js (#7772)
* chore: reexport all builders in discord.js

* chore: export all builder exports

* chore: use tslib
2022-04-17 10:54:14 +02:00
Jiralite
54e5629986 refactor(Util): remove splitting (#7780) 2022-04-17 10:52:28 +02:00
Suneet Tipirneni
75b6770933 chore(builders): simplify types (#7784)
* chore(builders): simplify types

* chore: removed uneeded partial
2022-04-17 10:51:11 +02:00
muchnameless
c2866504a3 fix(builders): add constructor default param (#7788)
* fix(builders): constructor default param

* fix: another one

* fix: and another one
2022-04-17 10:50:42 +02:00
Jiralite
f1d0084da2 docs(ApplicationCommand): Fix ApplicationCommandOptionChoice (#7794) 2022-04-17 10:49:37 +02:00
Suneet Tipirneni
b01f4147d4 feat: add guild directory support (#6788) 2022-04-14 12:49:33 +02:00
Jiralite
fc2a8bb675 feat(GuildBanManager): Support pagination results (#7734) 2022-04-14 12:46:51 +02:00
Jiralite
f094e33861 types: add missing typing (#7781) 2022-04-14 12:44:42 +02:00
Jiralite
446eb390ce types(VoiceChannel): nullify property (#7793) 2022-04-14 12:43:58 +02:00
Jiralite
96a0d83a13 refactor: Tidy up builders and components (#7711) 2022-04-14 12:42:25 +02:00
Suneet Tipirneni
01a423d110 feat(CommandInteraction): add support for localized slash commands (#7684)
* feat(commandInteraction): add support for localized slash commands

* chore: make requested changes

* chore: add better localizations in docs

* refactor: use dapi types

* types: reexport LocalizationMap

* fix: add name localizations for option choices

* feat: add missing props and fetch options

* Update packages/discord.js/src/managers/ApplicationCommandManager.js

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>

* chore: fix linting issues

* fix: fetching bugs

* chore: make requested changes

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-04-12 17:20:55 +02:00
Josh Wee
f0d0242c76 feat: support sodium-native lib for voice (#7698)
* chore: add sodium-native

* feat: wrap sodium-native methods

* chore: update dep listings

* chore: update dep report

* revert: "chore: add sodium-native"

This reverts commit 6a64db85d0.

* chore: consolidate buffer alloc

Co-authored-by: Vitor <milagre.vitor@gmail.com>

* chore: conslidate sodium.random

* chore: explicit param typing

* refactor: truthy style maintenance

Co-authored-by: Vitor <milagre.vitor@gmail.com>
2022-04-12 17:20:30 +02:00
muchnameless
b577bcc1df types(ModalSubmitInteraction): message (#7705) 2022-04-12 17:20:20 +02:00
Rodry
0faac04b69 feat: allow emoji strings to be passed through constructors (#7718)
* feat: allow strings to be passed through constructors

* fix: don't overwrite emoji with raw data
2022-04-12 17:19:27 +02:00
Harry Allen
9ff54254d8 fix: clarify that packages need to be locally built (#7720) 2022-04-12 17:18:43 +02:00
BaumianerNiklas
fd1dc72c0a typings(Embed): add missing getters and add video to EmbedData (#7728)
* typings(Embed): add missing author getter

* typings(Embed): add hexColor, provider, and length getters

* typings: EmbedVideoData + video fields in Embed[Data]
2022-04-12 17:18:15 +02:00
Almeida
29f8807955 feat(StageInstanceManager): add sendStartNotification option to create (#7730)
* feat(StageInstanceManager): add `sendStartNotification` option to create

* docs: update property description

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2022-04-12 17:17:49 +02:00
Vitor
6f4e97bfaf types(ModalSubmitInteraction): fix components type (#7732) 2022-04-12 17:16:36 +02:00
Vlad Frangu
3582fe917d chore: update the regex for command names/option names (#7733) 2022-04-12 17:16:08 +02:00
Jiralite
78a3afcd7f refactor: Remove nickname parsing (#7736)
* refactor: remove nickname parsing

* types: remove nickname import

* chore: update guildmember

* refactor: keep parsing

* refactor: string from user instead
2022-04-12 17:15:38 +02:00
muchnameless
3db20abdd2 fix(MessagePayload): resolveBody check body instead of data (#7738) 2022-04-12 17:15:21 +02:00
muchnameless
ebb4dfa262 fix(ActionRow): toJSON should include components (#7739)
* fix(ActionRow): toJSON should include components

* Update packages/discord.js/src/structures/ActionRow.js

Co-authored-by: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com>

* types: extend component

Co-authored-by: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com>
Co-authored-by: suneettipirneni <suneettipirneni@icloud.com>
2022-04-12 17:14:57 +02:00
A. Román
8eaec114a9 feat: add makeURLSearchParams utility function (#7744) 2022-04-12 17:14:30 +02:00
Jiralite
8625d81714 fix: Prevent NaN for nullable timestamps (#7750)
* fix(VoiceState): don't show `NaN`

* fix(Invite): handle NaN

* refactor: `&&` usage

Co-authored-by: Almeida <almeidx@pm.me>

Co-authored-by: Almeida <almeidx@pm.me>
2022-04-12 17:14:04 +02:00
Suneet Tipirneni
3037fca196 feat(modal): add awaitModalSubmit (#7751)
* feat(modal): add awaitModalSubmit

* fix: allow command interactions to await modal submissions

* Update packages/discord.js/src/structures/CommandInteraction.js

Co-authored-by: MateoDeveloper <79017590+Mateo-tem@users.noreply.github.com>

* chore: less is more

* Update packages/discord.js/src/structures/interfaces/InteractionResponses.js

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>

Co-authored-by: MateoDeveloper <79017590+Mateo-tem@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2022-04-12 17:13:46 +02:00
Suneet Tipirneni
e4f27051ca types(interactionCollector): filter should have a collected argument (#7753) 2022-04-12 17:13:03 +02:00
Jiralite
25fdb3894d fix(InteractionCreateAction): Ensure text-based channel for caching messages (#7755)
* fix: ensure text-based channel for adding messages

* fix: account for interaction-only applications

The event will emit for these types of bots. However, as the channel is not from a cached guild, they are safe from this crash.

* fix: typos

* refactor: more descriptive variable usage
2022-04-12 17:12:31 +02:00
Jiralite
a1329bd3eb docs: Enhance /rest README (#7757)
* docs: enhance README

* chore: formatting

* docs: Fix method

Co-authored-by: Almeida <almeidx@pm.me>

* chore: remove new line

* docs: can use top-level await

* docs: fix message sending example

Co-authored-by: Almeida <almeidx@pm.me>
2022-04-12 17:11:41 +02:00
Parbez
3c0bbac82f refactor: replace zod with shapeshift (#7547) 2022-04-09 11:37:16 +02:00
Synbulat Biishev
3f3e4327c8 feat(Actions): add parent structure to events parameters (#7577) 2022-04-09 11:35:55 +02:00
Almeida
6fec25239d feat: export UnsafeModalBuilder and UnsafeTextInputBuilder (#7628) 2022-04-09 11:34:46 +02:00
Jiralite
aedddb875e refactor: Remove store channels (#7634) 2022-04-09 11:34:05 +02:00
Jiralite
402514ff32 fix: pass force correctly (#7721) 2022-04-05 12:26:21 +02:00
Jiralite
3b3dabf3da feat(VoiceChannel): Support video_quality_mode (#7722) 2022-04-05 12:26:09 +02:00
Almeida
eb6b472f72 refactor(IntegrationApplication): remove summary (#7729) 2022-04-05 12:25:52 +02:00
Suneet Tipirneni
f88e1ac4be chore: make requested changes (#7000) 2022-04-05 12:22:56 +02:00
Jiralite
905a6a1166 fix: Support reason in setRTCRegion helpers (#7723) 2022-04-04 16:32:14 +02:00
Rodry
5748dbe087 types: fix regressions (#7649)
* types: fix regressions

* fix: make requested changes

* Apply suggestions from code review

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>

* types: action row data should take builders

* types: remove redundant overload

* fix(MessagePayload): ensure components are serialized correctly

* fix(MessagePayload): don't always create new action row

* refactor(UnsafeModalBuilder): make data public

* types: use type union

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>

* types: fix types and add tests

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-04-04 00:19:44 +02:00
Jeroen Claassens
ac4bc3a6c8 chore(build): disable tsup minification & add "use strict"; banner to CJS bundles (#7725)
* chore(build): disable tsup minification

* chore(build): add `"use strict";` to CJS bundles
2022-03-28 21:34:58 +02:00
Jiralite
520f471ac5 docs: add back static properties and methods (#7706) 2022-03-26 13:55:53 +01:00
Jiralite
6708533376 ci: Resolve invalid semver (#7709) 2022-03-26 13:55:42 +01:00
Skick
9afc03054e types(Constants): add NonSystemMessageTypes (#7678) 2022-03-26 13:46:31 +01:00
D Trombett
74bf7d57ab fix(GuildMemberManager): return type can be null (#7680) 2022-03-26 13:45:12 +01:00
Jiralite
8e3b2d7abd types: Fix auto archive duration type (#7688)
* types: fix auto archive shenanigans

* refactor: deduplicate into utility

* types: allow `MAX` for text channels

* docs(Util): english

* fix(ThreadManager): assign on `MAX`
2022-03-26 13:43:18 +01:00
Suneet Tipirneni
8880de0cec fix(gateway): use version 10 (#7689)
* fix: make gateway use version 10

* chore: fix readme rest versions
2022-03-26 13:42:13 +01:00
Jiralite
cedd0536ba refactor(GuildAuditLogs): remove build (#7704) 2022-03-24 22:11:18 +01:00
Jiralite
85e531f22d fix: Audit log static reference (#7703)
* fix: sort into new file

* refactor: move other stuff

* fix: errors
2022-03-24 21:00:51 +01:00
muchnameless
07b23a99c7 refactor(InteractionCollector): simplify constructor logic (#7667)
* refactor(InteractionCollector): simplify constructor logic

* fix: oversight
2022-03-24 21:00:30 +01:00
Jiralite
0c32332a5a fix: handle possibly missing property (#7641) 2022-03-24 21:00:12 +01:00
Parbez
d5369a56e3 fix(util): allow escapeInlineCode to escape double backtics (#7638)
* fix(util): allow scapeInlineCode to escape double backtics

* fix: replace backtics properly

* chore: fix lint
2022-03-24 21:00:04 +01:00
Jiralite
9a6e691eaa refactor: remove undocumented checks (#7637) 2022-03-24 20:59:56 +01:00
Almeida
4d2b55955d fix(GuildEditData): some fields can be null (#7632)
* fix(GuildEditData): some fields can be null

* fix: make even more things nullable
2022-03-24 20:59:38 +01:00
MateoDeveloper
cd79bef254 fix: TOKEN_INVALID error not thrown at login with invalid token (#7630) 2022-03-24 20:59:30 +01:00
Almeida
c684ac55e1 fix(GuildScheduledEvent): handle missing image (#7625) 2022-03-24 20:59:07 +01:00
Suneet Tipirneni
fb9a9c2211 refactor: allow builders to accept emoji strings (#7616)
* refactor: allow emoji strings in button builder

* refactor: add emoji string support for select menu options

* fix: export select menu option

* chore: make requested changes

* Update packages/discord.js/typings/index.test-d.ts

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-03-24 20:58:50 +01:00
muchnameless
daf2829cb5 types(InteractionResponseFields): add webhook (#7597) 2022-03-24 20:58:39 +01:00
Ryan Munro
98177aa38d fix(guild): throw if ownerId falsey (#7575) 2022-03-24 20:58:29 +01:00
Suneet Tipirneni
b1d63d919a fix: Validate select menu options (#7566)
* fix: validate select menu options

* chore: make requested changes

* refactor: make requested changes

* fix: tests
2022-03-24 20:57:53 +01:00
Vlad Frangu
b520c3df3c chore(ci): fix dev deploy workflow (#7694)
* chore(ci): fix dev deploy workflow

* chore: escape the dots too, for extra future safety
2022-03-24 02:40:13 +01:00
Suneet Tipirneni
e805777a7a refactor: use static fields (#7701)
* refactor: use static fields

* chore: refactor missed areas

* chore: remove memberof docs

* chore: make type changes
2022-03-24 02:38:05 +01:00
Suneet Tipirneni
72577c4bfd feat: add API v10 support (#7477)
* feat: add API v10 support

* refactor: update deps

* chore: rebase fixes
2022-03-15 21:37:07 +01:00
Ben
9b0d8cb2d8 feat(embed): remove Embed.setColor (#7662) 2022-03-15 21:36:20 +01:00
Synbulat Biishev
8fb98165a9 types(Embed): add forgotten footer type (#7665) 2022-03-15 21:30:22 +01:00
Ben
f4729759f6 refactor(EmbedBuilder): allow hex strings in setColor (#7673)
* refactor(EmbedBuilder): allow hex strings in setColor

* Apply suggestions from code review

Co-authored-by: Almeida <almeidx@pm.me>

Co-authored-by: Almeida <almeidx@pm.me>
2022-03-15 21:29:19 +01:00
Rodry
2297c2b947 types(ColorResolvable): simplify string types (#7643) 2022-03-14 12:04:07 +01:00
Jiralite
87a6b8445b fix: Remove Modal export (#7654) 2022-03-13 15:06:41 +01:00
Suneet Tipirneni
549716e4fc refactor: Don't return builders from API data (#7584)
* refactor: don't return builders from API data

* Update packages/discord.js/src/structures/ActionRow.js

Co-authored-by: Antonio Román <kyradiscord@gmail.com>

* fix: circular dependency

* fix: circular dependency pt.2

* chore: make requested changes

* chore: bump dapi-types

* chore: convert text input

* chore: convert text input

* feat: handle cases of unknown component types better

* refactor: refactor modal to builder

* feat: add #from for easy builder conversions

* refactor: make requested changes

* chore: make requested changes

* style: fix linting error

Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: almeidx <almeidx@pm.me>
2022-03-12 19:39:23 +01:00
Suneet Tipirneni
230c0c4cb1 types: allow component classes in action row data (#7614)
* types: allow component classes in action row data

* types: allow components to be passed inside objects in messages

Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2022-03-12 17:58:35 +01:00
Almeida
dcd479767b fix(SelectMenu): set placeholder max to 150 (#7538) 2022-03-10 09:00:39 +01:00
Suneet Tipirneni
3dff31f63f feat(StageInstance): Add support for associated guild event (#7576) 2022-03-10 08:57:41 +01:00
RAIDEN
cbdb408dff fix(Embed): fix incorrect destructuring import (#7615) 2022-03-10 08:55:10 +01:00
Jiralite
e787cd5fa5 docs(InteractionCollector): Document channel option type (#7551) 2022-03-09 16:18:18 +01:00
Rodry
b162f27e46 feat(VoiceState): add edit method (#7569)
Co-authored-by: muchnameless <12682826+muchnameless@users.noreply.github.com>
2022-03-07 08:53:44 +01:00
Vlad Frangu
b9ff7b0573 fix(RequestHandler): only reset tokens for authenticated 401s (#7508) 2022-03-06 20:43:12 +01:00
Jiralite
c12d61a342 fix(ThreadMembersUpdate): Only emit added & removed thread members (#7539) 2022-03-06 20:42:33 +01:00
Rodry
e71c76c7f7 types(ActionRow): allow components to be passed to constructors (#7531)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2022-03-06 16:27:44 +01:00
Parbez
851f380eb1 fix(Util): escapeInlineCode properly (#7587) 2022-03-06 16:27:29 +01:00
Almeida
10607dbdaf refactor: remove obsolete builder methods (#7590) 2022-03-06 16:27:17 +01:00
Suneet Tipirneni
79d6c0489c refactor(embed): allow hex strings in setColor() (#7593) 2022-03-06 16:26:41 +01:00
muchnameless
89073903a2 feat(ModalSubmitInteraction): add boolean properties (#7596) 2022-03-06 16:26:32 +01:00
Vlad Frangu
8f1986a6aa feat: add support for module: NodeNext in TS and ESM (#7598) 2022-03-06 16:26:11 +01:00
Almeida
0d7e4edd96 types(showModal): align types with the documentation (#7600) 2022-03-06 16:25:56 +01:00
muchnameless
fac55bcfd1 refactor(InteractionResponses): use ClientOptions.jsonTransformer (#7599) 2022-03-06 16:25:50 +01:00
Rodry
4b08d9b376 fix(GuildStickerManager): correctly access guild ID (#7605) 2022-03-06 16:25:01 +01:00
IRONM00N
93854a8013 types: modals type and doc fixes (#7608) 2022-03-06 16:24:43 +01:00
muchnameless
cb566c8b6a fix(MessageManager): pin route (#7610) 2022-03-06 16:24:03 +01:00
Suneet Tipirneni
6f7a366956 chore: bump turborepo (#7568) 2022-03-04 08:54:29 +01:00
Suneet Tipirneni
ed92015634 feat: Add Modals and Text Inputs (#7023)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Ryan Munro <monbrey@gmail.com>
Co-authored-by: Vitor <milagre.vitor@gmail.com>
2022-03-04 08:53:41 +01:00
muchnameless
53defb82e3 types(InteractionResponseFields): add boolean properties (#7565) 2022-03-02 10:41:56 +01:00
Parbez
8478d2f4de refactor(Embed): remove add field (#7522) 2022-03-02 10:37:30 +01:00
Suneet Tipirneni
2d4971b032 types: allow raw components for reply and message options (#7573) 2022-03-02 10:34:22 +01:00
Jiralite
c6cb5e9ebb fix: Handle partial data for Typing#user (#7542) 2022-03-02 10:30:25 +01:00
Suneet Tipirneni
a8321d8026 types: fix component *Data types (#7536) 2022-02-26 11:17:03 +01:00
Jiralite
1a14c0ca56 docs: Completely fix builders example link (#7543) 2022-02-26 11:15:52 +01:00
Jiralite
44a57a1b0c revert: chore: commit scope name in lowercase (#7550) 2022-02-26 11:14:32 +01:00
Suneet Tipirneni
0aa48516a4 fix: only check instanceof Component once (#7546) 2022-02-26 11:14:04 +01:00
Synbulat Biishev
83460037be types: use discord-api-types Locale (#7541) 2022-02-26 11:13:49 +01:00
Ben
8203c5d843 fix(guild): fix typo accessing user instead of users (#7537) 2022-02-23 22:35:25 +01:00
Khafra
51583320d3 feat(discord.js): partial transition to undici (#7482) 2022-02-23 08:40:00 +01:00
Rodry
cf669301c7 types(anychannel): add PartialGroupDMChannel (#7472) 2022-02-23 08:39:33 +01:00
Parbez
d1d1b076be fix(test): MessageActionRow to ActionRow (#7523) 2022-02-23 08:39:24 +01:00
Almeida
00728f72b3 feat(message): add reason on pin and unpin (#7520) 2022-02-23 08:38:50 +01:00
ckohen
4f306521d8 fix(MessagePayload): don't set reply flags to target flags (#7514) 2022-02-23 08:37:52 +01:00
muchnameless
6a2fa70b8e feat: re-export AuditLogEvent enum (#7528) 2022-02-23 08:36:11 +01:00
Jiralite
46b53f4365 chore: Correct gateway intent on issue form (#7532) 2022-02-23 08:33:21 +01:00
Rodry
78aa36f9f5 fix(invite): add back channelId property (#7501) 2022-02-20 13:46:15 +01:00
Skick
3baa340821 fix(builders): allow negative min/max value of number/integer option (#7484) 2022-02-20 13:43:50 +01:00
Suneet Tipirneni
ba31203a0a refactor: make data public in builders (#7486) 2022-02-20 13:43:27 +01:00
Suneet Tipirneni
8dbd34544c fix: properly serialize undefined values (#7497) 2022-02-20 13:41:50 +01:00
Suneet Tipirneni
942ea1acbf fix: allow unsafe embeds to be serialized (#7494) 2022-02-20 13:40:01 +01:00
Almeida
b3fa2ece40 refactor(embed): remove array support in favor of rest params (#7498) 2022-02-20 13:38:13 +01:00
IRONM00N
ffecf08495 docs: correctly type getters (#7500) 2022-02-20 13:36:46 +01:00
Vlad Frangu
3e105a0bbb chore: disable scope-case rule for commitlint (#7507) 2022-02-20 13:35:20 +01:00
Rodry
b12214922c refactor(components): default set boolean methods to true (#7502) 2022-02-20 13:35:00 +01:00
Jiralite
71f4fa82ed types: Remove ApplicationCommandInteractionOptionResolver (#7491) 2022-02-20 13:33:45 +01:00
Suneet Tipirneni
f7257f0765 feat: add missing v13 component methods (#7466)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-18 01:04:34 +01:00
Khafra
395a68ff49 fix: attachment types (#7478) 2022-02-17 17:45:42 +01:00
Suneet Tipirneni
dee27db35a feat(options): add support for custom JSON transformers (#7476) 2022-02-16 18:49:24 +01:00
KonkenBonken
d32db8833e docs: ApplicationCommandData typedef (#7389)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-16 14:02:50 +01:00
Rodry
5cf5071061 feat!: add CategoryChannelChildManager (#7320)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-16 14:02:12 +01:00
Suneet Tipirneni
2d4554440e fix: use case converter for json component serialization (#7464)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-02-16 14:01:41 +01:00
Rodry
7959a68d8e types(embed): fix timestamp allowed types (#7470) 2022-02-16 08:36:56 +01:00
Almeida
d2bc9d444f refactor: deprecate invite stage instance (#7437) 2022-02-16 08:35:11 +01:00
Khafra
868e2f3230 rest: prefer arrayBuffer over buffer (#7318) 2022-02-16 08:34:54 +01:00
IRONM00N
c1b27f8eed fix(GuildAuditLogs): typings and consistency (#7445) 2022-02-15 18:47:12 +01:00
nev
9311fa7b42 fix(dataresolver): ensure fetched file is convert to a buffer (#7457)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2022-02-15 18:36:21 +01:00
Almeida
6d3da226d3 refactor(guild): move premiumSubscriptionCount to AnonymousGuild (#7451) 2022-02-15 18:32:11 +01:00
muchnameless
a8106f7c58 fix(messagepayload): resolveFile property names (#7458) 2022-02-15 18:32:03 +01:00
muchnameless
32985109c3 refactor(requestmanager): use timestampfrom (#7459) 2022-02-15 18:31:54 +01:00
Jiralite
2d2de1d3fd types: Remove duplicate rate limit for thread creation (#7465) 2022-02-15 18:31:41 +01:00
muchnameless
d1bb36256f refactor(actions): use optional chaining (#7460) 2022-02-15 18:31:29 +01:00
muchnameless
36173590a7 fix(components): setX should take rest parameters (#7461) 2022-02-15 18:31:08 +01:00
Amitoj Singh
003439671d feat: attachment application command option type (#7200) 2022-02-14 08:41:15 +01:00
Rodry
0dfdb2cf11 refactor(guildbanmanager)!: rename days option to deleteMessageDays (#7447) 2022-02-13 16:51:56 +01:00
Amitoj Singh
ae0f35f51d feat(builders): add attachment command option type (#7203) 2022-02-13 14:02:14 +01:00
Suneet Tipirneni
0af9bc841f fix(ci): ci error (#7454)
Co-authored-by: Almeida <almeidx@pm.me>
2022-02-13 13:37:41 +01:00
Suneet Tipirneni
e8252ed3b9 refactor: make public builder props getters (#7422)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-13 13:06:11 +01:00
Sanjay Kumar Baskaran
3ae6f3c313 docs: add slash command builders example, fixes #7338 (#7339)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-13 12:42:01 +01:00
Vlad Frangu
6ce906a02f typings: correct types for InteractionCollector guild and channel (#7452) 2022-02-13 12:40:12 +01:00
Rodry
532846b1f8 refactor!: remove redundant API defaults (#7449) 2022-02-13 12:29:22 +01:00
Suneet Tipirneni
94bf727cc3 refactor: allow discord.js builders to accept camelCase (#7424) 2022-02-13 12:27:42 +01:00
Ben
f4953647ff refactor(builders-methods): make methods consistent (#7395)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-02-12 19:03:13 +01:00
PlavorSeol
861f0e2134 fix(threads): require being sendable to be unarchivable (#7406) 2022-02-12 12:09:04 +01:00
fowlerro
81d8b54ff6 fix(guildmember): check if member has administrator permission (#7384) 2022-02-12 12:08:50 +01:00
CallMe AsYouFeel
fa97a31504 voice: pass joinConfig.group to getVoiceConnection (#7442) 2022-02-12 10:22:25 +01:00
Almeida
55b388a763 fix(guild): remove maximumPresences default value (#7440) 2022-02-12 10:21:48 +01:00
Ben
fbc71ef6b6 feat(scheduledevents): add image option (#7436)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-12 10:21:28 +01:00
muchnameless
b97aedd8e1 fix(guildchannelmanager): edit always sets parent to null (#7446) 2022-02-12 10:21:06 +01:00
iCrawl
298b22604b chore: bump to the correct version 2022-02-10 17:35:20 +01:00
Almeida
fe11ff5f6e fix(guildmember): make pending nullable (#7401) 2022-02-09 09:18:50 +01:00
Rodry
dd751ae19d feat: add methods to managers (#7300)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
Co-authored-by: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-09 09:18:37 +01:00
Milo
f59d6305cb feat(channel): add .url getter (#7402)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-09 09:18:30 +01:00
Suneet Tipirneni
09098240bf refactor: remove conditional autocomplete option return types (#7396)
Co-authored-by: Almeida <almeidx@pm.me>
2022-02-09 09:18:08 +01:00
Almeida
cc25455d2c refactor: replace WSCodes, WSEvents, and InviteScopes with discord-api-types equivalent (#7409) 2022-02-09 09:17:45 +01:00
Almeida
3d8c77600b types: fix GuildAuditLogsTypes keys & typos (#7423) 2022-02-09 09:16:52 +01:00
Jiralite
83458ff7c7 types: Remove duplicate GuildChannelOverwriteOptions interface (#7428) 2022-02-09 09:14:08 +01:00
Suneet Tipirneni
b936103395 fix: unsafe embed builder field normalization (#7418) 2022-02-07 11:52:10 +01:00
Tobias Peltzer
a921ec7dc5 fix(clientpresence): fix used opcodes (#7415) 2022-02-07 11:51:11 +01:00
Angga Islami
aadfbda586 fix: correctly export UnsafeSelectMenuComponent from builders (#7421) 2022-02-07 11:50:42 +01:00
Tobias Peltzer
538e9cef45 fix: use png as extension for defaultAvatarURL (#7414) 2022-02-07 11:50:09 +01:00
Parbez
f2a7a9f1b3 docs(channel): fix isDMBased docs (#7411) 2022-02-07 11:49:38 +01:00
n1ck_pro
2800e07e59 docs(messageattachment): fix contentType docs (#7413) 2022-02-07 11:49:27 +01:00
Suneet Tipirneni
d8184f94dd refactor: Make constants enums top level and PascalCase (#7379)
Co-authored-by: Vitor <milagre.vitor@gmail.com>
Co-authored-by: almeidx <almeidx@pm.me>
2022-02-05 19:56:11 +01:00
GodderE2D
cd2f566052 chore(CONTRIBUTING.md): update to yarn instructions (#7403)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-02-05 15:50:41 +01:00
Vitor
8bb3751340 docs: add supported option types for autocomplete (#7368) 2022-02-05 14:31:34 +01:00
ckohen
733ac82d5d fix(rest): sublimit all requests on unhandled routes (#7366) 2022-02-05 14:30:55 +01:00
Almeida
a7b80b9d9b types: use GuildFeature enum from discord-api-types (#7397) 2022-02-05 14:30:14 +01:00
iCrawl
5f4b44d580 chore: dev-bump all versions 2022-02-05 14:20:46 +01:00
iCrawl
c15100574b chore: fix workflows for publishing 2022-02-05 14:17:41 +01:00
iCrawl
1c186fabeb chore: fixup workflow 2022-02-04 22:29:49 +01:00
iCrawl
6faeddcd0d chore: add version plugin 2022-02-04 22:25:22 +01:00
iCrawl
87ca2854c2 chore: remove swc for now 2022-02-04 22:07:55 +01:00
iCrawl
741452b9be chore: fix publish dev workflow 2022-02-04 21:58:22 +01:00
iCrawl
37c1cb4495 chore: yarn 3 at last 2022-02-04 21:47:25 +01:00
iCrawl
cd5c7fa20e feat: expand workflows to all packages 2022-02-04 21:23:43 +01:00
Suneet Tipirneni
6b6222bf51 feat(components): Add unsafe message component builders (#7387) 2022-02-04 20:29:41 +01:00
Wilson
04502ce702 fix: messageReaction.me being false when it shouldn't (#7378) 2022-02-03 08:30:05 +01:00
Suneet Tipirneni
51beda56f7 feat(thread): add newlyCreated to threadCreate event (#7386) 2022-02-02 22:11:26 +01:00
D Trombett
92a04f4d98 fix: fix some typos (#7393) 2022-02-02 22:10:47 +01:00
Suneet Tipirneni
0b866c9fb2 docs: add external builder docs links (#7390) 2022-02-02 22:10:03 +01:00
D Trombett
4abb28c0a1 fix(builders): make type optional in constructor (#7391) 2022-02-02 21:43:27 +01:00
D Trombett
34120bba97 chore: add keepNames tsup option (#7385) 2022-02-02 15:20:16 +01:00
Jiralite
088394367b chore: Specify new root (#7382) 2022-02-02 10:55:14 +01:00
Suneet Tipirneni
0803665183 chore: bump turborepo (#7369) 2022-01-31 17:11:32 +01:00
Rodry
875c86a4ef revert: refactor(invite): make channel a getter (#7365) 2022-01-31 17:10:32 +01:00
Rodry
e6a26d25b3 types: fix *BitField.Flags properties (#7363) 2022-01-31 17:10:20 +01:00
Rodry
388f53550c feat(channel): add isDMBased typeguard (#7362) 2022-01-30 12:57:03 +01:00
Matthew1177
567db60475 feat(Interaction): add .commandType property to CommandInteraction and AutocompleteInteraction (#7357) 2022-01-30 12:56:38 +01:00
Suneet Tipirneni
fbb1d0328b refactor(Bitfield): use discord-api-types enums instead (#7313)
Co-authored-by: Almeida <almeidx@pm.me>
2022-01-28 19:14:20 +01:00
Suneet Tipirneni
74f627c379 chore: make @types/node-fetch a regular dependency (#7350) 2022-01-28 19:14:11 +01:00
Synbulat Biishev
3a5ab2c4e5 fix(messagementions): fix has method (#7292)
Co-authored-by: Almeida <almeidx@pm.me>
2022-01-28 19:13:59 +01:00
muchnameless
00ce1c56ac fix(guildmembermanager): use rest in edit (#7356) 2022-01-28 01:41:52 +01:00
Rodry
72767a1059 docs: add EnumResolvers (#7353) 2022-01-27 10:25:25 +01:00
Suneet Tipirneni
1a6c5ab145 chore: use performance.now for time-based unit tests (#7354) 2022-01-27 10:05:14 +01:00
Suneet Tipirneni
355f579771 feat(scheduledevent): add support for event cover images (#7337) 2022-01-26 21:47:47 +01:00
1Computer1
e4bd07b239 feat(Collection): add merging functions (#7299)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-01-26 21:46:31 +01:00
Casper
e1ecc1a80a fix(typings): mark RESTOptions as Partial in ClientOptions (#7349) 2022-01-26 21:45:25 +01:00
RAIDEN
11e5e5ac5b fix(Webhook): use correct method name (#7348) 2022-01-26 13:42:32 +01:00
Jan
ec0fba1ed0 refactor: use @discordjs/rest (#7298)
Co-authored-by: ckohen <chaikohen@gmail.com>
2022-01-26 10:45:04 +01:00
Suneet Tipirneni
ac26d9b130 feat(cdn): add support for scheduled event image covers (#7335) 2022-01-26 10:24:43 +01:00
Suneet Tipirneni
2db0cdd357 fix(thread): don't assign directly to getters (#7346) 2022-01-26 10:24:19 +01:00
IRONM00N
9a566e8068 feat(enumResolvers): strengthen typings (#7344) 2022-01-26 10:24:13 +01:00
Rodry
d6b56d0080 fix: don't create new instances of builders classes (#7343) 2022-01-26 10:23:58 +01:00
Rodry
b6402723c3 docs(locales): update Discord API docs link (#7266) 2022-01-25 21:23:45 +01:00
Almeida
706db9228a feat: allow setting message flags when sending (#7312) 2022-01-25 21:23:38 +01:00
IRONM00N
47633f0fd2 fix: missed enums and typings from #7290 (#7331) 2022-01-25 21:23:13 +01:00
ckohen
67250382f9 refactor(files): remove redundant file property names (#7340) 2022-01-25 15:35:04 +01:00
oof2win2
5ccdb0ab26 feat(minor): add application_id to Webhook (#7317)
Co-authored-by: Casper <53900565+Dev-CasperTheGhost@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2022-01-25 08:34:46 +01:00
Suneet Tipirneni
9a1623425a feat(threadchannel): add createdTimestamp field (#7306)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
2022-01-25 08:34:26 +01:00
oof2win2
c05b38873b types: fix MessageMentions channel types (#7316) 2022-01-25 08:34:04 +01:00
Suneet Tipirneni
31768fcd69 refactor(embed): mark properties as readonly (#7332) 2022-01-24 20:26:36 +01:00
Rodry
bcc5cda8a9 feat(embed): add setFields (#7322) 2022-01-24 20:26:23 +01:00
Antonio Román
d2d3a80c55 refactor: switch to /builders Embed (#7067) 2022-01-24 20:17:21 +01:00
iCrawl
2f16f879aa chore: deps 2022-01-24 17:28:30 +01:00
iCrawl
a319607af6 chore(release): builders, collection, rest and voice 2022-01-24 17:14:02 +01:00
iCrawl
487a5a2669 chore: update changelogs 2022-01-24 16:42:33 +01:00
Suneet Tipirneni
c10afeadc7 types: make required a boolean (#7307) 2022-01-20 14:30:03 +01:00
ckohen
d0fa5aaa26 fix(rest): don't add empty query (#7308) 2022-01-20 12:14:31 +01:00
ckohen
d8ea572fb8 fix(rest): use http agent when protocol is not https (#7309) 2022-01-20 12:14:12 +01:00
Jiralite
1c6c9449ad types: Fix channel create overloads (#7294) 2022-01-19 22:06:07 +01:00
Jan
b4ed8fd3ed refactor: remove transformPermissions (#7303) 2022-01-19 22:05:54 +01:00
Suneet Tipirneni
857bba4480 fix(guildchannelmanager): remove reverse enum lookup (#7304) 2022-01-19 22:05:38 +01:00
Shubham Parihar
bd33ebb507 docs(StageInstance): deprecate discoverableDisabled (#7179) 2022-01-19 20:37:05 +01:00
Jiralite
cf25de9373 feat(GuildPreview): Add stickers (#7152) 2022-01-19 20:36:05 +01:00
SpaceEEC
5b4dbc3359 ci(publish-dev): only build dependencies when releasing (#7302) 2022-01-19 14:54:25 +01:00
Suneet Tipirneni
213acd7997 feat: Enum resolvers & internal enum string removal (#7290)
Co-authored-by: Almeida <almeidx@pm.me>
2022-01-19 14:11:10 +01:00
Jiralite
164589c551 refactor: Remove VoiceChannel#editable (#7291) 2022-01-19 07:14:33 +01:00
Jiralite
347ff80bbc refactor: Remove boolean option for Webhook#fetchMessage (#7293) 2022-01-19 07:13:38 +01:00
Khafra
307389a335 BaseClient: pass captureRejections option (#7288) 2022-01-18 11:21:05 +01:00
awned
9181a31e0b feat(guildemojimanager): add delete and edit methods (#7286)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-01-18 08:35:36 +01:00
Almeida
86d9d06743 fix(builders): dont export Button component stuff twice (#7289) 2022-01-17 22:13:51 +01:00
Suneet Tipirneni
da05a8856b feat(interaction): add isRepliable type guard (#7259)
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2022-01-17 20:17:34 +01:00
Parbez
6112767128 refactor(subcommandgroup): required default to false (#7217) 2022-01-17 16:46:31 +01:00
Rodry
26a9dc3206 types: fix regressions and inconsistencies (#7260) 2022-01-17 16:45:23 +01:00
Almeida
18b0ed4cbe refactor(invite): make channel and inviter getters (#7278) 2022-01-17 13:51:34 +01:00
Parbez
c90e47f904 refactor: remove required from getMember (#7188) 2022-01-17 13:51:13 +01:00
Suneet Tipirneni
3bb4829800 feat: rest hash and handler sweeping (#7255)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-01-17 13:50:41 +01:00
Almeida
e65da44d9c docs(shardingmanager): fix type of execArgv option (#7284) 2022-01-17 13:15:46 +01:00
Suneet Tipirneni
0951309b32 chore(cdn): default to animated images (#7265)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
2022-01-17 13:14:03 +01:00
Suneet Tipirneni
101d7c5ffa refactor: remove djs components and use /builders components instead (#7252)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-01-17 13:13:48 +01:00
Jan
599f96740e ci: fix docs workflow (#7287) 2022-01-17 11:40:53 +01:00
Jan
9054f2f7ad feat: rest docs (#7281) 2022-01-17 10:56:48 +01:00
Almeida
ecf2430f6e ci: dont run auto-deprecated and publish-dev on forks (#7279) 2022-01-16 21:24:31 +01:00
Jiralite
7c07976018 refactor: Default *URL methods to animated hash (#7149)
Co-authored-by: Jan <66554238+vaporox@users.noreply.github.com>
2022-01-14 18:03:09 +01:00
Antonio Román
8ddd44ed85 fix: import clear{Timeout,Interval} from node:timers (#7269) 2022-01-14 13:34:59 +01:00
Jan
0b23b7f039 refactor: use setPosition inside edit (#7263) 2022-01-14 00:21:32 +01:00
Koyamie
06f5210f58 fix(ApplicationCommand): use new ApplicationCommandOptionType enums (#7257) 2022-01-14 00:20:45 +01:00
Almeida
f284a4641f fix: use enums from discord-api-types (#7258) 2022-01-14 00:19:35 +01:00
Rodry
37ec0bda6d docs(interaction): add locale list link (#7261) 2022-01-13 18:19:30 +01:00
Jan
0a5d5f38c0 refactor: don't disable import order lint (#7262) 2022-01-13 17:59:49 +01:00
Vitor
0dd56afe1c docs: fix a typo and use milliseconds instead of ms (#7251) 2022-01-13 17:59:28 +01:00
Jiralite
7b53978a73 chore: Add prefer-object-has-own rule (#7264) 2022-01-13 17:59:10 +01:00
Suneet Tipirneni
2bb40fd767 feat: add components to /builders (#7195)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2022-01-12 20:50:08 +01:00
Rodry
37a22e04c2 feat(Channel): improve typeguards (#6957)
Co-authored-by: Papageorgiadis Savvas <50584606+papsavas@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
2022-01-12 20:30:06 +01:00
Koyamie
f753882592 fix(exports): export ApplicationCommandType properly (#7256) 2022-01-12 20:27:41 +01:00
Suneet Tipirneni
aa6d1c74de refactor: remove discord.js enums and use discord-api-types enums instead (#7077) 2022-01-12 02:00:41 +01:00
Jan
1479e40bce refactor(application): remove fetchAssets (#7250) 2022-01-11 22:03:17 +01:00
Voxelli
1745973024 refactor: PresenceUpdate and demuxProbe (#7248) 2022-01-11 22:02:54 +01:00
iCrawl
62c74b8333 test(voice): fix tests 2022-01-11 21:53:08 +01:00
Suneet Tipirneni
db25f529b2 types: add ReadonlyCollection (#7245)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-01-11 12:30:16 +01:00
Noel
16938da355 chore: improve linting (#7244) 2022-01-11 12:30:08 +01:00
Voxelli
ff3a8b8323 fix(Shard): EventEmitter listener warning (#7240)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2022-01-11 12:30:00 +01:00
ckohen
86ab526d49 refactor(files): file data can be much more than buffer (#7238) 2022-01-11 12:29:48 +01:00
Suneet Tipirneni
d8efba24e0 refactor: make intersect perform a true intersection (#7211)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-01-11 12:29:41 +01:00
Suneet Tipirneni
9052e321d1 feat: Add Locales to Interactions (#7131)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2022-01-11 08:55:49 +01:00
Parbez
22fdbb0a29 chore: commit scope name in lowercase (#7246) 2022-01-11 08:53:26 +01:00
Suneet Tipirneni
ed0cfd91ed fix: ref delay for rate limited requests (#7239) 2022-01-10 10:21:44 +01:00
Noel
b2dfb2ec70 revert "chore: optimize Turbo pipelines" (#7237) 2022-01-09 23:22:25 +01:00
iCrawl
56b69a749a ci: only run assignment when a pr opens 2022-01-09 22:44:06 +01:00
Jonah Snider
fae39efc7f chore: optimize Turbo pipelines (#7236) 2022-01-09 22:32:02 +01:00
iCrawl
7ddd337c4a ci: more automation for prs 2022-01-09 22:30:52 +01:00
Rodry
a8509c91ca fix(timestamps): account for timestamps of 0 when creating Dates (#7226) 2022-01-09 21:48:45 +01:00
Jonah Snider
a0a4a2258a chore: format all supported Prettier files (#7233) 2022-01-09 21:42:04 +01:00
Almeida
4770c814b2 chore: update readme links (#7229) 2022-01-09 19:35:18 +01:00
iCrawl
4917eb3539 ci: revert auto-labeling 2022-01-09 19:28:32 +01:00
iCrawl
c0824ae419 ci: try different syntax in yaml file 2022-01-09 19:23:33 +01:00
iCrawl
174782e132 ci: update version of labeler 2022-01-09 19:15:21 +01:00
iCrawl
538d6683bc ci: escape backslashes in yml 2022-01-09 18:57:19 +01:00
iCrawl
0236308581 ci: better labeler for issues and prs 2022-01-09 18:33:27 +01:00
Rodry
822dc678da refactor(embeds): don't create new embed instances when unnecessary (#7227) 2022-01-09 17:35:32 +01:00
Suneet Tipirneni
f1d4bd68ec chore: allow typescript to typecheck .d.ts files (#7222) 2022-01-09 15:14:29 +01:00
Hyro
e38d79988a chore: license for REST module (#7223) 2022-01-09 13:21:43 +01:00
Vitor
bd7a6f2652 docs(SlashCommandSubcommands): updating old links from Discord developer portal (#7224) 2022-01-09 13:20:43 +01:00
Raiden-Ei
37cad54dbd fix(MessageEmbed): createdAt field can be zero (#7218) 2022-01-09 13:20:07 +01:00
Rodry
4fd127e79e refactor(GuildMember): throw better errors on #kickable and #bannable (#7137) 2022-01-09 13:18:50 +01:00
J-Human
ab3ff5a262 feat(Permissions): remove deprecated thread-related permissions (#6755) 2022-01-09 11:49:27 +01:00
J-Human
b92a7d7233 fix(BaseClient): do not append default options if provided is not an object (#6453) 2022-01-09 11:49:03 +01:00
J-Human
caaef53dd9 feat(VoiceRegion): remove the unsent vip field (#6759) 2022-01-09 11:48:15 +01:00
muchnameless
68b9564f18 types(interaction): remove renamed typeguards (#7220) 2022-01-09 11:44:24 +01:00
muchnameless
962f4bf882 fix: snowflakeutil import (#7219) 2022-01-09 11:43:35 +01:00
iCrawl
e07c374337 ci: fix publishing dev versions 2022-01-08 23:30:28 +01:00
iCrawl
7832dbc07a chore: yarn lock 2022-01-08 23:17:01 +01:00
iCrawl
4a2dbd6238 test: fix voice secretbox tests 2022-01-08 23:16:38 +01:00
iCrawl
b593bd32a9 test: fix voice tests 2022-01-08 22:57:29 +01:00
iCrawl
1d532d9468 ci: don't cache deps for publish 2022-01-08 22:53:10 +01:00
iCrawl
3f36746561 types: assertType -> expectType 2022-01-08 20:52:11 +01:00
Antonio Román
e082dfb158 refactor(SnowflakeUtil): switch to @sapphire/snowflake (#7079) 2022-01-08 19:11:33 +01:00
Matt (IPv4) Cowley
ae876d9624 refactor(InteractionCreate): remove interaction event (#6326) 2022-01-08 14:43:30 +01:00
Matt (IPv4) Cowley
171e917fb9 refactor(MessageCreate): remove message event (#6324) 2022-01-08 14:43:12 +01:00
Koyamie
63034b44c9 fix(Role): remove unused process (#7215) 2022-01-08 14:10:56 +01:00
Rodry
13eb78256d refactor(integration): turn undefined into null and consistency (#7209) 2022-01-08 12:44:28 +01:00
IlluminatiFish
1c615d1bb2 fix(WebhookClient): Updated webhook url regex (#6804) 2022-01-08 12:42:50 +01:00
Suneet Tipirneni
1db6c2d37e chore(ThreadMemberManager): make #fetch only take one object parameter (#6997) 2022-01-08 12:42:30 +01:00
Antonio Román
cee7fd181c refactor: remove deleted field (#7092) 2022-01-08 12:41:35 +01:00
Jan
55e21f5366 refactor(Dates): save timestamps everywhere and use Date.parse (#7108) 2022-01-08 12:41:20 +01:00
Commandtechno
d06d70ccf2 feat(richpresenceassets): add YouTube and custom image support (#7184) 2022-01-08 12:40:35 +01:00
Koyamie
95f8375d42 fix(Sweepers): add sweepStickers function (#7213) 2022-01-08 12:39:48 +01:00
Suneet Tipirneni
137ea249df docs: fix command interaction docs (#7212) 2022-01-08 11:21:06 +01:00
Koyamie
49dada35f9 fix(InteractionCreate): use ChatInputCommandInteraction instead (#7210) 2022-01-08 02:31:23 +01:00
iCrawl
53971f0de9 ci: use yarn to create new version 2022-01-08 01:47:00 +01:00
iCrawl
9760fd1b77 ci: fix publishing dev version 2022-01-08 01:44:17 +01:00
Raiden-Ei
fbef454894 fix(Structues): rename old module's name (#7207) 2022-01-08 01:41:22 +01:00
Jiralite
fbbac27978 refactor(RoleManager): Remove comparePositions() (#7201) 2022-01-08 01:35:32 +01:00
Rodry
dbf5ce3e6c ci(documentation): add repository_owner check (#7205) 2022-01-08 01:35:20 +01:00
Antonio Román
ef6f035b5d chore: add myself to contributors (#7206) 2022-01-08 01:35:07 +01:00
iCrawl
9d17904eff chore: deps 2022-01-08 01:33:47 +01:00
Raiden-Ei
033151cf92 fix(WebSocket): Remove application command handler (#7202) 2022-01-08 01:29:56 +01:00
Rodry
3269ec1984 chore(VSCode): add extension recommendations (#6666) 2022-01-08 00:51:19 +01:00
ckohen
c969cbf652 refactor(rest): rename attachment to file (#7199) 2022-01-08 00:49:34 +01:00
Suneet Tipirneni
3872acfeb8 fix(User): bannerURL() should not throw when not present (#6789) 2022-01-08 00:48:46 +01:00
ckohen
12ffa069aa chore(Caching): clean up deprecated cache sweeping (#7118)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2022-01-08 00:48:17 +01:00
Suneet Tipirneni
1f9b9225f2 types(Collection): union types on intersect and difference (#7196) 2022-01-08 00:47:55 +01:00
Suneet Tipirneni
b7856e7809 refactor: Better Command Terminology (#7197) 2022-01-08 00:47:41 +01:00
Jan
5022b14da0 refactor(Actions): remove deleted maps (#7076) 2022-01-08 00:34:47 +01:00
iCrawl
fbe40031cf chore: manually update changelog 2022-01-08 00:03:51 +01:00
Jiralite
a0d5f13dd9 fix(VoiceState): Ensure suppress & streaming have proper fallback values (#6377) 2022-01-07 23:40:58 +01:00
Rodry
6085b4f727 refactor(Client): remove applicationCommand events (#6492) 2022-01-07 23:40:50 +01:00
Jiralite
0c24cc8ec0 refactor: Remove Util.removeMentions() (#6530) 2022-01-07 23:40:36 +01:00
Rodry
75616a305f refactor(Constants): change APPLICATION_COMMAND -> CHAT_INPUT_COMMAND (#7018) 2022-01-07 23:40:01 +01:00
Antonio Román
2b480cb14e feat(Collector): yield all collected values (#7073) 2022-01-07 23:39:49 +01:00
LePtitMetalleux
b454740ae8 docs(TextBasedChannel): fixed syntax error in examples (#7163) 2022-01-07 23:38:58 +01:00
Suneet Tipirneni
c978dbb623 types: fix cache types resolving to never (#7164) 2022-01-07 23:37:17 +01:00
n1ck_pro
d4e6e03708 docs(TextBasedChannel): fix #createMessageComponentCollector description (#7168) 2022-01-07 23:18:46 +01:00
GoldenAngel
db669b8971 docs: fixes the examples for kick and ban (#7170) 2022-01-07 23:18:25 +01:00
awned
f79ea67d3a docs(RoleManager): fix incorrect example (#7174) 2022-01-07 23:17:57 +01:00
ckohen
ae2f013653 fix(sweepers): provide default for object param (#7182) 2022-01-07 23:16:00 +01:00
Souji
37587e2bcb chore: issue template changes for monorepo (#7198) 2022-01-07 23:13:04 +01:00
Almeida
43e5e3c339 refactor(Guild): remove deprecated setXPositions methods (#6897) 2022-01-07 23:12:31 +01:00
Almeida
b246fc4101 refactor(UserFlags): update flag names (#6938) 2022-01-07 23:12:05 +01:00
Antonio Román
4293b74253 chore: bump Node.js to 16.9.0 (#7035) 2022-01-07 21:03:00 +01:00
iCrawl
c8bfb24589 ci: use pull_request_target for auto labeling 2022-01-07 20:54:51 +01:00
iCrawl
b08c41d425 chore: remove labeling chore for now 2022-01-07 20:49:47 +01:00
iCrawl
4a80710e7a chore: add auto-labeler 2022-01-07 20:42:43 +01:00
iCrawl
1060dcdd4e chore: add more labels 2022-01-07 20:17:48 +01:00
iCrawl
967e9ace21 ci: max simultaneous of 1 for documentation runners 2022-01-07 17:27:26 +01:00
iCrawl
3c9a9c2c18 ci: force push to avoid non-fast-forward errors 2022-01-07 17:23:13 +01:00
Noel
16390efe6e chore: monorepo setup (#7175) 2022-01-07 17:18:25 +01:00
Attituding
780b7ed39f docs(Sweepers): fix typo (#7165) 2021-12-30 10:13:51 +01:00
iCrawl
9cdc4482a0 chore: dev version 2021-12-29 12:08:52 +01:00
iCrawl
2f6f365098 chore(release): version 2021-12-29 12:00:43 +01:00
iCrawl
22cadaf40f chore: deps 2021-12-29 11:19:20 +01:00
Jiralite
3496516dc9 refactor(MessageEmbed): Deprecate strings for setAuthor() (completely) and setFooter() (#7153) 2021-12-29 11:04:16 +01:00
Shubham Parihar
baacd6ba69 feat(GuildMember): add method to check timeout (#7146)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-12-29 10:52:15 +01:00
Suneet Tipirneni
1391c363e5 chore: bump dapi-types (#7159) 2021-12-29 00:34:14 +01:00
iCrawl
4cc6331e5c chore: fixup commits in changelog 2021-12-28 12:36:06 +01:00
iCrawl
1ae1853788 chore: fixup changelog generation 2021-12-28 12:17:23 +01:00
iCrawl
d80fddf06d chore: better changelog generation 2021-12-28 12:13:38 +01:00
Antonio Román
3c62bd2d47 refactor: import timers, process, and Buffer from node: (#7157)
Co-authored-by: muchnameless <12682826+muchnameless@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
2021-12-28 10:15:24 +01:00
muchnameless
d0c3961aef fix(GuildMemberManager): nick endpoint (#7151) 2021-12-26 18:52:48 +01:00
D Trombett
fc4292e2e9 fix(Permissions): toArray shouldn't check admin (#7144) 2021-12-26 15:46:35 +01:00
Jiralite
7e5f16b6b3 fix: Remove deprecation warning on Message#cleanContent (#7143) 2021-12-26 15:46:28 +01:00
Superchupu
f1d35e32ee ci: use correct capitalization of npm (#7150) 2021-12-26 12:57:24 +01:00
Kyler Chin
2bfc638a5c feat(ClientOptions): waitGuildTimeout amount client option (#6576)
Co-authored-by: D Trombett <73136330+DTrombett@users.noreply.github.com>
Co-authored-by: Hackerboi 69 <62872992+thehackerboi69github@users.noreply.github.com>
Co-authored-by: monbrey <rsm999@uowmail.edu.au>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Yoshida Tomio <mail@tomio.codes>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-12-24 14:30:00 +01:00
iCrawl
ea9e897b92 chore: bump version 2021-12-24 12:26:51 +01:00
iCrawl
bf346e7fdf chore: release 2021-12-24 12:25:12 +01:00
iCrawl
391211040a chore: deps 2021-12-24 12:21:53 +01:00
Rodry
1626dded5b types(CategoryChannel): fix createChannel return type (#7138) 2021-12-24 11:58:50 +01:00
Rodry
e6f41b578a fix(BaseMessageComponent): don't create new class instances (#7140) 2021-12-24 11:58:37 +01:00
Shubham Parihar
1316fd4c6a feat: add support for GuildScheduledEvent (#6493)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: GoldenAngel <50855202+GoldenAngel2@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2021-12-23 13:39:09 +01:00
Jiralite
aa7c1b2081 feat(GuildMember): Add timeouts (#7104)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Tiemen <ThaTiemsz@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-12-22 17:54:44 +01:00
Jiralite
2ed02f7fc7 refactor(UserManager): Move methods to the manager (#7087)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-12-22 14:25:52 +01:00
Suneet Tipirneni
a0a5b0e4fa types(CategoryChannel): createChannel should default to a text channel (#7132) 2021-12-22 14:00:07 +01:00
RaZe
b763dabaa9 fix: Make the followUp function error more clear (#7129)
Co-authored-by: D Trombett <maxtromb.dt@gmail.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-12-22 11:13:34 +01:00
Antonio Román
7b65a04cb1 types: make channel types a lot stricter (#7120) 2021-12-22 11:13:01 +01:00
Jiralite
6bb03f2c34 fix(StickerPack): Nullify bannerId (#7119) 2021-12-21 09:16:30 +01:00
Suneet Tipirneni
645b3f84f4 fix: webhook typeguards should use string comparisons (#7127) 2021-12-21 09:16:11 +01:00
Suneet Tipirneni
77489b90fc types: forward cache types to collector filters (#7126) 2021-12-21 09:16:02 +01:00
muchnameless
b9b60a37b3 feat: export Sweepers (#7117) 2021-12-16 10:06:37 +01:00
Jiralite
55960cc778 feat: Add API error code 50109 (#7112) 2021-12-16 10:04:03 +01:00
Jiralite
8efc5c7b8d chore(GuildMemberManager): Update nick path (#7114) 2021-12-15 20:43:12 +01:00
ckohen
d1ef2f5e8b feat(Client): add global sweepers (#6825)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
2021-12-15 13:39:27 +01:00
Jiralite
bc6a6c539f types: Fix possibly null message properties (#7111) 2021-12-15 13:39:05 +01:00
Antonio Román
a0fe0acbf1 fix(Message): remove usage of .deleted (#7109) 2021-12-14 21:10:14 +01:00
Antonio Román
d43f68488e docs: deprecate .deleted getters (#7107) 2021-12-14 19:34:27 +01:00
Jiralite
1e00fc2001 refactor(RoleManager): Move some methods over from Role (#7096) 2021-12-14 19:04:07 +01:00
Suneet Tipirneni
49f9a18020 types: use mapped enums instead of overloads (#7088) 2021-12-14 19:03:39 +01:00
Jiralite
9cf44d1c0e fix(GuildAuditLog): Remove Promises in constructor (#7089) 2021-12-14 19:03:21 +01:00
Jiralite
2ce244b502 types(MessageComponentInteraction): Ensure component is not null (#7099) 2021-12-12 22:06:24 +01:00
Jan
717e0e963f refactor(Guild): remove duplicate methods (#7100) 2021-12-12 22:06:11 +01:00
Jiralite
ee91f5a19c docs(Sticker): Fix typo (#7085) 2021-12-10 10:09:45 +01:00
Jiralite
5a5c045534 types(GuildAuditLog): Strengthen types (#7090) 2021-12-10 10:07:57 +01:00
Antonio Román
de61fe4854 fix(ShardingManager): fix respawnAll not passing delay correctly (#7084) 2021-12-10 10:07:35 +01:00
Jiralite
6e57b65e99 docs(Constants): Document missing errors (#7086) 2021-12-08 23:50:04 +01:00
Antonio Román
25b8491235 refactor(Util): replace Util.delayFor with tp.setTimeout (#7082) 2021-12-08 21:31:01 +01:00
Jiralite
23513d1917 docs(Constants): Adjust GUILD_STORE warning placement (#7083) 2021-12-08 21:30:40 +01:00
Rodry
fdba146f9b docs(StoreChannel): add deprecation warnings (#7080)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-12-08 18:51:07 +01:00
iCrawl
4515bb1ab2 chore: deps 2021-12-08 10:53:37 +01:00
Suneet Tipirneni
1230bee9bc types(Message): guild should be non-null when message is in guild (#6933) 2021-12-08 10:49:17 +01:00
Antonio Román
b0937502d3 refactor: make Structure#deleted a getter to a WeakSet (#7074) 2021-12-08 10:47:54 +01:00
Shubham Parihar
f410536c51 feat: add API error code 20029 (#7078) 2021-12-08 10:40:49 +01:00
SethCohen
6f58e8122d docs(GuildStickerManager): fix create() example (#7060) 2021-12-07 20:15:24 +01:00
Antonio Román
5ec542d61f fix(StoreChannel): mark as deprecated (#7072) 2021-12-07 20:15:04 +01:00
Rodry
7f980e38b6 feat(ApplicationCommand): add setX methods for easier editing (#7063)
Co-authored-by: awned <65061212+ceilingfans@users.noreply.github.com>
2021-12-07 20:14:49 +01:00
Antonio Román
b5cd2884b6 fix(InteractionCollector): handle thread (and parent) deletion (#7070) 2021-12-07 11:21:26 +01:00
Jiralite
f028aea333 feat: Add API error code 50055 (#7068) 2021-12-07 11:19:45 +01:00
Antonio Román
3846f0d97c fix(ReactionCollector): check for channel.threads (#7069) 2021-12-07 11:19:36 +01:00
Elliot
b6b4570482 types: improve audit logs' typings (#6647)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Noel <buechler.noel@outlook.com>
Co-authored-by: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com>
2021-12-06 08:57:12 +01:00
Antonio Román
8b200c0fee feat(SnowflakeUtil): add timestampFrom (#7058) 2021-12-06 08:56:29 +01:00
GodderE2D
1c93faa3ab chore: format .github/tsc.json (#7062) 2021-12-06 08:55:16 +01:00
Jiralite
01f8d1bed5 types(Interaction): Narrow memberPermissions (#7054) 2021-12-02 14:29:54 +01:00
That_Guy977
5fcda73d9f fix(GuildChannel): default to this.rawPosition in clone() (#7057) 2021-12-02 14:29:21 +01:00
Rodry
552d89fd4e feat(Guild): add premiumProgressbarEnabled (#6887)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-12-01 12:40:49 +01:00
Rodry
b183a8eece docs(Invite): add info blocks for missing props (#7014) 2021-12-01 12:33:28 +01:00
Suneet Tipirneni
da86bd4fa3 fix: Interaction channel type should be GuildTextBasedChannels when in guild (#6998) 2021-12-01 12:33:11 +01:00
That_Guy977
c07207f219 fix(Util): fix sorting for GuildChannels (#7002) 2021-12-01 12:32:13 +01:00
GrapeColor
4fe063f0d0 feat: add UserContextMenuInteraction and MessageContextMenuInteraction (#7003)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: GrapeColor <grapecolor@users.noreply.github.com>
2021-12-01 12:31:37 +01:00
Suneet Tipirneni
a39d8c4d9d Revert "types(ApplicationCommandManager): Deprecate old *Data type …usages and allow camel cased dapi types to be used (#7052) 2021-12-01 12:28:22 +01:00
Jiralite
85e6812ce2 docs(MessageReference): Fix static link (#7041) 2021-12-01 12:27:24 +01:00
Suneet Tipirneni
e305156769 chore: bump deps (#7048) 2021-11-29 19:32:26 +01:00
Antonio Román
374f970efe chore: add myself as contributor in package.json (#7037) 2021-11-29 11:20:52 +01:00
Antonio Román
e59fac3fe3 refactor(SnowflakeUtil): clean up utils and improve perf (#7036) 2021-11-29 11:20:18 +01:00
Antonio Román
fd63139b41 fix(MessageManager): do not use client.emojis (#7039) 2021-11-29 11:19:32 +01:00
Antonio Román
0193efae71 fix(ActionsManager): revert to manual requires (#7034) 2021-11-29 11:19:21 +01:00
Antonio Román
fabd34381c fix(MessagePayload): prevent spread of undefined (#7029) 2021-11-29 11:18:41 +01:00
Suneet Tipirneni
2c91c488e8 types(ApplicationCommandManager): Deprecate old *Data type usages and allow camel cased dapi types to be used (#6959) 2021-11-29 11:17:57 +01:00
Jiralite
54f937d82c fix(MessageManager): Allow a string for edit() (#7033) 2021-11-25 12:42:11 +01:00
Suneet Tipirneni
9f3bf2927c CI: Use tsd for Testing Types (#6983)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-11-23 18:00:58 +01:00
Jiralite
2a0dedf3e9 chore: Emit deprecation messages (#6994) 2021-11-23 10:29:45 +01:00
SpaceEEC
7efeff461f fix: avoid sending bot auth on token endpoints (#7022) 2021-11-23 10:28:09 +01:00
Rodry
099536ee60 types(WebhookMessageOptions): disallow stickers (#7012) 2021-11-23 10:27:03 +01:00
dai
77aff08345 feat(Shard): add eval context (#7011)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2021-11-23 10:26:46 +01:00
Suneet Tipirneni
c1f2fe29ef types: remove unneeded collector types (#7008) 2021-11-23 10:26:18 +01:00
GodderE2D
a1a8ca4814 docs(Constants): fix typo "announcement" (#7016) 2021-11-23 10:24:14 +01:00
Suneet Tipirneni
48555cb8eb types: make event emitters use mapped event types (#7019) 2021-11-23 10:23:14 +01:00
Suneet Tipirneni
802a5ac228 chore: collector type cleanup (#6991) 2021-11-18 07:58:17 +01:00
Suneet Tipirneni
db09d79423 feat(ThreadChannel): add ThreadChannel#viewable (#6975) 2021-11-18 07:58:05 +01:00
Suneet Tipirneni
0c5c7210e7 chore: bump typescript to 4.5 (#6999) 2021-11-18 07:55:19 +01:00
Suneet Tipirneni
493e4f9350 feat(ThreadManager): add slowmode option on thread creation (#6989)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2021-11-17 22:47:50 +01:00
SpaceEEC
c0ba2d46d0 fix(Sharding): properly handle errors in fetchClientValues (#6990) 2021-11-16 18:40:45 +01:00
SpaceEEC
fdb09cbe03 fix(VoiceState): set streaming to false when the stream ended (#6992) 2021-11-16 18:40:19 +01:00
Suneet Tipirneni
ecc61f3c74 types(ApplicationSubcommandData): allow autocomplete to be true (#6981) 2021-11-16 18:32:25 +01:00
Hackerboi 69
06cd16fe97 types: fix interaction typeguards (#6976) 2021-11-16 18:32:16 +01:00
Jiralite
73854ee852 refactor(MessageEmbed): Utilise an object approach for .setAuthor() (#6966)
Co-authored-by: Almeida <almeidx@pm.me>
2021-11-16 18:31:08 +01:00
Jake Ward
5e0a7d51fc feat(MessageAttachment): description (alt text) support (#6871)
Co-authored-by: D Trombett <maxtromb.dt@gmail.com>
2021-11-11 20:29:17 +01:00
Suneet Tipirneni
7630158f59 types: Strengthen autocomplete option types (#6950)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-11-11 19:38:34 +01:00
Suneet Tipirneni
9f240ea0d1 types: fix cache type fallback types (#6961) 2021-11-11 19:37:53 +01:00
GrapeColor
b001e194f1 fix(MessageReaction): Cache myself when MessageReaction#me is true. (#6956)
Co-authored-by: GrapeColor <grapecolor@users.noreply.github.com>
2021-11-11 19:21:45 +01:00
Vlad Frangu
8e881d2b96 types: unify ApplicationCommandManager#create overloads (#6970) 2021-11-11 19:08:28 +01:00
ckohen
c30a818ca9 feat(ApplicationCommand): add support for min and max values (#6855)
Co-authored-by: Noel <buechler.noel@outlook.com>
Co-authored-by: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com>
2021-11-11 19:07:21 +01:00
GodderE2D
3c857a6363 docs(README): add installation instruction on @discordjs/voice (#6964) 2021-11-11 03:31:09 +01:00
iCrawl
b256ae1fa6 chore: open collective funding 2021-11-09 18:51:43 +01:00
Almeida
49e3ce2133 feat(SystemChannelFlags): add new flag (#6870)
Co-authored-by: Shubham Parihar <shubhamparihar391@gmail.com>
2021-11-06 01:00:18 +01:00
ckohen
c297829d54 types(Events): rest events can be emitted on BaseClient (#6936) 2021-11-06 00:58:54 +01:00
すずねーう
dc6454104f docs(Guild): fix setOwner() example (#6929)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-11-05 10:32:49 +01:00
Jiralite
28688e27d5 refactor: Deprecate application command events (#6937) 2021-11-02 14:43:30 +01:00
Tiemen
f43140abac feature(UserFlags): add BOT_HTTP_INTERACTIONS (#6733) 2021-11-01 18:50:42 +01:00
Almeida
47d74ebf81 feat: add new activity flags (#6699) 2021-11-01 18:50:36 +01:00
Advaith
e94073a6ab feat(ApplicationFlags): add message content intent flags (#6888) 2021-11-01 18:50:23 +01:00
iCrawl
076524a064 chore: dev version 2021-11-01 18:48:21 +01:00
iCrawl
5ec04e077b chore(Release): version 13.3.1 2021-11-01 18:46:16 +01:00
SpaceEEC
9bd3689fb1 fix: assert channel types in message actions (#6919) 2021-11-01 18:40:19 +01:00
Rodry
95d2a4d35e fix(MessageEmbed): only compare image urls in #equals (#6926) 2021-11-01 18:36:41 +01:00
Superchupu
bb245b7b35 docs(README): use correct capitalization of npm (#6930) 2021-11-01 18:36:26 +01:00
Rodry
204aee799a types: improve toJSON methods for message components & embeds (#6925) 2021-11-01 15:09:00 +01:00
Rodry
2d9ffb8c5b fix: correctly access guild IDs inside managers (#6927) 2021-11-01 15:07:55 +01:00
Indian Ocean Roleplay
b6484ac117 ci: validate typings (#6913) 2021-11-01 15:07:27 +01:00
Indian Ocean Roleplay
761a901885 chore: next dev version (#6920) 2021-10-29 22:11:00 +02:00
iCrawl
0238da45c5 chore(Release): publish 2021-10-29 20:10:45 +02:00
iCrawl
27fb5e5c6b chore: repo changes 2021-10-29 19:53:54 +02:00
Indian Ocean Roleplay
673c03f7cf types(fix): BaseCommandInteractionOptionResolver and CommandInteraction (#6910) 2021-10-29 19:38:21 +02:00
Jiralite
d6685b1c50 fix: Handle message bulk delete and thread delete in collectors (#6902) 2021-10-29 14:58:31 +02:00
Suneet Tipirneni
14716df6b6 feat(ThreadMemberManager): allow individual members to be fetched (#6889)
Co-authored-by: ckohen <chaikohen@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-10-29 14:57:53 +02:00
Jiralite
aa4d05504f docs(Constants): Document missing autocomplete interaction constants (#6916) 2021-10-29 14:57:35 +02:00
Almeida
7be9170659 types(Constants): remove deleted properties from Package (#6908) 2021-10-29 14:57:12 +02:00
Jiralite
5d987ee56e docs(InteractionCollector): Add info block about being prone to always running (#6906) 2021-10-29 01:39:24 +02:00
Indian Ocean Roleplay
49e686a721 ci: release dev version only if required (#6879) 2021-10-29 01:24:04 +02:00
Micah Benac
ddf759c811 feat: add support for autocomplete interactions (#6672)
Co-authored-by: Suneet Tipirneni <suneettipirneni@icloud.com>
2021-10-29 00:47:50 +02:00
SpaceEEC
14d9a9901b types(Shard): eval returns a promise resolving with T instead of T[] (#6901) 2021-10-29 00:47:18 +02:00
Vlad Frangu
ee93a27e15 types(ApplicationCommandManager): add missing overload for fetch (#6904) 2021-10-28 16:19:19 +02:00
Suneet Tipirneni
91a432e49d types(TextBasedChannel): text channel interaction collectors should have message option (#6903) 2021-10-28 16:19:08 +02:00
iCrawl
c278674e8a chore: change testing to tests for workflow 2021-10-28 02:02:53 +02:00
iCrawl
aa532946c9 chore: repo cleanup 2021-10-28 02:01:19 +02:00
GodderE2D
bdd841a1e7 docs(GuildStickerManager): fix create() example (#6900) 2021-10-28 01:21:52 +02:00
Rodry
fae4abf2f7 feat(MessageEmbed): add #equals (#6885) 2021-10-27 12:08:20 +02:00
Suneet Tipirneni
b2836daafe typings: cache types cleanup (#6867)
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-10-27 12:08:01 +02:00
Advaith
f169c8fe46 fix(ApplicationCommandManager): update guild command cache on c/u/d (#6841) 2021-10-27 12:07:50 +02:00
Rodry
740d3f006e feat(StartThreadOptions): default autoArchiveDuration to channel's defaultAutoArchiveDuration (#6278) 2021-10-27 12:07:28 +02:00
GodderE2D
88060395d1 docs(InteractionResponses): move embed var position in example (#6896) 2021-10-27 01:08:20 +02:00
Suneet Tipirneni
acbfc5c866 chore: bump discord-api-types & builders (#6894) 2021-10-26 21:29:23 +02:00
Rodry
e12a5b6a0c refactor: move Guild setPositions methods to managers (#6875)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2021-10-26 21:28:56 +02:00
Lin
b27888455f refactor: remove gen-esm-wrapper dependency (#6884) 2021-10-26 18:12:16 +02:00
GodderE2D
76856b967a docs(Application): rename Oauth2Application to Application (#6891) 2021-10-26 18:04:10 +02:00
StefansArya
ceaf738d2e fix(TextBasedChannel): return the cached message instead of clone it (#6877) 2021-10-25 00:35:59 +02:00
Jiralite
b6c9fd691f docs(Util): Deprecate .removeMentions() (#6866) 2021-10-25 00:35:13 +02:00
chrdek
7621e9da4c fix(MessageComponentInteraction): component getter is not null anymore (#6835) 2021-10-25 00:34:53 +02:00
Almeida
672baa49e6 refactor: fix typos (#6852) 2021-10-24 21:34:37 +02:00
Suneet Tipirneni
c3948f8253 types: allow message cached props to be narrowed (#6838)
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-10-24 21:31:42 +02:00
Jiralite
579569ae18 refactor(GuildManager): Remove redundant check (#6859) 2021-10-19 16:11:50 +02:00
Jiralite
399e720b92 feat: Add rtcRegion to GuildManager#create() (#6858) 2021-10-19 16:11:29 +02:00
Suneet Tipirneni
e0afcadda4 feat: add typeguards to webhooks (#6850) 2021-10-19 16:11:21 +02:00
Suneet Tipirneni
4dff279a6f fix: PartialGuildMember#id is not null (#6840) 2021-10-17 16:19:42 +02:00
Skick
487d32d303 feat(GuildChannelManager): add 'rtcRegion' option to 'create' method (#6849)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-10-17 16:18:33 +02:00
ckohen
7513b4528c feat(Permissions): add checkAdmin to permission overwrite checks (#6847) 2021-10-17 00:27:52 +02:00
Suneet Tipirneni
e8b69974dc types(CommandInteractionOptionResolver): allow narrowing of getMember() (#6831) 2021-10-17 00:19:49 +02:00
Jiralite
d27fddbf9a types(BaseMessageComponent): Remove third parameter of create() (#6833) 2021-10-17 00:19:36 +02:00
Jiralite
d193d04cea fix(Webhook): Resolve source guild only if cached (#6834) 2021-10-17 00:19:23 +02:00
ObscuritySRL
ef01b84fa8 fix(AllowedImageSizes): add new image sizes (#6844) 2021-10-17 00:18:17 +02:00
Jiralite
f7b7aac8b6 docs: Correct tags used for objects (#6846) 2021-10-17 00:17:33 +02:00
Jiralite
267a4b3f68 fix(MessageReaction): Prevent event double fire from uncached messages (#6818) 2021-10-17 00:16:05 +02:00
Jiralite
38cc89e5ae docs: Redirect to events correctly (#6845) 2021-10-16 00:18:13 +02:00
Jiralite
12ab5c8878 chore: Add missing intent to issue form (#6829) 2021-10-14 20:26:52 +02:00
Jiralite
c44ea50157 docs: Typos, consistency and grammar fixes (#6811) 2021-10-13 12:20:44 +02:00
Oscar Dominguez
046f44b807 ci(workflow): add cache to workflows using actions/setup-node (#6821) 2021-10-13 12:19:07 +02:00
Jiralite
4354c37762 docs(Message): Specify Snowflake in return type of awaitReactions() (#6822) 2021-10-13 12:18:00 +02:00
Suneet Tipirneni
b541d0a524 types: message component cached props narrowing (#6809) 2021-10-12 21:11:37 +02:00
Hackerboi 69
6898fa3b37 feat(Interaction): add isApplicationCommand check (#6801) 2021-10-12 21:11:32 +02:00
Jiralite
460df9eb4d refactor: Remove redundant user agent parsing (#6820) 2021-10-12 21:11:25 +02:00
Rodry
bd48e6df84 feat(CommandInteraction): add toString method (#6793) 2021-10-12 21:11:18 +02:00
Rodry
5566404850 types(ApplicationCommandOptionData): remove required on subcommands (#6790) 2021-10-12 21:11:11 +02:00
Alessandro Impellizzeri
29667c96e5 fix(Guild): guild.available is never set on new joins (#6769) 2021-10-12 21:10:59 +02:00
Jeroen Claassens
b47467755c fix(Types): export more types (#6808) 2021-10-12 19:38:12 +02:00
Jiralite
187581dd84 types(Integration): Add IntegrationType values (#6815) 2021-10-12 19:35:26 +02:00
Jiralite
b030130df1 docs: Replace FetchOwnerOptions type definition (#6814) 2021-10-12 19:35:16 +02:00
Jiralite
d57ec7ab68 docs: Remove dangling reference (#6810) 2021-10-11 13:57:00 +02:00
Brage
b1b9c83df0 docs(InteractionCollector): remove repeated "the" (#6802) 2021-10-11 13:54:16 +02:00
Shubham Parihar
bfb89de864 fix(GuildBanManager): send reason in the headers instead of json body (#6800) 2021-10-09 15:02:39 +02:00
ckohen
26f927b9fe feat(Client): add apiResponse and apiRequest events (#6739)
Co-authored-by: Shubham Parihar <shubhamparihar391@gmail.com>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: SpaceEEC <24881032+SpaceEEC@users.noreply.github.com>
2021-10-09 13:56:25 +02:00
Rodry
0d599a1a76 fix(User): don't generate the banner URL when not cached (#6783) 2021-10-08 12:36:14 +02:00
Bas950
e24209a8b1 refactor: remove unnecessary checks (#6777) 2021-10-08 12:35:24 +02:00
Nico Rausch
d399a28323 feat(ModuleImporter): implement import module compatible with bundlers (#6709) 2021-10-08 12:35:13 +02:00
Shubham Parihar
872e7a59b2 refactor(Role): move initialization of delete prop out of _patch (#6776) 2021-10-07 23:17:47 +02:00
MarkusRost
78124aed28 chore(GuildMemberRoleManager): Remove unnecessary !prev check (#6781)
Co-authored-by: Bas950 <bas.van.zanten007@gmail.com>
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-10-07 18:29:00 +02:00
ckohen
b1656bfb4f fix(GuildMember): more explicit partial check (#6760) 2021-10-07 18:28:32 +02:00
MarkusRost
03c4b60384 GuildMemberRoleManager: add role that sets the role icon/emoji (#6768)
Co-authored-by: Almeida <almeidx@pm.me>
2021-10-07 18:28:12 +02:00
Jiralite
45ebea3216 types(WelcomeChannelData): Allow store channels (#6778) 2021-10-07 18:24:53 +02:00
Suneet Tipirneni
a84e51b767 types: make embed author and footer props name and text required (#6779) 2021-10-07 18:24:48 +02:00
Shubham Parihar
e31c5ca1a8 fix(Role): check for presence of icon and unicode_emoji before patching (#6780) 2021-10-07 18:24:33 +02:00
J-Human
d32956c6b7 docs(MessagePayload): change the typo of "wether" to "whether" (#6771) 2021-10-06 08:40:25 +02:00
iCrawl
adc850aa67 chore: release 2021-10-05 16:17:53 +02:00
iCrawl
26340acad9 chore(Release): version 2021-10-05 16:09:40 +02:00
Souji
8bc1ece98e docs: fetchReply info + example (#6753) 2021-10-05 01:37:04 +02:00
Rodry
ba93e85d0d refactor(User): set accentColor and banner to undefined when not yet received (#6721)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2021-10-05 00:16:59 +02:00
ObscuritySRL
d0025beb7b fix(AllowedImageSizes): add new image sizes (#6754) 2021-10-05 00:10:54 +02:00
Demir
c5421af68e chore(package): change homepage (#6550) 2021-10-05 00:08:13 +02:00
Almeida
a194d9c37f refactor: use optional chaining (#6757) 2021-10-05 00:04:53 +02:00
Suneet Tipirneni
d873a19d34 types(Interaction): allow Interaction cached properties to be type narrowed (#6668)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-10-05 00:01:43 +02:00
Antonio Román
f88f4cca64 types: rename Awaited<T> to Awaitable<T> (#6756) 2021-10-04 14:11:42 +02:00
Rodry
00e1e2673b fix(User): compare flags in #equals (#6750) 2021-10-04 09:38:28 +02:00
Rodry
1db3e76054 docs(GuildMemberUpdateAction): event doesn't get emitted on user update (#6752) 2021-10-04 09:38:07 +02:00
Jiralite
7eec06145a fix(VoiceState): Patch streaming value (#6747) 2021-10-03 22:55:27 +02:00
Rodry
c3f4de4801 types(GuildBanManager): remove can return null (#6748) 2021-10-03 22:55:14 +02:00
Rodry
42acc6eef9 types: add ExcludeEnum utility for easier typings (#6746)
Co-authored-by: Jan <66554238+vaporox@users.noreply.github.com>
2021-10-03 22:54:43 +02:00
Jiralite
32b5c2e617 types(Webhook): More accurate type for sourceChannel (#6751) 2021-10-03 22:53:37 +02:00
Jiralite
abf158dc94 types(WebhooksUpdate): Allow NewsChannels (#6749)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2021-10-03 22:53:20 +02:00
Shubham Parihar
7129965423 feat: add support for role icons (#6633) 2021-10-03 18:55:29 +02:00
SpaceEEC
a8c21cd754 fix(Message): avoid overwriting properties in _patch (#6738) 2021-10-03 15:27:00 +02:00
Jiralite
6e5c768379 docs: Better links for .toJSON() of button and select menu (#6745)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2021-10-03 15:26:21 +02:00
SpaceEEC
d15dd5f07d fix(ReactionCollector): only call the filter function once (#6734) 2021-10-03 15:04:37 +02:00
SpaceEEC
905d100d4d fix(Shard): use provided timeout when respawning (#6735) 2021-10-03 15:04:23 +02:00
SpaceEEC
34b2ad0d8e docs: undocument private constructors (#6732) 2021-10-03 15:02:11 +02:00
Jiralite
a8e60105fb types: More accurate types instead of GuildChannelResolvable (#6744) 2021-10-03 15:01:38 +02:00
Almeida
9e421f6ccf fix(Role): toJSON() throwing due to permission bigints (#6724) 2021-10-03 15:01:24 +02:00
ObscuritySRL
28d96e344b feat(Interaction): add memberPermissions (#6741)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2021-10-03 15:01:07 +02:00
Rodry
3eacf7a587 feat(CategoryChannel): add createChannel shortcut method (#6614) 2021-10-03 15:00:41 +02:00
Almeida
e9daa31eaf perf: use logical assignments instead of if statements (#6693) 2021-10-03 14:59:57 +02:00
Rodry
9eb9591473 fix: don't patch set data with undefined (#6694) 2021-10-03 14:59:52 +02:00
Rodry
8b4456e0aa types(ChannelTypes): remove unknown from CHANNEL options (#6701) 2021-10-03 14:59:45 +02:00
Rodry
b76bb8a409 fix(Invite): #guild never resolving into a Guild (#6742)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2021-10-02 23:46:32 +02:00
Jiralite
107822d28d feat: Allow webhooks to fetch, edit and delete messages in threads (#6695)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-10-02 13:42:25 +02:00
Nyan Spaghetti
cdf65f74e1 fix(GuildManager): add missing types and converts (#6683)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2021-10-02 13:42:10 +02:00
muchnameless
a7cb314e07 types(TextBasedChannels): fix awaitMessageComponent return type (#6723) 2021-10-02 13:41:53 +02:00
Jiralite
3a978f347c types(Vanity): Make uses non-nullable (#6715) 2021-10-02 13:41:30 +02:00
Advaith
10478ad148 feat(Threads): update permissions and fix getters (#6466) 2021-10-02 13:41:05 +02:00
muchnameless
7c4d1dffb4 types(Role): Role#comparePositionTo accepts RoleResolvable (#6722) 2021-10-02 13:40:52 +02:00
Jiralite
2803db683d feat(PartialGroupDMChannel): Add recipients & fix name (#6713) 2021-10-02 13:40:40 +02:00
cherryblossom000
3f1100976f docs(Message): fix return type for reply (#6720) 2021-10-02 13:40:15 +02:00
Almeida
531b46c60d refactor: use the node: protocol (#6710) 2021-10-02 13:40:02 +02:00
Rodry
466e796a1d docs(CommandInteractionResolvedData): fix key type (#6729) 2021-10-02 13:38:59 +02:00
Almeida
8d80fec86d fix(Util): default animated to false when omitted on resolvePartialEmoji (#6725) 2021-10-02 13:38:37 +02:00
Rodry
fe9500538e types(Presence): fix ActivityOptions#type and Activity#id types (#6696) 2021-09-28 18:57:09 +02:00
ckohen
da3ae4854e types: fix missing channel type in subcommand options (#6706) 2021-09-28 18:55:39 +02:00
Rodry
dfd7b403a9 feat(GuildMember): add guild avatars (#5696)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Shubham Parihar <shubhamparihar391@gmail.com>
Co-authored-by: GoldenAngel <50855202+GoldenAngel2@users.noreply.github.com>
2021-09-28 18:53:37 +02:00
Shubham Parihar
7cba67620e docs(EmojiResolvable): update description of typedef to remove ambiguity (#6708) 2021-09-28 18:52:47 +02:00
Shubham Parihar
c5db0ff606 feat(MessageAttachment): add support for ephemeral property (#6652)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2021-09-28 18:52:03 +02:00
Rodry
60aa9ae478 fix(Message): throw error on missing channel (#6581)
Co-authored-by: D Trombett <73136330+DTrombett@users.noreply.github.com>
2021-09-28 18:51:42 +02:00
ckohen
3b14883e34 feat(ApplicationCommand): add support for channel_types (#6640)
Co-authored-by: Tiemen <ThaTiemsz@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2021-09-27 13:49:39 +02:00
Shubham Parihar
8426770865 fix(CachedManager): return updated data when cache is false (#6685) 2021-09-27 13:49:25 +02:00
Rodry
79b1b20562 chore(IssueForms): remove default titles (#6659)
Co-authored-by: Souji <timoqueezle@gmail.com>
2021-09-26 21:39:52 +02:00
Jiralite
60b8ba6b86 fix(GuildEmoji): Cache restricted roles and author data (#6675) 2021-09-26 21:38:58 +02:00
Rodry
d3da83368d fix(Constants): allow undefined size (#6686)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-09-26 21:38:11 +02:00
Jiralite
f8aa4bd470 fix(*RoleManager): Create set of role ids correctly (#6674)
Co-authored-by: Jan <66554238+vaporox@users.noreply.github.com>
2021-09-26 21:33:59 +02:00
Shubham Parihar
a06a87a7c4 feat(UserManager): allow #fetch to take UserResolvable (#6677) 2021-09-26 21:33:50 +02:00
Advaith
1ca8d2c8e8 types: add GuildEmojiManager to Caches (#6671) 2021-09-26 21:33:25 +02:00
Shubham Parihar
42fdcaa1da feat: add api error code 50101 (#6663) 2021-09-26 21:33:20 +02:00
Andreas Clausen
94ca0f599d typings(VoiceState): allow moving members to stage channels (#6684) 2021-09-26 21:33:11 +02:00
Megatank58
839974ca43 docs(ApplicationCommandPermissionsManager): fix example set method (#6658) 2021-09-23 14:04:49 +02:00
D Trombett
5070d23914 fix(Shard): eval promise never resolves (#6649) 2021-09-23 13:48:22 +02:00
Suneet Tipirneni
ecd637f7d6 feat: Add support for API command types in ApplicationCommandManager (#6621) 2021-09-23 13:47:17 +02:00
Advaith
66a90d3f89 feat(Permissions): add START_EMBEDDED_ACTIVITIES (#6622) 2021-09-23 13:47:09 +02:00
Rodry
caa3b60c30 feat(Integration): add missing props and fix docs/types (#6623)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-09-23 13:47:01 +02:00
Rodry
29dd319b68 refactor(VoiceState): use manager edit method to remove error (#6631) 2021-09-23 13:46:55 +02:00
Rodry
124e177e91 refactor(Constants): better type error in cdn endpoints (#6637) 2021-09-23 13:46:40 +02:00
Apokalypt
034782641a types(Interaction): improve type guard for inGuild() (#6644) 2021-09-23 13:42:27 +02:00
Jiralite
b9a4899491 docs(Shard): Point to correct events (#6641) 2021-09-23 13:41:26 +02:00
tig
5d87398f9f fix(xxxable): follow more properly with discord behavior (#6551)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2021-09-23 13:41:18 +02:00
Shubham Parihar
603350645d fix: allow null to be passed in order to reset icon/avatar (#6646) 2021-09-23 13:40:51 +02:00
Rodry
92f6471e8e types(MessageOptions): allow APIEmbed (#6656) 2021-09-18 01:09:49 +02:00
tig
88e2622dde docs(VoiceChannel): deprecate editable (#6613) 2021-09-15 00:26:10 +02:00
Jiralite
75d85f7838 types(WelcomeChannel): Allow store channels (#6615) 2021-09-15 00:26:03 +02:00
Rodry
8add4b08f5 feat: default values for setX boolean methods (#6619) 2021-09-15 00:25:50 +02:00
Souji
0a71a4d18f chore: issue forms (#6611) 2021-09-15 00:25:19 +02:00
Shubham Parihar
183dbd7e53 feat: add api error code 30042 (#6635) 2021-09-15 00:24:16 +02:00
Rodry
256fb905fe types(MessageEmbed): allow APIEmbed type (#6629) 2021-09-15 00:19:49 +02:00
Jiralite
3c3522ae8a docs(PermissionOverwriteManager): Correct @returns of delete (#6632) 2021-09-15 00:19:04 +02:00
Suneet Tipirneni
be8912a421 feat: Give removed MessageReactions on messageReactionRemoveAll event (#6607)
Co-authored-by: D Trombett <maxtromb.dt@gmail.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2021-09-10 20:32:05 +02:00
Shubham Parihar
1b016a30c8 types(TextBasedChannelFields): add back createMessageCollector (#6616) 2021-09-10 20:31:29 +02:00
Rodry
3183b1166a fix(Message): pinnable returning false in non-DEFAULT messages (#6585) 2021-09-09 19:51:21 +02:00
Shubham Parihar
f866512e84 feat(ApplicationCommand): add version property (#6603)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-09-09 18:52:39 +02:00
Suneet Tipirneni
8cc3885739 typings: make channelId non-nullable on MessageComponentInteraction (#6600) 2021-09-08 14:42:05 +02:00
Suneet Tipirneni
c62823e43d typings: Message#createMessageComponentCollector use MessageComponentInteractionOptions<T> (#6596) 2021-09-08 14:36:15 +02:00
Jiralite
ea3695585d types(MessagePayload): Specify typings for files and resolveFile (#6608) 2021-09-08 14:34:53 +02:00
Jiralite
ea6a57e927 docs(MessagePayload): Correct return type of resolveFile() (#6605) 2021-09-08 14:34:26 +02:00
Hackerboi 69
f57791c5fe chore: remove jsdoc.json (#6587) 2021-09-05 15:40:41 +01:00
Bvdgames
8826e9ffbc fix(threadMembersUpdate): fixed typo (#6589) 2021-09-05 15:39:47 +01:00
Rodry
db73cf9255 docs(MessageButton): fix info tag (#6590) 2021-09-05 15:39:27 +01:00
Rodry
08edc0b1db fix(ThreadChannel): fetchStarterMessage bug (#6584) 2021-09-03 18:22:49 +01:00
Rodry
00bd92a451 refactor: ES2021 features (#6540)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Voltrex <mohammadkeyvanzade94@gmail.com>
2021-09-03 12:58:01 +01:00
Advaith
d81590d566 feat(MessageTypes): add CONTEXT_MENU_COMMAND (23) (#6425) 2021-09-03 12:57:33 +01:00
Souji
06460565e4 chore: issue forms (#6583) 2021-09-03 12:53:05 +01:00
Suneet Tipirneni
08419561ed typings: Collector filter parameter inference (#6574) 2021-09-01 11:07:26 +01:00
Shubham Parihar
d16ada9708 feat: add api error code 160002 (#6566) 2021-08-31 11:38:27 +01:00
Rodry
cdb00053de typings(MessageReference): correctly add undefined type (#6563) 2021-08-31 11:38:12 +01:00
Jiralite
2c219cb982 types: @typedef for StageChannelResolvable (#6568) 2021-08-30 21:57:54 +01:00
ckohen
581921f8b7 feat(ApplicationCommand): add #equals (#6414)
Co-authored-by: Juruel Keanu Lorenzo <keanulorenzo32@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2021-08-30 11:56:47 +01:00
Suneet Tipirneni
f49f70a4eb fix: await message component collectors should return component interactions not collectors (#6562) 2021-08-30 11:55:39 +01:00
Souji
54b33dd7df chore: issue forms (#6560)
* workflow: issue forms

* chore: make intents and partials dropdowns

* chore: add tip about multi-select

* chore: use typescript for cb
2021-08-30 11:53:55 +01:00
GodderE2D
33f6f8211f docs(WidgetMember): fix typo for deaf (#6564) 2021-08-30 08:10:59 +01:00
Jiralite
29d5fd163c docs(Constants): Fix interaction type link (#6558) 2021-08-29 23:45:59 +01:00
Jiralite
34024f5ef6 docs: Fix JSDoc for ClientUser#edit (#6554) 2021-08-29 20:55:39 +01:00
DraftMan
9301c9b420 fix(GuildChannel): Fix manageable method for voice-channels (#6447)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Kyra <kyranet@users.noreply.github.com>
Co-authored-by: ckohen <chaikohen@gmail.com>
2021-08-29 16:26:05 +01:00
Suneet Tipirneni
03d5549461 typings: Allow message component interaction collectors to infer collected interaction types (#6476) 2021-08-29 16:25:58 +01:00
Jiralite
774e9609d2 typings(CommandInteractionOptionResolver): Document & type thread channels (#6521) 2021-08-29 13:23:20 +01:00
ckohen
a6932546e2 feat(Threads): add support for invitable in private threads (#6501)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-29 13:23:01 +01:00
Rodry
0fe5f88316 types(MessageComponentInteraction): fix componentType (#6536) 2021-08-29 13:22:53 +01:00
Jiralite
b89280a1dd docs(Util): Correct @param for cleanContent() (#6531) 2021-08-27 09:39:19 +01:00
Casper
fc51f61f0c feat(BaseGuildTextChannel): export BaseGuildTextChannel (#6527) 2021-08-25 23:41:15 +01:00
Jeroen Claassens
49e3a14d30 ci: setup npm auto deprecate workflow (#6520)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-25 18:22:24 +01:00
Megatank58
7d4a40a26d docs(Formatters): fix typo of TimestampStyles (#6523) 2021-08-25 13:20:00 +01:00
Sugden
8a8c69a257 fix(MessageAttachment): re-assign name (#6518) 2021-08-24 21:32:56 +01:00
Advaith
839c6da03d feat(User): banners and accent colors (#6117)
* feat(User): support banners

don't mind it for now, just trying

* feat(User): support banners

* fix(Constants): declare dynamic

* fix(User): eslint

* typings: update User typings

* fix(User): add banner to equals and json bannerURL

* typings: missing dynamic

* refactor: xID to xId

* types: re-add typings

* feat: add banner color and fetch note

* feat: switch to accent color (swap hex and dec))

* Update src/structures/User.js

Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>

* Update typings/index.d.ts

Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Koyamie <koyamie1@gmail.com>
Co-authored-by: Noel <icrawltogo@gmail.com>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
2021-08-24 21:32:18 +01:00
Justin
96e26c428d feat(MessageAttachment): allow files to be marked as spoilers (#6509)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-08-24 21:25:45 +01:00
Danny May
5c276398d6 typings: mark enums as const enums (#6394)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-24 21:24:34 +01:00
Rodry
705c5a1c17 feat(ThreadChannel): add fetchStarterMessage (#6488)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-08-24 21:22:11 +01:00
Rodry
4bfd5d3e74 docs(GuildChannelCreateOptions): fix #type type (#6502) 2021-08-24 21:21:43 +01:00
Jiralite
8a95211230 docs(ThreadManager): Fix typo (#6485) 2021-08-24 21:21:22 +01:00
Kevin
141864917a fix(UserUpdateAction): rely on client.user when ids match (#6511) 2021-08-24 21:21:07 +01:00
Jiralite
57b94b9adf feat(Message): Add method to resolve a component by id (#6484) 2021-08-24 21:20:43 +01:00
Megatank58
9ca10cce06 docs: fix wrong type being displayed in docs (#6504) 2021-08-24 21:20:23 +01:00
Rodry
fb50dd9841 feat: set methods for MessageActionRow and MessageSelectMenu (#6490) 2021-08-24 21:20:03 +01:00
Jeroen Claassens
7aff15a055 typings(MessageEmbed): allow null for setTimestamp (#6514) 2021-08-24 21:19:03 +01:00
monbrey
c232baa715 typings: require component type in raw object formats (#6452) 2021-08-23 15:26:22 +01:00
Deivid
656b51875f typings(CommandInteractionOptionResolver): add missing parameter (#6497) 2021-08-23 15:23:27 +01:00
Walker Gray
c14e594d8a feat: export BaseCommandInteraction (#6478) 2021-08-23 15:22:48 +01:00
Francis Rivard
21983de3e0 feat(Guild): Add Guild#maximumBitrate getter. (#6455)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2021-08-23 15:19:55 +01:00
Francis Rivard
f39b597e31 feat(Message): prevent fetching an interaction webhook. (#6468) 2021-08-23 15:18:49 +01:00
Rodry
70cc0295f8 docs(MessageManager): fix typo (#6482) 2021-08-21 20:14:18 +01:00
MarkusRost
d6e6244336 fix(Util): allow empty strings in splitMessage (#6437) 2021-08-18 09:47:13 +01:00
Rodry
93a83c2cf7 docs(MessageReference): add possible message types (#6464) 2021-08-17 21:50:14 +01:00
Rodry
17b407935b docs(ApplicationCommandType): add DAPI link (#6463) 2021-08-17 21:49:53 +01:00
Rodry
6cac03a394 types(ClientPresence): add type declarations and docs (#6450) 2021-08-17 21:49:36 +01:00
Milo
76cf52cd0d chore(Typings): fix WebhookEditMessageOptions not having attachments (#6430) 2021-08-17 21:49:26 +01:00
Shubham Parihar
a4b8623b60 feat: add maximum prune requests reached api error (#6427) 2021-08-17 21:46:17 +01:00
Shino
5eb3553fd1 feat(Rest): expose https.Agent options (#6177)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-08-17 21:45:32 +01:00
ckohen
16493e65fd docs(BufferResolvable): add warning for URL input (#6451) 2021-08-17 21:44:37 +01:00
Synbulat Biishev
f294d1eff2 typings(GuildChannel): Added missing typing (#6454) 2021-08-17 21:44:02 +01:00
HyRo
9a833b1e0e fix(BaseClient): Remove selfbot ability (#6429) 2021-08-16 08:30:35 +01:00
monbrey
d289d5ccb7 feat(InteractionReponses): allow fetching of ephemeral messages (#6426) 2021-08-15 12:10:43 +01:00
Jiralite
2c449b6b48 fix(Sticker): Rename method correctly to _add (#6421) 2021-08-15 12:10:31 +01:00
BannerBomb
81bb68d3be typings: Message#_patch typings return type (#6433) 2021-08-15 12:09:49 +01:00
Koyamie
170c0c4985 feat: export ContextMenuInteraction (#6434) 2021-08-15 12:09:21 +01:00
ahmood
ecb6e50b46 fix(Message): fix typo (#6435) 2021-08-15 12:08:51 +01:00
Jiralite
0109ad0466 chore: Ignore .DS_Store (#6438) 2021-08-15 12:08:20 +01:00
Jiralite
84bb4f4153 docs(Formatters): Use id over ID (#6439) 2021-08-15 12:08:06 +01:00
Sugden
71fdf6fae0 refactor(Channel): make delete async (#6417) 2021-08-14 03:50:53 +01:00
Gm
759faa4174 docs(RoleManager): error in examples (#6416) 2021-08-14 03:50:44 +01:00
monbrey
615afab8bb docs: rename implementation of deferReply (#6412) 2021-08-13 01:24:05 +01:00
iCrawl
f1d5ffce04 chore: set dev version 2021-08-13 00:35:05 +02:00
iCrawl
d0bc4d7ff0 chore(Release): version 2021-08-13 00:32:27 +02:00
Ben
2bf09703c1 feat(GuildMemberManager): add 'list' method (#6403)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Ben <BenjammingKirby@users.noreply.github.com>
2021-08-12 23:05:06 +01:00
Suneet Tipirneni
dcc556c311 typings(ApplicationCommandData): make type field optional (#6405) 2021-08-12 22:12:29 +01:00
Jan
14aea12900 feat(GuildManager): allow setting with_counts to false (#6407) 2021-08-12 22:12:11 +01:00
Jan
e6f48d849f docs: remove unparsed examples (#6404) 2021-08-12 18:01:09 +01:00
Jan
933d2c5eb7 docs(GuildManager): increase fetch limit to 200 (#6406) 2021-08-12 17:29:30 +01:00
Mestery
bbda3c4beb chore(exports): allow imports of specific paths (#6367) 2021-08-12 15:10:38 +01:00
Jiralite
dce8fc7b9d fix(StageInstance): Ensure discoverableDisabled is not undefined (#6395) 2021-08-12 15:06:26 +01:00
Jiralite
44bbfa5c46 fix(WidgetMember): Default to null and not undefined (#6399) 2021-08-12 15:06:11 +01:00
Jiralite
4a64662a7d fix(Guild): preferredLocale to always be a string (#6402) 2021-08-12 15:06:03 +01:00
Suneet Tipirneni
6342430073 typings(Constants): add ApplicationCommandTypes to Constants (#6398) 2021-08-12 15:05:57 +01:00
Suneet Tipirneni
297a9118e7 typings(ApplicationCommandOptionData): Align command data options types more with discord API (#6247)
* types(ApplicationCommandData): align command data more with discord API

* types(ApplicationCommandData): clean up type definitions a bit

* types(ApplicationCommandData): fix issue where  could be used with  and

* types(ApplicationCommandOptionData): make subcommand option stronger

* test(ApplicationCommandOptionData): add typing tests
2021-08-12 15:05:41 +01:00
monbrey
fff887b2f4 feat(CommandInteractionResolvedData): access to "raw" resolved data (#6384)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2021-08-12 15:04:40 +01:00
monbrey
d9456a1a76 fix(ContextMenuInteractin): store message as raw value (#6400) 2021-08-12 11:38:42 +01:00
Jeroen Claassens
cd4029218f feat(Utils): add additional formatters (#6388) 2021-08-11 21:06:10 +01:00
Suneet Tipirneni
75b48d8d0f types(ApplicationCommandData): Stronger typings for ApplicationCommandData variants. (#6382) 2021-08-11 08:14:54 +01:00
DaStormer
de3c86f804 docs(ApplicationCommandData): fix type property (#6385) 2021-08-11 08:04:49 +01:00
monbrey
0266f28096 feat: right-clickybois (context menu support for ApplicationCommand and CommandInteraction) (#6176)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2021-08-10 23:56:12 +01:00
ckohen
779e14ef61 docs: update links for api-docs (#6380) 2021-08-10 23:52:51 +01:00
ckohen
4c8dc4cda6 docs: switch urls from upstream rearranging (#6378) 2021-08-10 21:33:32 +01:00
Jiralite
49d3c0bf87 docs: Correct wrong interaction links (#6274)
* docs: Correct wrong interaction links

* docs: fix errors and apply single option

* Update src/structures/CommandInteraction.js

Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-10 21:32:28 +01:00
Nico
3c17939fd5 fix(Util): remove truthy check before isNaN check (#6358)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-08-10 21:14:41 +01:00
Kevin
2a3e819fcf typings(Options): createDefaultOptions => createDefault (#6376) 2021-08-10 21:08:41 +01:00
Francis Rivard
006edca410 typings(Events): renamed messageReactionAdd's reaction parameter (#6371)
Nothing important but why not update it.
2021-08-10 15:33:51 +01:00
Noel
91740ecc30 chore(README): extend installation 2021-08-10 15:27:06 +01:00
Gilang Ramadhan
2985e5380f chore(README): more explanation in README.md (#6354)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-10 15:25:59 +01:00
Casper
0062aa6f72 docs(Invite): MANAGE_CHANNELS instead of MANAGE_CHANNEL (#6361) 2021-08-09 17:30:30 +01:00
Koyamie
ea8d77ea62 docs(Options): defaultMakeCacheSettings typo (#6365)
fix defaultMakeCacheSettings to be consistant with the actual name.
2021-08-09 17:29:21 +01:00
Sugden
cd393fd421 chore: update conventional commit URL (#6351) 2021-08-08 18:11:45 +01:00
JeroenoBoy
efc20ff669 types(ApplicationCommandOptionData) changed options type (#6347)
* Changed ApplicationCommandOptionData interface

The options type `this[]` as a self reference causes issues when implementing this interface. Changing this to ApplicationCommandOptionData[] fixes this issue
https://imgur.com/a/0eVBoJU

* fixed ApplicationCommandOption

* Update typings/index.d.ts

Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-08 17:37:58 +01:00
Almeida
5f1def3793 types(ImageURLOptions): allow 'gif' format (#6342)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2021-08-08 17:36:16 +01:00
Advaith
47d2ef3e40 fix(Constants): fix CDN endpoint typings (#6332) 2021-08-08 12:45:00 +01:00
Muhimur
f13d27ca2e docs: grammar fixes (#6345) 2021-08-08 11:57:50 +01:00
Jiralite
570fba33d3 chore: Rename various stuff to "main" (#6343)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-08 00:08:00 +01:00
Shino
94bb953bf1 ci(PublishDev): remove t and hardcoded dev version (#6238)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-07 21:20:32 +01:00
ahmood
917e71a9ee fix(Managers): fix typo in unsupported warning (#6338) 2021-08-07 21:19:51 +01:00
Papageorgiadis Savvas
394d48649f feat(Threads): max autoArchiveDuration option (#6304)
Co-authored-by: Noel <buechler.noel@outlook.com>
2021-08-07 21:19:29 +01:00
SinisterDeveloper
d87299ba20 fix(GuildMemberRoleManager): typo (#6335) 2021-08-07 16:50:28 +01:00
ckohen
d14a6bfe1d refactor(Options): separate default settings for make cache (#6330) 2021-08-07 16:41:12 +01:00
iCrawl
68c059165b chore: fix bug report and feature request templates 2021-08-07 13:41:41 +02:00
iCrawl
d1d740c1a5 chore: even more labels 2021-08-07 13:31:23 +02:00
iCrawl
ed0f605b23 chore: add additional topic labels 2021-08-07 13:21:37 +02:00
Noel
b2e23ca03c chore: give labels a facelift (#6333) 2021-08-07 12:07:03 +01:00
iCrawl
0d765f53d2 chore: dev version 2021-08-07 11:46:31 +02:00
632 changed files with 55170 additions and 37250 deletions

View File

@@ -1,26 +1,11 @@
{
"extends": ["@commitlint/config-angular"],
"rules": {
"scope-case": [2, "always", "pascal-case"],
"type-enum": [
2,
"always",
[
"chore",
"build",
"ci",
"docs",
"feat",
"fix",
"perf",
"refactor",
"revert",
"style",
"test",
"types",
"workflow",
"wip"
]
]
}
"extends": ["@commitlint/config-angular"],
"rules": {
"type-enum": [
2,
"always",
["chore", "build", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test", "types", "typings"]
],
"scope-case": [0]
}
}

View File

@@ -3,7 +3,7 @@
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
@@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
@@ -45,12 +45,12 @@ threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
## Enforcement

91
.github/COMMIT_CONVENTION.md vendored Normal file
View File

@@ -0,0 +1,91 @@
## Git Commit Message Convention
> This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular).
#### TL;DR:
Messages must be matched by the following regex:
```js
/^(revert: )?(feat|fix|docs|style|refactor|perf|test|workflow|build|ci|chore|types|wip)(\(.+\))?: .{1,72}/;
```
#### Examples
Appears under "Features" header, `GuildMember` subheader:
```
feat(GuildMember): add 'tag' method
```
Appears under "Bug Fixes" header, `Guild` subheader, with a link to issue #28:
```
fix(Guild): handle events correctly
close #28
```
Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:
```
perf(core): improve patching by removing 'bar' option
BREAKING CHANGE: The 'bar' option has been removed.
```
The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.
```
revert: feat(Managers): add Managers
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
```
### Full Message Format
A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
### Revert
If the commit reverts a previous commit, it should begin with `revert:`, followed by the header of the reverted commit. In the body, it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However, if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog.
Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks.
### Scope
The scope could be anything specifying the place of the commit change. For example `GuildMember`, `Guild`, `Message`, `TextChannel` etc...
### Subject
The subject contains a succinct description of the change:
- use the imperative, present tense: "change" not "changed" nor "changes"
- don't capitalize the first letter
- no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.

View File

@@ -10,8 +10,9 @@ is a great boon to your development process.
To get ready to work on the codebase, please do the following:
1. Fork & clone the repository, and make sure you're on the **master** branch
2. Run `npm ci`
3. Code your heart out!
4. Run `npm test` to run ESLint and ensure any JSDoc changes are valid
5. [Submit a pull request](https://github.com/discordjs/discord.js/compare) (Make sure you follow the [conventional commit format](https://github.com/discordjs/discord.js-next/blob/master/.github/COMMIT_CONVENTION.md))
1. Fork & clone the repository, and make sure you're on the **main** branch
2. Run `yarn --immutable` ([install](https://yarnpkg.com/getting-started/install))
3. Run `yarn build` to build local packages
4. Code your heart out!
5. Run `yarn test` to run ESLint and ensure any JSDoc changes are valid
6. [Submit a pull request](https://github.com/discordjs/discord.js/compare) (Make sure you follow the [conventional commit format](https://github.com/discordjs/discord.js/blob/main/.github/COMMIT_CONVENTION.md))

4
.github/FUNDING.yml vendored
View File

@@ -1,2 +1,2 @@
github: [amishshah, iCrawl, vladfrangu, kyranet]
patreon: discordjs
github: [iCrawl, amishshah, vladfrangu, kyranet]
open_collective: discordjs

View File

@@ -1,38 +0,0 @@
---
name: Bug report
about: Report incorrect or unexpected behavior of discord.js
title: ''
labels: 's: unverified, type: bug'
assignees: ''
---
<!-- Use Discord for questions: https://discord.gg/djs -->
<!-- If you are reporting a voice issue, please post your issue at https://github.com/discordjs/voice/issues -->
**Please describe the problem you are having in as much detail as possible:**
**Include a reproducible code sample here, if possible:**
```js
// Place your code here
```
**Further details:**
- discord.js version:
- Node.js version:
- Operating system:
- Priority this issue should have please be realistic and elaborate if possible:
**Relevant client options:**
- partials: none
- gateway intents: none
- other: none
<!--
Remove the comment and fill out the commit hash if this applies to you:
(While it's not a requirement to test your issue on the master branch, it would make fixing the problem a lot easier for us, so please do so if possible.)
- I have also tested the issue on latest master, commit hash: `xxx`
-->

141
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,141 @@
name: Bug report
description: Report incorrect or unexpected behavior of a package
labels: [bug, need repro]
body:
- type: markdown
attributes:
value: |
Use Discord for questions: https://discord.gg/djs
- type: dropdown
id: package
attributes:
label: Which package is this bug report for?
options:
- discord.js
- builders
- collection
- rest
- voice
validations:
required: true
- type: textarea
id: description
attributes:
label: Issue description
description: |
Describe the issue in as much detail as possible.
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files into it.
placeholder: |
Steps to reproduce with below code sample:
1. do thing
2. do thing in Discord client
3. observe behavior
4. see error logs below
validations:
required: true
- type: textarea
id: codesample
attributes:
label: Code sample
description: Include a reproducible, minimal code sample. This will be automatically formatted into code, so no need for backticks.
render: typescript
placeholder: |
Your code sample should be...
... Minimal - Use as little code as possible that still produces the same problem (and is understandable)
... Complete - Provide all parts someone else needs to reproduce your problem
... Reproducible - Test the code you're about to provide to make sure it reproduces the problem
- type: input
id: djs-version
attributes:
label: Package version
description: Which version of are you using? Run `npm list <package>` in your project directory and paste the output.
placeholder: We no longer support version 12 or earlier of discord.js
validations:
required: true
- type: input
id: node-version
attributes:
label: Node.js version
description: |
Which version of Node.js are you using? Run `node --version` in your project directory and paste the output.
If you are using TypeScript, please include its version (`npm list typescript`) as well.
placeholder: Node.js version 16.9+ is required for version 14.0.0+
validations:
required: true
- type: input
id: os
attributes:
label: Operating system
description: Which OS does your application run on?
- type: dropdown
id: priority
attributes:
label: Priority this issue should have
description: Please be realistic. If you need to elaborate on your reasoning, please use the Issue description field above.
options:
- Low (slightly annoying)
- Medium (should be fixed soon)
- High (immediate attention needed)
validations:
required: true
- type: dropdown
id: partials
attributes:
label: Which partials do you have configured?
description: |
Check your Client constructor for the `partials` key.
Tip: you can select multiple items
options:
- Not applicable (subpackage bug)
- No Partials
- User
- Channel
- GuildMember
- Message
- Reaction
- GuildScheduledEvent
- ThreadMember
multiple: true
validations:
required: true
- type: dropdown
id: intents
attributes:
label: Which gateway intents are you subscribing to?
description: |
Check your Client constructor options for the `intents` key.
Tip: you can select multiple items
options:
- Not applicable (subpackage bug)
- No Intents
- Guilds
- GuildMembers
- GuildBans
- GuildEmojisAndStickers
- GuildIntegrations
- GuildWebhooks
- GuildInvites
- GuildVoiceStates
- GuildPresences
- GuildMessages
- GuildMessageReactions
- GuildMessageTyping
- DirectMessages
- DirectMessageReactions
- DirectMessageTyping
- GuildScheduledEvents
multiple: true
validations:
required: true
- type: input
id: dev-release
attributes:
label: I have tested this issue on a development release
placeholder: d23280c (commit hash)
description: |
The issue might already be fixed in a development release or main. This is not required, but helps us greatly.
[discord.js only] To install the latest development release run `npm i discord.js@dev` in your project directory.
Run `npm list discord.js` and use the last part of the printed information (`d23280c` for `discord.js@xx.x.x-dev.1530234593.d23280c`)

View File

@@ -1,21 +0,0 @@
---
name: Feature request
about: Request a feature for the core discord.js library
title: ''
labels: 'type: enhancement'
assignees: ''
---
<!-- Use Discord for questions: https://discord.gg/djs -->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Eg. I'm always frustrated when [...]
**Describe the ideal solution**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -0,0 +1,47 @@
name: Feature request
description: Request a new feature (discord.js accepts documented features of the official Discord developer API only!)
labels: [feature request]
body:
- type: markdown
attributes:
value: |
We can only implement features that Discord publishes, documents and merges into the Discord API documentation.
We do not implement unreleased features.
Use Discord for questions: https://discord.gg/djs
- type: dropdown
id: package
attributes:
label: Which package is the feature request for?
options:
- discord.js
- builders
- collection
- rest
- voice
validations:
required: true
- type: textarea
id: description
attributes:
label: Feature
description: A clear and concise description of what the problem is, or what feature you want to be implemented.
placeholder: I'm always frustrated when..., Discord has recently released..., A good addition would be...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Ideal solution or implementation
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternative solutions or implementations
description: A clear and concise description of any alternative solutions or features you have considered.
- type: textarea
id: additional-context
attributes:
label: Other context
description: Any other context, screenshots, or file uploads that help us understand your feature request.

View File

@@ -1,7 +1,5 @@
**Please describe the changes this PR makes and why it should be merged:**
**Status and versioning classification:**
<!--

7
.github/auto_assign.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
addReviewers: true
reviewers:
- iCrawl
- SpaceEEC
- kyranet
- vladfrangu
numberOfReviewers: 0

27
.github/labeler.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
chore:
- any: ['*']
all: ['!packages/*', '!packages/**/*']
'packages:builders':
- packages/builders/*
- packages/builders/**/*
'packages:collection':
- packages/collection/*
- packages/collection/**/*
'packages:discord.js':
- packages/discord.js/*
- packages/discord.js/**/*
'packages:rest':
- packages/rest/*
- packages/rest/**/*
'packages:voice':
- packages/voice/*
- packages/voice/**/*
'packages:ws':
- packages/ws/*
- packages/ws/**/*

92
.github/labels.yml vendored Normal file
View File

@@ -0,0 +1,92 @@
- name: 'api changes'
color: '5663e9'
- name: 'api support'
color: '5663e9'
- name: 'backlog'
color: '7ef7ef'
- name: 'bug'
color: 'd73a4a'
- name: 'caching'
color: '80c042'
- name: 'chore'
color: 'ffffff'
- name: 'ci'
color: '0075ca'
- name: 'dependencies'
color: '276bd1'
- name: 'discussion'
color: 'b6b1f9'
- name: 'discord'
color: '5663e9'
- name: 'documentation'
color: '0075ca'
- name: 'duplicate'
color: 'cfd3d7'
- name: 'error handling'
color: '80c042'
- name: 'feature request'
color: 'fcf95a'
- name: 'gateway'
color: '80c042'
- name: 'good first issue'
color: '7057ff'
- name: 'has PR'
color: '4b1f8e'
- name: 'help wanted'
color: '008672'
- name: 'interactions'
color: '80c042'
- name: 'in progress'
color: 'ffccd7'
- name: 'in review'
color: 'aed5fc'
- name: 'invalid'
color: 'e4e669'
- name: 'need repro'
color: 'c66037'
- name: 'packages:builders'
color: 'fbca04'
- name: 'packages:collection'
color: 'fbca04'
- name: 'packages:discord.js'
color: 'fbca04'
- name: 'packages:rest'
color: 'fbca04'
- name: 'packages:voice'
color: 'fbca04'
- name: 'packages:ws'
color: 'fbca04'
- name: 'performance'
color: '80c042'
- name: 'permissions'
color: '80c042'
- name: 'priority:high'
color: 'fc1423'
- name: 'question (please use Discord instead)'
color: 'd876e3'
- name: 'ratelimits'
color: '80c042'
- name: 'refactor'
color: '1d637f'
- name: 'regression'
color: 'ea8785'
- name: 'REST'
color: '80c042'
- name: 'semver:major'
color: 'c10f47'
- name: 'semver:minor'
color: 'e4f486'
- name: 'semver:patch'
color: 'e8be8b'
- name: 'sharding'
color: '80c042'
- name: 'tests'
color: 'f06dff'
- name: 'threads'
color: '80c042'
- name: 'typings'
color: '80c042'
- name: 'utility'
color: '80c042'
- name: 'wontfix'
color: 'ffffff'

32
.github/tsc.json vendored
View File

@@ -1,18 +1,18 @@
{
"problemMatcher": [
{
"owner": "tsc",
"pattern": [
{
"regexp": "^(?:\\s+\\d+\\>)?([^\\s].*)\\((\\d+),(\\d+)\\)\\s*:\\s+(error|warning|info)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"code": 5,
"message": 6
}
]
}
]
"problemMatcher": [
{
"owner": "tsc",
"pattern": [
{
"regexp": "^(?:\\s+\\d+\\>)?([^\\s].*)\\((\\d+),(\\d+)\\)\\s*:\\s+(error|warning|info)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"code": 5,
"message": 6
}
]
}
]
}

28
.github/workflows/auto-deprecate.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: npm auto deprecate
on:
workflow_dispatch:
schedule:
- cron: '0 1 * * *'
jobs:
auto-deprecate:
name: npm auto deprecate
runs-on: ubuntu-latest
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install node.js v16
uses: actions/setup-node@v2
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: yarn --immutable
- name: Deprecate versions
run: 'yarn npm-deprecate --name "*dev*" --package @discordjs/builders @discordjs/collection discord.js @discordjs/rest @discordjs/voice'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}

View File

@@ -1,28 +0,0 @@
name: Deployment
on:
push:
branches:
- '*'
- '!docs'
tags:
- '*'
jobs:
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
uses: actions/setup-node@v2
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Build and deploy documentation
uses: discordjs/action-docs@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

127
.github/workflows/documentation.yml vendored Normal file
View File

@@ -0,0 +1,127 @@
name: Documentation
on:
push:
branches:
- 'main'
- 'stable'
- '!docs'
tags:
- '**'
jobs:
build:
name: Build documentation
runs-on: ubuntu-latest
if: github.repository_owner == 'discordjs'
outputs:
BRANCH_NAME: ${{ steps.env.outputs.BRANCH_NAME }}
BRANCH_OR_TAG: ${{ steps.env.outputs.BRANCH_OR_TAG }}
SHA: ${{ steps.env.outputs.SHA }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install node.js v16
uses: actions/setup-node@v2
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Turbo cache
id: turbo-cache
uses: actions/cache@v2
with:
path: .turbo
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
turbo-${{ github.job }}-${{ github.ref_name }}-
- name: Install dependencies
run: yarn --immutable
- name: Build docs
run: yarn docs --cache-dir=".turbo"
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: docs
path: packages/*/docs/docs.json
- name: Set outputs for upload job
id: env
run: |
echo "::set-output name=BRANCH_NAME::${GITHUB_REF_NAME}"
echo "::set-output name=BRANCH_OR_TAG::${GITHUB_REF_TYPE}"
echo "::set-output name=SHA::${GITHUB_SHA}"
upload:
name: Upload Documentation
needs: build
strategy:
max-parallel: 1
fail-fast: false
matrix:
package: ['builders', 'collection', 'discord.js', 'rest', 'voice']
runs-on: ubuntu-latest
env:
BRANCH_NAME: ${{ needs.build.outputs.BRANCH_NAME }}
BRANCH_OR_TAG: ${{ needs.build.outputs.BRANCH_OR_TAG }}
SHA: ${{ needs.build.outputs.SHA }}
steps:
- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: docs
path: docs
- name: Checkout docs repository
uses: actions/checkout@v2
with:
repository: 'discordjs/docs'
token: ${{ secrets.DJS_DOCS }}
path: 'out'
- name: 'Extract package from tag'
if: env.BRANCH_OR_TAG == 'tag'
id: package-name
uses: frabert/replace-string-action@v2.0
with:
pattern: '(^@.*\\/(?<package>.*)@v?)?(?<semver>\\d+.\\d+.\\d+)-?.*'
string: ${{ env.BRANCH_NAME }}
replace-with: '$<package>'
- name: 'Extract semver from tag'
if: env.BRANCH_OR_TAG == 'tag'
id: semver
uses: frabert/replace-string-action@v2.0
with:
pattern: '(^@.*\\/(?<package>.*)@v?)?(?<semver>\\d+.\\d+.\\d+)-?.*'
string: ${{ env.BRANCH_NAME }}
replace-with: '$<semver>'
- name: Move docs to correct directory
if: env.BRANCH_OR_TAG == 'tag'
env:
PACKAGE: ${{ steps.package-name.outputs.replaced }}
SEMVER: ${{ steps.semver.outputs.replaced }}
run: |
mkdir -p out/${PACKAGE}
mv docs/${PACKAGE}/docs/docs.json out/${PACKAGE}/${SEMVER}.json
- name: Move docs to correct directory
if: env.BRANCH_OR_TAG == 'branch'
env:
PACKAGE: ${{ matrix.package }}
run: |
mkdir -p out/${PACKAGE}
mv docs/${PACKAGE}/docs/docs.json out/${PACKAGE}/${BRANCH_NAME}.json
- name: Commit and push
run: |
cd out
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add .
git commit -m "Docs build for ${BRANCH_OR_TAG} ${BRANCH_NAME}: ${SHA}" || true
git push

22
.github/workflows/labelsync.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Label Sync
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
push:
branches:
- main
paths:
- '.github/labels.yml'
jobs:
labelsync:
name: Label sync
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Label sync
uses: crazy-max/ghaction-github-labeler@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

16
.github/workflows/pr-automation.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: 'PR Automation'
on:
pull_request_target:
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Automatically label PR
uses: actions/labeler@v3
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
sync-labels: true
- name: Automatically assign reviewers
if: ${{ github.event.action == 'opened' }}
uses: kentaro-m/auto-assign-action@v1.1.2

View File

@@ -6,28 +6,68 @@ on:
jobs:
npm:
name: npm
strategy:
fail-fast: false
matrix:
include:
- package: '@discordjs/builders'
folder: 'builders'
- package: '@discordjs/collection'
folder: 'collection'
- package: 'discord.js'
folder: 'discord.js'
- package: '@discordjs/rest'
folder: 'rest'
- package: '@discordjs/voice'
folder: 'voice'
runs-on: ubuntu-latest
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
- name: Install node.js v16
uses: actions/setup-node@v2
with:
node-version: 16
registry-url: https://registry.npmjs.org/
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Turbo cache
id: turbo-cache
uses: actions/cache@v2
with:
path: .turbo
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
turbo-${{ github.job }}-${{ github.ref_name }}-
- name: Check previous released version
id: pre-release
run: |
if [[ $(npm view ${{ matrix.package }}@dev version | grep -e "$(jq --raw-output '.version' packages/${{ matrix.folder }}/package.json)\..*-$(git rev-parse --short HEAD)") ]]; \
then echo '::set-output name=release::false'; \
else echo '::set-output name=release::true'; fi
- name: Install dependencies
run: npm ci --ignore-scripts
if: steps.pre-release.outputs.release == 'true'
run: yarn --immutable
- name: Build dependencies
if: steps.pre-release.outputs.release == 'true'
run: yarn build --cache-dir=".turbo"
- name: Deprecate old versions
run: npm deprecate discord.js@"~$(jq --raw-output '.version' package.json)" "no longer supported" || true
if: steps.pre-release.outputs.release == 'true'
run: npm deprecate ${{ matrix.package }}@"~$(jq --raw-output '.version' packages/${{ matrix.folder }}/package.json)" "no longer supported" || true
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
- name: Publish
if: steps.pre-release.outputs.release == 'true'
run: |
npm version --git-tag-version=false $(jq --raw-output '.version' package.json).t$(date +%s).$(git rev-parse --short HEAD)
npm publish --tag dev || true
yarn workspace ${{ matrix.package }} version $(jq --raw-output '.version' packages/${{ matrix.folder }}/package.json).$(date +%s)-$(git rev-parse --short HEAD)
yarn workspace ${{ matrix.package }} npm publish --tag dev || true
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}

View File

@@ -1,79 +0,0 @@
name: Testing Cron
on:
schedule:
- cron: '0 */12 * * *'
jobs:
lint:
name: ESLint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
uses: actions/setup-node@v2
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
typings:
name: TSLint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
uses: actions/setup-node@v2
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Run TSLint
run: npm run lint:typings
typescript:
name: TypeScript
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
uses: actions/setup-node@v2
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Register Problem Matcher
run: echo "##[add-matcher].github/tsc.json"
- name: Run TypeScript compiler
run: npm run test:typescript
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
uses: actions/setup-node@v2
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Test documentation
run: npm run docs:test

View File

@@ -1,77 +1,37 @@
name: Testing
name: Tests
on: [push, pull_request]
jobs:
lint:
name: ESLint
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
- name: Install node.js v16
uses: actions/setup-node@v2
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
typings:
name: TSLint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
uses: actions/setup-node@v2
- name: Turbo cache
id: turbo-cache
uses: actions/cache@v2
with:
node-version: 16
path: .turbo
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
turbo-${{ github.job }}-${{ github.ref_name }}-
- name: Install dependencies
run: npm ci
run: yarn --immutable
- name: Run TSLint
run: npm run lint:typings
- name: ESLint
run: yarn lint --cache-dir=".turbo"
typescript:
name: TypeScript
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Tests
run: yarn test --cache-dir=".turbo"
- name: Install Node v16
uses: actions/setup-node@v2
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Register Problem Matcher
run: echo "##[add-matcher].github/tsc.json"
- name: Run TypeScript compiler
run: npm run test:typescript
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v16
uses: actions/setup-node@v2
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Test documentation
run: npm run docs:test
- name: Build
run: yarn build --cache-dir=".turbo"

38
.gitignore vendored
View File

@@ -1,25 +1,37 @@
# Packages
node_modules/
yarn.lock
# Log files
logs/
*.log
npm-debug.log*
# Authentication
test/auth.json
test/auth.js
docs/deploy/deploy_key
docs/deploy/deploy_key.pub
deploy/deploy_key
deploy/deploy_key.pub
# Runtime data
pids
*.pid
*.seed
# Env
.env
# Dist
dist/
# Miscellaneous
.tmp/
.vscode/
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea/
docs/docs.json
typings/index.js
.DS_Store
.turbo
tsconfig.tsbuildinfo
# Autogenerated
src/index.mjs
# yarn
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

1
.husky/.gitignore vendored
View File

@@ -1 +0,0 @@
_

View File

@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1
yarn commitlint --edit $1

View File

@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install lint-staged
yarn format

View File

@@ -1,4 +0,0 @@
{
"*.{mjs,js}": "eslint --fix --ext mjs,js,ts",
"*.{ts,json,yml,yaml}": "prettier --write"
}

3
.npmrc
View File

@@ -1,3 +0,0 @@
audit=false
fund=false
legacy-peer-deps=true

View File

@@ -1,7 +1,8 @@
{
"singleQuote": true,
"printWidth": 120,
"trailingComma": "all",
"endOfLine": "lf",
"arrowParens": "avoid"
"printWidth": 120,
"useTabs": true,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"endOfLine": "lf"
}

View File

@@ -1,14 +0,0 @@
{
"ecmaVersion": 7,
"libs": [],
"loadEagerly": ["./src/*.js"],
"dontLoad": ["node_modules/**"],
"plugins": {
"es_modules": {},
"node": {},
"doc_comment": {
"fullDocs": true,
"strong": true
},
}
}

12
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"tamasfe.even-better-toml",
"github.vscode-pull-request-github",
"codezombiech.gitignore",
"eamodio.gitlens",
"christian-kohler.npm-intellisense",
"christian-kohler.path-intellisense"
]
}

9
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,9 @@
{
"eslint.workingDirectories": [{ "pattern": "./packages/*" }],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": false
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

768
.yarn/releases/yarn-3.1.1.cjs vendored Normal file

File diff suppressed because one or more lines are too long

11
.yarnrc.yml Normal file
View File

@@ -0,0 +1,11 @@
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
spec: "@yarnpkg/plugin-version"
yarnPath: .yarn/releases/yarn-3.1.1.cjs

View File

@@ -1,324 +0,0 @@
## [13.0.1](https://github.com/discordjs/discord.js/compare/13.0.0...13.0.1) (2021-08-07)
### Bug Fixes
* **GuildMemberManager:** refactor fetchMany ([#6328](https://github.com/discordjs/discord.js/issues/6328)) ([909c873](https://github.com/discordjs/discord.js/commit/909c87353e24eb7947d1cabc78d9c0ee97c3902d))
* **Message:** handle fetched messages ([#6325](https://github.com/discordjs/discord.js/issues/6325)) ([ceae596](https://github.com/discordjs/discord.js/commit/ceae5960edefc63be5f16a52e286e390c14e0d29))
# [13.0.0](https://github.com/discordjs/discord.js/compare/12.5.0...13.0.0) (2021-08-06)
### Bug Fixes
* **Action:** getChannel interaction DM ([#6280](https://github.com/discordjs/discord.js/issues/6280)) ([a72b5a3](https://github.com/discordjs/discord.js/commit/a72b5a355e443f17edf1b348f63d314c743093b9))
* **BaseGuildTextChannel:** call patch ([#6298](https://github.com/discordjs/discord.js/issues/6298)) ([3eb4140](https://github.com/discordjs/discord.js/commit/3eb41405f412ee2b2d05c4245c4ebb80adfcec6b))
* **Caching:** sweep archived threads in all channel caches ([#6312](https://github.com/discordjs/discord.js/issues/6312)) ([3725dca](https://github.com/discordjs/discord.js/commit/3725dcafc0cbb4a40d3ff66d2a9718e986f47c5b))
* **Channel:** add default for destructured options ([#6203](https://github.com/discordjs/discord.js/issues/6203)) ([6872547](https://github.com/discordjs/discord.js/commit/68725476b39d5ef5793ccf62cfb468073e7d9cb2))
* **ChannelUpdate:** restore accidentally removed line ([#6263](https://github.com/discordjs/discord.js/issues/6263)) ([774f5b7](https://github.com/discordjs/discord.js/commit/774f5b77ec6218c30360c773b5fe6185d1efd146))
* **CommandInteractionOptionResolver:** Export CommandInteractionOptio… ([#6146](https://github.com/discordjs/discord.js/issues/6146)) ([8ccfd6e](https://github.com/discordjs/discord.js/commit/8ccfd6e07b3208568c495110c80990366637818e))
* **CommandInteractionOptionResolver:** type should be USER ([#6148](https://github.com/discordjs/discord.js/issues/6148)) ([02f55f0](https://github.com/discordjs/discord.js/commit/02f55f09712af5d6a6f67b5ac369b1969801e23f))
* **Guild:** add invite manager property, extend CachedManager ([#6049](https://github.com/discordjs/discord.js/issues/6049)) ([e3d877d](https://github.com/discordjs/discord.js/commit/e3d877d542518d0f82c476d921968338a859722b))
* **GuildChannel:** Add missing 'cache' property ([#6019](https://github.com/discordjs/discord.js/issues/6019)) ([7e30011](https://github.com/discordjs/discord.js/commit/7e3001191c1529b9db09b6168ddd0c09931598f5))
* **GuildChannel:** setParent not working ([#6276](https://github.com/discordjs/discord.js/issues/6276)) ([7e0618f](https://github.com/discordjs/discord.js/commit/7e0618f17a786708093bc532501b261191e85561))
* **GuildChannel:** use map method on cache not its manager ([#6032](https://github.com/discordjs/discord.js/issues/6032)) ([d58f0d2](https://github.com/discordjs/discord.js/commit/d58f0d243c9bbd803cff7b8da2056c11e0416bef))
* **GuildMemberManager:** fetchMany fixes ([#6314](https://github.com/discordjs/discord.js/issues/6314)) ([52817fc](https://github.com/discordjs/discord.js/commit/52817fc414eef5220043e055a740e4ad0f8287a0))
* **Message:** fix thread getter ([#6309](https://github.com/discordjs/discord.js/issues/6309)) ([913c9fa](https://github.com/discordjs/discord.js/commit/913c9fa17672fa914776beb556edcee5cd2d2dc8))
* **MessageMentions:** check guild exists before adding roles ([#6313](https://github.com/discordjs/discord.js/issues/6313)) ([1200bba](https://github.com/discordjs/discord.js/commit/1200bba7bcc48dab6a454925e533528a7e3c0cf7))
* export various classes that are exported in the typings ([#6166](https://github.com/discordjs/discord.js/issues/6166)) ([30a58dc](https://github.com/discordjs/discord.js/commit/30a58dc80130d334bf8c85e7b37513c109beda1b))
* remove support for overriding caches that break functionality ([#6282](https://github.com/discordjs/discord.js/issues/6282)) ([a6d4035](https://github.com/discordjs/discord.js/commit/a6d4035176ca784e75bd1cbdf30e039658c62fd4))
* **CommandInteraction:** change options type from Collection to array ([#6139](https://github.com/discordjs/discord.js/issues/6139)) ([77784ac](https://github.com/discordjs/discord.js/commit/77784aca431709ff3c17095bd06f9e4016fbd11d))
* **GuildAuditLog:** Assert `target` to null upon not finding invite codes ([#6171](https://github.com/discordjs/discord.js/issues/6171)) ([c8ca7bf](https://github.com/discordjs/discord.js/commit/c8ca7bfd2c5e7b29e54987a78301e9bdfa4a717b))
* **GuildChannel:** clone its PermissionOverwriteManager too ([#6083](https://github.com/discordjs/discord.js/issues/6083)) ([f72ce7c](https://github.com/discordjs/discord.js/commit/f72ce7c136cf2dfe31a67b190c00e30ba7d70bfa))
* **GuildChannel:** only fetch invites for the specific channel ([#6132](https://github.com/discordjs/discord.js/issues/6132)) ([c40c0f9](https://github.com/discordjs/discord.js/commit/c40c0f934a571c100e4b3aa633a80fe48661d836))
* **InviteScope:** added missing 'bot' scope ([#6052](https://github.com/discordjs/discord.js/issues/6052)) ([93e2c04](https://github.com/discordjs/discord.js/commit/93e2c04ec27c44a8c955e576944023dc25075647))
* **Message:** fix typo in sticker_items ([#6173](https://github.com/discordjs/discord.js/issues/6173)) ([870a0de](https://github.com/discordjs/discord.js/commit/870a0de53c01331c9357df4808fc0979ff17b9a4))
* **Message:** make #channel and #guild getters ([#6271](https://github.com/discordjs/discord.js/issues/6271)) ([6e3236a](https://github.com/discordjs/discord.js/commit/6e3236ab64549d27445c631cbb3d88c2bb9bf289))
* **PermissionOverwriteManager:** pass ID to API correctly ([#6026](https://github.com/discordjs/discord.js/issues/6026)) ([8077e4f](https://github.com/discordjs/discord.js/commit/8077e4f4f132f95c4fa21e9fc7313b93a2c4b9d7))
* **PermissionOverwrites:** throw better error if resolving option fails ([#6219](https://github.com/discordjs/discord.js/issues/6219)) ([42a0313](https://github.com/discordjs/discord.js/commit/42a03130345d3a3841f5271d82a2cb8725b6fa0e))
* **PermissionsOverwrites:** only convert type if number ([#6092](https://github.com/discordjs/discord.js/issues/6092)) ([dee5c83](https://github.com/discordjs/discord.js/commit/dee5c83fc0d1147d5b65151a8f91a4a089687a73))
* **PresenceUpdate:** use added presence over nullable getter ([#6077](https://github.com/discordjs/discord.js/issues/6077)) ([637c8e0](https://github.com/discordjs/discord.js/commit/637c8e0fdfb4ce15361646017718c72c3d6af538))
* **SelectMenuInteraction:** set values to empty array if not provided ([#6045](https://github.com/discordjs/discord.js/issues/6045)) ([34708d6](https://github.com/discordjs/discord.js/commit/34708d6d18f94b5c8d9c582973d057e1f89bfe1f))
* **Sticker:** replace 'this.guildID' (undefined) by 'this.guildId' in fetchUser ([#6160](https://github.com/discordjs/discord.js/issues/6160)) ([07017a9](https://github.com/discordjs/discord.js/commit/07017a9699eecc4af7824ace39dd91e8b689f3c6))
* **Structures:** remove Structures ([#6027](https://github.com/discordjs/discord.js/issues/6027)) ([ab0b3b9](https://github.com/discordjs/discord.js/commit/ab0b3b9a07f5e4987e4f25e41b2a007f2db06322))
* **TeamMember:** Fixed incorrect return types. ([#6044](https://github.com/discordjs/discord.js/issues/6044)) ([fe5d56c](https://github.com/discordjs/discord.js/commit/fe5d56c9b11b3e5f05933c6d746237b9f353b392))
* **TextBasedChannel:** Fix MessageCreate handling ([#6217](https://github.com/discordjs/discord.js/issues/6217)) ([6b85f90](https://github.com/discordjs/discord.js/commit/6b85f900fa8e6cc01f7ee14ae730950cf1635dd5))
* **ThreadChannel:** better property handling ([#6172](https://github.com/discordjs/discord.js/issues/6172)) ([9679b90](https://github.com/discordjs/discord.js/commit/9679b9087200e29d2f488d84d115465449021b51))
* **Util:** fix collection import ([#6256](https://github.com/discordjs/discord.js/issues/6256)) ([93e0239](https://github.com/discordjs/discord.js/commit/93e0239c8054293eac63338819a10490dbd49ff1))
* **WebSocketShard:** mark shard ready if no guilds intent ([#6284](https://github.com/discordjs/discord.js/issues/6284)) ([09471be](https://github.com/discordjs/discord.js/commit/09471be30eea2540999c3d5a2b001a985a0d27cc))
* array/keyArray removed ([#6245](https://github.com/discordjs/discord.js/issues/6245)) ([bf221f2](https://github.com/discordjs/discord.js/commit/bf221f2bef2871f019aa4a6978deb8460fff85b9))
* Use `string` instead of `Snowflake` for invites ([#6202](https://github.com/discordjs/discord.js/issues/6202)) ([f060a3f](https://github.com/discordjs/discord.js/commit/f060a3fcd7e1ad30789d582e8baf28dbdddf8063))
* **Typings:** type attachments to InteractionUpdateOptions ([#6162](https://github.com/discordjs/discord.js/issues/6162)) ([4f8ca29](https://github.com/discordjs/discord.js/commit/4f8ca2936a85109757fb3225e9d6cf9aae9714e2))
* channel type check in actions ([#6086](https://github.com/discordjs/discord.js/issues/6086)) ([d433fe8](https://github.com/discordjs/discord.js/commit/d433fe8a0827e6275e2a7ceed537be38411f4f67))
* Remove `connection.url` from open debug message ([#6018](https://github.com/discordjs/discord.js/issues/6018)) ([39db953](https://github.com/discordjs/discord.js/commit/39db95352c91faf175c2fd8ed365f293f965a0e4))
* **Util:** splitMessage not working with array ([#6008](https://github.com/discordjs/discord.js/issues/6008)) ([bd25ff5](https://github.com/discordjs/discord.js/commit/bd25ff59133ba31713647d3e6a5ef66abc4d54fb))
* correct permissions checks and cache on update ([#6015](https://github.com/discordjs/discord.js/issues/6015)) ([568691c](https://github.com/discordjs/discord.js/commit/568691ce6a7994adc85db2b2a5b2227ece8c8358))
* typedefs and typings for image & webhook options ([#5805](https://github.com/discordjs/discord.js/issues/5805)) ([a5a6e22](https://github.com/discordjs/discord.js/commit/a5a6e223166cf9af430da9003780e6582ea17b1c))
* **ApplicationCommand:** default option.required fix ([#5848](https://github.com/discordjs/discord.js/issues/5848)) ([a1f94f6](https://github.com/discordjs/discord.js/commit/a1f94f670e5b6009b9c33932ce06ed512447b953))
* **ApplicationCommand:** default option.required to false ([#5838](https://github.com/discordjs/discord.js/issues/5838)) ([77c1f15](https://github.com/discordjs/discord.js/commit/77c1f15c9f7562465c07727602c3213ddcf02778))
* **ApplicationCommand:** fix typo in JSDoc ([#5994](https://github.com/discordjs/discord.js/issues/5994)) ([6edf55c](https://github.com/discordjs/discord.js/commit/6edf55c04b970235fdc92c00808ee86002e589b6))
* **ApplicationCommand:** stringType isn't supposed to be sent to the API ([#5916](https://github.com/discordjs/discord.js/issues/5916)) ([ca2a36b](https://github.com/discordjs/discord.js/commit/ca2a36b1d713a743045b15adf99eda69a6fdbec7))
* **ApplicationCommands:** allow managing commands for uncached guilds ([#5729](https://github.com/discordjs/discord.js/issues/5729)) ([24e5868](https://github.com/discordjs/discord.js/commit/24e586881865c187ff0a3044ac37f6e338cc51ee))
* **ClientApplication:** freeze flags ([#5811](https://github.com/discordjs/discord.js/issues/5811)) ([e990c35](https://github.com/discordjs/discord.js/commit/e990c35476fb6f7e1a5449493833140144e0469c))
* **Collector:** docs and types ([#5937](https://github.com/discordjs/discord.js/issues/5937)) ([6c447b1](https://github.com/discordjs/discord.js/commit/6c447b12e3f978328cb2577ea3f81a5ab1531bbf))
* **Guild:** don't patch before instance properties ([#5885](https://github.com/discordjs/discord.js/issues/5885)) ([174b7a7](https://github.com/discordjs/discord.js/commit/174b7a7f9c5f95ab182a2c90dae43ccd4f55357b))
* **Guild:** setChannelPositions null parenting ([#5841](https://github.com/discordjs/discord.js/issues/5841)) ([01a1fd6](https://github.com/discordjs/discord.js/commit/01a1fd615bbf017e18bbffe8e97336345f42564a))
* **GuildChannel:** clone errors when options.name isn't provided ([#5804](https://github.com/discordjs/discord.js/issues/5804)) ([41673b7](https://github.com/discordjs/discord.js/commit/41673b738232f64da2ded3b15be0f798135ae351))
* **GuildChannel:** don't force parentID/permissionOverwrites to empty on create ([#5823](https://github.com/discordjs/discord.js/issues/5823)) ([c585933](https://github.com/discordjs/discord.js/commit/c5859337b616c1fe2a60884595d27db4f13d8fee))
* **GuildChannel:** improve empty overwrite handling for permissionsLocked ([#5821](https://github.com/discordjs/discord.js/issues/5821)) ([6df3623](https://github.com/discordjs/discord.js/commit/6df36232a05e396d31461200725755745526d2ed))
* **GuildChannel:** spread clone options to avoid infinite recursion ([#5800](https://github.com/discordjs/discord.js/issues/5800)) ([2f5424b](https://github.com/discordjs/discord.js/commit/2f5424bdac7c97d0a371dd72084ac02d5e774f1a))
* **GuildManager:** #create throws when systemChannelFlags is undefined ([#5832](https://github.com/discordjs/discord.js/issues/5832)) ([29173bf](https://github.com/discordjs/discord.js/commit/29173bf814e2cd795467b9b3814f0eaf0773e9ae))
* **Hooks:** make husky hooks executable ([#5812](https://github.com/discordjs/discord.js/issues/5812)) ([77e28cf](https://github.com/discordjs/discord.js/commit/77e28cf65b0fb3fc2fb7ab07fc7bb0f2f5a400b5))
* **InteractionResponses:** set replied status on editReply ([#5899](https://github.com/discordjs/discord.js/issues/5899)) ([6d3d00b](https://github.com/discordjs/discord.js/commit/6d3d00b44577a70e840f0187d6894043677c5329))
* **Message:** editedTimestamp defaulting to 0 ([#5847](https://github.com/discordjs/discord.js/issues/5847)) ([671436c](https://github.com/discordjs/discord.js/commit/671436cbb89f7f48bd9ae0ccb9dd75a376cc5281))
* **Message:** flags not being parsed on some edits ([#5886](https://github.com/discordjs/discord.js/issues/5886)) ([2d7c12b](https://github.com/discordjs/discord.js/commit/2d7c12b0e9387f56f1809822bc2c8c4ee52a00e9))
* **Message:** Make author of referenced message nullable ([#5929](https://github.com/discordjs/discord.js/issues/5929)) ([dc671c8](https://github.com/discordjs/discord.js/commit/dc671c8ac418c1f932034e82f38def28575a4b65))
* **PermissionOverwrites:** optional allow/deny OverwriteData ([#5810](https://github.com/discordjs/discord.js/issues/5810)) ([a7ebb21](https://github.com/discordjs/discord.js/commit/a7ebb2145c380214567514906393c4ab87932e95))
* **Permissions:** allow admin to override in the missing method ([#5911](https://github.com/discordjs/discord.js/issues/5911)) ([ee025b0](https://github.com/discordjs/discord.js/commit/ee025b05588493b55057b237ca96f88ecc5f0b02))
* **presenceUpdate:** fire when only state/details change on an activity ([#5846](https://github.com/discordjs/discord.js/issues/5846)) ([1f8f3ab](https://github.com/discordjs/discord.js/commit/1f8f3ab0f8dbd346154bbfa14a98726b8df25d57))
* **Sharding:** strict type context and return ([#5933](https://github.com/discordjs/discord.js/issues/5933)) ([1925d01](https://github.com/discordjs/discord.js/commit/1925d01d8f05ca10b2a39b91f25ffcabe363874b))
* **TextBasedChannel:** allow passing an APIMessage with split ([#5815](https://github.com/discordjs/discord.js/issues/5815)) ([93b0a4e](https://github.com/discordjs/discord.js/commit/93b0a4e005b5b1d371f7936238556db2e36cc982))
* **Thread:** make archive_timestamp not nullable ([#5965](https://github.com/discordjs/discord.js/issues/5965)) ([edab5af](https://github.com/discordjs/discord.js/commit/edab5afff9a4c79e5965c7c52b0a0d5ebb9ba35a))
* **ThreadChannel:** check for existence of properties when patching ([#5961](https://github.com/discordjs/discord.js/issues/5961)) ([9ac6867](https://github.com/discordjs/discord.js/commit/9ac68670d782fc81e266784e790af699f280eb0e))
* **ThreadManager:** fixed wrong private and fetchAll check ([#6012](https://github.com/discordjs/discord.js/issues/6012)) ([e4be666](https://github.com/discordjs/discord.js/commit/e4be666c2c273c56f04b8f965efc88bb9aff0032))
* **ThreadMemberManager:** fix ThreadMemberManager#add and ThreadMemberManager#fetch ([#5927](https://github.com/discordjs/discord.js/issues/5927)) ([adecead](https://github.com/discordjs/discord.js/commit/adecead716670278516fd031f240e05792420c75))
* **Typings:** erronous RawMessage ([5842e35](https://github.com/discordjs/discord.js/commit/5842e35881755350764b557d66b475c2c03f249a))
* **Typings:** Fix BitField toJSON/valueOf return types ([#5806](https://github.com/discordjs/discord.js/issues/5806)) ([935f819](https://github.com/discordjs/discord.js/commit/935f819207ac4219d37f3b99a2508e368626e6da))
* **Typings:** Improve components typings in MessageEditOptions ([#6002](https://github.com/discordjs/discord.js/issues/6002)) ([3a718d8](https://github.com/discordjs/discord.js/commit/3a718d8c625ab45bc9f4dfcd9d6bbdef67ae75b4))
* **User:** fix bot and system properties being incorrect in some cases ([#5923](https://github.com/discordjs/discord.js/issues/5923)) ([e44ae96](https://github.com/discordjs/discord.js/commit/e44ae961005358dac7032c75bfc74be3b719e5a1))
* **Webhook:** resolve non-string avatars too ([#5914](https://github.com/discordjs/discord.js/issues/5914)) ([4714a96](https://github.com/discordjs/discord.js/commit/4714a961b87746b0f85214c756614d276666f285))
* **Webhook:** return void from #delete for consistency. ([#5954](https://github.com/discordjs/discord.js/issues/5954)) ([5ad83a6](https://github.com/discordjs/discord.js/commit/5ad83a6a65e5944ceb3a41fee2df40ba1f5b03e4))
* **Webhook:** throw an error if no token is available when it's required ([#5798](https://github.com/discordjs/discord.js/issues/5798)) ([eb98e33](https://github.com/discordjs/discord.js/commit/eb98e33a85cc9bb235ceb509ed01218bae44ba73))
* **WebSocketShard:** don't catch errors thrown in event handlers ([#5803](https://github.com/discordjs/discord.js/issues/5803)) ([53d8e49](https://github.com/discordjs/discord.js/commit/53d8e49dca2d83fe2e066fb0b3d10418acbbc244))
* don't patch missing properties from partial payloads ([#5796](https://github.com/discordjs/discord.js/issues/5796)) ([097c7b9](https://github.com/discordjs/discord.js/commit/097c7b9cdd5e1bb52b037272eed19f556800ccff))
* add missing imports for custom errors ([#5767](https://github.com/discordjs/discord.js/issues/5767)) ([e980948](https://github.com/discordjs/discord.js/commit/e980948de55e91e59c9e3293ac76bc645a058a53))
* **ApiMessage:** only pass objects as options directly ([#5793](https://github.com/discordjs/discord.js/issues/5793)) ([3578159](https://github.com/discordjs/discord.js/commit/35781597d032fa7821e010e483c89f70ec51926c))
* **BitField:** ensure missing returns an array of strings ([#5795](https://github.com/discordjs/discord.js/issues/5795)) ([68f7aeb](https://github.com/discordjs/discord.js/commit/68f7aebcafcfd62bef02de855ca0c304a54e8d4c))
* **BitField:** throw an error if bit to resolve is undefined ([#5565](https://github.com/discordjs/discord.js/issues/5565)) ([0156f69](https://github.com/discordjs/discord.js/commit/0156f693e08fe2ad75133bf67c4aeb3e9c91a02d))
* **ClientPresence:** produce valid activities for set presences ([#5799](https://github.com/discordjs/discord.js/issues/5799)) ([ea0e06f](https://github.com/discordjs/discord.js/commit/ea0e06f9802fb57b41f471413b39ccd09546bb67))
* add components to MessageOption typedefs ([#5768](https://github.com/discordjs/discord.js/issues/5768)) ([657635c](https://github.com/discordjs/discord.js/commit/657635c1c09aa68211130bc3c56d6e8bb6e8e773))
* remove remnants of awaitMessageComponentInteractions ([#5783](https://github.com/discordjs/discord.js/issues/5783)) ([ae78a33](https://github.com/discordjs/discord.js/commit/ae78a336e1d0d190ec9f525449332dc781e0b3bf))
* **APIMessage:** document Interaction as valid MessageTarget ([#5678](https://github.com/discordjs/discord.js/issues/5678)) ([9f491ff](https://github.com/discordjs/discord.js/commit/9f491ffeb96ff380f2ab5ab2f86201d58be64c41))
* **ApplicationCommand:** return string equivalent of ApplicationCommandOptionType ([#5617](https://github.com/discordjs/discord.js/issues/5617)) ([a6079bc](https://github.com/discordjs/discord.js/commit/a6079bc9ce40ecbb4adace033dbf201897b5459f))
* **ApplicationCommandManager:** fix typo in JSDoc ([#5603](https://github.com/discordjs/discord.js/issues/5603)) ([3392eb7](https://github.com/discordjs/discord.js/commit/3392eb7de270842dbf5a54d19aa3e703dd445ba0))
* **ApplicationCommandManager:** limit permission methods to guilds ([#5613](https://github.com/discordjs/discord.js/issues/5613)) ([03256bd](https://github.com/discordjs/discord.js/commit/03256bd9f88c63dc5c2169e2c09ac8078ea84992))
* **ApplicationCommandOptionData:** options property should be itself ([#5679](https://github.com/discordjs/discord.js/issues/5679)) ([b90b0c3](https://github.com/discordjs/discord.js/commit/b90b0c3cfa2278caa38d1ff41eef2ccf4428b99e))
* **CommandInteraction:** channel type should be text based channels ([#5690](https://github.com/discordjs/discord.js/issues/5690)) ([5141ea4](https://github.com/discordjs/discord.js/commit/5141ea4f0694a60375d8bc0801b1225928bb3bd1))
* **CommandInteraction:** cmds with no options throw error ([#5734](https://github.com/discordjs/discord.js/issues/5734)) ([af2fad9](https://github.com/discordjs/discord.js/commit/af2fad94732eeb620fe17d9b537c279471c567c0))
* **CommandInteraction:** update typings and docs for #editReply ([#5630](https://github.com/discordjs/discord.js/issues/5630)) ([56d44fb](https://github.com/discordjs/discord.js/commit/56d44fbf1c922260c497350e8829d7151eb7a331))
* **DataResolver:** fix circular dependency error with GuildTemplate ([#5622](https://github.com/discordjs/discord.js/issues/5622)) ([b376f31](https://github.com/discordjs/discord.js/commit/b376f31af9881b9cd3f82ac4a42a468947cce482))
* **Emoji:** name can be null ([#5513](https://github.com/discordjs/discord.js/issues/5513)) ([5397021](https://github.com/discordjs/discord.js/commit/5397021efb1f9883cf4b48a0ca78d12b713a61fd))
* **GuildEmojiRoleManager:** bug in #remove ([#5666](https://github.com/discordjs/discord.js/issues/5666)) ([c89bdd7](https://github.com/discordjs/discord.js/commit/c89bdd7566599a95a404b0f9e4b0828a866d0a71))
* **GuildMemberManager:** allow moving members to any non-text channel ([#5681](https://github.com/discordjs/discord.js/issues/5681)) ([d21e6af](https://github.com/discordjs/discord.js/commit/d21e6af1d2b81db9847336b3f964f9d2693394e6))
* **GuildMemberRoleManager:** unable to remove roles when passed an array ([#5556](https://github.com/discordjs/discord.js/issues/5556)) ([9572521](https://github.com/discordjs/discord.js/commit/9572521e3c390e610de8e4dc79e4086b3b1d6e44))
* **HTTPOptions:** change default value in jsdoc to 8 ([#5547](https://github.com/discordjs/discord.js/issues/5547)) ([cb50241](https://github.com/discordjs/discord.js/commit/cb50241e6fa7c95891925c8b18840c17df078620))
* **Interaction:** add missing types and fix docs lists ([#5762](https://github.com/discordjs/discord.js/issues/5762)) ([1d57754](https://github.com/discordjs/discord.js/commit/1d57754d4654c5c95aa14afc13f8abe335314767))
* **Message:** bug in #suppressEmbeds due to [#5612](https://github.com/discordjs/discord.js/issues/5612) ([#5644](https://github.com/discordjs/discord.js/issues/5644)) ([840ad0a](https://github.com/discordjs/discord.js/commit/840ad0a35a344a19c5bb84c421f80802fb186d0b))
* **Message:** editing with MessageEmbed or APIMessage ([#5612](https://github.com/discordjs/discord.js/issues/5612)) ([74e97ef](https://github.com/discordjs/discord.js/commit/74e97ef91b413300c83f163bc3914eaf8bd45d89))
* **Message:** update typings and docs related to #edit ([#5745](https://github.com/discordjs/discord.js/issues/5745)) ([a2f0c11](https://github.com/discordjs/discord.js/commit/a2f0c11474826bfd5b770d2a6990b6bd41c89451))
* **MessageComponentInteraction:** correctly type defer method ([#5760](https://github.com/discordjs/discord.js/issues/5760)) ([f0dad26](https://github.com/discordjs/discord.js/commit/f0dad26a5b8c3139b2519d1895df2fe23352b102))
* **MessageEmbed:** import custom RangeError class ([#5740](https://github.com/discordjs/discord.js/issues/5740)) ([bfe01b5](https://github.com/discordjs/discord.js/commit/bfe01b52ab29df1bb26fc2d385f63fb5adbb12b2))
* **PermissionOverwrites:** fix typo in typedef jsdoc ([#5704](https://github.com/discordjs/discord.js/issues/5704)) ([6567ba8](https://github.com/discordjs/discord.js/commit/6567ba821a54d3dc97d07ce8ac55335fef2f346b))
* **RoleManager:** bug in #create ([#5730](https://github.com/discordjs/discord.js/issues/5730)) ([cf22456](https://github.com/discordjs/discord.js/commit/cf224560bc59c05f7801088b0db2ec76c5369302))
* **ShardingManager:** client error event cannot be emitted ([#5559](https://github.com/discordjs/discord.js/issues/5559)) ([d1c5b6f](https://github.com/discordjs/discord.js/commit/d1c5b6fe9e18b532ad69ed4bd82e1874a6dff4df))
* **Types:** make event listeners accept async callbacks ([#5602](https://github.com/discordjs/discord.js/issues/5602)) ([a73a5cf](https://github.com/discordjs/discord.js/commit/a73a5cf91498cf7b08cea85753ad481c194ec089))
* **Typings:** add missing typings for `HttpError` -> `requestData` ([#5742](https://github.com/discordjs/discord.js/issues/5742)) ([3e9ce35](https://github.com/discordjs/discord.js/commit/3e9ce35023e71ffda1f4eaca6f109b0422ec7d29))
* **Webhook:** #editMessage throws error when content is null ([#5757](https://github.com/discordjs/discord.js/issues/5757)) ([2901fd5](https://github.com/discordjs/discord.js/commit/2901fd595be847a0e6c86155b3229d3341cfad32))
* interfaces not importing due to re-export of Snowflake ([#5723](https://github.com/discordjs/discord.js/issues/5723)) ([086c3f0](https://github.com/discordjs/discord.js/commit/086c3f0799d65c64c4e60d6370246a37a27a1eab))
* lint-staged for typescript files ([5f6ec22](https://github.com/discordjs/discord.js/commit/5f6ec2211d1e6555ab2d501579e4a1d97023c647))
* resolve emoji in Message#react ([#5614](https://github.com/discordjs/discord.js/issues/5614)) ([c733436](https://github.com/discordjs/discord.js/commit/c7334363b36c5f7f1c7880fe77a2e9b2eb1a6442))
* typo in GuildMemberManager ([#5616](https://github.com/discordjs/discord.js/issues/5616)) ([73f4114](https://github.com/discordjs/discord.js/commit/73f4114f59fc2f514d570ac8df3eac7d328cca3c))
* **Sticker:** file renamed to SnowflakeUtil ([#5573](https://github.com/discordjs/discord.js/issues/5573)) ([f830eb7](https://github.com/discordjs/discord.js/commit/f830eb7101d05f90bbbf44ff750e4012ecb72449))
* **VoiceReceiver:** fix memory leak ([#5609](https://github.com/discordjs/discord.js/issues/5609)) ([2eac842](https://github.com/discordjs/discord.js/commit/2eac84296b448907213680690ec766bb5fbe5990))
* typings for 'Message' ([#5518](https://github.com/discordjs/discord.js/issues/5518)) ([0d68ca8](https://github.com/discordjs/discord.js/commit/0d68ca8eb9abdb517acee562fe01374416d225ed))
* **ApiMessage:** remove resolve() from typings ([#5241](https://github.com/discordjs/discord.js/issues/5241)) ([a6bc39d](https://github.com/discordjs/discord.js/commit/a6bc39d3c699eec0b7851cda334335baa892c1de))
* **ApplicationFlags:** export class ([#5465](https://github.com/discordjs/discord.js/issues/5465)) ([404ce57](https://github.com/discordjs/discord.js/commit/404ce57bcc3ce39c807457f25a5679a80e69d1bb))
* **BaseGuildEmoji:** typo in requiresColons ([#5076](https://github.com/discordjs/discord.js/issues/5076)) ([e272fd6](https://github.com/discordjs/discord.js/commit/e272fd6909a17941d2d3e4840e75436d98a41198))
* **ChannelManager:** Avoid crash in remove method with uncached channel ([#4937](https://github.com/discordjs/discord.js/issues/4937)) ([12c909e](https://github.com/discordjs/discord.js/commit/12c909eeccb9ed6ab205d314ac8d63fc58713ae6))
* **Collection:** toJSON() errors if the collection includes empty values ([#5129](https://github.com/discordjs/discord.js/issues/5129)) ([2c2249e](https://github.com/discordjs/discord.js/commit/2c2249ee7314401b65be677c233370657e1d4695))
* **Collector:** throw an error if a non-function was provided as filter ([#5034](https://github.com/discordjs/discord.js/issues/5034)) ([7365f40](https://github.com/discordjs/discord.js/commit/7365f403006eeb28ab10f03cbf85416272678ef7))
* **Guild/GuildChannel:** methods reason arg usage ([#5419](https://github.com/discordjs/discord.js/issues/5419)) ([8411b9e](https://github.com/discordjs/discord.js/commit/8411b9e14211f83fddb00f622088979ee6586803))
* **GuildAuditLogsEntry:** executor can be missing ([#5500](https://github.com/discordjs/discord.js/issues/5500)) ([e9bf206](https://github.com/discordjs/discord.js/commit/e9bf206d88b9307e4098b7f89178105d08b07544))
* **GuildChannel:** check for community required channels in GuildChannel#deletable ([#5170](https://github.com/discordjs/discord.js/issues/5170)) ([b710a43](https://github.com/discordjs/discord.js/commit/b710a432326be823beb10f5f06f2a1e3fcd7c0ee))
* **GuildChannel:** overload permissionsFor and BaseManager#resolve[id] ([#5260](https://github.com/discordjs/discord.js/issues/5260)) ([41bd6c2](https://github.com/discordjs/discord.js/commit/41bd6c2717faeeaa36514d39a4816f7cf65b4c02))
* **GuildChannel:** regression on default channel type ([#5251](https://github.com/discordjs/discord.js/issues/5251)) ([e7c4f36](https://github.com/discordjs/discord.js/commit/e7c4f3672e7059c264ba67a94b87a655ea6e4da5))
* **GuildEmoji:** check for cahnges to available in equals ([#5201](https://github.com/discordjs/discord.js/issues/5201)) ([f95f5dc](https://github.com/discordjs/discord.js/commit/f95f5dcd791b39c6a4d60dc8d64b0287e06ed768))
* **GuildManager:** add missing toString() on Permission#resolve fns ([#5324](https://github.com/discordjs/discord.js/issues/5324)) ([0778926](https://github.com/discordjs/discord.js/commit/077892645bd59d1b5c50e3291701cb4241c0bbdf))
* **GuildMember:** correctly check for premium_since ([#5312](https://github.com/discordjs/discord.js/issues/5312)) ([aff3625](https://github.com/discordjs/discord.js/commit/aff3625d4fc3c738d77325f8492b72077e6345e7))
* **GuildTemplate:** 'guild' getter ([#5040](https://github.com/discordjs/discord.js/issues/5040)) ([53529bd](https://github.com/discordjs/discord.js/commit/53529bd05deb449d5d9bbfa332470c9881d8093c))
* **IntegrationApplication:** add missing export to index.js ([#5475](https://github.com/discordjs/discord.js/issues/5475)) ([8023250](https://github.com/discordjs/discord.js/commit/8023250ee7bb79a5e3f12d7297c29589f91d6b81))
* **InviteDelete:** guild can be missing ([#5457](https://github.com/discordjs/discord.js/issues/5457)) ([6c6b105](https://github.com/discordjs/discord.js/commit/6c6b1053b7a6778a5d0402941a13258ca13378f8))
* **Message:** #system non-zero message types are not guaranteed to be system ([#5108](https://github.com/discordjs/discord.js/issues/5108)) ([bb78120](https://github.com/discordjs/discord.js/commit/bb78120283b671d1926c8707a17a9d4d515aafdd))
* **Message:** update getters to take null permissions into account ([#5066](https://github.com/discordjs/discord.js/issues/5066)) ([98b1c58](https://github.com/discordjs/discord.js/commit/98b1c582189faee9ac40d81963008d94801f3837))
* **MessageEmbed:** include `author.name` in length getter ([#5167](https://github.com/discordjs/discord.js/issues/5167)) ([e37160f](https://github.com/discordjs/discord.js/commit/e37160f4e3d647e8e33b5b03d5f9e6c98b065499))
* **MessageMentions#channels:** Fix type of channels of mentions ([#5370](https://github.com/discordjs/discord.js/issues/5370)) ([565d7b3](https://github.com/discordjs/discord.js/commit/565d7b3747d59ceeb01e2d88b20d761a99927a12))
* **MessageReaction:** set MessageReaction#me in patch method ([#5047](https://github.com/discordjs/discord.js/issues/5047)) ([6b322f4](https://github.com/discordjs/discord.js/commit/6b322f47a0f86115dab71c06c7879fe82ea04ec4))
* **ReactionUserManager:** remove before query option ([#5281](https://github.com/discordjs/discord.js/issues/5281)) ([43bd568](https://github.com/discordjs/discord.js/commit/43bd568f1c38a6df38f56a8d607375ccc9da026a))
* **Resolvables:** valid resolvables throw error when uncached ([#5495](https://github.com/discordjs/discord.js/issues/5495)) ([fa5a37e](https://github.com/discordjs/discord.js/commit/fa5a37e51a14fdd95420092fb8c2acffad132c3b))
* **Role:** pass Permissions class, not the bitfield ([#5321](https://github.com/discordjs/discord.js/issues/5321)) ([d744e51](https://github.com/discordjs/discord.js/commit/d744e51c1bdb4c7a26c0faeea1f2f45baaf5fd3c))
* **RoleManager:** fix ID return value, change return type to collection ([#4935](https://github.com/discordjs/discord.js/issues/4935)) ([12a096b](https://github.com/discordjs/discord.js/commit/12a096b5f1c5ad518e73d1b9f50bb388928117dd))
* **typings:** return types for 'Webhook(Client)#send()' ([#4876](https://github.com/discordjs/discord.js/issues/4876)) ([eb28ee7](https://github.com/discordjs/discord.js/commit/eb28ee7905eee248b9ccd248f7d8275933dd0637))
* **typings:** update GuildMemberRoleManager typings to match implementation ([#5497](https://github.com/discordjs/discord.js/issues/5497)) ([900e576](https://github.com/discordjs/discord.js/commit/900e57657e80833df2557c60862fcd71b35d0df1))
* **UserFlags:** correct early bot dev name, remove deprecated aliases ([#5104](https://github.com/discordjs/discord.js/issues/5104)) ([b509862](https://github.com/discordjs/discord.js/commit/b509862bfa924494824af5e7729bd545315d2c67))
* **Voice:** disconnect if voice channel not cached ([#5467](https://github.com/discordjs/discord.js/issues/5467)) ([3af8179](https://github.com/discordjs/discord.js/commit/3af8179878c093985c8a94ee2fd7e99d45243bda))
* **Voice:** only skip undocumented voice packet byte if present ([#5309](https://github.com/discordjs/discord.js/issues/5309)) ([2b52cdc](https://github.com/discordjs/discord.js/commit/2b52cdc915146c6775bc7565e5ecf31e7c9880e7))
* add presence to ClientPresence from ClientOptions ([#5041](https://github.com/discordjs/discord.js/issues/5041)) ([9c7fe34](https://github.com/discordjs/discord.js/commit/9c7fe34c50808ba080527a1919b1846ed6585d4d))
* filtering of string forms of null and undefined ([#5075](https://github.com/discordjs/discord.js/issues/5075)) ([9042d19](https://github.com/discordjs/discord.js/commit/9042d19c4ef54d9976776f41336610ab0a24db27))
* implement valueOf on pseudomanagers ([#4595](https://github.com/discordjs/discord.js/issues/4595)) ([8883a01](https://github.com/discordjs/discord.js/commit/8883a0144b02e76c767c21ecf28fb430b7223c7f))
* typings for 'WebhookMessageOptions' ([#5476](https://github.com/discordjs/discord.js/issues/5476)) ([67025e6](https://github.com/discordjs/discord.js/commit/67025e63e4e8306a2b3ff62ae1067acf4b468a6a))
* **Voice*:** filter out silent audio from video users ([#5035](https://github.com/discordjs/discord.js/issues/5035)) ([4fcb9eb](https://github.com/discordjs/discord.js/commit/4fcb9ebf300633022e2b9867fa06a586307ff17a))
* **VoiceConnection:** make #dispatcher nullable ([#5217](https://github.com/discordjs/discord.js/issues/5217)) ([0d5de43](https://github.com/discordjs/discord.js/commit/0d5de4333d8afa57826aa75475fc4e3dfe8978c4))
* **WebSocketShard:** key name in WebSocketShard#_send. ([#5304](https://github.com/discordjs/discord.js/issues/5304)) ([56d8b44](https://github.com/discordjs/discord.js/commit/56d8b445ede6c7915aec173a68905cda3d91f0ca)), closes [#3722](https://github.com/discordjs/discord.js/issues/3722)
### Code Refactoring
* removed `code` and `split` options ([#5918](https://github.com/discordjs/discord.js/issues/5918)) ([985d4d6](https://github.com/discordjs/discord.js/commit/985d4d6a438fc9123264f6a1c600f34fccc1825f))
### Features
* **ApplicationCommandOptionType:** add NUMBER (10) ([#6128](https://github.com/discordjs/discord.js/issues/6128)) ([2f1cc1f](https://github.com/discordjs/discord.js/commit/2f1cc1fc27f5af6d9b88cdc353605a3ddf76e579))
* **Channel:** add isThread typeguard for better TS support ([#5978](https://github.com/discordjs/discord.js/issues/5978)) ([b7ed675](https://github.com/discordjs/discord.js/commit/b7ed6752ac98e56e79b6fd9fd3a5e47572454d85))
* **Channel:** add isVoice() ([#6297](https://github.com/discordjs/discord.js/issues/6297)) ([5b4efd1](https://github.com/discordjs/discord.js/commit/5b4efd13c9eced97f4160f9c4c19d1c843360943))
* **Client:** add conditional ready typings ([#6073](https://github.com/discordjs/discord.js/issues/6073)) ([4206e35](https://github.com/discordjs/discord.js/commit/4206e35b2316431c1a009664636dcda85d39fff8))
* **Client:** enforce passing scopes to generateInvite ([#6024](https://github.com/discordjs/discord.js/issues/6024)) ([c6e5521](https://github.com/discordjs/discord.js/commit/c6e55216874f1892727db927f55db3de6a1712d8))
* **Collector:** better types for events ([#6058](https://github.com/discordjs/discord.js/issues/6058)) ([c0a814f](https://github.com/discordjs/discord.js/commit/c0a814fdb35cb1fa7418bb3bdd3cec0a8a130bf5))
* **Collector:** return a boolean on checkEnd ([#6289](https://github.com/discordjs/discord.js/issues/6289)) ([f473f43](https://github.com/discordjs/discord.js/commit/f473f43d081c8c703a0888acaf3fdbaf4bb20c6d))
* **CommandInteraction:** add CommandInteractionOptionResolver ([#6107](https://github.com/discordjs/discord.js/issues/6107)) ([f293132](https://github.com/discordjs/discord.js/commit/f293132345294e33e80866272feaedf2e4a70d45))
* **CommandInteractionOptionResolver:** add sub-command required option ([#6165](https://github.com/discordjs/discord.js/issues/6165)) ([690c121](https://github.com/discordjs/discord.js/commit/690c121aa9575f7b878030229b0fedd56c3a1a87))
* **Constants:** added more error codes ([#6234](https://github.com/discordjs/discord.js/issues/6234)) ([6b2098f](https://github.com/discordjs/discord.js/commit/6b2098f7c7592eee2aedbf19e62d3c262e159cba))
* **FetchRecommendedShardsOptions:** account for large bot sharding ([#6184](https://github.com/discordjs/discord.js/issues/6184)) ([19b242a](https://github.com/discordjs/discord.js/commit/19b242ac10aa9b32c1a45a9178c97481d62a9400))
* **Formatters:** added new URL utilities and docs ([#6014](https://github.com/discordjs/discord.js/issues/6014)) ([98e45a5](https://github.com/discordjs/discord.js/commit/98e45a59957842fd1ee55d59e30ee868f985e15d))
* **Guild:** add fetchWidget() for getting widget data ([#6180](https://github.com/discordjs/discord.js/issues/6180)) ([b22272f](https://github.com/discordjs/discord.js/commit/b22272f86075ac5585abf05f54cf05187c4eabf9))
* **GuildAuditLogs:** add threads ([#6195](https://github.com/discordjs/discord.js/issues/6195)) ([26ba0e1](https://github.com/discordjs/discord.js/commit/26ba0e10368ff7c4b7a79a37450c8c0784185fb7))
* **GuildPreview:** add createdAt & createdTimestamp ([#6130](https://github.com/discordjs/discord.js/issues/6130)) ([9f039a8](https://github.com/discordjs/discord.js/commit/9f039a86798352e360d7e47d62d1b9c011c2ec71))
* **InteractionCollector:** reworked to be more generic ([#5999](https://github.com/discordjs/discord.js/issues/5999)) ([374c779](https://github.com/discordjs/discord.js/commit/374c779f7f8bbaa9bf06fa2b5b16f60da5095b5c))
* **Interactions:** option to auto-fetch replies ([#5831](https://github.com/discordjs/discord.js/issues/5831)) ([5e28ff8](https://github.com/discordjs/discord.js/commit/5e28ff83cbc04850077cc2f97bb2039c55b3b8ea))
* **LimitedCollection:** export LimitedCollection ([#6043](https://github.com/discordjs/discord.js/issues/6043)) ([31d3129](https://github.com/discordjs/discord.js/commit/31d31293d314492562104f02511d4d1e117711f3))
* **Managers:** ✨ Add GuildInviteManager ([#5889](https://github.com/discordjs/discord.js/issues/5889)) ([9e08b02](https://github.com/discordjs/discord.js/commit/9e08b02df2c9b31cfd91eac3ad008dab94855a59))
* **Managers:** add customizable caching for managers ([#6013](https://github.com/discordjs/discord.js/issues/6013)) ([8c7cb0e](https://github.com/discordjs/discord.js/commit/8c7cb0eff8e169836decf3c9843d7fa0998a5e84))
* **Message:** add 'failIfNotExists' to ClientOptions ([#6038](https://github.com/discordjs/discord.js/issues/6038)) ([28c5724](https://github.com/discordjs/discord.js/commit/28c57246d1d3cd7a22384ddc7970ab5263a4ace0))
* **MessageEmbed:** add setFields method ([#6186](https://github.com/discordjs/discord.js/issues/6186)) ([a25e165](https://github.com/discordjs/discord.js/commit/a25e16599a2b3d82aabebcaeaef663680f2982a8))
* **REST:** append additional information to the required User Agent ([#6112](https://github.com/discordjs/discord.js/issues/6112)) ([f200f14](https://github.com/discordjs/discord.js/commit/f200f14a409a56df5efe788de0ae45fc061bb46d))
* **RoleManager:** added `edit` method, alias `Role#edit` ([#5983](https://github.com/discordjs/discord.js/issues/5983)) ([1e73c25](https://github.com/discordjs/discord.js/commit/1e73c25fbfc9b3cb62bed719dc79de25f67707ee))
* **StageChannel:** add createStageInstance method & use better naming convention ([#5951](https://github.com/discordjs/discord.js/issues/5951)) ([71fb33a](https://github.com/discordjs/discord.js/commit/71fb33a5fea7398598b603a888e07519fddd56a9))
* **Sticker:** updates, sticker packs, and guild stickers ([#5867](https://github.com/discordjs/discord.js/issues/5867)) ([54d6a3a](https://github.com/discordjs/discord.js/commit/54d6a3a0708105acd6a3a709a8e1636d00c81fc8))
* **ThreadChannel:** add fetchOwner() method ([#6207](https://github.com/discordjs/discord.js/issues/6207)) ([331a9d3](https://github.com/discordjs/discord.js/commit/331a9d3ffc6e45c068bfb454e05b863130559d42))
* **Util:** add SweptCollection for auto sweeping of caches ([#6110](https://github.com/discordjs/discord.js/issues/6110)) ([dbb59ba](https://github.com/discordjs/discord.js/commit/dbb59ba1b29b2f75dd8faab5c3004ade51598abc))
* **Util:** added formatters ([#5976](https://github.com/discordjs/discord.js/issues/5976)) ([8c7a28f](https://github.com/discordjs/discord.js/commit/8c7a28f211dd05ec67cbce667b1d591ed59a40c6))
* **WebhookClient:** allow creation of clients via URLs ([#6192](https://github.com/discordjs/discord.js/issues/6192)) ([e000af5](https://github.com/discordjs/discord.js/commit/e000af5c98483046db25a46e905ed244bdcfe262))
* allow channels from uncached guilds to be returned from fetch ([#6034](https://github.com/discordjs/discord.js/issues/6034)) ([755c180](https://github.com/discordjs/discord.js/commit/755c180659c125532fe6f8e33e6c3b56e275311b))
* make Instance#fetch force true by default, and fix force parameter ([#6116](https://github.com/discordjs/discord.js/issues/6116)) ([366f3c9](https://github.com/discordjs/discord.js/commit/366f3c910a370ff1e184afae054f957db9a98293))
* PermissionOverwriteManager ([#5318](https://github.com/discordjs/discord.js/issues/5318)) ([e7ad2fe](https://github.com/discordjs/discord.js/commit/e7ad2fe20772915dcf3e9c4ae92a072b9c918a07))
* use enums for consistency and speed ([#5843](https://github.com/discordjs/discord.js/issues/5843)) ([f7eeccb](https://github.com/discordjs/discord.js/commit/f7eeccba4b7015496df811f10cc2da2b0fab0630))
* **Client:** make use of with_expiration in #fetchInvite ([#5764](https://github.com/discordjs/discord.js/issues/5764)) ([bf191df](https://github.com/discordjs/discord.js/commit/bf191df9c033404da3e717f73306cdb3f659fafc))
* **Esm:** use `gen-esm-wrapper` instead of manually making the file ([#5700](https://github.com/discordjs/discord.js/issues/5700)) ([db0d7d4](https://github.com/discordjs/discord.js/commit/db0d7d4ea8e7b2bae4d1548e5617875b5ae0bbd4))
* **Interaction:** add guild guard ([#5955](https://github.com/discordjs/discord.js/issues/5955)) ([87e8cdd](https://github.com/discordjs/discord.js/commit/87e8cdd3eba29ae1d741aa86572f1731b05c12fb))
* **Managers:** new ApplicationCommandPermissionsManager ([#5897](https://github.com/discordjs/discord.js/issues/5897)) ([6264c60](https://github.com/discordjs/discord.js/commit/6264c60e97da93b311a7a9fd92e16e59de94104a))
* **MessageComponentInteraction:** component getter ([#5840](https://github.com/discordjs/discord.js/issues/5840)) ([1439183](https://github.com/discordjs/discord.js/commit/1439183ad3f84b2b7500aaead2cf8779199b47d4))
* **MessageMentions:** add repliedUser ([#5905](https://github.com/discordjs/discord.js/issues/5905)) ([2616125](https://github.com/discordjs/discord.js/commit/261612596d37aa6fb48ae070d358b3fde953c769))
* **MessageSelectMenu:** droppybois ([#5692](https://github.com/discordjs/discord.js/issues/5692)) ([e5fcf0b](https://github.com/discordjs/discord.js/commit/e5fcf0bee53a15d7a87d4a5cf4e206823d6e7d87))
* api v9 and threads ([#5570](https://github.com/discordjs/discord.js/issues/5570)) ([7346621](https://github.com/discordjs/discord.js/commit/7346621d15c96906d5b848c483669750ff9c6e12))
* **InteractionCreate:** move to an Action handler ([#5906](https://github.com/discordjs/discord.js/issues/5906)) ([ea49f7c](https://github.com/discordjs/discord.js/commit/ea49f7ca74892495dd53f8d315086035c1814149))
* add missing APIError codes ([#5898](https://github.com/discordjs/discord.js/issues/5898)) ([d930c81](https://github.com/discordjs/discord.js/commit/d930c812bb4511a688b76d9bf1ac66e28bff033e))
* **GuildChannelManager:** add 'fetch' method ([#4966](https://github.com/discordjs/discord.js/issues/4966)) ([e798fb7](https://github.com/discordjs/discord.js/commit/e798fb720ee5ced008471fe899337f6817936770))
* **Interactions:** add InteractionWebhook for better internals ([#5712](https://github.com/discordjs/discord.js/issues/5712)) ([dec191a](https://github.com/discordjs/discord.js/commit/dec191aa1e4f22690285ca06c6eee7e6086b2930))
* **Interactions:** improve error handling for ephemeral responses ([#5892](https://github.com/discordjs/discord.js/issues/5892)) ([bd9f56a](https://github.com/discordjs/discord.js/commit/bd9f56af9a0a1fb12cfa30d9e2e0ad680eb80949))
* add APIError codes for stage instance ([#5888](https://github.com/discordjs/discord.js/issues/5888)) ([c850ae1](https://github.com/discordjs/discord.js/commit/c850ae10270076c4b2e10b130dd8f88eed4ed201))
* **Message:** applicationID for interaction responses ([#5765](https://github.com/discordjs/discord.js/issues/5765)) ([65dc00f](https://github.com/discordjs/discord.js/commit/65dc00f3210065015684b6d585f6747bd5ebadf1))
* **MessageComponents:** clickybois (MessageButton, MessageActionRow, associated Collectors) ([#5674](https://github.com/discordjs/discord.js/issues/5674)) ([cbd7f2b](https://github.com/discordjs/discord.js/commit/cbd7f2b9aa44a9240947ed716d0e72257ac499f7))
* **Rest:** optional ratelimit errors ([#5659](https://github.com/discordjs/discord.js/issues/5659)) ([16f261e](https://github.com/discordjs/discord.js/commit/16f261e773a353c54a75f38008f9b28435ae6603))
* **Sharding*:** contexts for broadcastEval ([#5756](https://github.com/discordjs/discord.js/issues/5756)) ([c6aeebb](https://github.com/discordjs/discord.js/commit/c6aeebb18d6b969f7c8bdb1b719883d4384dd03e))
* **WelcomeScreen:** welcome screens ([#5490](https://github.com/discordjs/discord.js/issues/5490)) ([44e2ee7](https://github.com/discordjs/discord.js/commit/44e2ee7b20dbec79c993dbc1f30ddb643d943347))
* stage instance invite ([#5856](https://github.com/discordjs/discord.js/issues/5856)) ([2d12db0](https://github.com/discordjs/discord.js/commit/2d12db000f2a0a22a8919d7a63989a6e762ae335))
* document and support embeds field in message create endpoint ([#5792](https://github.com/discordjs/discord.js/issues/5792)) ([99ff715](https://github.com/discordjs/discord.js/commit/99ff7151379fe03a1cfd52f252c0e6fc892d7776))
* **Guild:** add enum for mfa_level ([#5797](https://github.com/discordjs/discord.js/issues/5797)) ([ffabec3](https://github.com/discordjs/discord.js/commit/ffabec3a5e3651e5a0b8bcac83ee26bb909695fa))
* **Guild:** add enum for premium_tier ([#5868](https://github.com/discordjs/discord.js/issues/5868)) ([a3cbcca](https://github.com/discordjs/discord.js/commit/a3cbcca13da1af416c219bd64a0a6e84bb87a057))
* **GuildAuditLogs:** make #target a channel for channel related logs ([#5781](https://github.com/discordjs/discord.js/issues/5781)) ([eb0291d](https://github.com/discordjs/discord.js/commit/eb0291d9a5078836183c1b63ea96461ec112f96e))
* **RequestHandler:** emit more info when a rate limit was hit ([#5801](https://github.com/discordjs/discord.js/issues/5801)) ([18ac72e](https://github.com/discordjs/discord.js/commit/18ac72e457fa137d7f7f7bde876436ff643b4a63))
* **Widget:** wrapper for widget.json ([#5619](https://github.com/discordjs/discord.js/issues/5619)) ([038ee99](https://github.com/discordjs/discord.js/commit/038ee99604cded41d4c67edf4bd6bc7969712f52))
* add new APIErrors ([#5794](https://github.com/discordjs/discord.js/issues/5794)) ([e0ab836](https://github.com/discordjs/discord.js/commit/e0ab836b2d88caf0d9e1f9eba76ae46be9df0554))
* enforce strings ([#4880](https://github.com/discordjs/discord.js/issues/4880)) ([7b85a72](https://github.com/discordjs/discord.js/commit/7b85a7259f563ab14ae6c0a665a3dd43c486fde4))
* **APIRequest:** support setting global headers in HTTPOptions ([#5586](https://github.com/discordjs/discord.js/issues/5586)) ([135abcc](https://github.com/discordjs/discord.js/commit/135abccd9c75c33c8510cdcbe33b0dea4198fe33))
* **CommandInteraction:** ephemeral followup messages ([#5618](https://github.com/discordjs/discord.js/issues/5618)) ([68b40dd](https://github.com/discordjs/discord.js/commit/68b40dd91df70593c8271bd455fd0b3c6d19d334))
* **CommandInteraction:** make options a collection ([#5705](https://github.com/discordjs/discord.js/issues/5705)) ([fdad140](https://github.com/discordjs/discord.js/commit/fdad14099779e61cb84dcd1cb2497e0e853a6144))
* **Guild:** add the new nsfw_level property ([#5660](https://github.com/discordjs/discord.js/issues/5660)) ([3fe7add](https://github.com/discordjs/discord.js/commit/3fe7add2c5c07023d3cc83c06bba846c1328e446))
* **GuildChannel:** createInvite target options ([#5514](https://github.com/discordjs/discord.js/issues/5514)) ([f831872](https://github.com/discordjs/discord.js/commit/f831872125214e39c8866ce1cf7c63159a3dba39))
* **GuildChannel:** make createOverwrite and updateOverwrite not dependent on cache ([#5489](https://github.com/discordjs/discord.js/issues/5489)) ([58763b0](https://github.com/discordjs/discord.js/commit/58763b0e91b78d068121521ea3e853627b3ea325))
* **GuildChannel#clone:** support for position property ([#5236](https://github.com/discordjs/discord.js/issues/5236)) ([d455cb6](https://github.com/discordjs/discord.js/commit/d455cb65a6188e7d7b6720848b5ce37dbf8b5dff))
* **GuildMemberManager:** extend API coverage ([#4872](https://github.com/discordjs/discord.js/issues/4872)) ([2e2464b](https://github.com/discordjs/discord.js/commit/2e2464bf07c2b2e08d396b093126f887d19aec57))
* **Message:** add ReplyMessageOptions for #reply ([#5296](https://github.com/discordjs/discord.js/issues/5296)) ([7ce741d](https://github.com/discordjs/discord.js/commit/7ce741dacd06fd8af0ab501e38be08cf6b506a62))
* **Message:** allow editing files into messages ([#5718](https://github.com/discordjs/discord.js/issues/5718)) ([b212b64](https://github.com/discordjs/discord.js/commit/b212b64214ecee4f6118e78f9b90f3d3da574ecc))
* **Rest:** show the data that is sent to Discord when an errors occurs ([#5701](https://github.com/discordjs/discord.js/issues/5701)) ([ef92339](https://github.com/discordjs/discord.js/commit/ef92339d073f82cdaa2bc69f7be8443ec16789a7))
* add support for fetching multiple guilds ([#5472](https://github.com/discordjs/discord.js/issues/5472)) ([48d6850](https://github.com/discordjs/discord.js/commit/48d6850d9a8c34f407a22b6b401f2ed74415acd0))
* easier guards for channelUpdate ([#5716](https://github.com/discordjs/discord.js/issues/5716)) ([d52bcd4](https://github.com/discordjs/discord.js/commit/d52bcd46ec5985f9f18da37ba9d7d77209f58337))
* general component improvements ([#5787](https://github.com/discordjs/discord.js/issues/5787)) ([c4f1c75](https://github.com/discordjs/discord.js/commit/c4f1c75efa1cff1f9c775a266dccbe581305e79d))
* GuildBanManager ([#5276](https://github.com/discordjs/discord.js/issues/5276)) ([6d09160](https://github.com/discordjs/discord.js/commit/6d09160f5ba878fcd1f8bae88b5e6347e632cd2c))
* InteractionDeferOptions ([#5641](https://github.com/discordjs/discord.js/issues/5641)) ([ed593c9](https://github.com/discordjs/discord.js/commit/ed593c91fb7b87ae8b512c6f127e12f33c9631b6))
* **Guild:** allow description and features in edit ([#5505](https://github.com/discordjs/discord.js/issues/5505)) ([8a059cc](https://github.com/discordjs/discord.js/commit/8a059cccb8ecbd0bf60d2ed395a8de0806b3395a))
* **Guild:** nsfw guilds ([#5525](https://github.com/discordjs/discord.js/issues/5525)) ([5968323](https://github.com/discordjs/discord.js/commit/596832371cefef7739e8d714248d1c6d438eb8df))
* **Guild:** replace `owner` with `fetchOwner` ([#5480](https://github.com/discordjs/discord.js/issues/5480)) ([1be67b8](https://github.com/discordjs/discord.js/commit/1be67b88516b104073e46574a180498bad2aa02b))
* **Guild:** setChannelPositions parent, lockPermissions keys ([#5507](https://github.com/discordjs/discord.js/issues/5507)) ([4866e26](https://github.com/discordjs/discord.js/commit/4866e2672f28bfc481cf03533f7ba259050c80f4))
* **GuildFeatures:** added the new screening features ([#5328](https://github.com/discordjs/discord.js/issues/5328)) ([3c175cb](https://github.com/discordjs/discord.js/commit/3c175cb5116fe50ba3084163565dd244a25b657f))
* **GuildManager:** allow system channel flags in create ([#5504](https://github.com/discordjs/discord.js/issues/5504)) ([d9fa180](https://github.com/discordjs/discord.js/commit/d9fa180cf93f1a339192ae95dfb512482bd0ed0b))
* **Message:** allow removing attachments ([#5557](https://github.com/discordjs/discord.js/issues/5557)) ([ca9e5a0](https://github.com/discordjs/discord.js/commit/ca9e5a0ee1afca544192df1daef744d5a35f1727))
* **Message:** replace referencedMessage with fetchReference ([#5577](https://github.com/discordjs/discord.js/issues/5577)) ([1398431](https://github.com/discordjs/discord.js/commit/1398431bca9a3743758295f1effa2e7f6c35093e))
* **MessageEmbed:** remove normalizeField validation ([#5459](https://github.com/discordjs/discord.js/issues/5459)) ([ff2f737](https://github.com/discordjs/discord.js/commit/ff2f7372f23f901620d3afff215f33be487521d5))
* **MessageManager:** extend API coverage ([#4869](https://github.com/discordjs/discord.js/issues/4869)) ([c56c4a8](https://github.com/discordjs/discord.js/commit/c56c4a8dc86b0f37dd7c9ee9a4d422a52070b50c))
* **ShardingManager:** add options typings ([#5583](https://github.com/discordjs/discord.js/issues/5583)) ([31b4390](https://github.com/discordjs/discord.js/commit/31b4390042e6557f7f9d2f258c79ea50ba4929e2))
* add support for application command events ([#5596](https://github.com/discordjs/discord.js/issues/5596)) ([9f74f95](https://github.com/discordjs/discord.js/commit/9f74f95f69f4aa8a9a23c160e25dc61010c0a8e0))
* interactions ([#5448](https://github.com/discordjs/discord.js/issues/5448)) ([f7643f7](https://github.com/discordjs/discord.js/commit/f7643f7bbe64003ad8b221006190dd15529651e9))
* **Activity:** add missing fields ([#4984](https://github.com/discordjs/discord.js/issues/4984)) ([63ff6a0](https://github.com/discordjs/discord.js/commit/63ff6a07ebcba7e9134e3902e338e8dc6564ee63))
* **APIMessage:** remove disableMentions ([#4836](https://github.com/discordjs/discord.js/issues/4836)) ([4107899](https://github.com/discordjs/discord.js/commit/41078997aefce2a9e683b9805aad6436612a3aa7))
* **Application:** application flags ([#5147](https://github.com/discordjs/discord.js/issues/5147)) ([06e9d86](https://github.com/discordjs/discord.js/commit/06e9d86cb3dd11708c9cdd81f15970979e5b090d))
* **BitField:** move problematic bit into the error message ([#5228](https://github.com/discordjs/discord.js/issues/5228)) ([273e955](https://github.com/discordjs/discord.js/commit/273e9557be68eb1c2466f29e1c41e9b146a777c1))
* **Client:** add InviteGenerationOptions#additionalScopes ([#5215](https://github.com/discordjs/discord.js/issues/5215)) ([ae3c3d8](https://github.com/discordjs/discord.js/commit/ae3c3d80ee603fc46a28140107cb90c81da0afc9))
* **ClientEvents:** add tuple labels to event arguments ([#5225](https://github.com/discordjs/discord.js/issues/5225)) ([764966e](https://github.com/discordjs/discord.js/commit/764966e398e693a5ec868bc22d722f8518656b3a))
* **GuildChannel:** support conversion between text and news ([#5022](https://github.com/discordjs/discord.js/issues/5022)) ([5ac3b57](https://github.com/discordjs/discord.js/commit/5ac3b57f9bd53d1c20549a70942b023826f6f726))
* **GuildEmojiManager:** implement GuildEmojiManager#fetch ([#4933](https://github.com/discordjs/discord.js/issues/4933)) ([ffe3140](https://github.com/discordjs/discord.js/commit/ffe31405ff559202be55473db7e8b34894fbf4a7))
* **GuildMember:** #pending ([#5121](https://github.com/discordjs/discord.js/issues/5121)) ([c4c8171](https://github.com/discordjs/discord.js/commit/c4c817116f868cedb4ec20bcbf90b9b3d382621e))
* **GuildMember:** make GuildMember#setNickname first param nullable ([#5070](https://github.com/discordjs/discord.js/issues/5070)) ([d70127c](https://github.com/discordjs/discord.js/commit/d70127cee69e66e87702a6db4b58ad12aa85f96c))
* **GuildMemberManager:** add 'search' method ([#4154](https://github.com/discordjs/discord.js/issues/4154)) ([0ba2bcb](https://github.com/discordjs/discord.js/commit/0ba2bcb54582b38ee8eec8d1547b979bf1b7c755))
* **GuildMemberManager:** throw TypeError on incorrect GuildMemberManager#ban params ([#4816](https://github.com/discordjs/discord.js/issues/4816)) ([863734a](https://github.com/discordjs/discord.js/commit/863734aba46c5e0d04fbc83d2ed314726bddcbc2))
* **Message:** added string type for message nonce ([#4782](https://github.com/discordjs/discord.js/issues/4782)) ([4b555fd](https://github.com/discordjs/discord.js/commit/4b555fdf4c3b35fa0ea284f9cd56765ecb608b89))
* **MessageAttachment:** support for #contentType ([#5481](https://github.com/discordjs/discord.js/issues/5481)) ([7b161f9](https://github.com/discordjs/discord.js/commit/7b161f93a040a6bdce6e7e26d7a3c3b6c61a04fd))
* **SysChanFlags:** new flag and rename in sync with client ([#5506](https://github.com/discordjs/discord.js/issues/5506)) ([fe93a7e](https://github.com/discordjs/discord.js/commit/fe93a7e084189b54b8af82461809dee1da112b75))
* move internal regular expressions to static properties ([#5384](https://github.com/discordjs/discord.js/issues/5384)) ([207735c](https://github.com/discordjs/discord.js/commit/207735cedcf9a998571a328c7c7b2414d3ebe9d5))
* **Message|TextChannel:** Inline replies ([#4874](https://github.com/discordjs/discord.js/issues/4874)) ([60e5a0e](https://github.com/discordjs/discord.js/commit/60e5a0e46f57cf297b66f1a940d24a20f46b5319))
* **ReactionCollector:** event create ([#4108](https://github.com/discordjs/discord.js/issues/4108)) ([09d1f2f](https://github.com/discordjs/discord.js/commit/09d1f2f18f5ec536bb25156553986fee51c80d1e)), closes [#2844](https://github.com/discordjs/discord.js/issues/2844)
* **Rest:** better handling of global rate limit and invalid request tracking ([#4711](https://github.com/discordjs/discord.js/issues/4711)) ([9d2d606](https://github.com/discordjs/discord.js/commit/9d2d60691eb4bde729f40fb633ae257cf5bc6545))
* **typings:** add ShardingManager.shardList to type definitions ([#5446](https://github.com/discordjs/discord.js/issues/5446)) ([32b0d71](https://github.com/discordjs/discord.js/commit/32b0d71af7e3afc401898753b1e8cb1e991b70e7))
* **typings:** explicitly type PremiumTier and Collectors ([#5458](https://github.com/discordjs/discord.js/issues/5458)) ([7c49612](https://github.com/discordjs/discord.js/commit/7c49612d4bedfe13f7ed676c125cc7f7f33596df))
* jsdelivr default file support ([#5424](https://github.com/discordjs/discord.js/issues/5424)) ([f469402](https://github.com/discordjs/discord.js/commit/f46940228e9f82db4af09ae2f2dad684db0d74ed))
* make changes to PresenceData typings and docs ([#5317](https://github.com/discordjs/discord.js/issues/5317)) ([eb43ce4](https://github.com/discordjs/discord.js/commit/eb43ce4d4fb4d634696c5b0f026174dc0e435fe3))
* promisified single interaction collection ([#5770](https://github.com/discordjs/discord.js/issues/5770)) ([c2b3ed0](https://github.com/discordjs/discord.js/commit/c2b3ed09a0ec7f9b7453d0bcf9f2900e408f5001))
* **MessageTypes:** add 16 and 17 ([#4685](https://github.com/discordjs/discord.js/issues/4685)) ([c9107e3](https://github.com/discordjs/discord.js/commit/c9107e35fa8b74f8ad7a7d3ee7d7178a35790e18))
* stage channels ([#5456](https://github.com/discordjs/discord.js/issues/5456)) ([eec7cf7](https://github.com/discordjs/discord.js/commit/eec7cf7634653fc02ee4f94e970960174a0e6d1b))
* stage instances ([#5749](https://github.com/discordjs/discord.js/issues/5749)) ([918921e](https://github.com/discordjs/discord.js/commit/918921e8211fc16e9b12d2502f3168264246ea22))
* **Browser:** remove browser <20> ([#5113](https://github.com/discordjs/discord.js/issues/5113)) ([0a591a9](https://github.com/discordjs/discord.js/commit/0a591a96974ab8b2aef7d7b9b64ec63d0fbe4ec4))
* **Role:** role tags ([#4628](https://github.com/discordjs/discord.js/issues/4628)) ([d6234b7](https://github.com/discordjs/discord.js/commit/d6234b764ecbf12ebc0a795429a6aa3a650f5a6c))
* **ShardingManager:** Allow b-Eval/fetchClientValues on a specific shard when not all are ready ([#5222](https://github.com/discordjs/discord.js/issues/5222)) ([001676c](https://github.com/discordjs/discord.js/commit/001676c7a97f4e44c6601dd84aa0354ea94b7c25))
* **Sticker:** added Sticker ([#4909](https://github.com/discordjs/discord.js/issues/4909)) ([026afc2](https://github.com/discordjs/discord.js/commit/026afc2c1a88bc210c973bcf235fef3484571111))
* **Util:** allow array for StringOptions' char ([#5566](https://github.com/discordjs/discord.js/issues/5566)) ([fbcbb29](https://github.com/discordjs/discord.js/commit/fbcbb29884a35308a7af2169f5f9ae5658c458e8))
* **Util:** make `cleanContent` take a channel instead of a message ([#5535](https://github.com/discordjs/discord.js/issues/5535)) ([f1c0c04](https://github.com/discordjs/discord.js/commit/f1c0c043b516f4158ab9d473419e3b5e125a4c03))
* **Voice:** implement support for @discordjs/voice ([#5402](https://github.com/discordjs/discord.js/issues/5402)) ([7b2e12b](https://github.com/discordjs/discord.js/commit/7b2e12b102984abf61132e1057558ef7f04e6d83))
* **Webhook:** add '(edit|delete)Message' methods ([#5223](https://github.com/discordjs/discord.js/issues/5223)) ([7cabc1c](https://github.com/discordjs/discord.js/commit/7cabc1c490ddd9518528e12a58a746d65e43d4eb))
* **Webhook:** add 'fetchMessage' method ([#5530](https://github.com/discordjs/discord.js/issues/5530)) ([63398d6](https://github.com/discordjs/discord.js/commit/63398d6ae46f0487c4d5d8bfe823952a803e4a5a))
* **Webhook:** sourceGuild, sourceChannel, improve owner ([#5508](https://github.com/discordjs/discord.js/issues/5508)) ([116ecf2](https://github.com/discordjs/discord.js/commit/116ecf246e89db4d629a13877a440260c7504e30))
* **WebSocketManager:** let identify throw on depleted limits ([#5283](https://github.com/discordjs/discord.js/issues/5283)) ([624a446](https://github.com/discordjs/discord.js/commit/624a4464ca86bfa0b095ecb2cdaac2e8030cc413))
* BaseGuildEmojiManager ([#4934](https://github.com/discordjs/discord.js/issues/4934)) ([8d650a7](https://github.com/discordjs/discord.js/commit/8d650a72509a3f369ae31ec421d1892d182175e4))
### Reverts
* support for nested arrays of components, fix error handling ([#6081](https://github.com/discordjs/discord.js/issues/6081)) ([1dcad05](https://github.com/discordjs/discord.js/commit/1dcad051a835407bc24de3446dbd0ac3c0efeefc))
* **BitField:** ⏪ Bring back-compatibility after BitField serialization ([#5910](https://github.com/discordjs/discord.js/issues/5910)) ([0a0630c](https://github.com/discordjs/discord.js/commit/0a0630c0498d8ae24e703a2bfdf978541deb9b60))
* 5047 ([#5050](https://github.com/discordjs/discord.js/issues/5050)) ([b2a6720](https://github.com/discordjs/discord.js/commit/b2a672047745b0a47729ef775482e06a20b38db3))
### BREAKING CHANGES
For breaking changes please reference: <https://discordjs.guide/additional-info/changes-in-v13.html>

View File

@@ -6,10 +6,9 @@
<br />
<p>
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/v/discord.js.svg?maxAge=3600" alt="NPM version" /></a>
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/dt/discord.js.svg?maxAge=3600" alt="NPM downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/workflows/Testing/badge.svg" alt="Build status" /></a>
<a href="https://www.patreon.com/discordjs"><img src="https://img.shields.io/badge/donate-patreon-F96854.svg" alt="Patreon" /></a>
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/v/discord.js.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/dt/discord.js.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Tests status" /></a>
</p>
</div>
@@ -25,10 +24,12 @@ discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to
## Installation
**Node.js 16.6.0 or newer is required.**
**Node.js 16.9.0 or newer is required.**
```sh-session
npm install discord.js
yarn add discord.js
pnpm add discord.js
```
### Optional packages
@@ -37,53 +38,62 @@ npm install discord.js
- [erlpack](https://github.com/discord/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install discord/erlpack`)
- [bufferutil](https://www.npmjs.com/package/bufferutil) for a much faster WebSocket connection (`npm install bufferutil`)
- [utf-8-validate](https://www.npmjs.com/package/utf-8-validate) in combination with `bufferutil` for much faster WebSocket processing (`npm install utf-8-validate`)
- [@discordjs/voice](https://github.com/discordjs/voice) for interacting with the Discord Voice API
- [@discordjs/voice](https://www.npmjs.com/package/@discordjs/voice) for interacting with the Discord Voice API (`npm install @discordjs/voice`)
## Example usage
First, we need to register a slash command against the Discord API:
Install all required dependencies:
```sh-session
npm install discord.js @discordjs/rest discord-api-types
yarn add discord.js @discordjs/rest discord-api-types
pnpm add discord.js @discordjs/rest discord-api-types
```
Register a slash command against the Discord API:
```js
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { Routes } = require('discord-api-types/v10');
const commands = [{
name: 'ping',
description: 'Replies with Pong!'
}];
const commands = [
{
name: 'ping',
description: 'Replies with Pong!',
},
];
const rest = new REST({ version: '9' }).setToken('token');
const rest = new REST({ version: '10' }).setToken('token');
(async () => {
try {
console.log('Started refreshing application (/) commands.');
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID),
{ body: commands },
);
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), { body: commands });
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
```
Afterwards we can create a quite simple example bot:
```js
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
client.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return;
if (interaction.commandName === 'ping') {
await interaction.reply('Pong!');
}
if (interaction.commandName === 'ping') {
await interaction.reply('Pong!');
}
});
client.login('token');
@@ -92,13 +102,13 @@ client.login('token');
## Links
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
- [Documentation](https://discord.js.org/#/docs/main/master/general/welcome)
- [Documentation](https://discord.js.org/#/docs)
- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide))
See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-v13.html), including updated and removed items in the library.
- [Discord.js Discord server](https://discord.gg/djs)
- [discord.js Discord server](https://discord.gg/djs)
- [Discord API Discord server](https://discord.gg/discord-api)
- [GitHub](https://github.com/discordjs/discord.js)
- [NPM](https://www.npmjs.com/package/discord.js)
- [npm](https://www.npmjs.com/package/discord.js)
- [Related libraries](https://discord.com/developers/docs/topics/community-resources#libraries)
### Extensions
@@ -109,9 +119,9 @@ client.login('token');
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the
[documentation](https://discord.js.org/#/docs).
See [the contribution guide](https://github.com/discordjs/discord.js/blob/master/.github/CONTRIBUTING.md) if you'd like to submit a PR.
See [the contribution guide](https://github.com/discordjs/discord.js/blob/main/.github/CONTRIBUTING.md) if you'd like to submit a PR.
## Help
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
nudge in the right direction, please don't hesitate to join our official [Discord.js Server](https://discord.gg/djs).
nudge in the right direction, please don't hesitate to join our official [discord.js Server](https://discord.gg/djs).

View File

@@ -1,3 +0,0 @@
{
"plugins": ["node_modules/jsdoc-strip-async-await"]
}

20540
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,82 +1,56 @@
{
"name": "discord.js",
"version": "13.0.1",
"description": "A powerful library for interacting with the Discord API",
"main": "./src/index.js",
"module": "./src/index.mjs",
"types": "./typings/index.d.ts",
"files": [
"src",
"typings"
],
"exports": {
"require": "./src/index.js",
"import": "./src/index.mjs"
},
"scripts": {
"test": "npm run lint && npm run docs:test && npm run lint:typings",
"test:typescript": "tsc",
"docs": "docgen --source src --custom docs/index.yml --output docs/docs.json",
"docs:test": "docgen --source src --custom docs/index.yml",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"lint:typings": "tslint typings/index.d.ts",
"prettier": "prettier --write src/**/*.js typings/**/*.ts",
"prepublishOnly": "npm run test && gen-esm-wrapper ./src/index.js ./src/index.mjs",
"prepare": "is-ci || husky install",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
},
"repository": {
"type": "git",
"url": "https://github.com/discordjs/discord.js.git"
},
"keywords": [
"discord",
"api",
"bot",
"client",
"node",
"discordapp"
],
"author": "Amish Shah <amish@shah.gg>",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/discordjs/discord.js/issues"
},
"homepage": "https://github.com/discordjs/discord.js#readme",
"dependencies": {
"@discordjs/builders": "^0.4.0",
"@discordjs/collection": "^0.2.1",
"@discordjs/form-data": "^3.0.1",
"@sapphire/async-queue": "^1.1.4",
"@types/ws": "^7.4.7",
"discord-api-types": "^0.22.0",
"node-fetch": "^2.6.1",
"ws": "^7.5.1"
},
"devDependencies": {
"@commitlint/cli": "^13.1.0",
"@commitlint/config-angular": "^13.1.0",
"@discordjs/docgen": "^0.10.0",
"@types/node": "^16.4.12",
"conventional-changelog-cli": "^2.1.1",
"cross-env": "^7.0.3",
"dtslint": "^4.1.3",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-prettier": "^3.4.0",
"gen-esm-wrapper": "^1.1.2",
"husky": "^7.0.1",
"is-ci": "^3.0.0",
"jest": "^27.0.6",
"lint-staged": "^11.1.1",
"prettier": "^2.3.2",
"tslint": "^6.1.3",
"typescript": "^4.3.5"
},
"engines": {
"node": ">=16.6.0",
"npm": ">=7.0.0"
}
"name": "@discordjs/discord.js",
"version": "0.0.0",
"description": "A powerful library for interacting with the Discord API",
"private": true,
"scripts": {
"build": "turbo run build",
"test": "turbo run test",
"lint": "turbo run lint",
"format": "turbo run format",
"fmt": "turbo run format",
"postinstall": "is-ci || husky install",
"docs": "turbo run docs",
"changelog": "turbo run changelog",
"update": "yarn upgrade-interactive"
},
"contributors": [
"Crawl <icrawltogo@gmail.com>",
"Amish Shah <amishshah.2k@gmail.com>",
"Vlad Frangu <kingdgrizzle@gmail.com>",
"SpaceEEC <spaceeec@yahoo.com>",
"Antonio Roman <kyradiscord@gmail.com>"
],
"keywords": [
"discord",
"api",
"bot",
"client",
"node",
"discordapp"
],
"repository": {
"type": "git",
"url": "https://github.com/discordjs/discord.js.git"
},
"bugs": {
"url": "https://github.com/discordjs/discord.js/issues"
},
"homepage": "https://discord.js.org",
"devDependencies": {
"@commitlint/cli": "^16.2.3",
"@commitlint/config-angular": "^16.2.3",
"@favware/npm-deprecate": "^1.0.4",
"conventional-changelog-cli": "^2.2.2",
"husky": "^7.0.4",
"prettier": "^2.6.2",
"turbo": "^1.2.4"
},
"engines": {
"node": ">=16.9.0"
},
"workspaces": [
"packages/*"
],
"packageManager": "yarn@3.1.1"
}

View File

@@ -0,0 +1,12 @@
{
"root": true,
"extends": "marine/prettier/node",
"parserOptions": {
"project": "./tsconfig.eslint.json",
"extraFileExtensions": [".mjs"]
},
"ignorePatterns": ["**/dist/*"],
"env": {
"jest": true
}
}

29
packages/builders/.gitignore vendored Normal file
View File

@@ -0,0 +1,29 @@
# Packages
node_modules/
# Log files
logs/
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Env
.env
# Dist
dist/
typings/
docs/**/*
!docs/index.yml
!docs/README.md
!docs/examples/
!docs/examples/*.md
# Miscellaneous
.tmp/
coverage/

View File

@@ -0,0 +1,8 @@
# Autogenerated
CHANGELOG.md
.turbo
dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/

View File

@@ -0,0 +1,8 @@
{
"printWidth": 120,
"useTabs": true,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"endOfLine": "lf"
}

View File

@@ -0,0 +1,3 @@
{
"releaseCommitMessageFormat": "chore(Release): publish"
}

View File

@@ -0,0 +1,181 @@
# Changelog
All notable changes to this project will be documented in this file.
# [0.13.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.12.0...@discordjs/builders@0.13.0) (2022-04-17)
## Bug Fixes
- Validate select menu options (#7566) ([b1d63d9](https://github.com/discordjs/discord.js/commit/b1d63d919a61f309ac89f27016b0f148678dac2b))
- **SelectMenu:** Set `placeholder` max to 150 (#7538) ([dcd4797](https://github.com/discordjs/discord.js/commit/dcd479767b6ec980a373f2ea1f22754f41661c1e))
- Only check `instanceof Component` once (#7546) ([0aa4851](https://github.com/discordjs/discord.js/commit/0aa48516a4e33497e8e8dc50da164a57cdee09d3))
- **builders:** Allow negative min/max value of number/integer option (#7484) ([3baa340](https://github.com/discordjs/discord.js/commit/3baa340821b8ecf8a16253bc0917a1033250d7c9))
- **components:** SetX should take rest parameters (#7461) ([3617359](https://github.com/discordjs/discord.js/commit/36173590a712f041b087b7882054805a8bd42dae))
- Unsafe embed builder field normalization (#7418) ([b936103](https://github.com/discordjs/discord.js/commit/b936103395121cb21a8c616f669ddab1d2efb0f1))
- Fix some typos (#7393) ([92a04f4](https://github.com/discordjs/discord.js/commit/92a04f4d98f6c6760214034cc8f5a1eaa78893c7))
- **builders:** Make type optional in constructor (#7391) ([4abb28c](https://github.com/discordjs/discord.js/commit/4abb28c0a1256c57a60369a6b8ec9e98c265b489))
- Don't create new instances of builders classes (#7343) ([d6b56d0](https://github.com/discordjs/discord.js/commit/d6b56d0080c4c5f8ace731f1e8bcae0c9d3fb5a5))
- **builders:** Dont export `Button` component stuff twice (#7289) ([86d9d06](https://github.com/discordjs/discord.js/commit/86d9d0674347c08d056cd054cb4ce4253195bf94))
## Documentation
- Completely fix builders example link (#7543) ([1a14c0c](https://github.com/discordjs/discord.js/commit/1a14c0ca562ea173d363a770a0437209f461fd23))
- Add slash command builders example, fixes #7338 (#7339) ([3ae6f3c](https://github.com/discordjs/discord.js/commit/3ae6f3c313091151245d6e6b52337b459ecfc765))
- **SlashCommandSubcommands:** Updating old links from Discord developer portal (#7224) ([bd7a6f2](https://github.com/discordjs/discord.js/commit/bd7a6f265212624199fb0b2ddc8ece39759c63de))
## Features
- Slash command localization for builders (#7683) ([40b9a1d](https://github.com/discordjs/discord.js/commit/40b9a1d67d0b508ec593e030913acd8161cd17f8))
- Add API v10 support (#7477) ([72577c4](https://github.com/discordjs/discord.js/commit/72577c4bfd02524a27afb6ff4aebba9301a690d3))
- Add support for module: NodeNext in TS and ESM (#7598) ([8f1986a](https://github.com/discordjs/discord.js/commit/8f1986a6aa98365e09b00e84ad5f9f354ab61f3d))
- Add Modals and Text Inputs (#7023) ([ed92015](https://github.com/discordjs/discord.js/commit/ed920156344233241a21b0c0b99736a3a855c23c))
- Add missing `v13` component methods (#7466) ([f7257f0](https://github.com/discordjs/discord.js/commit/f7257f07655076eabfe355cb6a53260b39ca9670))
- **builders:** Add attachment command option type (#7203) ([ae0f35f](https://github.com/discordjs/discord.js/commit/ae0f35f51d68dfa5a7dc43d161ef9365171debdb))
- **components:** Add unsafe message component builders (#7387) ([6b6222b](https://github.com/discordjs/discord.js/commit/6b6222bf513d1ee8cd98fba0ad313def560b864f))
- **embed:** Add setFields (#7322) ([bcc5cda](https://github.com/discordjs/discord.js/commit/bcc5cda8a902ddb28c7e3578e0f29b4272832624))
- Add components to /builders (#7195) ([2bb40fd](https://github.com/discordjs/discord.js/commit/2bb40fd767cf5918e3ba422ff73082734bfa05b0))
## Refactor
- Remove nickname parsing (#7736) ([78a3afc](https://github.com/discordjs/discord.js/commit/78a3afcd7fdac358e06764cc0d675e1215c785f3))
- Replace zod with shapeshift (#7547) ([3c0bbac](https://github.com/discordjs/discord.js/commit/3c0bbac82fa9988af4a62ff00c66d149fbe6b921))
- Remove store channels (#7634) ([aedddb8](https://github.com/discordjs/discord.js/commit/aedddb875e740e1f1bd77f06ce1b361fd3b7bc36))
- Allow builders to accept emoji strings (#7616) ([fb9a9c2](https://github.com/discordjs/discord.js/commit/fb9a9c221121ee1c7986f9c775b77b9691a0ae15))
- Don't return builders from API data (#7584) ([549716e](https://github.com/discordjs/discord.js/commit/549716e4fcec89ca81216a6d22aa8e623175e37a))
- Remove obsolete builder methods (#7590) ([10607db](https://github.com/discordjs/discord.js/commit/10607dbdafe257c5cbf5b952b7eecec4919e8b4a))
- **Embed:** Remove add field (#7522) ([8478d2f](https://github.com/discordjs/discord.js/commit/8478d2f4de9ac013733850cbbc67902f7c5abc55))
- Make `data` public in builders (#7486) ([ba31203](https://github.com/discordjs/discord.js/commit/ba31203a0ad96e0a00f8312c397889351e4c5cfd))
- **embed:** Remove array support in favor of rest params (#7498) ([b3fa2ec](https://github.com/discordjs/discord.js/commit/b3fa2ece402839008738ad3adce3db958445838d))
- **components:** Default set boolean methods to true (#7502) ([b122149](https://github.com/discordjs/discord.js/commit/b12214922cea2f43afbe6b1555a74a3c8e16f798))
- Make public builder props getters (#7422) ([e8252ed](https://github.com/discordjs/discord.js/commit/e8252ed3b981a4b7e4013f12efadd2f5d9318d3e))
- **builders-methods:** Make methods consistent (#7395) ([f495364](https://github.com/discordjs/discord.js/commit/f4953647ff9f39127978c73bf8a62c08462802ca))
- Remove conditional autocomplete option return types (#7396) ([0909824](https://github.com/discordjs/discord.js/commit/09098240bfb13b8afafa4ab549f06d236e0ff1c9))
- **embed:** Mark properties as readonly (#7332) ([31768fc](https://github.com/discordjs/discord.js/commit/31768fcd69ed5b4566a340bda89ce881418e8272))
## Typings
- Fix regressions (#7649) ([5748dbe](https://github.com/discordjs/discord.js/commit/5748dbe08783beb80c526de38ccd105eb0e82664))
- Make `required` a boolean (#7307) ([c10afea](https://github.com/discordjs/discord.js/commit/c10afeadc702ab98bec5e077b3b92494a9596f9c))
# [0.12.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.11.0...@discordjs/builders@0.12.0) (2021-12-08)
## Bug Fixes
- **builders:** Dont export `Button` component stuff twice (#7289) ([86d9d06](https://github.com/discordjs/discord.js/commit/86d9d0674347c08d056cd054cb4ce4253195bf94))
## Documentation
- **SlashCommandSubcommands:** Updating old links from Discord developer portal (#7224) ([bd7a6f2](https://github.com/discordjs/discord.js/commit/bd7a6f265212624199fb0b2ddc8ece39759c63de))
## Features
- Add components to /builders (#7195) ([2bb40fd](https://github.com/discordjs/discord.js/commit/2bb40fd767cf5918e3ba422ff73082734bfa05b0))
## Typings
- Make `required` a boolean (#7307) ([c10afea](https://github.com/discordjs/discord.js/commit/c10afeadc702ab98bec5e077b3b92494a9596f9c))
# [0.11.0](https://github.com/discordjs/builders/compare/v0.10.0...v0.11.0) (2021-12-29)
## Bug Fixes
- **ApplicationCommandOptions:** clean up code for builder options ([#68](https://github.com/discordjs/builders/issues/68)) ([b5d0b15](https://github.com/discordjs/builders/commit/b5d0b157b1262bd01fa011f8e0cf33adb82776e7))
# [0.10.0](https://github.com/discordjs/builders/compare/v0.9.0...v0.10.0) (2021-12-24)
## Bug Fixes
- use zod instead of ow for max/min option validation ([#66](https://github.com/discordjs/builders/issues/66)) ([beb35fb](https://github.com/discordjs/builders/commit/beb35fb1f65bd6be2321e17cc792f67e8615fd48))
## Features
- add max/min option for int and number builder options ([#47](https://github.com/discordjs/builders/issues/47)) ([2e1e860](https://github.com/discordjs/builders/commit/2e1e860b46e3453398b20df63dabb6d4325e32d1))
# [0.9.0](https://github.com/discordjs/builders/compare/v0.8.2...v0.9.0) (2021-12-02)
## Bug Fixes
- replace ow with zod ([#58](https://github.com/discordjs/builders/issues/58)) ([0b6fb81](https://github.com/discordjs/builders/commit/0b6fb8161b858e42781855fb73aaa873fec58160))
## Features
- **SlashCommandBuilder:** add autocomplete ([#53](https://github.com/discordjs/builders/issues/53)) ([05b07a7](https://github.com/discordjs/builders/commit/05b07a7e88848188c27d7380d9f948cba25ef778))
## [0.8.2](https://github.com/discordjs/builders/compare/v0.8.1...v0.8.2) (2021-10-30)
## Bug Fixes
- downgrade ow because of esm issues ([#55](https://github.com/discordjs/builders/issues/55)) ([3722d2c](https://github.com/discordjs/builders/commit/3722d2c1109a7a5c0abad63c1a7eb944df6e46c8))
## [0.8.1](https://github.com/discordjs/builders/compare/v0.8.0...v0.8.1) (2021-10-29)
## Bug Fixes
- documentation ([e33ec8d](https://github.com/discordjs/builders/commit/e33ec8dfd5785312f82e0afb017a3dac614fd71d))
# [0.7.0](https://github.com/discordjs/builders/compare/v0.6.0...v0.7.0) (2021-10-18)
## Bug Fixes
- properly type `toJSON` methods ([#34](https://github.com/discordjs/builders/issues/34)) ([7723ad0](https://github.com/discordjs/builders/commit/7723ad0da169386e638188de220451a97513bc25))
## Features
- **ContextMenus:** add context menu command builder ([#29](https://github.com/discordjs/builders/issues/29)) ([f0641e5](https://github.com/discordjs/builders/commit/f0641e55733de8992600f3082bcf054e6f815cf7))
- add support for channel types on channel options ([#41](https://github.com/discordjs/builders/issues/41)) ([f6c187e](https://github.com/discordjs/builders/commit/f6c187e0ad6ebe03e65186ece3e95cb1db5aeb50))
# [0.6.0](https://github.com/discordjs/builders/compare/v0.5.0...v0.6.0) (2021-08-24)
## Bug Fixes
- **SlashCommandBuilder:** allow subcommands and groups to coexist at the root level ([#26](https://github.com/discordjs/builders/issues/26)) ([0be4daf](https://github.com/discordjs/builders/commit/0be4dafdfc0b5747c880be0078c00ada913eb4fb))
## Features
- create `Embed` builder ([#11](https://github.com/discordjs/builders/issues/11)) ([eb942a4](https://github.com/discordjs/builders/commit/eb942a4d1f3bcec9a4e370b6af602a713ad8f9b7))
- **SlashCommandBuilder:** create setDefaultPermission function ([#19](https://github.com/discordjs/builders/issues/19)) ([5d53759](https://github.com/discordjs/builders/commit/5d537593937a8da330153ce4711b7d093a80330e))
- **SlashCommands:** add number option type ([#23](https://github.com/discordjs/builders/issues/23)) ([1563991](https://github.com/discordjs/builders/commit/1563991d421bb07bf7a412c87e7613692d770f04))
# [0.5.0](https://github.com/discordjs/builders/compare/v0.3.0...v0.5.0) (2021-08-10)
## Features
- **Formatters:** add `formatEmoji` ([#20](https://github.com/discordjs/builders/issues/20)) ([c3d8bb5](https://github.com/discordjs/builders/commit/c3d8bb5363a1d46b45c0def4277da6921e2ba209))
# [0.4.0](https://github.com/discordjs/builders/compare/v0.3.0...v0.4.0) (2021-08-05)
## Features
- `sub command` => `subcommand` ([#18](https://github.com/discordjs/builders/pull/18)) ([95599c5](https://github.com/discordjs/builders/commit/95599c5b5366ebd054c4c277c52f1a44cda1209d))
# [0.3.0](https://github.com/discordjs/builders/compare/v0.2.0...v0.3.0) (2021-08-01)
## Bug Fixes
- **Shrug:** Update comment ([#14](https://github.com/discordjs/builders/issues/14)) ([6fa6c40](https://github.com/discordjs/builders/commit/6fa6c405f2ea733811677d3d1bfb1e2806d504d5))
- shrug face rendering ([#13](https://github.com/discordjs/builders/issues/13)) ([6ad24ec](https://github.com/discordjs/builders/commit/6ad24ecd96c82b0f576e78e9e53fc7bf9c36ef5d))
## Features
- **formatters:** mentions ([#9](https://github.com/discordjs/builders/issues/9)) ([f83fe99](https://github.com/discordjs/builders/commit/f83fe99b83188ed999845751ffb005c687dbd60a))
- **Formatters:** Add a spoiler function ([#16](https://github.com/discordjs/builders/issues/16)) ([c213a6a](https://github.com/discordjs/builders/commit/c213a6abb114f65653017a4edec4bdba2162d771))
- **SlashCommands:** add slash command builders ([#3](https://github.com/discordjs/builders/issues/3)) ([6aa3af0](https://github.com/discordjs/builders/commit/6aa3af07b0ee342fff91f080914bb12b3ab773f8))
- shrug, tableflip and unflip strings ([#5](https://github.com/discordjs/builders/issues/5)) ([de5fa82](https://github.com/discordjs/builders/commit/de5fa823cd6f1feba5b2d0a63b2cb1761dfd1814))
# [0.2.0](https://github.com/discordjs/builders/compare/v0.1.1...v0.2.0) (2021-07-03)
## Features
- **Formatters:** added `hyperlink` and `hideLinkEmbed` ([#4](https://github.com/discordjs/builders/issues/4)) ([c532daf](https://github.com/discordjs/builders/commit/c532daf2ba2feae75bf9668f63462e96a5314cff))
# [0.1.1](https://github.com/discordjs/builders/compare/v0.1.0...v0.1.1) (2021-06-30)
## Bug Fixes
- **Deps:** added `tslib` as dependency ([#2](https://github.com/discordjs/builders/issues/2)) ([5576ff3](https://github.com/discordjs/builders/commit/5576ff3b67136b957bed0ab8a4c655d5de322813))
# 0.1.0 (2021-06-30)
## Features
- added message formatters ([#1](https://github.com/discordjs/builders/issues/1)) ([765e46d](https://github.com/discordjs/builders/commit/765e46dac96c4e49d350243e5fad34c2bc738a7c))

191
packages/builders/LICENSE Normal file
View File

@@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2021 Noel Buechler
Copyright 2021 Vlad Frangu
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,53 @@
<div align="center">
<br />
<p>
<a href="https://discord.js.org"><img src="https://discord.js.org/static/logo.svg" width="546" alt="discord.js" /></a>
</p>
<br />
<p>
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
<a href="https://www.npmjs.com/package/@discordjs/builders"><img src="https://img.shields.io/npm/v/@discordjs/builders.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/builders"><img src="https://img.shields.io/npm/dt/@discordjs/builders.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/builders"><img src="https://codecov.io/gh/discordjs/builders/branch/main/graph/badge.svg" alt="Code coverage" /></a>
</p>
</div>
## Installation
**Node.js 16.9.0 or newer is required.**
```sh-session
npm install @discordjs/builders
yarn add @discordjs/builders
pnpm add @discordjs/builders
```
## Examples
Here are some examples for the builders and utilities you can find in this package:
- [Slash Command Builders](https://github.com/discordjs/discord.js/blob/main/packages/builders/docs/examples/Slash%20Command%20Builders.md)
## Links
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
- [Documentation](https://discord.js.org/#/docs/builders)
- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide))
See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-v13.html), including updated and removed items in the library.
- [discord.js Discord server](https://discord.gg/djs)
- [Discord API Discord server](https://discord.gg/discord-api)
- [GitHub](https://github.com/discordjs/discord.js/tree/main/packages/builders)
- [npm](https://www.npmjs.com/package/@discordjs/builders)
- [Related libraries](https://discord.com/developers/docs/topics/community-resources#libraries)
## Contributing
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the
[documentation](https://discord.js.org/#/docs/builders).
See [the contribution guide](https://github.com/discordjs/discord.js/blob/main/.github/CONTRIBUTING.md) if you'd like to submit a PR.
## Help
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
nudge in the right direction, please don't hesitate to join our official [discord.js Server](https://discord.gg/djs).

View File

@@ -0,0 +1,140 @@
import { APIActionRowComponent, APIMessageActionRowComponent, ButtonStyle, ComponentType } from 'discord-api-types/v10';
import {
ActionRowBuilder,
ButtonBuilder,
createComponentBuilder,
SelectMenuBuilder,
SelectMenuOptionBuilder,
} from '../../src';
const rowWithButtonData: APIActionRowComponent<APIMessageActionRowComponent> = {
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.Button,
label: 'test',
custom_id: '123',
style: ButtonStyle.Primary,
},
],
};
const rowWithSelectMenuData: APIActionRowComponent<APIMessageActionRowComponent> = {
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.SelectMenu,
custom_id: '1234',
options: [
{
label: 'one',
value: 'one',
},
{
label: 'two',
value: 'two',
},
],
max_values: 10,
min_values: 12,
},
],
};
describe('Action Row Components', () => {
describe('Assertion Tests', () => {
test('GIVEN valid components THEN do not throw', () => {
expect(() => new ActionRowBuilder().addComponents(new ButtonBuilder())).not.toThrowError();
expect(() => new ActionRowBuilder().setComponents(new ButtonBuilder())).not.toThrowError();
});
test('GIVEN valid JSON input THEN valid JSON output is given', () => {
const actionRowData: APIActionRowComponent<APIMessageActionRowComponent> = {
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.Button,
label: 'button',
style: ButtonStyle.Primary,
custom_id: 'test',
},
{
type: ComponentType.Button,
label: 'link',
style: ButtonStyle.Link,
url: 'https://google.com',
},
{
type: ComponentType.SelectMenu,
placeholder: 'test',
custom_id: 'test',
options: [
{
label: 'option',
value: 'option',
},
],
},
],
};
expect(new ActionRowBuilder(actionRowData).toJSON()).toEqual(actionRowData);
expect(new ActionRowBuilder().toJSON()).toEqual({ type: ComponentType.ActionRow, components: [] });
expect(() => createComponentBuilder({ type: ComponentType.ActionRow, components: [] })).not.toThrowError();
});
test('GIVEN valid builder options THEN valid JSON output is given', () => {
const rowWithButtonData: APIActionRowComponent<APIMessageActionRowComponent> = {
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.Button,
label: 'test',
custom_id: '123',
style: ButtonStyle.Primary,
},
],
};
const rowWithSelectMenuData: APIActionRowComponent<APIMessageActionRowComponent> = {
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.SelectMenu,
custom_id: '1234',
options: [
{
label: 'one',
value: 'one',
},
{
label: 'two',
value: 'two',
},
],
max_values: 10,
min_values: 12,
},
],
};
expect(new ActionRowBuilder(rowWithButtonData).toJSON()).toEqual(rowWithButtonData);
expect(new ActionRowBuilder(rowWithSelectMenuData).toJSON()).toEqual(rowWithSelectMenuData);
expect(new ActionRowBuilder().toJSON()).toEqual({ type: ComponentType.ActionRow, components: [] });
expect(() => createComponentBuilder({ type: ComponentType.ActionRow, components: [] })).not.toThrowError();
});
test('GIVEN valid builder options THEN valid JSON output is given', () => {
const button = new ButtonBuilder().setLabel('test').setStyle(ButtonStyle.Primary).setCustomId('123');
const selectMenu = new SelectMenuBuilder()
.setCustomId('1234')
.setMaxValues(10)
.setMinValues(12)
.setOptions(
new SelectMenuOptionBuilder().setLabel('one').setValue('one'),
new SelectMenuOptionBuilder().setLabel('two').setValue('two'),
);
expect(new ActionRowBuilder().addComponents(button).toJSON()).toEqual(rowWithButtonData);
expect(new ActionRowBuilder().addComponents(selectMenu).toJSON()).toEqual(rowWithSelectMenuData);
});
});
});

View File

@@ -0,0 +1,146 @@
import {
APIButtonComponentWithCustomId,
APIButtonComponentWithURL,
ButtonStyle,
ComponentType,
} from 'discord-api-types/v10';
import { buttonLabelValidator, buttonStyleValidator } from '../../src/components/Assertions';
import { ButtonBuilder } from '../../src/components/button/Button';
const buttonComponent = () => new ButtonBuilder();
const longStr =
'looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong';
describe('Button Components', () => {
describe('Assertion Tests', () => {
test('GIVEN valid label THEN validator does not throw', () => {
expect(() => buttonLabelValidator.parse('foobar')).not.toThrowError();
});
test('GIVEN invalid label THEN validator does throw', () => {
expect(() => buttonLabelValidator.parse(null)).toThrowError();
expect(() => buttonLabelValidator.parse('')).toThrowError();
expect(() => buttonLabelValidator.parse(longStr)).toThrowError();
});
test('GIVEN valid style THEN validator does not throw', () => {
expect(() => buttonStyleValidator.parse(3)).not.toThrowError();
expect(() => buttonStyleValidator.parse(ButtonStyle.Secondary)).not.toThrowError();
});
test('GIVEN invalid style THEN validator does not throw', () => {
expect(() => buttonStyleValidator.parse(7)).toThrowError();
});
test('GIVEN valid fields THEN builder does not throw', () => {
expect(() =>
buttonComponent().setCustomId('custom').setStyle(ButtonStyle.Primary).setLabel('test'),
).not.toThrowError();
expect(() => {
const button = buttonComponent()
.setCustomId('custom')
.setStyle(ButtonStyle.Primary)
.setDisabled(true)
.setEmoji({ name: 'test' });
button.toJSON();
}).not.toThrowError();
expect(() => buttonComponent().setURL('https://google.com')).not.toThrowError();
});
test('GIVEN invalid fields THEN build does throw', () => {
expect(() => {
buttonComponent().setCustomId(longStr);
}).toThrowError();
expect(() => {
const button = buttonComponent()
.setCustomId('custom')
.setStyle(ButtonStyle.Primary)
.setDisabled(true)
.setLabel('test')
.setURL('https://google.com')
.setEmoji({ name: 'test' });
button.toJSON();
}).toThrowError();
expect(() => {
// @ts-expect-error
const button = buttonComponent().setEmoji('test');
button.toJSON();
}).toThrowError();
expect(() => {
const button = buttonComponent().setStyle(ButtonStyle.Primary);
button.toJSON();
}).toThrowError();
expect(() => {
const button = buttonComponent().setStyle(ButtonStyle.Primary).setCustomId('test');
button.toJSON();
}).toThrowError();
expect(() => {
const button = buttonComponent().setStyle(ButtonStyle.Link);
button.toJSON();
}).toThrowError();
expect(() => {
const button = buttonComponent().setStyle(ButtonStyle.Primary).setLabel('test').setURL('https://google.com');
button.toJSON();
}).toThrowError();
expect(() => {
const button = buttonComponent().setStyle(ButtonStyle.Link).setLabel('test');
button.toJSON();
}).toThrowError();
expect(() => buttonComponent().setStyle(24)).toThrowError();
expect(() => buttonComponent().setLabel(longStr)).toThrowError();
// @ts-expect-error
expect(() => buttonComponent().setDisabled(0)).toThrowError();
// @ts-expect-error
expect(() => buttonComponent().setEmoji('foo')).toThrowError();
expect(() => buttonComponent().setURL('foobar')).toThrowError();
});
test('GiVEN valid input THEN valid JSON outputs are given', () => {
const interactionData: APIButtonComponentWithCustomId = {
type: ComponentType.Button,
custom_id: 'test',
label: 'test',
style: ButtonStyle.Primary,
disabled: true,
};
expect(new ButtonBuilder(interactionData).toJSON()).toEqual(interactionData);
expect(
buttonComponent()
.setCustomId(interactionData.custom_id)
.setLabel(interactionData.label)
.setStyle(interactionData.style)
.setDisabled(interactionData.disabled)
.toJSON(),
).toEqual(interactionData);
const linkData: APIButtonComponentWithURL = {
type: ComponentType.Button,
label: 'test',
style: ButtonStyle.Link,
disabled: true,
url: 'https://google.com',
};
expect(new ButtonBuilder(linkData).toJSON()).toEqual(linkData);
expect(buttonComponent().setLabel(linkData.label).setDisabled(true).setURL(linkData.url));
});
});
});

View File

@@ -0,0 +1,121 @@
import { APISelectMenuComponent, APISelectMenuOption, ComponentType } from 'discord-api-types/v10';
import { SelectMenuBuilder, SelectMenuOptionBuilder } from '../../src/index';
const selectMenu = () => new SelectMenuBuilder();
const selectMenuOption = () => new SelectMenuOptionBuilder();
const longStr = 'a'.repeat(256);
const selectMenuOptionData: APISelectMenuOption = {
label: 'test',
value: 'test',
emoji: { name: 'test' },
default: true,
description: 'test',
};
const selectMenuDataWithoutOptions = {
type: ComponentType.SelectMenu,
custom_id: 'test',
max_values: 10,
min_values: 3,
disabled: true,
placeholder: 'test',
} as const;
const selectMenuData: APISelectMenuComponent = {
...selectMenuDataWithoutOptions,
options: [selectMenuOptionData],
};
describe('Select Menu Components', () => {
describe('Assertion Tests', () => {
test('GIVEN valid inputs THEN Select Menu does not throw', () => {
expect(() => selectMenu().setCustomId('foo')).not.toThrowError();
expect(() => selectMenu().setMaxValues(10)).not.toThrowError();
expect(() => selectMenu().setMinValues(3)).not.toThrowError();
expect(() => selectMenu().setDisabled(true)).not.toThrowError();
expect(() => selectMenu().setDisabled()).not.toThrowError();
expect(() => selectMenu().setPlaceholder('description')).not.toThrowError();
const option = selectMenuOption()
.setLabel('test')
.setValue('test')
.setDefault(true)
.setEmoji({ name: 'test' })
.setDescription('description');
expect(() => selectMenu().addOptions(option)).not.toThrowError();
expect(() => selectMenu().setOptions(option)).not.toThrowError();
expect(() => selectMenu().setOptions({ label: 'test', value: 'test' })).not.toThrowError();
expect(() =>
selectMenu().addOptions({
label: 'test',
value: 'test',
emoji: {
id: '123',
name: 'test',
animated: true,
},
}),
).not.toThrowError();
const options = new Array<APISelectMenuOption>(25).fill({ label: 'test', value: 'test' });
expect(() => selectMenu().addOptions(...options)).not.toThrowError();
expect(() => selectMenu().setOptions(...options)).not.toThrowError();
expect(() =>
selectMenu()
.addOptions({ label: 'test', value: 'test' })
.addOptions(...new Array<APISelectMenuOption>(24).fill({ label: 'test', value: 'test' })),
).not.toThrowError();
});
test('GIVEN invalid inputs THEN Select Menu does throw', () => {
expect(() => selectMenu().setCustomId(longStr)).toThrowError();
expect(() => selectMenu().setMaxValues(30)).toThrowError();
expect(() => selectMenu().setMinValues(-20)).toThrowError();
// @ts-expect-error
expect(() => selectMenu().setDisabled(0)).toThrowError();
expect(() => selectMenu().setPlaceholder(longStr)).toThrowError();
// @ts-expect-error
expect(() => selectMenu().addOptions({ label: 'test' })).toThrowError();
expect(() => selectMenu().addOptions({ label: longStr, value: 'test' })).toThrowError();
expect(() => selectMenu().addOptions({ value: longStr, label: 'test' })).toThrowError();
expect(() => selectMenu().addOptions({ label: 'test', value: 'test', description: longStr })).toThrowError();
// @ts-expect-error
expect(() => selectMenu().addOptions({ label: 'test', value: 'test', default: 100 })).toThrowError();
// @ts-expect-error
expect(() => selectMenu().addOptions({ value: 'test' })).toThrowError();
// @ts-expect-error
expect(() => selectMenu().addOptions({ default: true })).toThrowError();
const tooManyOptions = new Array<APISelectMenuOption>(26).fill({ label: 'test', value: 'test' });
expect(() => selectMenu().setOptions(...tooManyOptions)).toThrowError();
expect(() =>
selectMenu()
.addOptions({ label: 'test', value: 'test' })
.addOptions(...tooManyOptions),
).toThrowError();
expect(() => {
selectMenuOption()
.setLabel(longStr)
.setValue(longStr)
// @ts-expect-error
.setDefault(-1)
// @ts-expect-error
.setEmoji({ name: 1 })
.setDescription(longStr);
}).toThrowError();
});
test('GIVEN valid JSON input THEN valid JSON history is correct', () => {
expect(
new SelectMenuBuilder(selectMenuDataWithoutOptions)
.addOptions(new SelectMenuOptionBuilder(selectMenuOptionData))
.toJSON(),
).toEqual(selectMenuData);
expect(new SelectMenuOptionBuilder(selectMenuOptionData).toJSON()).toEqual(selectMenuOptionData);
});
});
});

View File

@@ -0,0 +1,126 @@
import { APITextInputComponent, ComponentType, TextInputStyle } from 'discord-api-types/v10';
import {
labelValidator,
maxLengthValidator,
minLengthValidator,
placeholderValidator,
valueValidator,
textInputStyleValidator,
} from '../../src/components/textInput/Assertions';
import { TextInputBuilder } from '../../src/components/textInput/TextInput';
const superLongStr = 'a'.repeat(5000);
const textInputComponent = () => new TextInputBuilder();
describe('Text Input Components', () => {
describe('Assertion Tests', () => {
test('GIVEN valid label THEN validator does not throw', () => {
expect(() => labelValidator.parse('foobar')).not.toThrowError();
});
test('GIVEN invalid label THEN validator does throw', () => {
expect(() => labelValidator.parse(24)).toThrowError();
expect(() => labelValidator.parse(undefined)).toThrowError();
});
test('GIVEN valid style THEN validator does not throw', () => {
expect(() => textInputStyleValidator.parse(TextInputStyle.Paragraph)).not.toThrowError();
expect(() => textInputStyleValidator.parse(TextInputStyle.Short)).not.toThrowError();
});
test('GIVEN invalid style THEN validator does throw', () => {
expect(() => textInputStyleValidator.parse(24)).toThrowError();
});
test('GIVEN valid min length THEN validator does not throw', () => {
expect(() => minLengthValidator.parse(10)).not.toThrowError();
});
test('GIVEN invalid min length THEN validator does throw', () => {
expect(() => minLengthValidator.parse(-1)).toThrowError();
});
test('GIVEN valid max length THEN validator does not throw', () => {
expect(() => maxLengthValidator.parse(10)).not.toThrowError();
});
test('GIVEN invalid min length THEN validator does throw', () => {
expect(() => maxLengthValidator.parse(4001)).toThrowError();
});
test('GIVEN valid value THEN validator does not throw', () => {
expect(() => valueValidator.parse('foobar')).not.toThrowError();
});
test('GIVEN invalid value THEN validator does throw', () => {
expect(() => valueValidator.parse(superLongStr)).toThrowError();
});
test('GIVEN valid placeholder THEN validator does not throw', () => {
expect(() => placeholderValidator.parse('foobar')).not.toThrowError();
});
test('GIVEN invalid value THEN validator does throw', () => {
expect(() => placeholderValidator.parse(superLongStr)).toThrowError();
});
test('GIVEN valid fields THEN builder does not throw', () => {
expect(() => {
textInputComponent().setCustomId('foobar').setLabel('test').setStyle(TextInputStyle.Paragraph).toJSON();
}).not.toThrowError();
expect(() => {
textInputComponent()
.setCustomId('foobar')
.setLabel('test')
.setMaxLength(100)
.setMinLength(1)
.setPlaceholder('bar')
.setRequired(true)
.setStyle(TextInputStyle.Paragraph)
.toJSON();
}).not.toThrowError();
});
});
test('GIVEN invalid fields THEN builder throws', () => {
expect(() => textInputComponent().toJSON()).toThrowError();
expect(() => {
textInputComponent()
.setCustomId('test')
.setMaxLength(100)
.setPlaceholder('hello')
.setStyle(TextInputStyle.Paragraph)
.toJSON();
}).toThrowError();
});
test('GIVEN valid input THEN valid JSON outputs are given', () => {
const textInputData: APITextInputComponent = {
type: ComponentType.TextInput,
label: 'label',
custom_id: 'custom id',
placeholder: 'placeholder',
max_length: 100,
min_length: 10,
value: 'value',
required: false,
style: TextInputStyle.Paragraph,
};
expect(new TextInputBuilder(textInputData).toJSON()).toEqual(textInputData);
expect(
textInputComponent()
.setCustomId(textInputData.custom_id)
.setLabel(textInputData.label)
.setPlaceholder(textInputData.placeholder)
.setMaxLength(textInputData.max_length)
.setMinLength(textInputData.min_length)
.setValue(textInputData.value)
.setRequired(textInputData.required)
.setStyle(textInputData.style)
.toJSON(),
).toEqual(textInputData);
});
});

View File

@@ -0,0 +1,89 @@
import { ContextMenuCommandAssertions, ContextMenuCommandBuilder } from '../../src/index';
const getBuilder = () => new ContextMenuCommandBuilder();
describe('Context Menu Commands', () => {
describe('Assertions tests', () => {
test('GIVEN valid name THEN does not throw error', () => {
expect(() => ContextMenuCommandAssertions.validateName('ping')).not.toThrowError();
});
test('GIVEN invalid name THEN throw error', () => {
expect(() => ContextMenuCommandAssertions.validateName(null)).toThrowError();
// Too short of a name
expect(() => ContextMenuCommandAssertions.validateName('')).toThrowError();
// Invalid characters used
expect(() => ContextMenuCommandAssertions.validateName('ABC123$%^&')).toThrowError();
// Too long of a name
expect(() =>
ContextMenuCommandAssertions.validateName('qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm'),
).toThrowError();
});
test('GIVEN valid type THEN does not throw error', () => {
expect(() => ContextMenuCommandAssertions.validateType(3)).not.toThrowError();
});
test('GIVEN invalid type THEN throw error', () => {
expect(() => ContextMenuCommandAssertions.validateType(null)).toThrowError();
// Out of range
expect(() => ContextMenuCommandAssertions.validateType(1)).toThrowError();
});
test('GIVEN valid required parameters THEN does not throw error', () => {
expect(() => ContextMenuCommandAssertions.validateRequiredParameters('owo', 2)).not.toThrowError();
});
test('GIVEN valid default_permission THEN does not throw error', () => {
expect(() => ContextMenuCommandAssertions.validateDefaultPermission(true)).not.toThrowError();
});
test('GIVEN invalid default_permission THEN throw error', () => {
expect(() => ContextMenuCommandAssertions.validateDefaultPermission(null)).toThrowError();
});
});
describe('ContextMenuCommandBuilder', () => {
describe('Builder tests', () => {
test('GIVEN empty builder THEN throw error when calling toJSON', () => {
expect(() => getBuilder().toJSON()).toThrowError();
});
test('GIVEN valid builder THEN does not throw error', () => {
expect(() => getBuilder().setName('example').setType(3).toJSON()).not.toThrowError();
});
test('GIVEN invalid name THEN throw error', () => {
expect(() => getBuilder().setName('$$$')).toThrowError();
expect(() => getBuilder().setName(' ')).toThrowError();
});
test('GIVEN valid names THEN does not throw error', () => {
expect(() => getBuilder().setName('hi_there')).not.toThrowError();
expect(() => getBuilder().setName('A COMMAND')).not.toThrowError();
// Translation: a_command
expect(() => getBuilder().setName('o_comandă')).not.toThrowError();
// Translation: thx (according to GTranslate)
expect(() => getBuilder().setName('どうも')).not.toThrowError();
});
test('GIVEN valid types THEN does not throw error', () => {
expect(() => getBuilder().setType(2)).not.toThrowError();
expect(() => getBuilder().setType(3)).not.toThrowError();
});
test('GIVEN valid builder with defaultPermission false THEN does not throw error', () => {
expect(() => getBuilder().setName('foo').setDefaultPermission(false)).not.toThrowError();
});
});
});
});

View File

@@ -0,0 +1,205 @@
import {
APIApplicationCommandBooleanOption,
APIApplicationCommandChannelOption,
APIApplicationCommandIntegerOption,
APIApplicationCommandMentionableOption,
APIApplicationCommandNumberOption,
APIApplicationCommandRoleOption,
APIApplicationCommandStringOption,
APIApplicationCommandUserOption,
ApplicationCommandOptionType,
ChannelType,
} from 'discord-api-types/v10';
import {
SlashCommandBooleanOption,
SlashCommandChannelOption,
SlashCommandIntegerOption,
SlashCommandMentionableOption,
SlashCommandNumberOption,
SlashCommandRoleOption,
SlashCommandStringOption,
SlashCommandUserOption,
} from '../../../src/index';
const getBooleanOption = () =>
new SlashCommandBooleanOption().setName('owo').setDescription('Testing 123').setRequired(true);
const getChannelOption = () =>
new SlashCommandChannelOption()
.setName('owo')
.setDescription('Testing 123')
.setRequired(true)
.addChannelTypes(ChannelType.GuildText);
const getStringOption = () =>
new SlashCommandStringOption().setName('owo').setDescription('Testing 123').setRequired(true);
const getIntegerOption = () =>
new SlashCommandIntegerOption()
.setName('owo')
.setDescription('Testing 123')
.setRequired(true)
.setMinValue(-1)
.setMaxValue(10);
const getNumberOption = () =>
new SlashCommandNumberOption()
.setName('owo')
.setDescription('Testing 123')
.setRequired(true)
.setMinValue(-1.23)
.setMaxValue(10);
const getUserOption = () => new SlashCommandUserOption().setName('owo').setDescription('Testing 123').setRequired(true);
const getRoleOption = () => new SlashCommandRoleOption().setName('owo').setDescription('Testing 123').setRequired(true);
const getMentionableOption = () =>
new SlashCommandMentionableOption().setName('owo').setDescription('Testing 123').setRequired(true);
describe('Application Command toJSON() results', () => {
test('GIVEN a boolean option THEN calling toJSON should return a valid JSON', () => {
expect(getBooleanOption().toJSON()).toEqual<APIApplicationCommandBooleanOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Boolean,
required: true,
});
});
test('GIVEN a channel option THEN calling toJSON should return a valid JSON', () => {
expect(getChannelOption().toJSON()).toEqual<APIApplicationCommandChannelOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Channel,
required: true,
channel_types: [ChannelType.GuildText],
});
});
test('GIVEN a integer option THEN calling toJSON should return a valid JSON', () => {
expect(getIntegerOption().toJSON()).toEqual<APIApplicationCommandIntegerOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Integer,
required: true,
max_value: 10,
min_value: -1,
});
expect(getIntegerOption().setAutocomplete(true).setChoices().toJSON()).toEqual<APIApplicationCommandIntegerOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Integer,
required: true,
max_value: 10,
min_value: -1,
autocomplete: true,
// @ts-expect-error TODO: you *can* send an empty array with autocomplete: true, should correct that in types
choices: [],
});
expect(
getIntegerOption().addChoices({ name: 'uwu', value: 1 }).toJSON(),
).toEqual<APIApplicationCommandIntegerOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Integer,
required: true,
max_value: 10,
min_value: -1,
choices: [{ name: 'uwu', value: 1 }],
});
});
test('GIVEN a mentionable option THEN calling toJSON should return a valid JSON', () => {
expect(getMentionableOption().toJSON()).toEqual<APIApplicationCommandMentionableOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Mentionable,
required: true,
});
});
test('GIVEN a number option THEN calling toJSON should return a valid JSON', () => {
expect(getNumberOption().toJSON()).toEqual<APIApplicationCommandNumberOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Number,
required: true,
max_value: 10,
min_value: -1.23,
});
expect(getNumberOption().setAutocomplete(true).setChoices().toJSON()).toEqual<APIApplicationCommandNumberOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Number,
required: true,
max_value: 10,
min_value: -1.23,
autocomplete: true,
// @ts-expect-error TODO: you *can* send an empty array with autocomplete: true, should correct that in types
choices: [],
});
expect(getNumberOption().addChoices({ name: 'uwu', value: 1 }).toJSON()).toEqual<APIApplicationCommandNumberOption>(
{
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Number,
required: true,
max_value: 10,
min_value: -1.23,
choices: [{ name: 'uwu', value: 1 }],
},
);
});
test('GIVEN a role option THEN calling toJSON should return a valid JSON', () => {
expect(getRoleOption().toJSON()).toEqual<APIApplicationCommandRoleOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.Role,
required: true,
});
});
test('GIVEN a string option THEN calling toJSON should return a valid JSON', () => {
expect(getStringOption().toJSON()).toEqual<APIApplicationCommandStringOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.String,
required: true,
});
expect(getStringOption().setAutocomplete(true).setChoices().toJSON()).toEqual<APIApplicationCommandStringOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.String,
required: true,
autocomplete: true,
// @ts-expect-error TODO: you *can* send an empty array with autocomplete: true, should correct that in types
choices: [],
});
expect(
getStringOption().addChoices({ name: 'uwu', value: '1' }).toJSON(),
).toEqual<APIApplicationCommandStringOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.String,
required: true,
choices: [{ name: 'uwu', value: '1' }],
});
});
test('GIVEN a user option THEN calling toJSON should return a valid JSON', () => {
expect(getUserOption().toJSON()).toEqual<APIApplicationCommandUserOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.User,
required: true,
});
});
});

View File

@@ -0,0 +1,480 @@
import { APIApplicationCommandOptionChoice, ChannelType } from 'discord-api-types/v10';
import {
SlashCommandAssertions,
SlashCommandBooleanOption,
SlashCommandBuilder,
SlashCommandChannelOption,
SlashCommandIntegerOption,
SlashCommandMentionableOption,
SlashCommandNumberOption,
SlashCommandRoleOption,
SlashCommandAttachmentOption,
SlashCommandStringOption,
SlashCommandSubcommandBuilder,
SlashCommandSubcommandGroupBuilder,
SlashCommandUserOption,
} from '../../../src/index';
const largeArray = Array.from({ length: 26 }, () => 1 as unknown as APIApplicationCommandOptionChoice);
const getBuilder = () => new SlashCommandBuilder();
const getNamedBuilder = () => getBuilder().setName('example').setDescription('Example command');
const getStringOption = () => new SlashCommandStringOption().setName('owo').setDescription('Testing 123');
const getIntegerOption = () => new SlashCommandIntegerOption().setName('owo').setDescription('Testing 123');
const getNumberOption = () => new SlashCommandNumberOption().setName('owo').setDescription('Testing 123');
const getBooleanOption = () => new SlashCommandBooleanOption().setName('owo').setDescription('Testing 123');
const getUserOption = () => new SlashCommandUserOption().setName('owo').setDescription('Testing 123');
const getChannelOption = () => new SlashCommandChannelOption().setName('owo').setDescription('Testing 123');
const getRoleOption = () => new SlashCommandRoleOption().setName('owo').setDescription('Testing 123');
const getAttachmentOption = () => new SlashCommandAttachmentOption().setName('owo').setDescription('Testing 123');
const getMentionableOption = () => new SlashCommandMentionableOption().setName('owo').setDescription('Testing 123');
const getSubcommandGroup = () => new SlashCommandSubcommandGroupBuilder().setName('owo').setDescription('Testing 123');
const getSubcommand = () => new SlashCommandSubcommandBuilder().setName('owo').setDescription('Testing 123');
class Collection {
public get [Symbol.toStringTag]() {
return 'Map';
}
}
describe('Slash Commands', () => {
describe('Assertions tests', () => {
test('GIVEN valid name THEN does not throw error', () => {
expect(() => SlashCommandAssertions.validateName('ping')).not.toThrowError();
});
test('GIVEN invalid name THEN throw error', () => {
expect(() => SlashCommandAssertions.validateName(null)).toThrowError();
// Too short of a name
expect(() => SlashCommandAssertions.validateName('')).toThrowError();
// Invalid characters used
expect(() => SlashCommandAssertions.validateName('ABC123$%^&')).toThrowError();
// Too long of a name
expect(() =>
SlashCommandAssertions.validateName('qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm'),
).toThrowError();
});
test('GIVEN valid description THEN does not throw error', () => {
expect(() => SlashCommandAssertions.validateDescription('This is an OwO moment fur sure!~')).not.toThrowError();
});
test('GIVEN invalid description THEN throw error', () => {
expect(() => SlashCommandAssertions.validateDescription(null)).toThrowError();
// Too short of a description
expect(() => SlashCommandAssertions.validateDescription('')).toThrowError();
// Too long of a description
expect(() =>
SlashCommandAssertions.validateDescription(
'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magnam autem libero expedita vitae accusamus nostrum ipsam tempore repudiandae deserunt ipsum facilis, velit fugiat facere accusantium, explicabo corporis aliquam non quos.',
),
).toThrowError();
});
test('GIVEN valid default_permission THEN does not throw error', () => {
expect(() => SlashCommandAssertions.validateDefaultPermission(true)).not.toThrowError();
});
test('GIVEN invalid default_permission THEN throw error', () => {
expect(() => SlashCommandAssertions.validateDefaultPermission(null)).toThrowError();
});
test('GIVEN valid array of options or choices THEN does not throw error', () => {
expect(() => SlashCommandAssertions.validateMaxOptionsLength([])).not.toThrowError();
expect(() => SlashCommandAssertions.validateChoicesLength(25, [])).not.toThrowError();
});
test('GIVEN invalid options or choices THEN throw error', () => {
expect(() => SlashCommandAssertions.validateMaxOptionsLength(null)).toThrowError();
// Given an array that's too big
expect(() => SlashCommandAssertions.validateMaxOptionsLength(largeArray)).toThrowError();
expect(() => SlashCommandAssertions.validateChoicesLength(1, largeArray)).toThrowError();
});
test('GIVEN valid required parameters THEN does not throw error', () => {
expect(() =>
SlashCommandAssertions.validateRequiredParameters(
'owo',
'My fancy command that totally exists, to test assertions',
[],
),
).not.toThrowError();
});
});
describe('SlashCommandBuilder', () => {
describe('Builder with no options', () => {
test('GIVEN empty builder THEN throw error when calling toJSON', () => {
expect(() => getBuilder().toJSON()).toThrowError();
});
test('GIVEN valid builder THEN does not throw error', () => {
expect(() => getBuilder().setName('example').setDescription('Example command').toJSON()).not.toThrowError();
});
});
describe('Builder with simple options', () => {
test('GIVEN valid builder with options THEN does not throw error', () => {
expect(() =>
getBuilder()
.setName('example')
.setDescription('Example command')
.addBooleanOption((boolean) =>
boolean.setName('iscool').setDescription('Are we cool or what?').setRequired(true),
)
.addChannelOption((channel) => channel.setName('iscool').setDescription('Are we cool or what?'))
.addMentionableOption((mentionable) => mentionable.setName('iscool').setDescription('Are we cool or what?'))
.addRoleOption((role) => role.setName('iscool').setDescription('Are we cool or what?'))
.addUserOption((user) => user.setName('iscool').setDescription('Are we cool or what?'))
.addIntegerOption((integer) =>
integer
.setName('iscool')
.setDescription('Are we cool or what?')
.addChoices({ name: 'Very cool', value: 1_000 }),
)
.addNumberOption((number) =>
number
.setName('iscool')
.setDescription('Are we cool or what?')
.addChoices({ name: 'Very cool', value: 1.5 }),
)
.addStringOption((string) =>
string
.setName('iscool')
.setDescription('Are we cool or what?')
.addChoices(
{ name: 'Fancy Pants', value: 'fp_1' },
{ name: 'Fancy Shoes', value: 'fs_1' },
{ name: 'The Whole shebang', value: 'all' },
),
)
.addIntegerOption((integer) =>
integer.setName('iscool').setDescription('Are we cool or what?').setAutocomplete(true),
)
.addNumberOption((number) =>
number.setName('iscool').setDescription('Are we cool or what?').setAutocomplete(true),
)
.addStringOption((string) =>
string.setName('iscool').setDescription('Are we cool or what?').setAutocomplete(true),
)
.toJSON(),
).not.toThrowError();
});
test('GIVEN a builder with invalid autocomplete THEN does throw an error', () => {
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addStringOption(getStringOption().setAutocomplete('not a boolean'))).toThrowError();
});
test('GIVEN a builder with both choices and autocomplete THEN does throw an error', () => {
expect(() =>
getBuilder().addStringOption(
getStringOption().setAutocomplete(true).addChoices({ name: 'Fancy Pants', value: 'fp_1' }),
),
).toThrowError();
expect(() =>
getBuilder().addStringOption(
getStringOption()
.setAutocomplete(true)
.addChoices(
{ name: 'Fancy Pants', value: 'fp_1' },
{ name: 'Fancy Shoes', value: 'fs_1' },
{ name: 'The Whole shebang', value: 'all' },
),
),
).toThrowError();
expect(() =>
getBuilder().addStringOption(
getStringOption().addChoices({ name: 'Fancy Pants', value: 'fp_1' }).setAutocomplete(true),
),
).toThrowError();
expect(() => {
const option = getStringOption();
Reflect.set(option, 'autocomplete', true);
Reflect.set(option, 'choices', [{ name: 'Fancy Pants', value: 'fp_1' }]);
return option.toJSON();
}).toThrowError();
expect(() => {
const option = getNumberOption();
Reflect.set(option, 'autocomplete', true);
Reflect.set(option, 'choices', [{ name: 'Fancy Pants', value: 'fp_1' }]);
return option.toJSON();
}).toThrowError();
expect(() => {
const option = getIntegerOption();
Reflect.set(option, 'autocomplete', true);
Reflect.set(option, 'choices', [{ name: 'Fancy Pants', value: 'fp_1' }]);
return option.toJSON();
}).toThrowError();
});
test('GIVEN a builder with valid channel options and channel_types THEN does not throw an error', () => {
expect(() =>
getBuilder().addChannelOption(getChannelOption().addChannelTypes(ChannelType.GuildText)),
).not.toThrowError();
expect(() => {
getBuilder().addChannelOption(
getChannelOption().addChannelTypes(ChannelType.GuildNews, ChannelType.GuildText),
);
}).not.toThrowError();
});
test('GIVEN a builder with valid channel options and channel_types THEN does throw an error', () => {
expect(() => getBuilder().addChannelOption(getChannelOption().addChannelTypes(100))).toThrowError();
expect(() => getBuilder().addChannelOption(getChannelOption().addChannelTypes(100, 200))).toThrowError();
});
test('GIVEN a builder with invalid number min/max options THEN does throw an error', () => {
// @ts-expect-error
expect(() => getBuilder().addNumberOption(getNumberOption().setMaxValue('test'))).toThrowError();
// @ts-expect-error
expect(() => getBuilder().addIntegerOption(getIntegerOption().setMaxValue('test'))).toThrowError();
// @ts-expect-error
expect(() => getBuilder().addNumberOption(getNumberOption().setMinValue('test'))).toThrowError();
// @ts-expect-error
expect(() => getBuilder().addIntegerOption(getIntegerOption().setMinValue('test'))).toThrowError();
expect(() => getBuilder().addIntegerOption(getIntegerOption().setMinValue(1.5))).toThrowError();
});
test('GIVEN a builder with valid number min/max options THEN does not throw an error', () => {
expect(() => getBuilder().addIntegerOption(getIntegerOption().setMinValue(1))).not.toThrowError();
expect(() => getBuilder().addNumberOption(getNumberOption().setMinValue(1.5))).not.toThrowError();
expect(() => getBuilder().addIntegerOption(getIntegerOption().setMaxValue(1))).not.toThrowError();
expect(() => getBuilder().addNumberOption(getNumberOption().setMaxValue(1.5))).not.toThrowError();
});
test('GIVEN an already built builder THEN does not throw an error', () => {
expect(() => getBuilder().addStringOption(getStringOption())).not.toThrowError();
expect(() => getBuilder().addIntegerOption(getIntegerOption())).not.toThrowError();
expect(() => getBuilder().addNumberOption(getNumberOption())).not.toThrowError();
expect(() => getBuilder().addBooleanOption(getBooleanOption())).not.toThrowError();
expect(() => getBuilder().addUserOption(getUserOption())).not.toThrowError();
expect(() => getBuilder().addChannelOption(getChannelOption())).not.toThrowError();
expect(() => getBuilder().addRoleOption(getRoleOption())).not.toThrowError();
expect(() => getBuilder().addAttachmentOption(getAttachmentOption())).not.toThrowError();
expect(() => getBuilder().addMentionableOption(getMentionableOption())).not.toThrowError();
});
test('GIVEN no valid return for an addOption method THEN throw error', () => {
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addBooleanOption()).toThrowError();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addBooleanOption(getRoleOption())).toThrowError();
});
test('GIVEN invalid name THEN throw error', () => {
expect(() => getBuilder().setName('TEST_COMMAND')).toThrowError();
expect(() => getBuilder().setName('ĂĂĂĂĂĂ')).toThrowError();
});
test('GIVEN valid names THEN does not throw error', () => {
expect(() => getBuilder().setName('hi_there')).not.toThrowError();
// Translation: a_command
expect(() => getBuilder().setName('o_comandă')).not.toThrowError();
// Translation: thx (according to GTranslate)
expect(() => getBuilder().setName('どうも')).not.toThrowError();
});
test('GIVEN invalid returns for builder THEN throw error', () => {
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addBooleanOption(true)).toThrowError();
expect(() => getBuilder().addBooleanOption(null)).toThrowError();
expect(() => getBuilder().addBooleanOption(undefined)).toThrowError();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addBooleanOption(() => SlashCommandStringOption)).toThrowError();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addBooleanOption(() => new Collection())).toThrowError();
});
test('GIVEN valid builder with defaultPermission false THEN does not throw error', () => {
expect(() => getBuilder().setName('foo').setDescription('foo').setDefaultPermission(false)).not.toThrowError();
});
test('GIVEN an option that is autocompletable and has choices, THEN passing nothing to setChoices should not throw an error', () => {
expect(() =>
getBuilder().addStringOption(getStringOption().setAutocomplete(true).setChoices()),
).not.toThrowError();
});
test('GIVEN an option that is autocompletable, THEN setting choices should throw an error', () => {
expect(() =>
getBuilder().addStringOption(
getStringOption().setAutocomplete(true).setChoices({ name: 'owo', value: 'uwu' }),
),
).toThrowError();
});
test('GIVEN an option, THEN setting choices should not throw an error', () => {
expect(() =>
getBuilder().addStringOption(getStringOption().setChoices({ name: 'owo', value: 'uwu' })),
).not.toThrowError();
});
});
describe('Builder with subcommand (group) options', () => {
test('GIVEN builder with subcommand group THEN does not throw error', () => {
expect(() =>
getNamedBuilder().addSubcommandGroup((group) => group.setName('group').setDescription('Group us together!')),
).not.toThrowError();
});
test('GIVEN builder with subcommand THEN does not throw error', () => {
expect(() =>
getNamedBuilder().addSubcommand((subcommand) =>
subcommand.setName('boop').setDescription('Boops a fellow nerd (you)'),
),
).not.toThrowError();
});
test('GIVEN builder with already built subcommand group THEN does not throw error', () => {
expect(() => getNamedBuilder().addSubcommandGroup(getSubcommandGroup())).not.toThrowError();
});
test('GIVEN builder with already built subcommand THEN does not throw error', () => {
expect(() => getNamedBuilder().addSubcommand(getSubcommand())).not.toThrowError();
});
test('GIVEN builder with already built subcommand with options THEN does not throw error', () => {
expect(() =>
getNamedBuilder().addSubcommand(getSubcommand().addBooleanOption(getBooleanOption())),
).not.toThrowError();
});
test('GIVEN builder with a subcommand that tries to add an invalid result THEN throw error', () => {
expect(() =>
// @ts-expect-error Checking if check works JS-side too
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
getNamedBuilder().addSubcommand(getSubcommand()).addInteger(getInteger()),
).toThrowError();
});
test('GIVEN no valid return for an addSubcommand(Group) method THEN throw error', () => {
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addSubcommandGroup()).toThrowError();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addSubcommand()).toThrowError();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addSubcommand(getSubcommandGroup())).toThrowError();
});
});
describe('Subcommand group builder', () => {
test('GIVEN no valid subcommand THEN throw error', () => {
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getSubcommandGroup().addSubcommand()).toThrowError();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getSubcommandGroup().addSubcommand(getSubcommandGroup())).toThrowError();
});
test('GIVEN a valid subcommand THEN does not throw an error', () => {
expect(() =>
getSubcommandGroup()
.addSubcommand((sub) => sub.setName('sub').setDescription('Testing 123'))
.toJSON(),
).not.toThrowError();
});
});
describe('Subcommand builder', () => {
test('GIVEN a valid subcommand with options THEN does not throw error', () => {
expect(() => getSubcommand().addBooleanOption(getBooleanOption()).toJSON()).not.toThrowError();
});
});
describe('Slash command localizations', () => {
const expectedSingleLocale = { 'en-US': 'foobar' };
const expectedMultipleLocales = {
...expectedSingleLocale,
bg: 'test',
};
test('GIVEN valid name localizations THEN does not throw error', () => {
expect(() => getBuilder().setNameLocalization('en-US', 'foobar')).not.toThrowError();
expect(() => getBuilder().setNameLocalizations({ 'en-US': 'foobar' })).not.toThrowError();
});
test('GIVEN valid name localizations THEN does not throw error', () => {
// @ts-expect-error
expect(() => getBuilder().setNameLocalization('en-U', 'foobar')).toThrowError();
// @ts-expect-error
expect(() => getBuilder().setNameLocalizations({ 'en-U': 'foobar' })).toThrowError();
});
test('GIVEN valid name localizations THEN valid data is stored', () => {
expect(getBuilder().setNameLocalization('en-US', 'foobar').name_localizations).toEqual(expectedSingleLocale);
expect(getBuilder().setNameLocalizations({ 'en-US': 'foobar', bg: 'test' }).name_localizations).toEqual(
expectedMultipleLocales,
);
expect(getBuilder().setNameLocalizations(null).name_localizations).toBeNull();
expect(getBuilder().setNameLocalization('en-US', null).name_localizations).toEqual({
'en-US': null,
});
});
test('GIVEN valid description localizations THEN does not throw error', () => {
expect(() => getBuilder().setDescriptionLocalization('en-US', 'foobar')).not.toThrowError();
expect(() => getBuilder().setDescriptionLocalizations({ 'en-US': 'foobar' })).not.toThrowError();
});
test('GIVEN valid description localizations THEN does not throw error', () => {
// @ts-expect-error
expect(() => getBuilder().setDescriptionLocalization('en-U', 'foobar')).toThrowError();
// @ts-expect-error
expect(() => getBuilder().setDescriptionLocalizations({ 'en-U': 'foobar' })).toThrowError();
});
test('GIVEN valid description localizations THEN valid data is stored', () => {
expect(getBuilder().setDescriptionLocalization('en-US', 'foobar').description_localizations).toEqual(
expectedSingleLocale,
);
expect(
getBuilder().setDescriptionLocalizations({ 'en-US': 'foobar', bg: 'test' }).description_localizations,
).toEqual(expectedMultipleLocales);
expect(getBuilder().setDescriptionLocalizations(null).description_localizations).toBeNull();
expect(getBuilder().setDescriptionLocalization('en-US', null).description_localizations).toEqual({
'en-US': null,
});
});
});
});
});

View File

@@ -0,0 +1,98 @@
import { APIModalInteractionResponseCallbackData, ComponentType, TextInputStyle } from 'discord-api-types/v10';
import {
ActionRowBuilder,
ButtonBuilder,
ModalBuilder,
ModalActionRowComponentBuilder,
TextInputBuilder,
} from '../../src';
import {
componentsValidator,
titleValidator,
validateRequiredParameters,
} from '../../src/interactions/modals/Assertions';
const modal = () => new ModalBuilder();
describe('Modals', () => {
describe('Assertion Tests', () => {
test('GIVEN valid title THEN validator does not throw', () => {
expect(() => titleValidator.parse('foobar')).not.toThrowError();
});
test('GIVEN invalid title THEN validator does throw', () => {
expect(() => titleValidator.parse(42)).toThrowError();
});
test('GIVEN valid components THEN validator does not throw', () => {
expect(() => componentsValidator.parse([new ActionRowBuilder(), new ActionRowBuilder()])).not.toThrowError();
});
test('GIVEN invalid components THEN validator does throw', () => {
expect(() => componentsValidator.parse([new ButtonBuilder(), new TextInputBuilder()])).toThrowError();
});
test('GIVEN valid required parameters THEN validator does not throw', () => {
expect(() =>
validateRequiredParameters('123', 'title', [new ActionRowBuilder(), new ActionRowBuilder()]),
).not.toThrowError();
});
test('GIVEN invalid required parameters THEN validator does throw', () => {
expect(() =>
// @ts-expect-error
validateRequiredParameters('123', undefined, [new ActionRowBuilder(), new ButtonBuilder()]),
).toThrowError();
});
});
test('GIVEN valid fields THEN builder does not throw', () => {
expect(() =>
modal().setTitle('test').setCustomId('foobar').setComponents(new ActionRowBuilder()),
).not.toThrowError();
});
test('GIVEN invalid fields THEN builder does throw', () => {
expect(() =>
// @ts-expect-error
modal().setTitle('test').setCustomId('foobar').setComponents([new ActionRowBuilder()]).toJSON(),
).toThrowError();
expect(() => modal().setTitle('test').setCustomId('foobar').toJSON()).toThrowError();
// @ts-expect-error
expect(() => modal().setTitle('test').setCustomId(42).toJSON()).toThrowError();
});
test('GIVEN valid input THEN valid JSON outputs are given', () => {
const modalData: APIModalInteractionResponseCallbackData = {
title: 'title',
custom_id: 'custom id',
components: [
{
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.TextInput,
label: 'label',
style: TextInputStyle.Paragraph,
custom_id: 'custom id',
},
],
},
],
};
expect(new ModalBuilder(modalData).toJSON()).toEqual(modalData);
expect(
modal()
.setTitle(modalData.title)
.setCustomId('custom id')
.setComponents(
new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(
new TextInputBuilder().setCustomId('custom id').setLabel('label').setStyle(TextInputStyle.Paragraph),
),
)
.toJSON(),
).toEqual(modalData);
});
});

View File

@@ -0,0 +1,409 @@
import { EmbedBuilder, embedLength } from '../../src';
const alpha = 'abcdefghijklmnopqrstuvwxyz';
describe('Embed', () => {
describe('Embed getters', () => {
test('GIVEN an embed with specific amount of characters THEN returns amount of characters', () => {
const embed = new EmbedBuilder({
title: alpha,
description: alpha,
fields: [{ name: alpha, value: alpha }],
author: { name: alpha },
footer: { text: alpha },
});
expect(embedLength(embed.data)).toBe(alpha.length * 6);
});
test('GIVEN an embed with zero characters THEN returns amount of characters', () => {
const embed = new EmbedBuilder();
expect(embedLength(embed.data)).toBe(0);
});
});
describe('Embed title', () => {
test('GIVEN an embed with a pre-defined title THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ title: 'foo' });
expect(embed.toJSON()).toStrictEqual({ title: 'foo' });
});
test('GIVEN an embed using Embed#setTitle THEN return valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setTitle('foo');
expect(embed.toJSON()).toStrictEqual({ title: 'foo' });
});
test('GIVEN an embed with a pre-defined title THEN unset title THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ title: 'foo' });
embed.setTitle(null);
expect(embed.toJSON()).toStrictEqual({ title: undefined });
});
test('GIVEN an embed with an invalid title THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.setTitle('a'.repeat(257))).toThrowError();
});
});
describe('Embed description', () => {
test('GIVEN an embed with a pre-defined description THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ description: 'foo' });
expect(embed.toJSON()).toStrictEqual({ description: 'foo' });
});
test('GIVEN an embed using Embed#setDescription THEN return valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setDescription('foo');
expect(embed.toJSON()).toStrictEqual({ description: 'foo' });
});
test('GIVEN an embed with a pre-defined description THEN unset description THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ description: 'foo' });
embed.setDescription(null);
expect(embed.toJSON()).toStrictEqual({ description: undefined });
});
test('GIVEN an embed with an invalid description THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.setDescription('a'.repeat(4097))).toThrowError();
});
});
describe('Embed URL', () => {
test('GIVEN an embed with a pre-defined url THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({ url: 'https://discord.js.org/' });
expect(embed.toJSON()).toStrictEqual({
url: 'https://discord.js.org/',
});
});
test('GIVEN an embed using Embed#setURL THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setURL('https://discord.js.org/');
expect(embed.toJSON()).toStrictEqual({
url: 'https://discord.js.org/',
});
});
test('GIVEN an embed with a pre-defined title THEN unset title THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ url: 'https://discord.js.org' });
embed.setURL(null);
expect(embed.toJSON()).toStrictEqual({ url: undefined });
});
test.each(['owo', 'discord://user'])('GIVEN an embed with an invalid URL THEN throws error', (input) => {
const embed = new EmbedBuilder();
expect(() => embed.setURL(input)).toThrowError();
});
});
describe('Embed Color', () => {
test('GIVEN an embed with a pre-defined color THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({ color: 0xff0000 });
expect(embed.toJSON()).toStrictEqual({ color: 0xff0000 });
});
test('GIVEN an embed using Embed#setColor THEN returns valid toJSON data', () => {
expect(new EmbedBuilder().setColor(0xff0000).toJSON()).toStrictEqual({ color: 0xff0000 });
expect(new EmbedBuilder().setColor([242, 66, 245]).toJSON()).toStrictEqual({ color: 0xf242f5 });
});
test('GIVEN an embed with a pre-defined color THEN unset color THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ color: 0xff0000 });
embed.setColor(null);
expect(embed.toJSON()).toStrictEqual({ color: undefined });
});
test('GIVEN an embed with an invalid color THEN throws error', () => {
const embed = new EmbedBuilder();
// @ts-expect-error
expect(() => embed.setColor('RED')).toThrowError();
// @ts-expect-error
expect(() => embed.setColor([42, 36])).toThrowError();
expect(() => embed.setColor([42, 36, 1000])).toThrowError();
});
});
describe('Embed Timestamp', () => {
const now = new Date();
test('GIVEN an embed with a pre-defined timestamp THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({ timestamp: now.toISOString() });
expect(embed.toJSON()).toStrictEqual({ timestamp: now.toISOString() });
});
test('given an embed using Embed#setTimestamp (with Date) THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setTimestamp(now);
expect(embed.toJSON()).toStrictEqual({ timestamp: now.toISOString() });
});
test('GIVEN an embed using Embed#setTimestamp (with int) THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setTimestamp(now.getTime());
expect(embed.toJSON()).toStrictEqual({ timestamp: now.toISOString() });
});
test('GIVEN an embed using Embed#setTimestamp (default) THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setTimestamp();
expect(embed.toJSON()).toStrictEqual({ timestamp: embed.data.timestamp });
});
test('GIVEN an embed with a pre-defined timestamp THEN unset timestamp THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ timestamp: now.toISOString() });
embed.setTimestamp(null);
expect(embed.toJSON()).toStrictEqual({ timestamp: undefined });
});
});
describe('Embed Thumbnail', () => {
test('GIVEN an embed with a pre-defined thumbnail THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({ thumbnail: { url: 'https://discord.js.org/static/logo.svg' } });
expect(embed.toJSON()).toStrictEqual({
thumbnail: { url: 'https://discord.js.org/static/logo.svg' },
});
});
test('GIVEN an embed using Embed#setThumbnail THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setThumbnail('https://discord.js.org/static/logo.svg');
expect(embed.toJSON()).toStrictEqual({
thumbnail: { url: 'https://discord.js.org/static/logo.svg' },
});
});
test('GIVEN an embed with a pre-defined thumbnail THEN unset thumbnail THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ thumbnail: { url: 'https://discord.js.org/static/logo.svg' } });
embed.setThumbnail(null);
expect(embed.toJSON()).toStrictEqual({ thumbnail: undefined });
});
test('GIVEN an embed with an invalid thumbnail THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.setThumbnail('owo')).toThrowError();
});
});
describe('Embed Image', () => {
test('GIVEN an embed with a pre-defined image THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({ image: { url: 'https://discord.js.org/static/logo.svg' } });
expect(embed.toJSON()).toStrictEqual({
image: { url: 'https://discord.js.org/static/logo.svg' },
});
});
test('GIVEN an embed using Embed#setImage THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setImage('https://discord.js.org/static/logo.svg');
expect(embed.toJSON()).toStrictEqual({
image: { url: 'https://discord.js.org/static/logo.svg' },
});
});
test('GIVEN an embed with a pre-defined image THEN unset image THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ image: { url: 'https://discord.js/org/static/logo.svg' } });
embed.setImage(null);
expect(embed.toJSON()).toStrictEqual({ image: undefined });
});
test('GIVEN an embed with an invalid image THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.setImage('owo')).toThrowError();
});
});
describe('Embed Author', () => {
test('GIVEN an embed with a pre-defined author THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({
author: { name: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg', url: 'https://discord.js.org' },
});
expect(embed.toJSON()).toStrictEqual({
author: { name: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg', url: 'https://discord.js.org' },
});
});
test('GIVEN an embed using Embed#setAuthor THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setAuthor({
name: 'Wumpus',
iconURL: 'https://discord.js.org/static/logo.svg',
url: 'https://discord.js.org',
});
expect(embed.toJSON()).toStrictEqual({
author: { name: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg', url: 'https://discord.js.org' },
});
});
test('GIVEN an embed with a pre-defined author THEN unset author THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({
author: { name: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg', url: 'https://discord.js.org' },
});
embed.setAuthor(null);
expect(embed.toJSON()).toStrictEqual({ author: undefined });
});
test('GIVEN an embed with an invalid author name THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.setAuthor({ name: 'a'.repeat(257) })).toThrowError();
});
});
describe('Embed Footer', () => {
test('GIVEN an embed with a pre-defined footer THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({
footer: { text: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg' },
});
expect(embed.toJSON()).toStrictEqual({
footer: { text: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg' },
});
});
test('GIVEN an embed using Embed#setAuthor THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setFooter({ text: 'Wumpus', iconURL: 'https://discord.js.org/static/logo.svg' });
expect(embed.toJSON()).toStrictEqual({
footer: { text: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg' },
});
});
test('GIVEN an embed with a pre-defined footer THEN unset footer THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({
footer: { text: 'Wumpus', icon_url: 'https://discord.js.org/static/logo.svg' },
});
embed.setFooter(null);
expect(embed.toJSON()).toStrictEqual({ footer: undefined });
});
test('GIVEN an embed with invalid footer text THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.setFooter({ text: 'a'.repeat(2049) })).toThrowError();
});
});
describe('Embed Fields', () => {
test('GIVEN an embed with a pre-defined field THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder({
fields: [{ name: 'foo', value: 'bar' }],
});
expect(embed.toJSON()).toStrictEqual({
fields: [{ name: 'foo', value: 'bar' }],
});
});
test('GIVEN an embed using Embed#addFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.addFields({ name: 'foo', value: 'bar' });
expect(embed.toJSON()).toStrictEqual({
fields: [{ name: 'foo', value: 'bar', inline: undefined }],
});
});
test('GIVEN an embed using Embed#spliceFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.addFields({ name: 'foo', value: 'bar' }, { name: 'foo', value: 'baz' });
expect(embed.spliceFields(0, 1).toJSON()).toStrictEqual({
fields: [{ name: 'foo', value: 'baz', inline: undefined }],
});
});
test('GIVEN an embed using Embed#spliceFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.addFields(...Array.from({ length: 23 }, () => ({ name: 'foo', value: 'bar' })));
expect(() =>
embed.spliceFields(0, 3, ...Array.from({ length: 5 }, () => ({ name: 'foo', value: 'bar' }))),
).not.toThrowError();
});
test('GIVEN an embed using Embed#spliceFields that adds additional fields resulting in fields > 25 THEN throws error', () => {
const embed = new EmbedBuilder();
embed.addFields(...Array.from({ length: 23 }, () => ({ name: 'foo', value: 'bar' })));
expect(() =>
embed.spliceFields(0, 3, ...Array.from({ length: 8 }, () => ({ name: 'foo', value: 'bar' }))),
).toThrowError();
});
test('GIVEN an embed using Embed#setFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
expect(() =>
embed.setFields(...Array.from({ length: 25 }, () => ({ name: 'foo', value: 'bar' }))),
).not.toThrowError();
});
test('GIVEN an embed using Embed#setFields that sets more than 25 fields THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() =>
embed.setFields(...Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' }))),
).toThrowError();
});
describe('GIVEN invalid field amount THEN throws error', () => {
test('', () => {
const embed = new EmbedBuilder();
expect(() =>
embed.addFields(...Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' }))),
).toThrowError();
});
});
describe('GIVEN invalid field name THEN throws error', () => {
test('', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'bar' })).toThrowError();
});
});
describe('GIVEN invalid field name length THEN throws error', () => {
test('', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: 'a'.repeat(257), value: 'bar' })).toThrowError();
});
});
describe('GIVEN invalid field value length THEN throws error', () => {
test('', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'a'.repeat(1025) })).toThrowError();
});
});
});
});

View File

@@ -0,0 +1,199 @@
import {
blockQuote,
bold,
channelMention,
codeBlock,
Faces,
formatEmoji,
hideLinkEmbed,
hyperlink,
inlineCode,
italic,
quote,
roleMention,
spoiler,
strikethrough,
time,
TimestampStyles,
underscore,
userMention,
} from '../../src';
describe('Message formatters', () => {
describe('codeBlock', () => {
test('GIVEN "discord.js" with no language THEN returns "```\\ndiscord.js```"', () => {
expect<'```\ndiscord.js```'>(codeBlock('discord.js')).toBe('```\ndiscord.js```');
});
test('GIVEN "discord.js" with "js" as language THEN returns "```js\\ndiscord.js```"', () => {
expect<'```js\ndiscord.js```'>(codeBlock('js', 'discord.js')).toBe('```js\ndiscord.js```');
});
});
describe('inlineCode', () => {
test('GIVEN "discord.js" THEN returns "`discord.js`"', () => {
expect<'`discord.js`'>(inlineCode('discord.js')).toBe('`discord.js`');
});
});
describe('italic', () => {
test('GIVEN "discord.js" THEN returns "_discord.js_"', () => {
expect<'_discord.js_'>(italic('discord.js')).toBe('_discord.js_');
});
});
describe('bold', () => {
test('GIVEN "discord.js" THEN returns "**discord.js**"', () => {
expect<'**discord.js**'>(bold('discord.js')).toBe('**discord.js**');
});
});
describe('underscore', () => {
test('GIVEN "discord.js" THEN returns "__discord.js__"', () => {
expect<'__discord.js__'>(underscore('discord.js')).toBe('__discord.js__');
});
});
describe('strikethrough', () => {
test('GIVEN "discord.js" THEN returns "~~discord.js~~"', () => {
expect<'~~discord.js~~'>(strikethrough('discord.js')).toBe('~~discord.js~~');
});
});
describe('quote', () => {
test('GIVEN "discord.js" THEN returns "> discord.js"', () => {
expect<'> discord.js'>(quote('discord.js')).toBe('> discord.js');
});
});
describe('blockQuote', () => {
test('GIVEN "discord.js" THEN returns ">>> discord.js"', () => {
expect<'>>> discord.js'>(blockQuote('discord.js')).toBe('>>> discord.js');
});
});
describe('hideLinkEmbed', () => {
test('GIVEN "https://discord.js.org" THEN returns "<https://discord.js.org>"', () => {
expect<'<https://discord.js.org>'>(hideLinkEmbed('https://discord.js.org')).toBe('<https://discord.js.org>');
});
test('GIVEN new URL("https://discord.js.org") THEN returns "<https://discord.js.org>"', () => {
expect<`<${string}>`>(hideLinkEmbed(new URL('https://discord.js.org/'))).toBe('<https://discord.js.org/>');
});
});
describe('hyperlink', () => {
test('GIVEN content and string URL THEN returns "[content](url)"', () => {
expect<'[discord.js](https://discord.js.org)'>(hyperlink('discord.js', 'https://discord.js.org')).toBe(
'[discord.js](https://discord.js.org)',
);
});
test('GIVEN content and URL THEN returns "[content](url)"', () => {
expect<`[discord.js](${string})`>(hyperlink('discord.js', new URL('https://discord.js.org'))).toBe(
'[discord.js](https://discord.js.org/)',
);
});
test('GIVEN content, string URL, and title THEN returns "[content](url "title")"', () => {
expect<'[discord.js](https://discord.js.org "Official Documentation")'>(
hyperlink('discord.js', 'https://discord.js.org', 'Official Documentation'),
).toBe('[discord.js](https://discord.js.org "Official Documentation")');
});
test('GIVEN content, URL, and title THEN returns "[content](url "title")"', () => {
expect<`[discord.js](${string} "Official Documentation")`>(
hyperlink('discord.js', new URL('https://discord.js.org'), 'Official Documentation'),
).toBe('[discord.js](https://discord.js.org/ "Official Documentation")');
});
});
describe('spoiler', () => {
test('GIVEN "discord.js" THEN returns "||discord.js||"', () => {
expect<'||discord.js||'>(spoiler('discord.js')).toBe('||discord.js||');
});
});
describe('Mentions', () => {
describe('userMention', () => {
test('GIVEN userId THEN returns "<@[userId]>"', () => {
expect(userMention('139836912335716352')).toBe('<@139836912335716352>');
});
});
describe('channelMention', () => {
test('GIVEN channelId THEN returns "<#[channelId]>"', () => {
expect(channelMention('829924760309334087')).toBe('<#829924760309334087>');
});
});
describe('roleMention', () => {
test('GIVEN roleId THEN returns "<&[roleId]>"', () => {
expect(roleMention('815434166602170409')).toBe('<@&815434166602170409>');
});
});
});
describe('formatEmoji', () => {
test('GIVEN static emojiId THEN returns "<:_:${emojiId}>"', () => {
expect<`<:_:851461487498493952>`>(formatEmoji('851461487498493952')).toBe('<:_:851461487498493952>');
});
test('GIVEN static emojiId WITH animated explicitly false THEN returns "<:_:[emojiId]>"', () => {
expect<`<:_:851461487498493952>`>(formatEmoji('851461487498493952', false)).toBe('<:_:851461487498493952>');
});
test('GIVEN animated emojiId THEN returns "<a:_:${emojiId}>"', () => {
expect<`<a:_:827220205352255549>`>(formatEmoji('827220205352255549', true)).toBe('<a:_:827220205352255549>');
});
});
describe('time', () => {
test('GIVEN no arguments THEN returns "<t:${bigint}>"', () => {
jest.useFakeTimers('modern');
jest.setSystemTime(1566424897579);
expect<`<t:${bigint}>`>(time()).toBe('<t:1566424897>');
jest.useRealTimers();
});
test('GIVEN a date THEN returns "<t:${bigint}>"', () => {
expect<`<t:${bigint}>`>(time(new Date(1867424897579))).toBe('<t:1867424897>');
});
test('GIVEN a date and a style from string THEN returns "<t:${bigint}:${style}>"', () => {
expect<`<t:${bigint}:d>`>(time(new Date(1867424897579), 'd')).toBe('<t:1867424897:d>');
});
test('GIVEN a date and a format from enum THEN returns "<t:${bigint}:${style}>"', () => {
expect<`<t:${bigint}:R>`>(time(new Date(1867424897579), TimestampStyles.RelativeTime)).toBe('<t:1867424897:R>');
});
test('GIVEN a date THEN returns "<t:${time}>"', () => {
expect<'<t:1867424897>'>(time(1867424897)).toBe('<t:1867424897>');
});
test('GIVEN a date and a style from string THEN returns "<t:${time}:${style}>"', () => {
expect<'<t:1867424897:d>'>(time(1867424897, 'd')).toBe('<t:1867424897:d>');
});
test('GIVEN a date and a format from enum THEN returns "<t:${time}:${style}>"', () => {
expect<'<t:1867424897:R>'>(time(1867424897, TimestampStyles.RelativeTime)).toBe('<t:1867424897:R>');
});
});
describe('Faces', () => {
test('GIVEN Faces.Shrug THEN returns "¯\\_(ツ)\\_/¯"', () => {
expect<'¯\\_(ツ)\\_/¯'>(Faces.Shrug).toBe('¯\\_(ツ)\\_/¯');
});
test('GIVEN Faces.Tableflip THEN returns "(╯°□°)╯︵ ┻━┻"', () => {
expect<'(╯°□°)╯︵ ┻━┻'>(Faces.Tableflip).toBe('(╯°□°)╯︵ ┻━┻');
});
test('GIVEN Faces.Unflip THEN returns "┬─┬ ( ゜-゜ノ)"', () => {
expect<'┬─┬ ( ゜-゜ノ)'>(Faces.Unflip).toBe('┬─┬ ( ゜-゜ノ)');
});
});
});

View File

@@ -0,0 +1,18 @@
/**
* @type {import('@babel/core').TransformOptions}
*/
module.exports = {
parserOpts: { strictMode: true },
sourceMaps: 'inline',
presets: [
[
'@babel/preset-env',
{
targets: { node: 'current' },
modules: 'commonjs',
},
],
'@babel/preset-typescript',
],
plugins: ['babel-plugin-transform-typescript-metadata', ['@babel/plugin-proposal-decorators', { legacy: true }]],
};

View File

@@ -0,0 +1,62 @@
[changelog]
header = """
# Changelog
All notable changes to this project will be documented in this file.\n
"""
body = """
{% if version %}\
# [{{ version | trim_start_matches(pat="v") }}]\
{% if previous %}\
{% if previous.version %}\
(https://github.com/discordjs/discord.js/compare/{{ previous.version }}...{{ version }})\
{% else %}
(https://github.com/discordjs/discord.js/tree/{{ version }})\
{% endif %}\
{% endif %} \
- ({{ timestamp | date(format="%Y-%m-%d") }})
{% else %}\
# [unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
## {{ group | upper_first }}
{% for commit in commits %}
- {% if commit.breaking %}\
[**breaking**] \
{% endif %}\
{% if commit.scope %}\
**{{commit.scope}}:** \
{% endif %}\
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}](https://github.com/discordjs/discord.js/commit/{{ commit.id }}))\
{% endfor %}
{% endfor %}\n
"""
trim = true
footer = ""
[git]
conventional_commits = true
filter_unconventional = true
commit_parsers = [
{ message = "^feat", group = "Features"},
{ message = "^fix", group = "Bug Fixes"},
{ message = "^docs", group = "Documentation"},
{ message = "^perf", group = "Performance"},
{ message = "^refactor", group = "Refactor"},
{ message = "^typings", group = "Typings"},
{ message = "^types", group = "Typings"},
{ message = ".*deprecated", body = ".*deprecated", group = "Deprecation"},
{ message = "^revert", skip = true},
{ message = "^style", group = "Styling"},
{ message = "^test", group = "Testing"},
{ message = "^chore", skip = true},
{ message = "^ci", skip = true},
{ message = "^build", skip = true},
{ body = ".*security", group = "Security"},
]
filter_commits = true
tag_pattern = "@discordjs\\/builders@.*"
skip_tags = "v[0-9]*|11|12"
ignore_tags = ""
topo_order = false
sort_commits = "newest"

View File

@@ -0,0 +1,10 @@
coverage:
status:
project:
default:
target: 70%
threshold: 5%
patch:
default:
target: 70%
threshold: 5%

View File

@@ -0,0 +1 @@
## [View the documentation here.](https://discord.js.org/#/docs/builders)

View File

@@ -0,0 +1,99 @@
# Slash Command Builders
## Ping command
```ts
import { SlashCommandBuilder } from '@discordjs/builders';
// Create a slash command builder
const pingCommand = new SlashCommandBuilder().setName('ping').setDescription('Check if this interaction is responsive');
// Get the raw data that can be sent to Discord
const rawData = pingCommand.toJSON();
```
## Arguments
```ts
import { SlashCommandBuilder } from '@discordjs/builders';
// Creates a boop command
const boopCommand = new SlashCommandBuilder()
.setName('boop')
.setDescription('Boops the specified user, as many times as you want')
.addUserOption((option) => option.setName('user').setDescription('The user to boop').setRequired(true))
// Adds an integer option
.addIntegerOption((option) =>
option.setName('boop_amount').setDescription('How many times should the user be booped (defaults to 1)'),
)
// Supports choices too!
.addIntegerOption((option) =>
option
.setName('boop_reminder')
.setDescription('How often should we remind you to boop the user')
.addChoices({ name: 'Every day', value: 1 }, { name: 'Weekly', value: 7 }),
);
// Get the final raw data that can be sent to Discord
const rawData = boopCommand.toJSON();
```
## Subcommands and subcommand groups
```ts
import { SlashCommandBuilder } from '@discordjs/builders';
const pointsCommand = new SlashCommandBuilder()
.setName('points')
.setDescription('Lists or manages user points')
// Add a manage group
.addSubcommandGroup((group) =>
group
.setName('manage')
.setDescription('Shows or manages points in the server')
.addSubcommand((subcommand) =>
subcommand
.setName('user_points')
.setDescription("Alters a user's points")
.addUserOption((option) =>
option.setName('user').setDescription('The user whose points to alter').setRequired(true),
)
.addStringOption((option) =>
option
.setName('action')
.setDescription('What action should be taken with the users points?')
.addChoices(
{ name: 'Add points', value: 'add' },
{ name: 'Remove points', value: 'remove' },
{ name: 'Reset points', value: 'reset' },
)
.setRequired(true),
)
.addIntegerOption((option) => option.setName('points').setDescription('Points to add or remove')),
),
)
// Add an information group
.addSubcommandGroup((group) =>
group
.setName('info')
.setDescription('Shows information about points in the guild')
.addSubcommand((subcommand) =>
subcommand.setName('total').setDescription('Tells you the total amount of points given in the guild'),
)
.addSubcommand((subcommand) =>
subcommand
.setName('user')
.setDescription("Lists a user's points")
.addUserOption((option) =>
option.setName('user').setDescription('The user whose points to list').setRequired(true),
),
),
);
// Get the final raw data that can be sent to Discord
const rawData = pointsCommand.toJSON();
```

View File

@@ -0,0 +1,19 @@
/**
* @type {import('@jest/types').Config.InitialOptions}
*/
module.exports = {
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
testEnvironment: 'node',
collectCoverage: true,
collectCoverageFrom: ['src/**/*.ts'],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'clover'],
coverageThreshold: {
global: {
branches: 70,
lines: 70,
statements: 70,
},
},
coveragePathIgnorePatterns: ['src/index.ts'],
};

View File

@@ -0,0 +1,89 @@
{
"name": "@discordjs/builders",
"version": "0.14.0-dev",
"description": "A set of builders that you can use when creating your bot",
"scripts": {
"build": "tsup",
"test": "jest --pass-with-no-tests",
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
"docs": "typedoc --json docs/typedoc-out.json src/index.ts && node scripts/docs.mjs",
"prepublishOnly": "yarn build && yarn lint && yarn test",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/builders/*'"
},
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"directories": {
"lib": "src",
"test": "__tests__"
},
"files": [
"dist"
],
"contributors": [
"Vlad Frangu <kingdgrizzle@gmail.com>",
"Crawl <icrawltogo@gmail.com>",
"Amish Shah <amishshah.2k@gmail.com>",
"SpaceEEC <spaceeec@yahoo.com>",
"Antonio Roman <kyradiscord@gmail.com>"
],
"license": "Apache-2.0",
"keywords": [
"discord",
"api",
"bot",
"client",
"node",
"discordapp",
"discordjs"
],
"repository": {
"type": "git",
"url": "https://github.com/discordjs/discord.js.git"
},
"bugs": {
"url": "https://github.com/discordjs/discord.js/issues"
},
"homepage": "https://discord.js.org",
"dependencies": {
"@sapphire/shapeshift": "^2.0.0",
"@sindresorhus/is": "^4.6.0",
"discord-api-types": "^0.31.1",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.1",
"tslib": "^2.3.1"
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@babel/plugin-proposal-decorators": "^7.17.9",
"@babel/preset-env": "^7.16.11",
"@babel/preset-typescript": "^7.16.7",
"@discordjs/ts-docgen": "^0.4.1",
"@types/jest": "^27.4.1",
"@types/node": "^16.11.27",
"@typescript-eslint/eslint-plugin": "^5.19.0",
"@typescript-eslint/parser": "^5.19.0",
"babel-plugin-transform-typescript-metadata": "^0.3.2",
"eslint": "^8.13.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"jest": "^27.5.1",
"prettier": "^2.6.2",
"tsup": "^5.12.5",
"typedoc": "^0.22.15",
"typescript": "^4.6.3"
},
"engines": {
"node": ">=16.9.0"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,7 @@
import { runGenerator } from '@discordjs/ts-docgen';
runGenerator({
existingOutput: 'docs/typedoc-out.json',
custom: 'docs/index.yml',
output: 'docs/docs.json',
});

View File

@@ -0,0 +1,62 @@
import {
type APIActionRowComponent,
ComponentType,
APIMessageActionRowComponent,
APIModalActionRowComponent,
APIActionRowComponentTypes,
} from 'discord-api-types/v10';
import { ComponentBuilder } from './Component';
import { createComponentBuilder } from './Components';
import type { ButtonBuilder, SelectMenuBuilder, TextInputBuilder } from '..';
export type MessageComponentBuilder =
| MessageActionRowComponentBuilder
| ActionRowBuilder<MessageActionRowComponentBuilder>;
export type ModalComponentBuilder = ModalActionRowComponentBuilder | ActionRowBuilder<ModalActionRowComponentBuilder>;
export type MessageActionRowComponentBuilder = ButtonBuilder | SelectMenuBuilder;
export type ModalActionRowComponentBuilder = TextInputBuilder;
export type AnyComponentBuilder = MessageActionRowComponentBuilder | ModalActionRowComponentBuilder;
/**
* Represents an action row component
*/
export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBuilder<
APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>
> {
/**
* The components within this action row
*/
public readonly components: T[];
public constructor({ components, ...data }: Partial<APIActionRowComponent<APIActionRowComponentTypes>> = {}) {
super({ type: ComponentType.ActionRow, ...data });
this.components = (components?.map((c) => createComponentBuilder(c)) ?? []) as T[];
}
/**
* Adds components to this action row.
* @param components The components to add to this action row.
* @returns
*/
public addComponents(...components: T[]) {
this.components.push(...components);
return this;
}
/**
* Sets the components in this action row
* @param components The components to set this row to
*/
public setComponents(...components: T[]) {
this.components.splice(0, this.components.length, ...components);
return this;
}
public toJSON(): APIActionRowComponent<ReturnType<T['toJSON']>> {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
components: this.components.map((component) => component.toJSON()),
} as APIActionRowComponent<ReturnType<T['toJSON']>>;
}
}

View File

@@ -0,0 +1,76 @@
import { s } from '@sapphire/shapeshift';
import { APIMessageComponentEmoji, ButtonStyle } from 'discord-api-types/v10';
import type { SelectMenuOptionBuilder } from './selectMenu/SelectMenuOption';
import { UnsafeSelectMenuOptionBuilder } from './selectMenu/UnsafeSelectMenuOption';
export const customIdValidator = s.string.lengthGe(1).lengthLe(100);
export const emojiValidator = s.object({
id: s.string,
name: s.string,
animated: s.boolean,
}).partial.strict;
export const disabledValidator = s.boolean;
export const buttonLabelValidator = s.string.lengthGe(1).lengthLe(80);
export const buttonStyleValidator = s.nativeEnum(ButtonStyle);
export const placeholderValidator = s.string.lengthLe(150);
export const minMaxValidator = s.number.int.ge(0).le(25);
export const labelValueDescriptionValidator = s.string.lengthGe(1).lengthLe(100);
export const optionValidator = s.union(
s.object({
label: labelValueDescriptionValidator,
value: labelValueDescriptionValidator,
description: labelValueDescriptionValidator.optional,
emoji: emojiValidator.optional,
default: s.boolean.optional,
}),
s.instance(UnsafeSelectMenuOptionBuilder),
);
export const optionsValidator = optionValidator.array.lengthGe(0);
export const optionsLengthValidator = s.number.int.ge(0).le(25);
export function validateRequiredSelectMenuParameters(options: SelectMenuOptionBuilder[], customId?: string) {
customIdValidator.parse(customId);
optionsValidator.parse(options);
}
export const labelValueValidator = s.string.lengthGe(1).lengthLe(100);
export const defaultValidator = s.boolean;
export function validateRequiredSelectMenuOptionParameters(label?: string, value?: string) {
labelValueValidator.parse(label);
labelValueValidator.parse(value);
}
export const urlValidator = s.string.url({
allowedProtocols: ['http:', 'https:', 'discord:'],
});
export function validateRequiredButtonParameters(
style?: ButtonStyle,
label?: string,
emoji?: APIMessageComponentEmoji,
customId?: string,
url?: string,
) {
if (url && customId) {
throw new RangeError('URL and custom id are mutually exclusive');
}
if (!label && !emoji) {
throw new RangeError('Buttons must have a label and/or an emoji');
}
if (style === ButtonStyle.Link) {
if (!url) {
throw new RangeError('Link buttons must have a url');
}
} else if (url) {
throw new RangeError('Non-link buttons cannot have a url');
}
}

View File

@@ -0,0 +1,28 @@
import type {
APIActionRowComponent,
APIActionRowComponentTypes,
APIBaseComponent,
ComponentType,
} from 'discord-api-types/v10';
import type { JSONEncodable } from '../util/jsonEncodable';
export type AnyAPIActionRowComponent = APIActionRowComponentTypes | APIActionRowComponent<APIActionRowComponentTypes>;
/**
* Represents a discord component
*/
export abstract class ComponentBuilder<
DataType extends Partial<APIBaseComponent<ComponentType>> = APIBaseComponent<ComponentType>,
> implements JSONEncodable<AnyAPIActionRowComponent>
{
/**
* The API data associated with this component
*/
public readonly data: Partial<DataType>;
public abstract toJSON(): AnyAPIActionRowComponent;
public constructor(data: Partial<DataType>) {
this.data = data;
}
}

View File

@@ -0,0 +1,41 @@
import { APIMessageComponent, APIModalComponent, ComponentType } from 'discord-api-types/v10';
import type { AnyComponentBuilder, MessageComponentBuilder, ModalComponentBuilder } from './ActionRow';
import { ActionRowBuilder, ButtonBuilder, ComponentBuilder, SelectMenuBuilder, TextInputBuilder } from '../index';
export interface MappedComponentTypes {
[ComponentType.ActionRow]: ActionRowBuilder<AnyComponentBuilder>;
[ComponentType.Button]: ButtonBuilder;
[ComponentType.SelectMenu]: SelectMenuBuilder;
[ComponentType.TextInput]: TextInputBuilder;
}
/**
* Factory for creating components from API data
* @param data The api data to transform to a component class
*/
export function createComponentBuilder<T extends keyof MappedComponentTypes>(
data: (APIMessageComponent | APIModalComponent) & { type: T },
): MappedComponentTypes[T];
export function createComponentBuilder<C extends MessageComponentBuilder | ModalComponentBuilder>(data: C): C;
export function createComponentBuilder(
data: APIMessageComponent | APIModalComponent | MessageComponentBuilder,
): ComponentBuilder {
if (data instanceof ComponentBuilder) {
return data;
}
switch (data.type) {
case ComponentType.ActionRow:
return new ActionRowBuilder(data);
case ComponentType.Button:
return new ButtonBuilder(data);
case ComponentType.SelectMenu:
return new SelectMenuBuilder(data);
case ComponentType.TextInput:
return new TextInputBuilder(data);
default:
// @ts-expect-error
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Cannot properly serialize component type: ${data.type}`);
}
}

View File

@@ -0,0 +1,57 @@
import type {
ButtonStyle,
APIMessageComponentEmoji,
APIButtonComponent,
APIButtonComponentWithCustomId,
APIButtonComponentWithURL,
} from 'discord-api-types/v10';
import { UnsafeButtonBuilder } from './UnsafeButton';
import {
buttonLabelValidator,
buttonStyleValidator,
customIdValidator,
disabledValidator,
emojiValidator,
urlValidator,
validateRequiredButtonParameters,
} from '../Assertions';
/**
* Represents a validated button component
*/
export class ButtonBuilder extends UnsafeButtonBuilder {
public override setStyle(style: ButtonStyle) {
return super.setStyle(buttonStyleValidator.parse(style));
}
public override setURL(url: string) {
return super.setURL(urlValidator.parse(url));
}
public override setCustomId(customId: string) {
return super.setCustomId(customIdValidator.parse(customId));
}
public override setEmoji(emoji: APIMessageComponentEmoji) {
return super.setEmoji(emojiValidator.parse(emoji));
}
public override setDisabled(disabled = true) {
return super.setDisabled(disabledValidator.parse(disabled));
}
public override setLabel(label: string) {
return super.setLabel(buttonLabelValidator.parse(label));
}
public override toJSON(): APIButtonComponent {
validateRequiredButtonParameters(
this.data.style,
this.data.label,
this.data.emoji,
(this.data as APIButtonComponentWithCustomId).custom_id,
(this.data as APIButtonComponentWithURL).url,
);
return super.toJSON();
}
}

View File

@@ -0,0 +1,79 @@
import {
ComponentType,
ButtonStyle,
type APIMessageComponentEmoji,
type APIButtonComponent,
type APIButtonComponentWithURL,
type APIButtonComponentWithCustomId,
} from 'discord-api-types/v10';
import { ComponentBuilder } from '../Component';
/**
* Represents a non-validated button component
*/
export class UnsafeButtonBuilder extends ComponentBuilder<APIButtonComponent> {
public constructor(data?: Partial<APIButtonComponent>) {
super({ type: ComponentType.Button, ...data });
}
/**
* Sets the style of this button
* @param style The style of the button
*/
public setStyle(style: ButtonStyle) {
this.data.style = style;
return this;
}
/**
* Sets the URL for this button
* @param url The URL to open when this button is clicked
*/
public setURL(url: string) {
(this.data as APIButtonComponentWithURL).url = url;
return this;
}
/**
* Sets the custom Id for this button
* @param customId The custom id to use for this button
*/
public setCustomId(customId: string) {
(this.data as APIButtonComponentWithCustomId).custom_id = customId;
return this;
}
/**
* Sets the emoji to display on this button
* @param emoji The emoji to display on this button
*/
public setEmoji(emoji: APIMessageComponentEmoji) {
this.data.emoji = emoji;
return this;
}
/**
* Sets whether this button is disable or not
* @param disabled Whether or not to disable this button or not
*/
public setDisabled(disabled = true) {
this.data.disabled = disabled;
return this;
}
/**
* Sets the label for this button
* @param label The label to display on this button
*/
public setLabel(label: string) {
this.data.label = label;
return this;
}
public toJSON(): APIButtonComponent {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
} as APIButtonComponent;
}
}

View File

@@ -0,0 +1,68 @@
import type { APISelectMenuComponent, APISelectMenuOption } from 'discord-api-types/v10';
import { UnsafeSelectMenuBuilder } from './UnsafeSelectMenu';
import { UnsafeSelectMenuOptionBuilder } from './UnsafeSelectMenuOption';
import {
customIdValidator,
disabledValidator,
minMaxValidator,
optionsLengthValidator,
optionValidator,
placeholderValidator,
validateRequiredSelectMenuParameters,
} from '../Assertions';
/**
* Represents a validated select menu component
*/
export class SelectMenuBuilder extends UnsafeSelectMenuBuilder {
public override setPlaceholder(placeholder: string) {
return super.setPlaceholder(placeholderValidator.parse(placeholder));
}
public override setMinValues(minValues: number) {
return super.setMinValues(minMaxValidator.parse(minValues));
}
public override setMaxValues(maxValues: number) {
return super.setMaxValues(minMaxValidator.parse(maxValues));
}
public override setCustomId(customId: string) {
return super.setCustomId(customIdValidator.parse(customId));
}
public override setDisabled(disabled = true) {
return super.setDisabled(disabledValidator.parse(disabled));
}
public override addOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
optionsLengthValidator.parse(this.options.length + options.length);
this.options.push(
...options.map((option) =>
option instanceof UnsafeSelectMenuOptionBuilder
? option
: new UnsafeSelectMenuOptionBuilder(optionValidator.parse(option) as APISelectMenuOption),
),
);
return this;
}
public override setOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
optionsLengthValidator.parse(options.length);
this.options.splice(
0,
this.options.length,
...options.map((option) =>
option instanceof UnsafeSelectMenuOptionBuilder
? option
: new UnsafeSelectMenuOptionBuilder(optionValidator.parse(option) as APISelectMenuOption),
),
);
return this;
}
public override toJSON(): APISelectMenuComponent {
validateRequiredSelectMenuParameters(this.options, this.data.custom_id);
return super.toJSON();
}
}

View File

@@ -0,0 +1,30 @@
import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v10';
import { UnsafeSelectMenuOptionBuilder } from './UnsafeSelectMenuOption';
import {
defaultValidator,
emojiValidator,
labelValueValidator,
validateRequiredSelectMenuOptionParameters,
} from '../Assertions';
/**
* Represents a validated option within a select menu component
*/
export class SelectMenuOptionBuilder extends UnsafeSelectMenuOptionBuilder {
public override setDescription(description: string) {
return super.setDescription(labelValueValidator.parse(description));
}
public override setDefault(isDefault = true) {
return super.setDefault(defaultValidator.parse(isDefault));
}
public override setEmoji(emoji: APIMessageComponentEmoji) {
return super.setEmoji(emojiValidator.parse(emoji));
}
public override toJSON(): APISelectMenuOption {
validateRequiredSelectMenuOptionParameters(this.data.label, this.data.value);
return super.toJSON();
}
}

View File

@@ -0,0 +1,101 @@
import { APISelectMenuOption, ComponentType, type APISelectMenuComponent } from 'discord-api-types/v10';
import { UnsafeSelectMenuOptionBuilder } from './UnsafeSelectMenuOption';
import { ComponentBuilder } from '../Component';
/**
* Represents a non-validated select menu component
*/
export class UnsafeSelectMenuBuilder extends ComponentBuilder<APISelectMenuComponent> {
/**
* The options within this select menu
*/
public readonly options: UnsafeSelectMenuOptionBuilder[];
public constructor(data?: Partial<APISelectMenuComponent>) {
const { options, ...initData } = data ?? {};
super({ type: ComponentType.SelectMenu, ...initData });
this.options = options?.map((o) => new UnsafeSelectMenuOptionBuilder(o)) ?? [];
}
/**
* Sets the placeholder for this select menu
* @param placeholder The placeholder to use for this select menu
*/
public setPlaceholder(placeholder: string) {
this.data.placeholder = placeholder;
return this;
}
/**
* Sets the minimum values that must be selected in the select menu
* @param minValues The minimum values that must be selected
*/
public setMinValues(minValues: number) {
this.data.min_values = minValues;
return this;
}
/**
* Sets the maximum values that must be selected in the select menu
* @param minValues The maximum values that must be selected
*/
public setMaxValues(maxValues: number) {
this.data.max_values = maxValues;
return this;
}
/**
* Sets the custom Id for this select menu
* @param customId The custom id to use for this select menu
*/
public setCustomId(customId: string) {
this.data.custom_id = customId;
return this;
}
/**
* Sets whether or not this select menu is disabled
* @param disabled Whether or not this select menu is disabled
*/
public setDisabled(disabled = true) {
this.data.disabled = disabled;
return this;
}
/**
* Adds options to this select menu
* @param options The options to add to this select menu
* @returns
*/
public addOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
this.options.push(
...options.map((option) =>
option instanceof UnsafeSelectMenuOptionBuilder ? option : new UnsafeSelectMenuOptionBuilder(option),
),
);
return this;
}
/**
* Sets the options on this select menu
* @param options The options to set on this select menu
*/
public setOptions(...options: (UnsafeSelectMenuOptionBuilder | APISelectMenuOption)[]) {
this.options.splice(
0,
this.options.length,
...options.map((option) =>
option instanceof UnsafeSelectMenuOptionBuilder ? option : new UnsafeSelectMenuOptionBuilder(option),
),
);
return this;
}
public toJSON(): APISelectMenuComponent {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
options: this.options.map((o) => o.toJSON()),
} as APISelectMenuComponent;
}
}

View File

@@ -0,0 +1,60 @@
import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v10';
/**
* Represents a non-validated option within a select menu component
*/
export class UnsafeSelectMenuOptionBuilder {
public constructor(public data: Partial<APISelectMenuOption> = {}) {}
/**
* Sets the label of this option
* @param label The label to show on this option
*/
public setLabel(label: string) {
this.data.label = label;
return this;
}
/**
* Sets the value of this option
* @param value The value of this option
*/
public setValue(value: string) {
this.data.value = value;
return this;
}
/**
* Sets the description of this option.
* @param description The description of this option
*/
public setDescription(description: string) {
this.data.description = description;
return this;
}
/**
* Sets whether this option is selected by default
* @param isDefault Whether this option is selected by default
*/
public setDefault(isDefault = true) {
this.data.default = isDefault;
return this;
}
/**
* Sets the emoji to display on this option
* @param emoji The emoji to display on this option
*/
public setEmoji(emoji: APIMessageComponentEmoji) {
this.data.emoji = emoji;
return this;
}
public toJSON(): APISelectMenuOption {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
} as APISelectMenuOption;
}
}

View File

@@ -0,0 +1,17 @@
import { s } from '@sapphire/shapeshift';
import { TextInputStyle } from 'discord-api-types/v10';
import { customIdValidator } from '../Assertions';
export const textInputStyleValidator = s.nativeEnum(TextInputStyle);
export const minLengthValidator = s.number.int.ge(0).le(4000);
export const maxLengthValidator = s.number.int.ge(1).le(4000);
export const requiredValidator = s.boolean;
export const valueValidator = s.string.lengthLe(4000);
export const placeholderValidator = s.string.lengthLe(100);
export const labelValidator = s.string.lengthGe(1).lengthLe(45);
export function validateRequiredParameters(customId?: string, style?: TextInputStyle, label?: string) {
customIdValidator.parse(customId);
textInputStyleValidator.parse(style);
labelValidator.parse(label);
}

View File

@@ -0,0 +1,37 @@
import type { APITextInputComponent } from 'discord-api-types/v10';
import {
maxLengthValidator,
minLengthValidator,
placeholderValidator,
requiredValidator,
valueValidator,
validateRequiredParameters,
} from './Assertions';
import { UnsafeTextInputBuilder } from './UnsafeTextInput';
export class TextInputBuilder extends UnsafeTextInputBuilder {
public override setMinLength(minLength: number) {
return super.setMinLength(minLengthValidator.parse(minLength));
}
public override setMaxLength(maxLength: number) {
return super.setMaxLength(maxLengthValidator.parse(maxLength));
}
public override setRequired(required = true) {
return super.setRequired(requiredValidator.parse(required));
}
public override setValue(value: string) {
return super.setValue(valueValidator.parse(value));
}
public override setPlaceholder(placeholder: string) {
return super.setPlaceholder(placeholderValidator.parse(placeholder));
}
public override toJSON(): APITextInputComponent {
validateRequiredParameters(this.data.custom_id, this.data.style, this.data.label);
return super.toJSON();
}
}

View File

@@ -0,0 +1,96 @@
import { ComponentType, type TextInputStyle, type APITextInputComponent } from 'discord-api-types/v10';
import isEqual from 'fast-deep-equal';
import { ComponentBuilder } from '../../index';
export class UnsafeTextInputBuilder extends ComponentBuilder<APITextInputComponent> {
public constructor(data?: APITextInputComponent & { type?: ComponentType.TextInput }) {
super({ type: ComponentType.TextInput, ...data });
}
/**
* Sets the custom id for this text input
* @param customId The custom id of this text inputå
*/
public setCustomId(customId: string) {
this.data.custom_id = customId;
return this;
}
/**
* Sets the label for this text input
* @param label The label for this text input
*/
public setLabel(label: string) {
this.data.label = label;
return this;
}
/**
* Sets the style for this text input
* @param style The style for this text input
*/
public setStyle(style: TextInputStyle) {
this.data.style = style;
return this;
}
/**
* Sets the minimum length of text for this text input
* @param minLength The minimum length of text for this text input
*/
public setMinLength(minLength: number) {
this.data.min_length = minLength;
return this;
}
/**
* Sets the maximum length of text for this text input
* @param maxLength The maximum length of text for this text input
*/
public setMaxLength(maxLength: number) {
this.data.max_length = maxLength;
return this;
}
/**
* Sets the placeholder of this text input
* @param placeholder The placeholder of this text input
*/
public setPlaceholder(placeholder: string) {
this.data.placeholder = placeholder;
return this;
}
/**
* Sets the value of this text input
* @param value The value for this text input
*/
public setValue(value: string) {
this.data.value = value;
return this;
}
/**
* Sets whether this text input is required or not
* @param required Whether this text input is required or not
*/
public setRequired(required = true) {
this.data.required = required;
return this;
}
public toJSON(): APITextInputComponent {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
} as APITextInputComponent;
}
public equals(other: UnsafeTextInputBuilder | APITextInputComponent): boolean {
if (other instanceof UnsafeTextInputBuilder) {
return isEqual(other.data, this.data);
}
return isEqual(other, this.data);
}
}

View File

@@ -0,0 +1,41 @@
export * as EmbedAssertions from './messages/embed/Assertions';
export * from './messages/embed/Embed';
export * from './messages/formatters';
export * from './messages/embed/UnsafeEmbed';
export * as ComponentAssertions from './components/Assertions';
export * from './components/ActionRow';
export * from './components/button/Button';
export * from './components/Component';
export * from './components/Components';
export * from './components/textInput/TextInput';
export * as TextInputAssertions from './components/textInput/Assertions';
export * from './components/textInput/UnsafeTextInput';
export * from './interactions/modals/UnsafeModal';
export * from './interactions/modals/Modal';
export * as ModalAssertions from './interactions/modals/Assertions';
export * from './components/selectMenu/SelectMenu';
export * from './components/selectMenu/SelectMenuOption';
export * from './components/button/UnsafeButton';
export * from './components/selectMenu/UnsafeSelectMenu';
export * from './components/selectMenu/UnsafeSelectMenuOption';
export * as SlashCommandAssertions from './interactions/slashCommands/Assertions';
export * from './interactions/slashCommands/SlashCommandBuilder';
export * from './interactions/slashCommands/SlashCommandSubcommands';
export * from './interactions/slashCommands/options/boolean';
export * from './interactions/slashCommands/options/channel';
export * from './interactions/slashCommands/options/integer';
export * from './interactions/slashCommands/options/mentionable';
export * from './interactions/slashCommands/options/number';
export * from './interactions/slashCommands/options/role';
export * from './interactions/slashCommands/options/attachment';
export * from './interactions/slashCommands/options/string';
export * from './interactions/slashCommands/options/user';
export * as ContextMenuCommandAssertions from './interactions/contextMenuCommands/Assertions';
export * from './interactions/contextMenuCommands/ContextMenuCommandBuilder';
export * from './util/jsonEncodable';
export * from './util/equatable';
export * from './util/componentUtil';

View File

@@ -0,0 +1,32 @@
import { s } from '@sapphire/shapeshift';
import { ApplicationCommandType } from 'discord-api-types/v10';
import type { ContextMenuCommandType } from './ContextMenuCommandBuilder';
const namePredicate = s.string
.lengthGe(1)
.lengthLe(32)
.regex(/^( *[\p{L}\p{N}\p{sc=Devanagari}\p{sc=Thai}_-]+ *)+$/u);
const typePredicate = s.union(s.literal(ApplicationCommandType.User), s.literal(ApplicationCommandType.Message));
const booleanPredicate = s.boolean;
export function validateDefaultPermission(value: unknown): asserts value is boolean {
booleanPredicate.parse(value);
}
export function validateName(name: unknown): asserts name is string {
namePredicate.parse(name);
}
export function validateType(type: unknown): asserts type is ContextMenuCommandType {
typePredicate.parse(type);
}
export function validateRequiredParameters(name: string, type: number) {
// Assert name matches all conditions
validateName(name);
// Assert type is valid
validateType(type);
}

View File

@@ -0,0 +1,83 @@
import type { ApplicationCommandType, RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v10';
import { validateRequiredParameters, validateName, validateType, validateDefaultPermission } from './Assertions';
export class ContextMenuCommandBuilder {
/**
* The name of this context menu command
*/
public readonly name: string = undefined!;
/**
* The type of this context menu command
*/
public readonly type: ContextMenuCommandType = undefined!;
/**
* Whether the command is enabled by default when the app is added to a guild
*
* @default true
*/
public readonly defaultPermission: boolean | undefined = undefined;
/**
* Sets the name
*
* @param name The name
*/
public setName(name: string) {
// Assert the name matches the conditions
validateName(name);
Reflect.set(this, 'name', name);
return this;
}
/**
* Sets the type
*
* @param type The type
*/
public setType(type: ContextMenuCommandType) {
// Assert the type is valid
validateType(type);
Reflect.set(this, 'type', type);
return this;
}
/**
* Sets whether the command is enabled by default when the application is added to a guild.
*
* **Note**: If set to `false`, you will have to later `PUT` the permissions for this command.
*
* @param value Whether or not to enable this command by default
*
* @see https://discord.com/developers/docs/interactions/application-commands#permissions
*/
public setDefaultPermission(value: boolean) {
// Assert the value matches the conditions
validateDefaultPermission(value);
Reflect.set(this, 'defaultPermission', value);
return this;
}
/**
* Returns the final data that should be sent to Discord.
*
* **Note:** Calling this function will validate required properties based on their conditions.
*/
public toJSON(): RESTPostAPIApplicationCommandsJSONBody {
validateRequiredParameters(this.name, this.type);
return {
name: this.name,
type: this.type,
default_permission: this.defaultPermission,
};
}
}
export type ContextMenuCommandType = ApplicationCommandType.User | ApplicationCommandType.Message;

View File

@@ -0,0 +1,16 @@
import { s } from '@sapphire/shapeshift';
import { ActionRowBuilder, type ModalActionRowComponentBuilder } from '../..';
import { customIdValidator } from '../../components/Assertions';
export const titleValidator = s.string.lengthGe(1).lengthLe(45);
export const componentsValidator = s.instance(ActionRowBuilder).array.lengthGe(1);
export function validateRequiredParameters(
customId?: string,
title?: string,
components?: ActionRowBuilder<ModalActionRowComponentBuilder>[],
) {
customIdValidator.parse(customId);
titleValidator.parse(title);
componentsValidator.parse(components);
}

View File

@@ -0,0 +1,19 @@
import type { APIModalInteractionResponseCallbackData } from 'discord-api-types/v10';
import { titleValidator, validateRequiredParameters } from './Assertions';
import { UnsafeModalBuilder } from './UnsafeModal';
import { customIdValidator } from '../../components/Assertions';
export class ModalBuilder extends UnsafeModalBuilder {
public override setCustomId(customId: string): this {
return super.setCustomId(customIdValidator.parse(customId));
}
public override setTitle(title: string) {
return super.setTitle(titleValidator.parse(title));
}
public override toJSON(): APIModalInteractionResponseCallbackData {
validateRequiredParameters(this.data.custom_id, this.data.title, this.components);
return super.toJSON();
}
}

View File

@@ -0,0 +1,72 @@
import type {
APIActionRowComponent,
APIModalActionRowComponent,
APIModalInteractionResponseCallbackData,
} from 'discord-api-types/v10';
import { ActionRowBuilder, createComponentBuilder, JSONEncodable, ModalActionRowComponentBuilder } from '../../index';
export class UnsafeModalBuilder implements JSONEncodable<APIModalInteractionResponseCallbackData> {
public readonly data: Partial<APIModalInteractionResponseCallbackData>;
public readonly components: ActionRowBuilder<ModalActionRowComponentBuilder>[] = [];
public constructor({ components, ...data }: Partial<APIModalInteractionResponseCallbackData> = {}) {
this.data = { ...data };
this.components = (components?.map((c) => createComponentBuilder(c)) ??
[]) as ActionRowBuilder<ModalActionRowComponentBuilder>[];
}
/**
* Sets the title of the modal
* @param title The title of the modal
*/
public setTitle(title: string) {
this.data.title = title;
return this;
}
/**
* Sets the custom id of the modal
* @param customId The custom id of this modal
*/
public setCustomId(customId: string) {
this.data.custom_id = customId;
return this;
}
/**
* Adds components to this modal
* @param components The components to add to this modal
*/
public addComponents(
...components: (
| ActionRowBuilder<ModalActionRowComponentBuilder>
| APIActionRowComponent<APIModalActionRowComponent>
)[]
) {
this.components.push(
...components.map((component) =>
component instanceof ActionRowBuilder
? component
: new ActionRowBuilder<ModalActionRowComponentBuilder>(component),
),
);
return this;
}
/**
* Sets the components in this modal
* @param components The components to set this modal to
*/
public setComponents(...components: ActionRowBuilder<ModalActionRowComponentBuilder>[]) {
this.components.splice(0, this.components.length, ...components);
return this;
}
public toJSON(): APIModalInteractionResponseCallbackData {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
components: this.components.map((component) => component.toJSON()),
} as APIModalInteractionResponseCallbackData;
}
}

View File

@@ -0,0 +1,89 @@
import { s } from '@sapphire/shapeshift';
import is from '@sindresorhus/is';
import { type APIApplicationCommandOptionChoice, Locale } from 'discord-api-types/v10';
import type { ToAPIApplicationCommandOptions } from './SlashCommandBuilder';
import type { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands';
import type { ApplicationCommandOptionBase } from './mixins/ApplicationCommandOptionBase';
const namePredicate = s.string
.lengthGe(1)
.lengthLe(32)
.regex(/^[\P{Lu}\p{N}\p{sc=Devanagari}\p{sc=Thai}_-]+$/u);
export function validateName(name: unknown): asserts name is string {
namePredicate.parse(name);
}
const descriptionPredicate = s.string.lengthGe(1).lengthLe(100);
const localePredicate = s.nativeEnum(Locale);
export function validateDescription(description: unknown): asserts description is string {
descriptionPredicate.parse(description);
}
const maxArrayLengthPredicate = s.unknown.array.lengthLe(25);
export function validateLocale(locale: unknown) {
return localePredicate.parse(locale);
}
export function validateMaxOptionsLength(options: unknown): asserts options is ToAPIApplicationCommandOptions[] {
maxArrayLengthPredicate.parse(options);
}
export function validateRequiredParameters(
name: string,
description: string,
options: ToAPIApplicationCommandOptions[],
) {
// Assert name matches all conditions
validateName(name);
// Assert description conditions
validateDescription(description);
// Assert options conditions
validateMaxOptionsLength(options);
}
const booleanPredicate = s.boolean;
export function validateDefaultPermission(value: unknown): asserts value is boolean {
booleanPredicate.parse(value);
}
export function validateRequired(required: unknown): asserts required is boolean {
booleanPredicate.parse(required);
}
const choicesLengthPredicate = s.number.le(25);
export function validateChoicesLength(amountAdding: number, choices?: APIApplicationCommandOptionChoice[]): void {
choicesLengthPredicate.parse((choices?.length ?? 0) + amountAdding);
}
export function assertReturnOfBuilder<
T extends ApplicationCommandOptionBase | SlashCommandSubcommandBuilder | SlashCommandSubcommandGroupBuilder,
>(input: unknown, ExpectedInstanceOf: new () => T): asserts input is T {
const instanceName = ExpectedInstanceOf.name;
if (is.nullOrUndefined(input)) {
throw new TypeError(
`Expected to receive a ${instanceName} builder, got ${input === null ? 'null' : 'undefined'} instead.`,
);
}
if (is.primitive(input)) {
throw new TypeError(`Expected to receive a ${instanceName} builder, got a primitive (${typeof input}) instead.`);
}
if (!(input instanceof ExpectedInstanceOf)) {
const casted = input as Record<PropertyKey, unknown>;
const constructorName = is.function_(input) ? input.name : casted.constructor.name;
const stringTag = Reflect.get(casted, Symbol.toStringTag) as string | undefined;
const fullResultName = stringTag ? `${constructorName} [${stringTag}]` : constructorName;
throw new TypeError(`Expected to receive a ${instanceName} builder, got ${fullResultName} instead.`);
}
}

View File

@@ -0,0 +1,153 @@
import type {
APIApplicationCommandOption,
LocalizationMap,
RESTPostAPIApplicationCommandsJSONBody,
} from 'discord-api-types/v10';
import { mix } from 'ts-mixer';
import {
assertReturnOfBuilder,
validateDefaultPermission,
validateMaxOptionsLength,
validateRequiredParameters,
} from './Assertions';
import { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands';
import { SharedNameAndDescription } from './mixins/NameAndDescription';
import { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions';
@mix(SharedSlashCommandOptions, SharedNameAndDescription)
export class SlashCommandBuilder {
/**
* The name of this slash command
*/
public readonly name: string = undefined!;
/**
* The localized names for this command
*/
public readonly name_localizations?: LocalizationMap;
/**
* The description of this slash command
*/
public readonly description: string = undefined!;
/**
* The localized descriptions for this command
*/
public readonly description_localizations?: LocalizationMap;
/**
* The options of this slash command
*/
public readonly options: ToAPIApplicationCommandOptions[] = [];
/**
* Whether the command is enabled by default when the app is added to a guild
*
* @default true
*/
public readonly defaultPermission: boolean | undefined = undefined;
/**
* Returns the final data that should be sent to Discord.
*
* **Note:** Calling this function will validate required properties based on their conditions.
*/
public toJSON(): RESTPostAPIApplicationCommandsJSONBody {
validateRequiredParameters(this.name, this.description, this.options);
return {
name: this.name,
name_localizations: this.name_localizations,
description: this.description,
description_localizations: this.description_localizations,
options: this.options.map((option) => option.toJSON()),
default_permission: this.defaultPermission,
};
}
/**
* Sets whether the command is enabled by default when the application is added to a guild.
*
* **Note**: If set to `false`, you will have to later `PUT` the permissions for this command.
*
* @param value Whether or not to enable this command by default
*
* @see https://discord.com/developers/docs/interactions/application-commands#permissions
*/
public setDefaultPermission(value: boolean) {
// Assert the value matches the conditions
validateDefaultPermission(value);
Reflect.set(this, 'defaultPermission', value);
return this;
}
/**
* Adds a new subcommand group to this command
*
* @param input A function that returns a subcommand group builder, or an already built builder
*/
public addSubcommandGroup(
input:
| SlashCommandSubcommandGroupBuilder
| ((subcommandGroup: SlashCommandSubcommandGroupBuilder) => SlashCommandSubcommandGroupBuilder),
): SlashCommandSubcommandsOnlyBuilder {
const { options } = this;
// First, assert options conditions - we cannot have more than 25 options
validateMaxOptionsLength(options);
// Get the final result
const result = typeof input === 'function' ? input(new SlashCommandSubcommandGroupBuilder()) : input;
assertReturnOfBuilder(result, SlashCommandSubcommandGroupBuilder);
// Push it
options.push(result);
return this;
}
/**
* Adds a new subcommand to this command
*
* @param input A function that returns a subcommand builder, or an already built builder
*/
public addSubcommand(
input:
| SlashCommandSubcommandBuilder
| ((subcommandGroup: SlashCommandSubcommandBuilder) => SlashCommandSubcommandBuilder),
): SlashCommandSubcommandsOnlyBuilder {
const { options } = this;
// First, assert options conditions - we cannot have more than 25 options
validateMaxOptionsLength(options);
// Get the final result
const result = typeof input === 'function' ? input(new SlashCommandSubcommandBuilder()) : input;
assertReturnOfBuilder(result, SlashCommandSubcommandBuilder);
// Push it
options.push(result);
return this;
}
}
export interface SlashCommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions {}
export interface SlashCommandSubcommandsOnlyBuilder
extends SharedNameAndDescription,
Pick<SlashCommandBuilder, 'toJSON' | 'addSubcommand' | 'addSubcommandGroup'> {}
export interface SlashCommandOptionsOnlyBuilder
extends SharedNameAndDescription,
SharedSlashCommandOptions,
Pick<SlashCommandBuilder, 'toJSON'> {}
export interface ToAPIApplicationCommandOptions {
toJSON: () => APIApplicationCommandOption;
}

View File

@@ -0,0 +1,111 @@
import {
APIApplicationCommandSubcommandGroupOption,
APIApplicationCommandSubcommandOption,
ApplicationCommandOptionType,
} from 'discord-api-types/v10';
import { mix } from 'ts-mixer';
import { assertReturnOfBuilder, validateMaxOptionsLength, validateRequiredParameters } from './Assertions';
import type { ToAPIApplicationCommandOptions } from './SlashCommandBuilder';
import type { ApplicationCommandOptionBase } from './mixins/ApplicationCommandOptionBase';
import { SharedNameAndDescription } from './mixins/NameAndDescription';
import { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions';
/**
* Represents a folder for subcommands
*
* For more information, go to https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups
*/
@mix(SharedNameAndDescription)
export class SlashCommandSubcommandGroupBuilder implements ToAPIApplicationCommandOptions {
/**
* The name of this subcommand group
*/
public readonly name: string = undefined!;
/**
* The description of this subcommand group
*/
public readonly description: string = undefined!;
/**
* The subcommands part of this subcommand group
*/
public readonly options: SlashCommandSubcommandBuilder[] = [];
/**
* Adds a new subcommand to this group
*
* @param input A function that returns a subcommand builder, or an already built builder
*/
public addSubcommand(
input:
| SlashCommandSubcommandBuilder
| ((subcommandGroup: SlashCommandSubcommandBuilder) => SlashCommandSubcommandBuilder),
) {
const { options } = this;
// First, assert options conditions - we cannot have more than 25 options
validateMaxOptionsLength(options);
// Get the final result
// eslint-disable-next-line @typescript-eslint/no-use-before-define
const result = typeof input === 'function' ? input(new SlashCommandSubcommandBuilder()) : input;
// eslint-disable-next-line @typescript-eslint/no-use-before-define
assertReturnOfBuilder(result, SlashCommandSubcommandBuilder);
// Push it
options.push(result);
return this;
}
public toJSON(): APIApplicationCommandSubcommandGroupOption {
validateRequiredParameters(this.name, this.description, this.options);
return {
type: ApplicationCommandOptionType.SubcommandGroup,
name: this.name,
description: this.description,
options: this.options.map((option) => option.toJSON()),
};
}
}
export interface SlashCommandSubcommandGroupBuilder extends SharedNameAndDescription {}
/**
* Represents a subcommand
*
* For more information, go to https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups
*/
@mix(SharedNameAndDescription, SharedSlashCommandOptions)
export class SlashCommandSubcommandBuilder implements ToAPIApplicationCommandOptions {
/**
* The name of this subcommand
*/
public readonly name: string = undefined!;
/**
* The description of this subcommand
*/
public readonly description: string = undefined!;
/**
* The options of this subcommand
*/
public readonly options: ApplicationCommandOptionBase[] = [];
public toJSON(): APIApplicationCommandSubcommandOption {
validateRequiredParameters(this.name, this.description, this.options);
return {
type: ApplicationCommandOptionType.Subcommand,
name: this.name,
description: this.description,
options: this.options.map((option) => option.toJSON()),
};
}
}
export interface SlashCommandSubcommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions<false> {}

View File

@@ -0,0 +1,16 @@
export abstract class ApplicationCommandNumericOptionMinMaxValueMixin {
public readonly max_value?: number;
public readonly min_value?: number;
/**
* Sets the maximum number value of this option
* @param max The maximum value this option can be
*/
public abstract setMaxValue(max: number): this;
/**
* Sets the minimum number value of this option
* @param min The minimum value this option can be
*/
public abstract setMinValue(min: number): this;
}

View File

@@ -0,0 +1,32 @@
import type { APIApplicationCommandBasicOption, ApplicationCommandOptionType } from 'discord-api-types/v10';
import { SharedNameAndDescription } from './NameAndDescription';
import { validateRequiredParameters, validateRequired } from '../Assertions';
export abstract class ApplicationCommandOptionBase extends SharedNameAndDescription {
public abstract readonly type: ApplicationCommandOptionType;
public readonly required: boolean = false;
/**
* Marks the option as required
*
* @param required If this option should be required
*/
public setRequired(required: boolean) {
// Assert that you actually passed a boolean
validateRequired(required);
Reflect.set(this, 'required', required);
return this;
}
public abstract toJSON(): APIApplicationCommandBasicOption;
protected runRequiredValidations() {
validateRequiredParameters(this.name, this.description, []);
// Assert that you actually passed a boolean
validateRequired(this.required);
}
}

View File

@@ -0,0 +1,37 @@
import { s } from '@sapphire/shapeshift';
import { ChannelType } from 'discord-api-types/v10';
// Only allow valid channel types to be used. (This can't be dynamic because const enums are erased at runtime)
const allowedChannelTypes = [
ChannelType.GuildText,
ChannelType.GuildVoice,
ChannelType.GuildCategory,
ChannelType.GuildNews,
ChannelType.GuildNewsThread,
ChannelType.GuildPublicThread,
ChannelType.GuildPrivateThread,
ChannelType.GuildStageVoice,
] as const;
export type ApplicationCommandOptionAllowedChannelTypes = typeof allowedChannelTypes[number];
const channelTypesPredicate = s.array(s.union(...allowedChannelTypes.map((type) => s.literal(type))));
export class ApplicationCommandOptionChannelTypesMixin {
public readonly channel_types?: ApplicationCommandOptionAllowedChannelTypes[];
/**
* Adds channel types to this option
*
* @param channelTypes The channel types to add
*/
public addChannelTypes(...channelTypes: ApplicationCommandOptionAllowedChannelTypes[]) {
if (this.channel_types === undefined) {
Reflect.set(this, 'channel_types', []);
}
this.channel_types!.push(...channelTypesPredicate.parse(channelTypes));
return this;
}
}

View File

@@ -0,0 +1,78 @@
import { s } from '@sapphire/shapeshift';
import { APIApplicationCommandOptionChoice, ApplicationCommandOptionType } from 'discord-api-types/v10';
import { validateChoicesLength } from '../Assertions';
const stringPredicate = s.string.lengthGe(1).lengthLe(100);
const numberPredicate = s.number.gt(-Infinity).lt(Infinity);
const choicesPredicate = s.object({ name: stringPredicate, value: s.union(stringPredicate, numberPredicate) }).array;
const booleanPredicate = s.boolean;
export class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends string | number> {
public readonly choices?: APIApplicationCommandOptionChoice<T>[];
public readonly autocomplete?: boolean;
// Since this is present and this is a mixin, this is needed
public readonly type!: ApplicationCommandOptionType;
/**
* Adds multiple choices for this option
*
* @param choices The choices to add
*/
public addChoices(...choices: APIApplicationCommandOptionChoice<T>[]): this {
if (choices.length > 0 && this.autocomplete) {
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
}
choicesPredicate.parse(choices);
if (this.choices === undefined) {
Reflect.set(this, 'choices', []);
}
validateChoicesLength(choices.length, this.choices);
for (const { name, value } of choices) {
// Validate the value
if (this.type === ApplicationCommandOptionType.String) {
stringPredicate.parse(value);
} else {
numberPredicate.parse(value);
}
this.choices!.push({ name, value });
}
return this;
}
public setChoices<Input extends APIApplicationCommandOptionChoice<T>[]>(...choices: Input): this {
if (choices.length > 0 && this.autocomplete) {
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
}
choicesPredicate.parse(choices);
Reflect.set(this, 'choices', []);
this.addChoices(...choices);
return this;
}
/**
* Marks the option as autocompletable
* @param autocomplete If this option should be autocompletable
*/
public setAutocomplete(autocomplete: boolean): this {
// Assert that you actually passed a boolean
booleanPredicate.parse(autocomplete);
if (autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
}
Reflect.set(this, 'autocomplete', autocomplete);
return this;
}
}

View File

@@ -0,0 +1,118 @@
import type { LocaleString, LocalizationMap } from 'discord-api-types/v10';
import { validateDescription, validateLocale, validateName } from '../Assertions';
export class SharedNameAndDescription {
public readonly name!: string;
public readonly name_localizations?: LocalizationMap;
public readonly description!: string;
public readonly description_localizations?: LocalizationMap;
/**
* Sets the name
*
* @param name The name
*/
public setName(name: string): this {
// Assert the name matches the conditions
validateName(name);
Reflect.set(this, 'name', name);
return this;
}
/**
* Sets the description
*
* @param description The description
*/
public setDescription(description: string) {
// Assert the description matches the conditions
validateDescription(description);
Reflect.set(this, 'description', description);
return this;
}
/**
* Sets a name localization
*
* @param locale The locale to set a description for
* @param localizedName The localized description for the given locale
*/
public setNameLocalization(locale: LocaleString, localizedName: string | null) {
if (!this.name_localizations) {
Reflect.set(this, 'name_localizations', {});
}
if (localizedName === null) {
this.name_localizations![locale] = null;
return this;
}
validateName(localizedName);
this.name_localizations![validateLocale(locale)] = localizedName;
return this;
}
/**
* Sets the name localizations
*
* @param localizedNames The dictionary of localized descriptions to set
*/
public setNameLocalizations(localizedNames: LocalizationMap | null) {
if (localizedNames === null) {
Reflect.set(this, 'name_localizations', null);
return this;
}
Reflect.set(this, 'name_localizations', {});
Object.entries(localizedNames).forEach((args) =>
this.setNameLocalization(...(args as [LocaleString, string | null])),
);
return this;
}
/**
* Sets a description localization
*
* @param locale The locale to set a description for
* @param localizedDescription The localized description for the given locale
*/
public setDescriptionLocalization(locale: LocaleString, localizedDescription: string | null) {
if (!this.description_localizations) {
Reflect.set(this, 'description_localizations', {});
}
if (localizedDescription === null) {
this.description_localizations![locale] = null;
return this;
}
validateDescription(localizedDescription);
this.description_localizations![validateLocale(locale)] = localizedDescription;
return this;
}
/**
* Sets the description localizations
*
* @param localizedDescriptions The dictionary of localized descriptions to set
*/
public setDescriptionLocalizations(localizedDescriptions: LocalizationMap | null) {
if (localizedDescriptions === null) {
Reflect.set(this, 'description_localizations', null);
return this;
}
Reflect.set(this, 'description_localizations', {});
Object.entries(localizedDescriptions).forEach((args) =>
this.setDescriptionLocalization(...(args as [LocaleString, string | null])),
);
return this;
}
}

View File

@@ -0,0 +1,162 @@
import type { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase';
import { assertReturnOfBuilder, validateMaxOptionsLength } from '../Assertions';
import type { ToAPIApplicationCommandOptions } from '../SlashCommandBuilder';
import { SlashCommandAttachmentOption } from '../options/attachment';
import { SlashCommandBooleanOption } from '../options/boolean';
import { SlashCommandChannelOption } from '../options/channel';
import { SlashCommandIntegerOption } from '../options/integer';
import { SlashCommandMentionableOption } from '../options/mentionable';
import { SlashCommandNumberOption } from '../options/number';
import { SlashCommandRoleOption } from '../options/role';
import { SlashCommandStringOption } from '../options/string';
import { SlashCommandUserOption } from '../options/user';
export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
public readonly options!: ToAPIApplicationCommandOptions[];
/**
* Adds a boolean option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addBooleanOption(
input: SlashCommandBooleanOption | ((builder: SlashCommandBooleanOption) => SlashCommandBooleanOption),
) {
return this._sharedAddOptionMethod(input, SlashCommandBooleanOption);
}
/**
* Adds a user option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addUserOption(input: SlashCommandUserOption | ((builder: SlashCommandUserOption) => SlashCommandUserOption)) {
return this._sharedAddOptionMethod(input, SlashCommandUserOption);
}
/**
* Adds a channel option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addChannelOption(
input: SlashCommandChannelOption | ((builder: SlashCommandChannelOption) => SlashCommandChannelOption),
) {
return this._sharedAddOptionMethod(input, SlashCommandChannelOption);
}
/**
* Adds a role option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addRoleOption(input: SlashCommandRoleOption | ((builder: SlashCommandRoleOption) => SlashCommandRoleOption)) {
return this._sharedAddOptionMethod(input, SlashCommandRoleOption);
}
/**
* Adds an attachment option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addAttachmentOption(
input: SlashCommandAttachmentOption | ((builder: SlashCommandAttachmentOption) => SlashCommandAttachmentOption),
) {
return this._sharedAddOptionMethod(input, SlashCommandAttachmentOption);
}
/**
* Adds a mentionable option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addMentionableOption(
input: SlashCommandMentionableOption | ((builder: SlashCommandMentionableOption) => SlashCommandMentionableOption),
) {
return this._sharedAddOptionMethod(input, SlashCommandMentionableOption);
}
/**
* Adds a string option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addStringOption(
input:
| SlashCommandStringOption
| Omit<SlashCommandStringOption, 'setAutocomplete'>
| Omit<SlashCommandStringOption, 'addChoices'>
| ((
builder: SlashCommandStringOption,
) =>
| SlashCommandStringOption
| Omit<SlashCommandStringOption, 'setAutocomplete'>
| Omit<SlashCommandStringOption, 'addChoices'>),
) {
return this._sharedAddOptionMethod(input, SlashCommandStringOption);
}
/**
* Adds an integer option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addIntegerOption(
input:
| SlashCommandIntegerOption
| Omit<SlashCommandIntegerOption, 'setAutocomplete'>
| Omit<SlashCommandIntegerOption, 'addChoices'>
| ((
builder: SlashCommandIntegerOption,
) =>
| SlashCommandIntegerOption
| Omit<SlashCommandIntegerOption, 'setAutocomplete'>
| Omit<SlashCommandIntegerOption, 'addChoices'>),
) {
return this._sharedAddOptionMethod(input, SlashCommandIntegerOption);
}
/**
* Adds a number option
*
* @param input A function that returns an option builder, or an already built builder
*/
public addNumberOption(
input:
| SlashCommandNumberOption
| Omit<SlashCommandNumberOption, 'setAutocomplete'>
| Omit<SlashCommandNumberOption, 'addChoices'>
| ((
builder: SlashCommandNumberOption,
) =>
| SlashCommandNumberOption
| Omit<SlashCommandNumberOption, 'setAutocomplete'>
| Omit<SlashCommandNumberOption, 'addChoices'>),
) {
return this._sharedAddOptionMethod(input, SlashCommandNumberOption);
}
private _sharedAddOptionMethod<T extends ApplicationCommandOptionBase>(
input:
| T
| Omit<T, 'setAutocomplete'>
| Omit<T, 'addChoices'>
| ((builder: T) => T | Omit<T, 'setAutocomplete'> | Omit<T, 'addChoices'>),
Instance: new () => T,
): ShouldOmitSubcommandFunctions extends true ? Omit<this, 'addSubcommand' | 'addSubcommandGroup'> : this {
const { options } = this;
// First, assert options conditions - we cannot have more than 25 options
validateMaxOptionsLength(options);
// Get the final result
const result = typeof input === 'function' ? input(new Instance()) : input;
assertReturnOfBuilder(result, Instance);
// Push it
options.push(result);
return this;
}
}

View File

@@ -0,0 +1,12 @@
import { APIApplicationCommandAttachmentOption, ApplicationCommandOptionType } from 'discord-api-types/v10';
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';
export class SlashCommandAttachmentOption extends ApplicationCommandOptionBase {
public override readonly type = ApplicationCommandOptionType.Attachment as const;
public toJSON(): APIApplicationCommandAttachmentOption {
this.runRequiredValidations();
return { ...this };
}
}

View File

@@ -0,0 +1,12 @@
import { APIApplicationCommandBooleanOption, ApplicationCommandOptionType } from 'discord-api-types/v10';
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';
export class SlashCommandBooleanOption extends ApplicationCommandOptionBase {
public readonly type = ApplicationCommandOptionType.Boolean as const;
public toJSON(): APIApplicationCommandBooleanOption {
this.runRequiredValidations();
return { ...this };
}
}

View File

@@ -0,0 +1,17 @@
import { APIApplicationCommandChannelOption, ApplicationCommandOptionType } from 'discord-api-types/v10';
import { mix } from 'ts-mixer';
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';
import { ApplicationCommandOptionChannelTypesMixin } from '../mixins/ApplicationCommandOptionChannelTypesMixin';
@mix(ApplicationCommandOptionChannelTypesMixin)
export class SlashCommandChannelOption extends ApplicationCommandOptionBase {
public override readonly type = ApplicationCommandOptionType.Channel as const;
public toJSON(): APIApplicationCommandChannelOption {
this.runRequiredValidations();
return { ...this };
}
}
export interface SlashCommandChannelOption extends ApplicationCommandOptionChannelTypesMixin {}

Some files were not shown because too many files have changed in this diff Show More