Compare commits

..

729 Commits

Author SHA1 Message Date
iCrawl a7dc588d9f chore(proxy): release @discordjs/proxy@1.0.1 2022-07-27 14:16:56 +02:00
iCrawl 2291429d30 chore(ws): release @discordjs/ws@0.1.0 2022-07-27 14:15:59 +02:00
iCrawl bf7326729d chore(rest): release @discordjs/rest@1.0.1 2022-07-27 14:12:23 +02:00
iCrawl 124d8123b8 chore(collection): release @discordjs/collection@1.0.1 2022-07-27 14:10:17 +02:00
Jiralite 0b61dbf720 docs(InteractionResponses): Add showModal() return type (#8376) 2022-07-27 13:59:26 +02:00
Jiralite ba6797e742 docs(WebhookClient): Document working options (#8375) 2022-07-27 13:05:47 +02:00
Jiralite 7fd9ed8f13 refactor: Deprecate Formatter class (#8373) 2022-07-27 13:05:31 +02:00
iCrawl b6bba9901b chore: deps 2022-07-27 12:23:07 +02:00
Jiralite 2130aae321 docs(Message): Document gateway intent for content (#8364) 2022-07-27 12:10:05 +02:00
Jiralite 80b9738957 docs: Use info blocks for requirements (#8361) 2022-07-27 12:09:50 +02:00
A. Román 5d8bd030d6 fix(Formatters): add newline in codeBlock (#8369) 2022-07-27 12:09:34 +02:00
Jiralite e9920a9c98 docs(WebhookClient): Make constructor a union (#8370)
Co-authored-by: muchnameless <12682826+muchnameless@users.noreply.github.com>
2022-07-27 12:09:18 +02:00
Jiralite 6d248051cf refactor(PermissionOverwriteManager): Use OverwriteType (#8374) 2022-07-27 12:06:59 +02:00
iCrawl 798466a696 fix: various css for the sidebar 2022-07-26 09:48:40 +02:00
Suneet Tipirneni 1275918ca8 feat(website): group items by symbol kind (#8360)
* feat(website): group items by symbol kind

* chore: make requested changes

* chore: fix darkmode colors

* chore: make requested changes

* Update packages/website/src/components/ListSidebar.tsx

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

Co-authored-by: Almeida <almeidx@pm.me>
2022-07-26 09:30:57 +02:00
SpaceEEC a7d49e56fc fix(GuildChannelManager): allow unsetting rtcRegion (#8359) 2022-07-26 09:29:30 +02:00
Ryan Munro 34ba9d1c4c docs: update docs and examples to PascalCase links (#8305)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2022-07-25 11:13:09 +02:00
Ryan Munro 77ed407f6a feat: restore missing typeguards (#8328) 2022-07-25 11:12:48 +02:00
Rodry 4fc2c60a3b feat(GuildMember): add dmChannel getter (#8281) 2022-07-25 11:12:00 +02:00
Jiralite 9f4446b10f chore: Update update guide link (#8358)
chore: update update guide
2022-07-25 11:09:58 +02:00
Jiralite 78d4295a40 fix(WebSocketShard): Use correct import (#8357) 2022-07-25 11:09:27 +02:00
iCrawl 5a3c9996e0 fix(enums): dark theme colors 2022-07-25 01:38:17 +02:00
iCrawl 4fff6076e7 refactor: cleanup css 2022-07-25 00:55:40 +02:00
Suneet Tipirneni 4bda24678a refactor(website): add typography improvements (#8355)
* refactor(website): add typography improvements

* chore: bold on hover
2022-07-24 21:56:50 +02:00
iCrawl 9ae461d84d chore: rename docker publish 2022-07-24 18:51:26 +02:00
iCrawl 160487d866 chore: fix dockerbuild and add ws props everywhere 2022-07-24 18:49:06 +02:00
iCrawl 41e4e10b48 fix(Layout): refactor to sidebar layout component 2022-07-24 18:28:32 +02:00
Jiralite 200ab91f52 types(GuildAuditLogsEntryExtraField): Use AuditLogOptionsType (#8349) 2022-07-24 17:26:55 +02:00
Jiralite 3839958e3f fix(ThreadChannel): Omit webhook fetching (#8351) 2022-07-24 17:18:08 +02:00
thehairy 58c1b51c5c fix(GuildAuditLogsEntry): replace OverwriteType with AuditLogOptionsType (#8345) 2022-07-24 16:15:51 +02:00
Suneet Tipirneni 6a2d0d8e96 fix(selectMenu): allow json to be used for select menu options (#8322) 2022-07-24 15:14:33 +02:00
Suneet Tipirneni 335695c698 refactor: use next links (#8344)
* chore(website): use next links

* chore: fix deploy check

* chore: use ligher syntax highlighter
2022-07-24 15:14:18 +02:00
DD 8e520f946a fix(ShardClientUtil#_respond): construct global error (#8348) 2022-07-24 15:13:13 +02:00
Jiralite 59a7e52224 fix: Ensure returns for function type definitions (#8346) 2022-07-24 13:44:46 +02:00
Jiralite af837debe3 chore: Use raw GitHub link to show Vercel logo on website (#8343)
chore: use raw GitHub link to show on docs
2022-07-23 23:38:49 +02:00
Jiralite df42fdfc42 fix(Presence): Do not return NaN for activity timestamp (#8340) 2022-07-23 18:21:47 +02:00
iCrawl 5f667c0c82 fix: correctly configure middleware 2022-07-23 04:13:16 +02:00
iCrawl 90cbd2bbd5 fix: move middleware into source directory
This needs to be on the same level as the pages directory, sometimes the documentation mentioned "root", but that obviously is not true if you use a src directory
2022-07-23 02:49:24 +02:00
iCrawl f50382e1ce feat: add middleware for path rewriting 2022-07-23 02:35:21 +02:00
iCrawl 1b03631205 chore: patch all versions of tsdoc-config 2022-07-23 01:57:47 +02:00
iCrawl a490adfe36 chore: remove hoist and install normally 2022-07-23 01:41:12 +02:00
iCrawl f097f0bc1f chore: create patch for tsdoc-config 2022-07-23 01:38:21 +02:00
iCrawl 1d63d3ce1c build: explicitly add deps 2022-07-23 01:24:45 +02:00
iCrawl 6d25fb8856 fix(yarn): don't hoist packages for website 2022-07-23 00:36:00 +02:00
iCrawl 86a9be7d33 fix(IRS): also generate index routes 2022-07-23 00:11:19 +02:00
iCrawl 82165d4f80 feat(IRS): next IRS 2022-07-22 23:39:48 +02:00
iCrawl ee455c812e refactor: switch to next.js 2022-07-22 21:47:06 +02:00
iCrawl 0d687b5606 chore: deps 2022-07-22 19:25:24 +02:00
DD 748d7271c4 feat: @discordjs/ws (#8260)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
2022-07-22 19:13:47 +02:00
SpaceEEC 830c670c61 fix(Client): omit private properties from toJSON (#8337) 2022-07-22 17:11:54 +02:00
iCrawl 74ec7be346 chore: add lint-staged 2022-07-22 01:32:19 +02:00
iCrawl 96b62b6539 ci: rename files to match better naming 2022-07-20 22:33:23 +02:00
iCrawl 8a6ee906a7 ci: better naming for ci 2022-07-20 20:24:09 +02:00
Almeida 1fb7b30963 fix(ApplicationCommandManager): allow passing 0n to defaultMemberPermissions (#8311)
* fix(ApplicationCommandManager): allow passing 0n to defaultMemberPermissions

* fix(ApplicationCommand): equals()
2022-07-20 20:12:58 +02:00
iCrawl 45c9659080 ci: fix vercel deploy check 2022-07-20 19:03:48 +02:00
iCrawl 07a5cd7048 ci: check deploy branch vercel 2022-07-20 18:49:24 +02:00
iCrawl d0e3c972b4 chore: reorder release steps 2022-07-20 18:44:44 +02:00
iCrawl a05386a46c ci: fix docs and dev publishes 2022-07-20 17:22:57 +02:00
Noel 3b0197bd8e build: refactor build system (#8324) 2022-07-20 16:36:42 +02:00
iCrawl d1245418f9 chore: add license to root 2022-07-19 20:11:23 +02:00
iCrawl e7d4d41640 chore: use full link for vercel banner in readmes 2022-07-19 19:43:14 +02:00
iCrawl ce1807dc80 fix(landing): vercel banner not wrapped in a tag 2022-07-19 19:41:14 +02:00
iCrawl 34d3917a28 chore: spacing on vercel logo 2022-07-19 19:38:11 +02:00
iCrawl 9e624abf1a chore(discord.js): release discord.js 2022-07-19 18:40:01 +02:00
iCrawl 8c4b9865e1 fix(landing): vercel banner 2022-07-19 18:33:50 +02:00
iCrawl dbad1c468b chore: fix root vercel banner 2022-07-19 18:29:41 +02:00
iCrawl 4ffd7f9f80 chore: vercel banner 2022-07-19 18:26:03 +02:00
advaith 660e212e83 fix(Components): support emoji id strings (#8310) 2022-07-19 14:56:21 +02:00
iCrawl 70dd757ec3 refactor(theme): switch theme detection to use class 2022-07-18 19:53:07 +02:00
Suneet Tipirneni b5d4b2d78b feat(website): add basic landing page (#8313)
Co-authored-by: Noel <buechler.noel@outlook.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2022-07-18 19:11:18 +02:00
iCrawl 78d013f87c ci: fix building before linting/testing 2022-07-18 14:20:11 +02:00
iCrawl 21d61ca260 chore: remove parallel execution 2022-07-18 14:09:45 +02:00
iCrawl b316ac7cc4 ci: remove turbo cache 2022-07-18 13:16:16 +02:00
iCrawl ed94b3d9ec chore: change versions 2022-07-18 12:52:15 +02:00
iCrawl dcbbecfed2 chore: dev version 2022-07-18 12:28:39 +02:00
iCrawl 0c5e37d515 chore(discord.js): release discord.js 2022-07-18 12:26:49 +02:00
iCrawl 656e9550db fix: default package to discord.js 2022-07-18 12:21:48 +02:00
DD 3a7e93df57 fix(DataResolver#resolveImage): adjust to updated resolveFile (#8308) 2022-07-18 12:17:46 +02:00
iCrawl 66092cad8b feat(theme): dark theme detection 2022-07-18 02:57:29 +02:00
iCrawl ec230faa4d feat(theme): better dark theme 2022-07-18 02:35:34 +02:00
iCrawl cd13a4a902 fix(sidebar): styling issues 2022-07-18 02:14:38 +02:00
iCrawl dda2895bfb chore: release bump 2022-07-17 22:37:01 +02:00
iCrawl f0b77348d3 chore: bump dev version 2022-07-17 22:18:45 +02:00
iCrawl b0a9131b1c chore(discord.js): release discord.js 2022-07-17 22:15:00 +02:00
iCrawl 29be5b570b chore: deps 2022-07-17 22:06:54 +02:00
iCrawl d677c31161 chore: update dev versions 2022-07-17 22:05:32 +02:00
iCrawl f6ef92ad6a chore: release @discordjs/builders, @discordjs/collection, @discordjs/proxy, @discordjs/rest 2022-07-17 22:02:32 +02:00
Jiralite 52a9e213c2 fix(GuildMemberManager): Allow setting own nickname (#8066) 2022-07-17 21:47:02 +02:00
Almeida b7e62380f2 test(builders): improve coverage (#8274) 2022-07-17 21:20:26 +02:00
Lo cafde77d73 refactor(Util)!: rename fetchRecommendedShards (#8298) 2022-07-17 21:17:49 +02:00
Rodry b7d4e55419 types(GuildFeature): allow feature strings to be passed (#8264)
Co-authored-by: Synbulat Biishev <syjalo.dev@gmail.com>
2022-07-17 21:14:54 +02:00
Almeida 5aeed99350 docs: align webhook method return types with implementation (#8253) 2022-07-17 21:14:25 +02:00
Jiralite 452dec57ca docs: Remove @private constructor documentation (#8255) 2022-07-17 21:13:54 +02:00
Jiralite 64f814066c refactor(Embed): Add all the types (#8254) 2022-07-17 21:13:40 +02:00
Rodry 33a7a5cbdc types(CategoryChannelChildManager): fix Holds type (#8288) 2022-07-17 21:12:22 +02:00
iCrawl edf83f02ea chore: bump dev versions 2022-07-17 21:05:21 +02:00
iCrawl 25bd771559 chore(voice): release @discordjs/voice@0.11.0 2022-07-17 21:04:18 +02:00
iCrawl f2ca0ca6f9 chore(rest): release @discordjs/rest@0.6.0 2022-07-17 21:03:35 +02:00
iCrawl 6712de9752 chore(collection): release @discordjs/collection@0.8.0 2022-07-17 20:59:54 +02:00
iCrawl 28cd293f14 chore: update changelog 2022-07-17 19:42:10 +02:00
iCrawl 3f5690afe1 chore(builders): bump dev version 2022-07-17 19:31:32 +02:00
iCrawl 015ab69956 chore(builders): release @discordjs/builders@0.16.0 2022-07-17 19:28:12 +02:00
iCrawl caecc574f0 chore: deps 2022-07-17 19:20:40 +02:00
BattleEye 3bf30b1e6d fix(PermissionOverwriteManager): mutates user (#8283) 2022-07-17 18:59:10 +02:00
DD 103a3584c9 refactor(rest): add content-type(s) to uploads (#8290) 2022-07-17 18:55:25 +02:00
Almeida bf65b37d1a types: remove MemberMention (#8292) 2022-07-17 18:54:44 +02:00
Parbez 7e6dbaaed9 types: remove expect error (#8242) 2022-07-17 18:53:40 +02:00
CallMe AsYouFeel 1a6ddbbe7b fix(VoiceReceiver): parsePacket correctly (#8277) 2022-07-17 18:52:35 +02:00
Tiemen 32f9056b15 fix: slash command name regex (#8265) 2022-07-17 18:52:18 +02:00
Jiralite 3648f6d567 fix(GuildChannelManager): Access resolveId correctly (#8296) 2022-07-17 18:51:25 +02:00
Almeida bddb6a461c chore: ignore index files in coverage (#8293)
Co-authored-by: ckohen <chaikohen@gmail.com>
2022-07-17 18:51:03 +02:00
Jiralite fe34f48efb chore: Remove --cache (#8279) 2022-07-13 16:58:40 +02:00
Jeroen Claassens 30a8d3231f chore: update Git Cliff TOMLs (#8276) 2022-07-13 09:49:17 +02:00
Suneet Tipirneni 1ed605eaa4 feat(website): add extends clauses, enum members and automatic -types links (#8270)
* feat(website): add extends clauses, enum members and automatic -types links

* chore: remove vscode settings

* refactor: remove util file
2022-07-12 22:42:32 +02:00
muchnameless 787654816d fix(GuildChannelManager): edit lockPermissions (#8269) 2022-07-12 22:34:14 +02:00
Eejit f0b68d5736 refactor: make GuildAuditLogsEntry.action return an AuditLogEvent (#8256) 2022-07-09 19:55:24 +02:00
Jiralite 75256153a9 types(GuildMemberManager): Fix placement for fetchMe() (#8258) 2022-07-09 19:43:02 +02:00
Suneet Tipirneni 33ae7df000 feat(website): add detailed property and method documentation (#8252)
Co-authored-by: Noel <buechler.noel@outlook.com>
2022-07-08 22:03:18 +02:00
Tyler Resch feb3bdda0a types: convert Events to an enum (#8246) 2022-07-08 16:02:48 +02:00
Suneet Tipirneni e78c9c9ee9 feat(website): show package members in a sidebar (#8245)
* feat(website): show package members in a sidebar

* fix: put response instead of loader

* Apply suggestions from code review

Co-authored-by: Noel <buechler.noel@outlook.com>

* chore: make requested changes

* refactor: make only package list scrollable

* feat: make sidebar mobile responsive

* fix: breakpoints for sidebar

Co-authored-by: Noel <buechler.noel@outlook.com>
2022-07-07 22:09:19 +02:00
MateoDeveloper 43f62bb667 docs(ApplicationCommand): add min_length and max_length to ApplicationCommandOptionData (#8239) 2022-07-07 20:46:06 +02:00
Parbez 96c8d21f95 feat(builder): add max min length in string option (#8214) 2022-07-07 20:45:32 +02:00
Anton Istomin 10ba0080cc fix(recorder-example): bump dependencies (#8123) 2022-07-06 22:25:10 +02:00
iCrawl 0b979b04f2 chore: add blocked label 2022-07-06 21:17:07 +02:00
Parbez a4d1862982 refactor(builder): remove unsafe*Builders (#8074) 2022-07-06 20:42:51 +02:00
Suneet Tipirneni 34531c45e3 feat(website): add support for type parameter documentation (#8237) 2022-07-06 17:37:33 +02:00
Parbez 8198da5cd0 types(builder): remove casting (#8241) 2022-07-06 12:28:00 +02:00
iCrawl ba10637529 chore: deps 2022-07-06 10:43:06 +02:00
iCrawl 68c3d8743e refactor(createApiModel): reusable function for api model creation 2022-07-05 17:00:44 +02:00
Almeida a51f7215ec test(collection): improve coverage (#8222) 2022-07-05 16:10:42 +02:00
Jiralite c271e05223 fix(SpeakingMap): Allow docgen to detect event name (#8236) 2022-07-05 16:10:23 +02:00
Almeida d2e74003d5 chore: remove docgen test stuff (#8231) 2022-07-05 14:13:11 +02:00
ckohen fd1c24036f fix(codecov): use cobertura (#8235) 2022-07-05 12:32:05 +02:00
ckohen eb9ad46d4f fix(coverage): upload lcov instead of clover (#8234) 2022-07-05 10:52:38 +02:00
Almeida 5bd6b28b3e fix(Collection): make error messages consistent (#8224) 2022-07-04 17:40:33 +02:00
ckohen f6db285c07 docs: add codecov coverage badge to readmes (#8226)
* docs: add codecov coverage badge to readmes

* docs: fix tab-space consistency
2022-07-04 14:00:27 +02:00
Almeida 68ade870f8 chore: upgrade vitest and add it as dep on each workspace (#8223) 2022-07-04 11:51:48 +02:00
Jiralite c7a205f7b9 types(GuildMemberManager): Non-void return of edit() (#8186) 2022-07-03 18:04:29 +02:00
Almeida c5750d59f5 refactor: make ShardEvents the events of Shard (#8185) 2022-07-03 18:04:19 +02:00
Suneet Tipirneni 31d5930464 fix(SelectMenuBuilder): properly accept SelectMenuOptionBuilders (#8174) 2022-07-03 18:04:08 +02:00
Jiralite cdd9214212 fix: Remove global flag on regular expressions (#8177) 2022-07-03 15:36:53 +02:00
A. Román fa010b5162 fix(MessagePayload): guard against repliedUser property (#8211) 2022-07-03 15:36:32 +02:00
A. Román 6b20645740 refactor(Util): make single replace call in cleanContent (#8210)
Co-authored-by: Almeida <almeidx@pm.me>
2022-07-03 15:36:20 +02:00
Almeida 50d55bd6b8 fix(ApplicationCommandManager): explicitly allow passing builders to methods (#8209) 2022-07-03 15:35:59 +02:00
Almeida 2d9dfa3c6e fix(TextInputBuilder): parse custom_id, label, and style (#8216) 2022-07-03 15:35:19 +02:00
Tyler Resch ab238a9046 docs(MessageInteraction#commandName): updated description (#8212)
Co-authored-by: A. Román <kyradiscord@gmail.com>
2022-07-03 15:34:47 +02:00
Parbez 94ee60d3d4 feat(applicationCommand): add max min length in string option (#8215) 2022-07-03 15:34:04 +02:00
ckohen f10f4cdcd8 feat: codecov (#8219) 2022-07-03 15:33:18 +02:00
Suneet Tipirneni d95197cc78 feat: add website documentation early mvp (#8183)
Co-authored-by: iCrawl <buechler.noel@outlook.com>
2022-07-01 20:54:15 +02:00
Jiralite e0c8282490 docs: Add missing @extends (#8205) 2022-07-01 17:48:11 +02:00
tnfAngel 741b3c8e27 docs: Remove Music bot in voice examples (#8203) 2022-07-01 10:54:11 +02:00
iCrawl 819a1fdf7d ci: check for main package before moving api-extractor docs 2022-06-30 16:17:52 +02:00
iCrawl ce9afbb8e4 ci: fix building before generating docs 2022-06-30 15:56:07 +02:00
iCrawl b2776c22d4 ci: api-extractor support for docs 2022-06-30 15:46:14 +02:00
DD 525bf031a5 chore: revert pre-commit hook to not change state (#8200) 2022-06-30 11:47:27 +02:00
CarelessInternet 27d8deb471 types: add missing shard types (#8180) 2022-06-30 00:37:55 +02:00
Xaliks 11b1739319 fix(GuildMemberRemove): remove member's presence (#8181) 2022-06-30 00:37:47 +02:00
Jiralite b83e0c0caf types: Implement GuildChannelEditOptions (#8184) 2022-06-30 00:37:38 +02:00
Almeida 8421f9203b types(Status): add missing members (#8179) 2022-06-30 00:37:31 +02:00
A. Román cb3dca4ae0 refactor(ApplicationCommandManager): use makeURLSearchParams (#8196) 2022-06-30 00:36:47 +02:00
MateoDeveloper 002d6a5aed feat(BaseInteraction): add support for app_permissions (#8194)
Co-authored-by: Almeida <almeidx@pm.me>
2022-06-30 00:36:32 +02:00
DD c4653f97b1 feat(util): parseWebhookURL (#8166)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2022-06-25 11:02:11 +02:00
Suneet Tipirneni e24970e3c3 refactor: Use Base prefix for channel and interaction base classes (#8099) 2022-06-24 10:42:50 +02:00
Tyler Resch 65dc8d677e types(GuildScheduledEvent#scheduledStartAt): should be nullish (#8111) 2022-06-24 10:42:39 +02:00
Almeida 0ffbef506a fix: edit() data can be partial and defaultMemberPermissions can be null (#8163) 2022-06-24 10:42:20 +02:00
iCrawl 5d3dd55a26 chore(changelog): add v13 changelog 2022-06-23 18:28:32 +02:00
Skick 70b42bb64a types(voice): bring back typed events (#8109) 2022-06-23 12:39:36 +02:00
Jan af04992ed3 docs(Constants): fix SweeperKeys type (#8157) 2022-06-23 12:37:12 +02:00
ckohen bbdb5d980b revert: refactor: move eslint.tsconfig.json to root (#8159) 2022-06-23 12:36:42 +02:00
Suneet Tipirneni 7279f9c31b types: fix modal builder constructor data type (#8143) 2022-06-22 20:37:46 +02:00
Jiralite 5e5853a4e8 docs(Channels): internally document channel creation (#8154) 2022-06-22 20:37:24 +02:00
Jiralite cd17aad720 refactor(Constants): Remove leftover code (#8156)
* refactor(Constants): tidy up file

* docs(Constants): add type definition
2022-06-22 20:36:58 +02:00
Jiralite ee36d60dc6 docs: Update threads to use ThreadAutoArchiveDuration (#8153) 2022-06-22 20:34:41 +02:00
SpaceEEC c34c02ab8d fix(WebSocketShard): keep an error handler on connections (#8150) 2022-06-22 20:34:11 +02:00
Almeida 31f658247f fix(DJSError): error code validation (#8149) 2022-06-22 20:33:47 +02:00
Jiralite a3799f9ebb types: Use ThreadAutoArchiveDuration from discord-api-types (#8145) 2022-06-22 11:23:39 +02:00
Jiralite a061233510 docs(APITypes): Remove duplicate type definition (#8144) 2022-06-22 11:23:17 +02:00
Jiralite 203bc4a2cf docs: Document missing type definitions (#8130)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-06-22 11:23:03 +02:00
Parbez 65d1879c0a chore: move deps to root and some miscellaneous changes (#8129) 2022-06-21 15:15:38 +02:00
Parbez c6f285b7b0 refactor: remove @sindresorhus/is as it's now esm only (#8133) 2022-06-21 14:41:33 +02:00
pat 2eeaad6f27 fix(vcs): nsfw property (#8132) 2022-06-21 14:35:42 +02:00
pat f1ac17c961 docs(InteractionResponse): fix return (#8141) 2022-06-21 14:35:33 +02:00
Jiralite db2b0333d9 fix(WebSocketManager): Correct error name (#8138) 2022-06-21 14:35:17 +02:00
DD 94f7ca9474 chore: update proxy-container README (#8122)
Co-authored-by: Almeida <almeidx@pm.me>
2022-06-20 14:47:19 +02:00
DD e68effa822 refactor: errors (#8068)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
Co-authored-by: A. Román <kyradiscord@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2022-06-20 14:46:35 +02:00
iCrawl 358c3f4a46 chore: upgrade deps 2022-06-19 13:19:24 +02:00
DD 268a9b4be5 fix: vitest recursion (#8121) 2022-06-19 13:18:36 +02:00
KinectTheUnknown 95e6d6ede0 types(Shard#reconnecting): fix event name (#8118) 2022-06-19 12:24:04 +02:00
DD 17867f9154 fix(proxy-container): proper deps (#8120) 2022-06-19 12:17:47 +02:00
Jiralite 3a77ce0b18 docs(PermissionsBitField): Fix @name of bitfield (#8115)
docs(PermissionsBitField): `Permission` -> `PermissionsBitField`
2022-06-18 18:42:47 +02:00
Jiralite 23e183a9ac fix(WebSocketShard): Disconnected casing (#8117) 2022-06-18 18:42:30 +02:00
Parbez b3c3a94d5d ci: don't run publish workflow on forks (#8116) 2022-06-18 18:42:09 +02:00
DD 8610700c87 fix(ci): log into dockerhub properly (#8114) 2022-06-18 13:59:05 +02:00
Jiralite db663a55c2 docs: TextBasedChannel -> TextBasedChannels typos (#8110) 2022-06-18 13:02:41 +02:00
DD 0673ea377a fix(proxy-container): add @discordjs/rest to deps (#8113) 2022-06-18 13:02:12 +02:00
DD 2681929e42 feat: proxy container (#8000) 2022-06-17 23:29:50 +02:00
Jiralite 0a138dab95 docs: Remove numbers from enums (#8098) 2022-06-17 23:28:30 +02:00
Jiralite 415513696c docs(GuildAuditLogs): Fix and reimplement type definitions (#8108) 2022-06-17 23:27:54 +02:00
Almeida 90a98fee16 refactor(ClientOptions): remove $ prefix from ws.properties keys (#8094) 2022-06-17 23:26:42 +02:00
advaith 386c41f24f docs(WebSocketOptions): add version to docs and typings (#8050) 2022-06-17 23:26:08 +02:00
pat d54bf5d286 fix(webhooks): revert webhook caching (and returning Message) (#8038) 2022-06-17 23:25:46 +02:00
Jiralite e5ec1c4dbc refactor: Use GuildFeature enum (#8101) 2022-06-17 23:25:29 +02:00
Jiralite ad9ab2b177 chore: Add MessageContent to issue form (#8106) 2022-06-17 23:24:26 +02:00
Rodry 4df491ce85 types(ApplicationCommand): fix typo in setDMPermission (#8097) 2022-06-16 09:59:46 +02:00
Jiralite 0a44b05db8 fix(ApplicationCommand): Remove autocomplete check at the top level and correctly check for dmPermission (#8100) 2022-06-16 09:58:54 +02:00
Almeida b4e28a8ff6 types: fix setType() parameter and ChannelData.type (#8089) 2022-06-13 23:43:10 +02:00
Jiralite 9c0f190de1 docs(BaseGuildTextChannel): Update setType()'s parameter type (#8088) 2022-06-13 22:09:00 +02:00
BaumianerNiklas 093117d938 chore: remove -types import in readme example (#8085) 2022-06-13 21:42:28 +02:00
Suneet Tipirneni e53d162198 refactor(util): make utility functions top level (#8052)
* refactor(util): make functions top level

* types: make channel typeguards more strict

* chore: make requested changes
2022-06-13 20:04:53 +02:00
Almeida 51eadf3737 docs: update outdated examples (#8081) 2022-06-13 18:18:15 +02:00
Jiralite 552ec72542 docs(ThreadMemberManager): Require member in FetchThreadMemberOptions (#8079) 2022-06-13 18:17:44 +02:00
Ben ac7bf692bf docs(AutocompleteInteraction): change useless log in responds example (#8077) 2022-06-13 18:16:54 +02:00
n1ck_pro 9964454c29 types: fix ApplicationCommandPermissionsUpdate event typings (#8071) 2022-06-13 18:16:07 +02:00
Rodry 476b7d519c types(AutocompleteOption): fix and improve types (#8069) 2022-06-13 18:15:31 +02:00
Jiralite 10a6c4287d feat(AutocompleteInteraction): Add commandGuildId (#8086) 2022-06-13 18:14:01 +02:00
Jiralite a2eebf6c66 docs: Description and missing @typedef fixes (#8087) 2022-06-13 18:12:08 +02:00
CodeGoat 96053babe1 fix(ApplicationCommand): fix default member permissions assignment (#8067) 2022-06-11 11:05:43 +02:00
ckohen f527dea36e fix(scripts): read directory and rerun (#8065) 2022-06-11 11:04:53 +02:00
ckohen c7391db11b refactor(ApplicationCommand): permissions v2 (#7857)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-06-10 21:34:17 +02:00
Suneet Tipirneni c5176be14b feat(guild): add support for setting MFA level (#8024) 2022-06-10 21:26:11 +02:00
Parbez fbe67e1025 fix: select menu options to accept both rest and array (#8032)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2022-06-10 21:22:04 +02:00
Parbez 3bb9c0e5c3 fix: check for function type (#8064) 2022-06-10 21:21:45 +02:00
DD 9c8b3102ce refactor(*): include name/reason/etc fields into options/data params (#8026) 2022-06-10 21:20:59 +02:00
Jiralite 2392a6f5de types(ThreadMemberManager): Fix return type of fetching members with no arguments (#8060)
* types(ThreadMemberManager): non-optional first overload for fetching

* test: organisation
2022-06-10 21:20:00 +02:00
Parbez c0f079d232 typings: remove isAutocomplete typeguard from typings (#8063) 2022-06-10 21:19:44 +02:00
Jiralite d8077c6839 fix(CommandInteractionOptionResolver): Handle autocompletion interactions (#8058) 2022-06-10 21:19:27 +02:00
iCrawl d4b41dd081 feat(docgen): proper event parsing for typescript 2022-06-10 16:22:11 +02:00
pat 0415300243 feat(vcs): add missing property and methods (#8002) 2022-06-10 13:42:53 +02:00
Jeroen Claassens caee94897f build: fix git cliff config files (#8057) 2022-06-10 13:37:24 +02:00
iCrawl b3346f4b9b feat(docgen): update typedoc 2022-06-10 12:59:46 +02:00
iCrawl 2791c86cdf chore: remove unneeded tsc build 2022-06-09 21:27:06 +02:00
Almeida c8f1690896 refactor(collection): remove default property (#8055) 2022-06-09 20:53:23 +02:00
Jiralite da9107c007 refactor(ThreadMemberManager): Consistent thread member fetching (#8021) 2022-06-09 20:52:56 +02:00
Suneet Tipirneni f57d6768ad refactor(interactions): remove redundant interaction typeguards (#8027) 2022-06-09 20:52:44 +02:00
iCrawl d7b8357dcb fix(docgen): strip dots from return types 2022-06-09 20:47:51 +02:00
A. Román 16810f3e41 refactor(collection): remove default export (#8053) 2022-06-09 16:53:01 +02:00
A. Román 598f61b992 fix(scripts): add quotes around blob arguments (#8054) 2022-06-09 16:52:18 +02:00
iCrawl 50401453e7 fix(docgen): shorten output for path info 2022-06-09 16:14:37 +02:00
Almeida 94bdcaca62 docs: ignore docs of unexported functions (#8051) 2022-06-09 13:58:42 +02:00
iCrawl eea139b346 feat(docgen): support for ignore tag 2022-06-09 13:54:35 +02:00
iCrawl 50822f5254 fix(docgen): parsing constructor 2022-06-09 11:37:22 +02:00
muchnameless f2b267c079 fix(Message): force fetching (#8047) 2022-06-09 10:35:52 +02:00
advaith b2eea1c900 docs(ClientOptions): fix closeTimeout default (#8049) 2022-06-09 10:35:27 +02:00
iCrawl 3ae2633c3f feat(website): add some styling 2022-06-08 23:40:03 +02:00
iCrawl 3937b402c0 fix(website): don't build concurrently 2022-06-08 22:26:39 +02:00
iCrawl 256c4f955c feat(website): unocss 2022-06-08 21:45:16 +02:00
iCrawl 33cdcdbb7a fix: vercel deployment 2022-06-08 20:09:23 +02:00
iCrawl bc466a5997 fix(website): deployment 2022-06-08 19:36:09 +02:00
Noel 127931d1df feat: website (#8043) 2022-06-08 19:13:31 +02:00
iCrawl 5259639c2c fix: doc generation for return types 2022-06-08 19:12:42 +02:00
iCrawl 5de9b80814 fix: returns for typescript parsing 2022-06-08 18:41:22 +02:00
iCrawl bc4fbcef2e fix(serializer): properly serialize data 2022-06-08 18:11:25 +02:00
iCrawl 3279b40912 feat(docgen): typescript support 2022-06-08 17:26:54 +02:00
Synbulat Biishev 1afae909d7 fix(Attachment): do not destructure data (#8041) 2022-06-08 13:30:06 +02:00
iCrawl 65cb36166f fix(VarType): parsing type names 2022-06-08 13:27:41 +02:00
Superchupu ecc6600df2 refactor(docgen): use the node: protocol (#8034)
Co-authored-by: Synbulat Biishev <syjalo.dev@gmail.com>
2022-06-08 00:17:48 +02:00
iCrawl 314d76e907 fix(docgen): fix up method return types 2022-06-07 15:19:42 +02:00
Parbez 769ea0bfe7 refactor: move all the config files to root (#8033) 2022-06-07 12:35:19 +02:00
Noel 8b979c0245 feat: docgen package (#8029) 2022-06-07 10:51:33 +02:00
Noel 5475767c2c build: use cliff-jumper for releases (#8030) 2022-06-07 00:59:21 +02:00
Jiralite 86d8fbc023 fix(DirectoryChannel): Type name and handle url (#8023) 2022-06-06 15:47:13 +02:00
iCrawl fba9710fc9 chore(builders): dev version 2022-06-06 14:45:46 +02:00
iCrawl 5ca3974301 chore(release): version 2022-06-06 14:44:25 +02:00
iCrawl 3202c91c5a chore: properly adapt changelog script 2022-06-06 14:43:15 +02:00
Jiralite f3f34f07b3 docs(DirectoryChannel): Extend Channel (#8022) 2022-06-06 14:24:35 +02:00
Parbez f8ed71bfca fix: readd isThread type guard (#8019) 2022-06-06 14:24:03 +02:00
Voxelli e1176faa27 feat: backport handle zombie connection (#7626)
* feat: backport zombie connection fixes

* fix: enums

* fix: prettier

* feat: add zombie connection event to shard events

* Apply suggestions from code review

Co-authored-by: muchnameless <12682826+muchnameless@users.noreply.github.com>

* fix: prettier

* fix: handleZombieConnection

* feat: backport new logic of handling zombie connection

Co-authored-by: muchnameless <12682826+muchnameless@users.noreply.github.com>
2022-06-06 12:21:35 +02:00
Caleb Lam aa59a409b3 feat(CommandInteraction): add 'commandGuildId' (#8018) 2022-06-06 10:07:37 +02:00
Rodry 7fa698d23e types(AttachmentBuilder): fix data type (#8016)
* types(AttachmentBuilder): fix data type

* types(MessageOptions): add AttachmentPayload
2022-06-06 10:07:15 +02:00
markisha64 b9df37a89f refact: Sticker's tags property (#8010) 2022-06-05 23:29:31 +02:00
Rodry ad75be9a9c feat: allow builders to accept rest params and arrays (#7874)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
Co-authored-by: Khafra <42794878+KhafraDev@users.noreply.github.com>
2022-06-05 23:29:16 +02:00
Suneet Tipirneni 70c733bb9a refactor(channel): remove redundant channel type guards (#8012) 2022-06-05 23:29:05 +02:00
Rodry a3287782b5 feat(MessageReaction): add react method (#7810) 2022-06-05 23:28:44 +02:00
Suneet Tipirneni 0ccc243c8f types(modal): fix showModal() typings (#8014) 2022-06-05 23:28:28 +02:00
Almeida 0a7953e463 docs(Attachment): remove constructor doc (#8009) 2022-06-05 23:28:18 +02:00
Parbez 6aa623240e types: fix some attachment related typings (#8013) 2022-06-05 22:37:56 +02:00
n1ck_pro 6266b0c1e3 types(AttachmentBuilder): remove name parameter from constructor (#8008) 2022-06-05 22:37:01 +02:00
Suneet Tipirneni 9720e55534 refactor: always return Message instances in interactions (#7917)
Co-authored-by: Almeida <almeidx@pm.me>
2022-06-05 19:00:35 +02:00
Parbez ad36c0be77 fix: add static method from in builders (#7990) 2022-06-05 18:33:19 +02:00
SpaceEEC 5987dbe5cf docs(VoiceChannel): annotate that it is implementing TextBasedChannel (#8007) 2022-06-05 18:30:14 +02:00
Rodry 5244fe3c1c feat(Collector): add ignore event (#7644)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
2022-06-05 18:29:13 +02:00
Synbulat Biishev 349766dd69 feat(GuildMemberManager): add GuildMemberManager#fetchMe() (#7526) 2022-06-05 18:29:00 +02:00
markisha64 7a1095b66b fix: typings (#7965)
Co-authored-by: Almeida <almeidx@pm.me>
2022-06-05 09:36:59 +02:00
iCrawl 10009a43ee ci: remove cache-dir from test 2022-06-05 01:14:39 +02:00
iCrawl 8d8e6c03de feat: use vitest instead of jest for more speed 2022-06-05 01:07:10 +02:00
Suneet Tipirneni dfadcbc2fd refactor(attachment): don't return attachment builders from API (#7852)
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: A. Román <kyradiscord@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2022-06-04 22:33:13 +02:00
n1ck_pro 546d48655f docs: add missing discord-api-types external types (#8001) 2022-06-04 22:27:01 +02:00
iCrawl f8739bd9c0 fix(voice): re-add accidental removal of postbuild script 2022-06-04 19:15:28 +02:00
iCrawl f2ae1f9348 feat: add scripts package for locally used scripts 2022-06-04 19:07:50 +02:00
iCrawl 3401fd4eb6 chore: remove leftover files from pre-monorepo era 2022-06-04 18:41:37 +02:00
iCrawl fdbd229832 ci: equality check on tag and package name 2022-06-04 17:57:07 +02:00
iCrawl 9e8e2411c1 ci: check for the correct prop to be defined 2022-06-04 17:51:31 +02:00
iCrawl c02ced9a22 ci: fix if checks for branch/tag when using workflow dispatch 2022-06-04 17:37:00 +02:00
iCrawl 8c5a7f80ef ci: fix inputs for workflow dispatches 2022-06-04 17:15:08 +02:00
iCrawl 14018b0118 ci: allow workflow dispatches 2022-06-04 17:13:40 +02:00
iCrawl 8095723604 chore: only build cjs for actions 2022-06-04 17:08:26 +02:00
iCrawl e17bb54c85 chore: update dev versions 2022-06-04 17:01:47 +02:00
iCrawl e92d937bcc chore: release packages 2022-06-04 16:59:00 +02:00
iCrawl 091f1bd170 chore: deps 2022-06-04 16:49:47 +02:00
iCrawl bd2cf20ecb chore: re-generate changelogs 2022-06-04 16:42:00 +02:00
iCrawl 8af916dba0 chore: remove accidental changelog for voice 2022-06-04 16:22:31 +02:00
iCrawl 781a6e013c chore: fix changelogs 2022-06-04 16:20:33 +02:00
iCrawl 2172a00c50 chore: remove unneeded actions dep 2022-06-04 15:45:18 +02:00
iCrawl 271b1c8e5d feat: actions for workflows 2022-06-04 15:34:40 +02:00
iCrawl 6b8ef20cb3 style: cleanup tests and tsup configs 2022-06-04 15:21:57 +02:00
iCrawl a45bef4cad fix(proxy): add docs script 2022-06-04 13:34:57 +02:00
DD 1ba2d2a898 feat: @discordjs/proxy (#7925)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
2022-06-04 13:26:25 +02:00
iCrawl e518c8a137 chore: update yarn 2022-06-04 13:13:52 +02:00
iCrawl 80cd4a4a43 ci: run assigning reviewers also on drafts 2022-06-04 12:59:54 +02:00
iCrawl 8a7cd10554 fix(builders): leftover invalid null type 2022-06-04 12:59:26 +02:00
iCrawl 251862ea57 chore: deps 2022-06-04 12:58:09 +02:00
Jiralite 2f03f9ad3f fix(GuildAuditLogs): Cache guild scheduled events (#7951) 2022-06-04 09:04:08 +02:00
Suneet Tipirneni db81127886 chore: add external links for dapi-types (#7966) 2022-06-04 09:03:05 +02:00
Suneet Tipirneni cdd2ba036a feat(guildChannelManager): add videoQualityMode option for create() (#7980)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2022-06-04 09:02:21 +02:00
Suneet Tipirneni 97eaab35d7 feat(rest): add guild member banner cdn url (#7973) 2022-06-04 09:00:39 +02:00
Suneet Tipirneni d60c464e61 types: add types to EventEmitter static methods (#7986) 2022-06-04 08:58:15 +02:00
Suneet Tipirneni 643dab3b1b refactor: clean up modal submissions (#7994)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2022-06-04 08:57:19 +02:00
Azarias B 68d5169f66 feat: Export types from interactions/slashCommands/mixins (#7942) 2022-05-25 10:04:20 +02:00
Suneet Tipirneni 7f4d411e73 chore: reexport all dapi-types (#7909) 2022-05-25 10:03:51 +02:00
Jeroen Claassens 636d4f263b chore: fix git cliff configs (#7948)
Co-authored-by: Vlad <kingdgrizzle@gmail.com>
2022-05-25 10:02:17 +02:00
Jiralite fdeac9d9fb types: nullify guildScheduledEventUpdate's old parameter (#7955) 2022-05-21 02:02:57 +02:00
Suneet Tipirneni adf461baf4 fix: make sure action row builders create djs builders (#7945) 2022-05-18 21:56:56 +02:00
DD 191510b7f8 fix(TextBasedChannel#bulkDelete): return deleted message (#7943) 2022-05-18 19:58:39 +02:00
DD e2f5a4a494 chore: enable noUncheckedIndexAccess (#7931) 2022-05-18 19:56:42 +02:00
A. Román 993eb74475 chore(deps): update discord-api-types and /voice (#7934) 2022-05-18 19:54:35 +02:00
DD dfe449c253 feat: REST#raw (#7929) 2022-05-17 16:31:19 +02:00
Jiralite 5e9b757a37 fix: Remove trailing invites on channel deletion (#7932) 2022-05-16 12:13:02 +02:00
Sam 28172ca7b5 fix(DataResolver): fix check for readable streams (#7928) 2022-05-16 12:12:34 +02:00
Vlad Frangu 7ce641d33a fix(SlashCommandBuilder): import Permissions correctly (#7921) 2022-05-14 22:47:26 +02:00
Khafra e92b17d855 fix(REST): remove dom types (#7922) 2022-05-14 18:39:12 +02:00
Khafra d1504f2ae1 fix: ok statusCode can be 200..299 (#7919) 2022-05-14 18:38:05 +02:00
Jiralite b1a3aa97ea chore: bump discord-api-types (#7923) 2022-05-14 18:37:01 +02:00
iCrawl d522320aa4 chore: update v13 changelog 2022-05-13 12:11:36 +02:00
Khafra 76694c1497 feat(EnumResolvers): remove Enumresolvers (#7876) 2022-05-13 11:35:08 +02:00
Vlad Frangu de3f1573f0 feat(builders): add new command permissions v2 (#7861) 2022-05-13 11:33:40 +02:00
Synbulat Biishev aed687b09f feat: move me to GuildMemberManager manager (#7669)
Co-authored-by: muchnameless <12682826+muchnameless@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
2022-05-12 22:51:28 +02:00
n1ck_pro e07b910e68 types: make CacheType generic more accurate for return values (#7868) 2022-05-12 22:50:31 +02:00
Khafra d1ec8c37ff feat(rest): use undici (#7747)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: ckohen <chaikohen@gmail.com>
2022-05-12 22:49:15 +02:00
Parbez 4515a1ea80 chore: bump shapeshift for faster object validation (#7914) 2022-05-12 12:09:50 +02:00
Vlad Frangu c1b5e731da fix: add localizations for subcommand builders and option choices (#7862) 2022-05-12 10:32:27 +02:00
Suneet Tipirneni 64bdf53116 types(guildScheduledEvent): Mark entityMetadata as nullable (#7908) 2022-05-12 10:30:26 +02:00
Ben d308c66eec docs(InteractionResponses): replace outdated Embed example for reply (#7875) 2022-05-12 10:29:44 +02:00
Jiralite dfd9eb20b2 refactor(ThreadChannel): Remove MAX helper from threads (#7846) 2022-05-12 10:29:21 +02:00
Ryan Munro 19eaed6390 fix(AuditLog): default changes to empty array (#7880) 2022-05-12 10:26:07 +02:00
SpaceEEC 4ba0f56b6a feat(VoiceChannel): add support for text in voice (#6921) 2022-05-02 09:39:14 +02:00
advaith 5eeef3f708 types(discord.js): export missing enums (#7864) 2022-05-02 09:37:46 +02:00
with-heart 679dcda970 feat(REST): enable setting default authPrefix (#7853) 2022-04-28 13:08:02 +02:00
newracket df64d3ea38 fix(Util): flatten ignoring certain fields (#7773) 2022-04-26 00:45:52 +02:00
Jiralite 6239d83c4d fix: possibly missing (#7829) 2022-04-26 00:31:21 +02:00
Khafra 0c18dab128 fix: endReason not being properly set in base Collector (#7833)
* fix: `endReason` not being properly set in base Collector

* types: add _endReason type
2022-04-26 00:31:12 +02:00
Almeida ece628986c types: fix return type of toString() on channels (#7836)
* types(DMChannel): `toString()` returns a `UserMention`

* test: add more tests
2022-04-26 00:31:05 +02:00
Jiralite f4ccc6772c docs: require parameter (#7838) 2022-04-26 00:30:58 +02:00
Almeida 5ba7740fcf refactor(Activity): remove undocumented properties (#7844) 2022-04-26 00:30:45 +02:00
Almeida bfeaf856f7 types(Message#activity): make partyId optional and use enum for type (#7845) 2022-04-26 00:30:13 +02:00
FIRE 361709332b fix(SelectMenuBuilder): options array (#7826) 2022-04-22 20:50:36 +02:00
Rodry 61a44c509c docs(ApplicationCommand): fix and improve localization docs (#7804) 2022-04-21 19:07:49 +02:00
Hyro 4ac91c61d0 fix(Activity): platform type (#7805) 2022-04-21 19:07:18 +02:00
Hyro 4972bd87c1 fix(ApplicationCommand): equal nameLocalizations and descriptionLocalizations (#7802) 2022-04-21 19:06:42 +02:00
Euan Caskie a1b145e0ce makeContent should accept empty strings (#7764) 2022-04-21 18:57:00 +02:00
Suneet Tipirneni 29293d7bbb refactor: use arrays instead of rest parameters for builders (#7759) 2022-04-21 18:56:10 +02:00
Rodry f22245e9d0 feat(SelectMenu): allow emojis in options and option constructors (#7797) 2022-04-21 18:55:51 +02:00
Suneet Tipirneni 585169f2f0 types: cleanup *Data type definitions (#7716) 2022-04-19 16:00:55 +02:00
Ryan Munro ec8d87f932 feat(builders): improve embed errors and predicates (#7795)
* feat(builders): improve embed errors

* fix: use imageURLPredicates

Co-authored-by: Synbulat Biishev <arziksin@gmail.com>

Co-authored-by: Synbulat Biishev <arziksin@gmail.com>
2022-04-19 15:58:47 +02:00
n1ck_pro 440ac243ca types: fix BooleanCache never resolving to true (#7809)
* types: fix BooleanCache never resolving to true

* fix: broke other types by accident
2022-04-19 15:57:44 +02:00
Ryan Munro c5fb548529 fix(InteractionResponses): use optional chaining on nullable property (#7812)
* fix(InteractionResponses): use optional chaining on nullable property

* fix: one more spot
2022-04-19 15:56:45 +02:00
Almeida a6d9ce57c6 types(CommandInteraction): add awaitModalSubmit (#7811) 2022-04-19 15:56:22 +02:00
Rodry 08574763eb types(ThreadChannel): fix autoArchiveDuration types (#7816) 2022-04-19 15:54:54 +02:00
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
875 changed files with 63238 additions and 40658 deletions
+38
View File
@@ -0,0 +1,38 @@
# Packages
node_modules/
# Log files
logs/
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Env
.env
# Dist
dist/
# Miscellaneous
.tmp/
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea/
.DS_Store
.turbo
tsconfig.tsbuildinfo
# yarn
.pnp.*
.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
+5 -194
View File
@@ -1,200 +1,11 @@
{
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"plugins": ["import"],
"root": true,
"extends": "marine/prettier/node",
"parserOptions": {
"ecmaVersion": 2021
"project": "./tsconfig.eslint.json"
},
"ignorePatterns": ["**/dist/*"],
"env": {
"es2021": true,
"node": true
},
"rules": {
"import/order": [
"error",
{
"groups": ["builtin", "external", "internal", "index", "sibling", "parent"],
"alphabetize": {
"order": "asc"
}
}
],
"prettier/prettier": [
2,
{
"printWidth": 120,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"endOfLine": "lf",
"arrowParens": "avoid"
}
],
"strict": ["error", "global"],
"no-await-in-loop": "warn",
"no-compare-neg-zero": "error",
"no-template-curly-in-string": "error",
"no-unsafe-negation": "error",
"valid-jsdoc": [
"error",
{
"requireReturn": false,
"requireReturnDescription": false,
"prefer": {
"return": "returns",
"arg": "param"
},
"preferType": {
"String": "string",
"Number": "number",
"Boolean": "boolean",
"Symbol": "symbol",
"object": "Object",
"function": "Function",
"array": "Array",
"date": "Date",
"error": "Error",
"null": "void"
}
}
],
"accessor-pairs": "warn",
"array-callback-return": "error",
"consistent-return": "error",
"curly": ["error", "multi-line", "consistent"],
"dot-location": ["error", "property"],
"dot-notation": "error",
"eqeqeq": "error",
"no-empty-function": "error",
"no-floating-decimal": "error",
"no-implied-eval": "error",
"no-invalid-this": "error",
"no-lone-blocks": "error",
"no-multi-spaces": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-new": "error",
"no-octal-escape": "error",
"no-return-assign": "error",
"no-return-await": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
"no-unmodified-loop-condition": "error",
"no-unused-expressions": "error",
"no-useless-call": "error",
"no-useless-concat": "error",
"no-useless-escape": "error",
"no-useless-return": "error",
"no-void": "error",
"no-warning-comments": "warn",
"prefer-promise-reject-errors": "error",
"require-await": "warn",
"wrap-iife": "error",
"yoda": "error",
"no-label-var": "error",
"no-shadow": "error",
"no-undef-init": "error",
"callback-return": "error",
"getter-return": "off",
"handle-callback-err": "error",
"no-mixed-requires": "error",
"no-new-require": "error",
"no-path-concat": "error",
"array-bracket-spacing": "error",
"block-spacing": "error",
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"capitalized-comments": ["error", "always", { "ignoreConsecutiveComments": true }],
"comma-dangle": ["error", "always-multiline"],
"comma-spacing": "error",
"comma-style": "error",
"computed-property-spacing": "error",
"consistent-this": ["error", "$this"],
"eol-last": "error",
"func-names": "error",
"func-name-matching": "error",
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
"key-spacing": "error",
"keyword-spacing": "error",
"max-depth": "error",
"max-len": ["error", 120, 2],
"max-nested-callbacks": ["error", { "max": 4 }],
"max-statements-per-line": ["error", { "max": 2 }],
"new-cap": "off",
"newline-per-chained-call": ["error", { "ignoreChainWithDepth": 3 }],
"no-array-constructor": "error",
"no-inline-comments": "error",
"no-lonely-if": "error",
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
"no-new-object": "error",
"no-spaced-func": "error",
"no-trailing-spaces": "error",
"no-unneeded-ternary": "error",
"no-whitespace-before-property": "error",
"nonblock-statement-body-position": "error",
"object-curly-spacing": ["error", "always"],
"operator-assignment": "error",
"padded-blocks": ["error", "never"],
"quote-props": ["error", "as-needed"],
"quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }],
"semi-spacing": "error",
"semi": "error",
"space-before-blocks": "error",
"space-before-function-paren": [
"error",
{
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"spaced-comment": "error",
"template-tag-spacing": "error",
"unicode-bom": "error",
"arrow-body-style": "error",
"arrow-parens": ["error", "as-needed"],
"arrow-spacing": "error",
"no-duplicate-imports": "error",
"no-useless-computed-key": "error",
"no-useless-constructor": "error",
"prefer-arrow-callback": "error",
"prefer-numeric-literals": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "error",
"rest-spread-spacing": "error",
"template-curly-spacing": "error",
"yield-star-spacing": "error",
"no-restricted-globals": [
"error",
{
"name": "Buffer",
"message": "Import Buffer from `node:buffer` instead"
},
{
"name": "process",
"message": "Import process from `node:process` instead"
},
{
"name": "setTimeout",
"message": "Import setTimeout from `node:timers` instead"
},
{
"name": "setInterval",
"message": "Import setInterval from `node:timers` instead"
},
{
"name": "setImmediate",
"message": "Import setImmediate from `node:timers` instead"
}
]
"jest": true
}
}
-11
View File
@@ -1,11 +0,0 @@
version = 1
[merge]
require_automerge_label = false
blocking_labels = ['blocked']
method = 'squash'
[merge.message]
title = 'pull_request_title'
strip_html_comments = true
include_coauthors = true
+1 -1
View File
@@ -68,7 +68,7 @@ Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`
### Scope
The scope could be anything specifying the place of the commit change. For example `GuildMember`, `Guild`, `Message`, `MessageEmbed` etc...
The scope could be anything specifying the place of the commit change. For example `GuildMember`, `Guild`, `Message`, `TextChannel` etc...
### Subject
+5 -4
View File
@@ -11,7 +11,8 @@ 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 **main** 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/blob/main/.github/COMMIT_CONVENTION.md))
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))
+55 -48
View File
@@ -1,12 +1,26 @@
name: Bug report
description: Report incorrect or unexpected behavior of discord.js
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
If you are reporting a voice issue, please post your issue at https://github.com/discordjs/voice/issues
- type: dropdown
id: package
attributes:
label: Which package is this bug report for?
options:
- discord.js
- builders
- collection
- rest
- proxy
- proxy-container
- voice
- ws
validations:
required: true
- type: textarea
id: description
attributes:
@@ -30,28 +44,16 @@ body:
description: Include a reproducible, minimal code sample. This will be automatically formatted into code, so no need for backticks.
render: typescript
placeholder: |
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
if (interaction.commandName === 'ping') {
await interaction.reply('Pong!');
}
});
client.login('token');
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: discord.js version
description: Which version of discord.js are you using? Run `npm list discord.js` in your project directory and paste the output.
placeholder: 13.x.x (we no longer support version 12 or earlier)
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
@@ -61,7 +63,7 @@ body:
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.6+ is required for version 13.0.0+
placeholder: Node.js version 16.9+ is required for version 14.0.0+
validations:
required: true
- type: input
@@ -89,13 +91,15 @@ body:
Tip: you can select multiple items
options:
- Not applicable (subpackage bug)
- No Partials
- USER
- CHANNEL
- GUILD_MEMBER
- MESSAGE
- REACTION
- GUILD_SCHEDULED_EVENT
- User
- Channel
- GuildMember
- Message
- Reaction
- GuildScheduledEvent
- ThreadMember
multiple: true
validations:
required: true
@@ -104,26 +108,29 @@ body:
attributes:
label: Which gateway intents are you subscribing to?
description: |
Check your Client constructor for the `intents` key.
Check your Client constructor options for the `intents` key.
Tip: you can select multiple items
options:
- GUILDS
- GUILD_MEMBERS
- GUILD_BANS
- GUILD_EMOJIS_AND_STICKERS
- GUILD_INTEGRATIONS
- GUILD_WEBHOOKS
- GUILD_INVITES
- GUILD_VOICE_STATES
- GUILD_PRESENCES
- GUILD_MESSAGES
- GUILD_MESSAGE_REACTIONS
- GUILD_MESSAGE_TYPING
- DIRECT_MESSAGES
- DIRECT_MESSAGE_REACTIONS
- DIRECT_MESSAGE_TYPING
- GUILD_SCHEDULED_EVENTS
- Not applicable (subpackage bug)
- No Intents
- Guilds
- GuildMembers
- GuildBans
- GuildEmojisAndStickers
- GuildIntegrations
- GuildWebhooks
- GuildInvites
- GuildVoiceStates
- GuildPresences
- GuildMessages
- GuildMessageReactions
- GuildMessageTyping
- DirectMessages
- DirectMessageReactions
- DirectMessageTyping
- MessageContent
- GuildScheduledEvents
multiple: true
validations:
required: true
@@ -131,8 +138,8 @@ body:
id: dev-release
attributes:
label: I have tested this issue on a development release
placeholder: d23280c
placeholder: d23280c (commit hash)
description: |
The issue might already be fixed in a development release. This is not required, but helps us greatly.
To install the latest development release run `npm i discord.js@dev` in your project directory.
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`)
+16 -1
View File
@@ -1,5 +1,5 @@
name: Feature request
description: Request a new feature (documented features of the official Discord developer API only!)
description: Request a new feature (discord.js accepts documented features of the official Discord developer API only!)
labels: [feature request]
body:
- type: markdown
@@ -8,6 +8,21 @@ body:
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
- proxy
- proxy-container
- voice
- ws
validations:
required: true
- type: textarea
id: description
attributes:
-2
View File
@@ -1,7 +1,5 @@
**Please describe the changes this PR makes and why it should be merged:**
**Status and versioning classification:**
<!--
+1 -1
View File
@@ -2,7 +2,7 @@
git diff HEAD^ HEAD --quiet .
if [[ "$VERCEL_GIT_COMMIT_REF" == "main" && $? -eq 1 ]]; then
if [[ "$VERCEL_GIT_COMMIT_REF" == "main" || $? -eq 1 ]]; then
# Proceed with the build
echo "✅ - Proceed"
exit 1;
+43 -15
View File
@@ -1,15 +1,43 @@
apps:guide:
- apps/guide/*
- apps/guide/**/*
apps:website:
- apps/website/*
- apps/website/**/*
packages:discord.js:
- scripts/*
- scripts/**/*
- src/*
- src/**/*
- test/*
- test/**/*
- typings/*
- typings/**/*
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:docgen':
- packages/docgen/*
- packages/docgen/**/*
'packages:proxy':
- packages/proxy/*
- packages/proxy/**/*
'packages:proxy-container':
- packages/proxy-container/*
- packages/proxy-container/**/*
'packages:rest':
- packages/rest/*
- packages/rest/**/*
'packages:voice':
- packages/voice/*
- packages/voice/**/*
'packages:website':
- packages/website/*
- packages/website/**/*
'packages:ws':
- packages/ws/*
- packages/ws/**/*
+22
View File
@@ -4,6 +4,8 @@
color: '5663e9'
- name: 'backlog'
color: '7ef7ef'
- name: 'blocked'
color: 'fc1423'
- name: 'bug'
color: 'd73a4a'
- name: 'caching'
@@ -44,6 +46,26 @@
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:docgen'
color: 'fbca04'
- name: 'packages:proxy'
color: 'fbca04'
- name: 'packages:proxy-container'
color: 'fbca04'
- name: 'packages:rest'
color: 'fbca04'
- name: 'packages:voice'
color: 'fbca04'
- name: 'packages:website'
color: 'fbca04'
- name: 'packages:ws'
color: 'fbca04'
- name: 'performance'
color: '80c042'
- name: 'permissions'
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 KiB

-26
View File
@@ -1,26 +0,0 @@
name: npm auto deprecate
on:
workflow_dispatch:
schedule:
- cron: '0 1 * * *'
jobs:
auto-deprecate:
name: npm auto deprecate
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
cache: npm
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Deprecate versions
run: 'npm exec --no npm-deprecate -- --name "*dev*" --package "discord.js"'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
+60 -11
View File
@@ -2,7 +2,8 @@ name: Documentation
on:
push:
branches:
- 'v13'
- 'main'
- 'stable'
- '!docs'
tags:
- '**'
@@ -30,20 +31,29 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
cache-dependency-path: package-lock.json
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: npm ci
run: yarn --immutable
- name: Build dependencies
run: yarn build
- name: Build docs
run: npm run docs
run: yarn docs
- name: Upload docgen artifacts
uses: actions/upload-artifact@v3
with:
name: docgen
path: docs/docs.json
path: packages/*/docs/docs.json
- name: Upload api-extractor artifacts
uses: actions/upload-artifact@v3
with:
name: api-extractor
path: packages/*/docs/docs.api.json
- name: Set outputs for upload job
id: env
@@ -55,6 +65,11 @@ jobs:
upload:
name: Upload Documentation
needs: build
strategy:
max-parallel: 1
fail-fast: false
matrix:
package: ['builders', 'collection', 'discord.js', 'proxy', 'rest', 'voice', 'ws']
runs-on: ubuntu-latest
env:
BRANCH_NAME: ${{ github.event.inputs.ref || needs.build.outputs.BRANCH_NAME }}
@@ -68,11 +83,14 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
cache-dependency-path: package-lock.json
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: npm ci
run: yarn --immutable
- name: Build actions
run: yarn build
- name: Download docgen artifacts
uses: actions/download-artifact@v3
@@ -80,6 +98,12 @@ jobs:
name: docgen
path: docs
- name: Download api-extractor artifacts
uses: actions/download-artifact@v3
with:
name: api-extractor
path: docs
- name: Checkout docs repository
uses: actions/checkout@v3
with:
@@ -87,10 +111,35 @@ jobs:
token: ${{ secrets.DJS_DOCS }}
path: 'out'
- name: Extract package and semver from tag
if: ${{ github.event.inputs.ref || env.BRANCH_OR_TAG == 'tag' }}
id: extract-tag
uses: ./packages/actions/src/formatTag
with:
tag: ${{ env.BRANCH_NAME }}
- name: Move docs to correct directory
if: ${{ (github.event.inputs.ref || env.BRANCH_OR_TAG == 'tag') && matrix.package == steps.extract-tag.outputs.package }}
env:
PACKAGE: ${{ steps.extract-tag.outputs.package }}
SEMVER: ${{ steps.extract-tag.outputs.semver }}
run: |
mkdir -p out/discord.js
mv docs/docs.json out/discord.js/${BRANCH_NAME}.json
mkdir -p out/${PACKAGE}
mv docs/${PACKAGE}/docs/docs.json out/${PACKAGE}/${SEMVER}.json
if [[ $PACKAGE != "discord.js" ]]; then
mv docs/${PACKAGE}/docs/docs.api.json out/${PACKAGE}/${SEMVER}.api.json
fi
- name: Move docs to correct directory
if: ${{ !github.event.inputs.ref && 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
if [[ $PACKAGE != "discord.js" ]]; then
mv docs/${PACKAGE}/docs/docs.api.json out/${PACKAGE}/${BRANCH_NAME}.api.json
fi
- name: Commit and push
run: |
@@ -1,4 +1,4 @@
name: Label Sync
name: Label sync
on:
schedule:
- cron: '0 0 * * *'
@@ -9,14 +9,15 @@ on:
paths:
- '.github/labels.yml'
jobs:
labeler:
name: Labeler
label-sync:
name: Label sync
runs-on: ubuntu-latest
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Run Label Sync
uses: crazy-max/ghaction-github-labeler@v3
- name: Label sync
uses: crazy-max/ghaction-github-labeler@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
+28
View File
@@ -0,0 +1,28 @@
name: npm auto deprecate
on:
workflow_dispatch:
schedule:
- cron: '0 1 * * *'
jobs:
npm-auto-deprecate:
name: npm auto deprecate
runs-on: ubuntu-latest
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install node.js v16
uses: actions/setup-node@v3
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/proxy @discordjs/rest @discordjs/voice'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
+1 -1
View File
@@ -14,4 +14,4 @@ jobs:
- name: Automatically assign reviewers
if: github.event.action == 'opened'
uses: kentaro-m/auto-assign-action@v1.2.4
uses: kentaro-m/auto-assign-action@v1.2.1
+25
View File
@@ -0,0 +1,25 @@
name: Publish dev docker images
on:
workflow_dispatch:
schedule:
- cron: '0 */12 * * *'
jobs:
docker-publish:
name: Docker publish
runs-on: ubuntu-latest
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
run: echo ${{ secrets.DOCKER_ACCESS_TOKEN }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
- name: Build the image
run: docker build -t discordjs/proxy:latest -f packages/proxy-container/Dockerfile .
- name: Push image to DockerHub
run: docker push discordjs/proxy:latest
+33 -25
View File
@@ -4,41 +4,49 @@ on:
schedule:
- cron: '0 */12 * * *'
jobs:
npm:
name: npm
npm-publish:
name: npm publish
strategy:
fail-fast: false
matrix:
include:
- package: '@discordjs/builders'
folder: 'builders'
- package: '@discordjs/collection'
folder: 'collection'
- package: 'discord.js'
folder: 'discord.js'
- package: '@discordjs/proxy'
folder: 'proxy'
- package: '@discordjs/rest'
folder: 'rest'
- package: '@discordjs/voice'
folder: 'voice'
- package: '@discordjs/ws'
folder: 'ws'
runs-on: ubuntu-latest
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install Node v16
uses: actions/setup-node@v2
- name: Install node.js v16
uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
cache: npm
- name: Check previous released version
id: pre-release
run: |
if [[ $(npm view discord.js@dev version | grep -e "$(jq --raw-output '.version' package.json).*.$(git rev-parse --short HEAD | cut -b1-3)") ]]; \
then echo '::set-output name=release::false'; \
else echo '::set-output name=release::true'; fi
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
if: steps.pre-release.outputs.release == 'true'
run: npm ci --ignore-scripts
run: yarn --immutable
- name: Deprecate old versions
if: steps.pre-release.outputs.release == 'true'
run: npm deprecate discord.js@"~$(jq --raw-output '.version' package.json)" "no longer supported" || true
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
- name: Build dependencies
run: yarn build
- name: Publish
if: steps.pre-release.outputs.release == 'true'
- name: Publish package
run: |
npm version --git-tag-version=false $(jq --raw-output '.version' package.json).$(date +%s).$(git rev-parse --short HEAD)
npm publish --tag dev || true
yarn workspace ${{ matrix.package }} release --preid "dev.$(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 }}
+25
View File
@@ -0,0 +1,25 @@
name: Publish docker images
on:
workflow_dispatch:
jobs:
docker-publish:
name: Docker publish
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
run: echo ${{ secrets.DOCKER_ACCESS_TOKEN }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
- name: Build docker image
run: docker build -t discordjs/proxy:latest -f packages/proxy-container/Dockerfile .
- name: Tag image with major
run: docker tag discordjs/proxy discordjs/proxy:$(cut -d '.' -f1 <<< $(jq --raw-output '.version' packages/proxy-container/package.json))
- name: Push image to DockerHub
run: docker push --all-tags discordjs/proxy
-30
View File
@@ -1,30 +0,0 @@
name: Publish Release
on:
release:
types: [released]
jobs:
npm-publish:
name: npm publish
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install node.js v16
uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
cache: npm
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Publish package (v13)
run: npm publish --tag v13-lts
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
-81
View File
@@ -1,81 +0,0 @@
name: Tests
on: [push, pull_request]
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
cache: npm
- 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
cache: npm
- 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
cache: npm
- name: Install dependencies
run: npm ci
- name: Register Problem Matcher
run: echo "##[add-matcher].github/tsc.json"
- name: Run Type Tests
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
cache: npm
- name: Install dependencies
run: npm ci
- name: Test documentation
run: npm run docs:test
+32
View File
@@ -0,0 +1,32 @@
name: Tests
on: [push, pull_request]
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install node.js v16
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: yarn --immutable
- name: Build dependencies
run: yarn build
- name: ESLint
run: yarn lint
- name: Tests
run: yarn test
- name: Upload Coverage
uses: ./packages/actions/src/uploadCoverage
if: github.repository_owner == 'discordjs'
+19 -9
View File
@@ -13,20 +13,30 @@ pids
# Env
.env
test/auth.json
test/auth.js
docs/deploy/deploy_key
docs/deploy/deploy_key.pub
deploy/deploy_key
deploy/deploy_key.pub
# Dist
dist/
docs/docs.json
# Miscellaneous
.tmp/
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea/
.DS_Store
.yarn/
.turbo/
.turbo
tsconfig.tsbuildinfo
coverage/
# yarn
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Cache
.prettiercache
.eslintcache
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1
yarn commitlint --edit $1
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install lint-staged
yarn build && yarn lint-staged
+3 -2
View File
@@ -1,4 +1,5 @@
{
"*.{mjs,js}": "eslint --fix --ext mjs,js,ts",
"*.{ts,json,yml,yaml}": "prettier --write"
"*": "prettier --ignore-unknown --write",
"{src/**,__tests__/**}.{mjs,js,ts}": "eslint --ext mjs,js,ts --fix",
"src/**.ts": "vitest related"
}
-5
View File
@@ -1,5 +0,0 @@
audit=false
fund=false
legacy-peer-deps=true
tag-version-prefix=""
message="chore(Release): %s"
+4 -3
View File
@@ -1,7 +1,8 @@
{
"singleQuote": true,
"printWidth": 120,
"useTabs": true,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"endOfLine": "lf",
"arrowParens": "avoid"
"endOfLine": "lf"
}
-14
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
},
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"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",
"antfu.unocss"
]
}
+11
View File
@@ -0,0 +1,11 @@
{
"eslint.workingDirectories": [{ "pattern": "./packages/*" }],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": false
},
"unocss.root": "./packages/website",
"typescript.tsdk": "node_modules/typescript/lib"
}
@@ -0,0 +1,14 @@
diff --git a/lib/TSDocConfigFile.js b/lib/TSDocConfigFile.js
index caf3515d60fd386c5909db5a0aa8b4180b10d602..6fa4f1984b6ba6b3a7aecd05e54477ebf141af94 100644
--- a/lib/TSDocConfigFile.js
+++ b/lib/TSDocConfigFile.js
@@ -31,8 +31,7 @@ const ajv_1 = __importDefault(require("ajv"));
const jju = __importStar(require("jju"));
const ajv = new ajv_1.default({ verbose: true });
function initializeSchemaValidator() {
- const jsonSchemaPath = resolve.sync('@microsoft/tsdoc/schemas/tsdoc.schema.json', { basedir: __dirname });
- const jsonSchemaContent = fs.readFileSync(jsonSchemaPath).toString();
+ const jsonSchemaContent = "{\"title\":\"TSDoc Configuration\",\"description\":\"Describes the TSDoc configuration for a TypeScript project\",\"type\":\"object\",\"properties\":{\"$schema\":{\"description\":\"Part of the JSON Schema standard, this optional keyword declares the URL of the schema that the file conforms to. Editors may download the schema and use it to perform syntax highlighting.\",\"type\":\"string\"},\"extends\":{\"description\":\"Optionally specifies one or more JSON config files that will be combined with this file. This provides a way for standard settings to be shared across multiple projects. Important: The \\\"extends\\\" paths are resolved using NodeJS module resolution, so a path to a local file MUST be prefixed with \\\"./\\\".\",\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"noStandardTags\":{\"description\":\"By default, the config file loader will predefine all of the standardized TSDoc tags. To disable this and start with a completely empty configuration, set \\\"noStandardTags\\\"=true.\",\"type\":\"boolean\"},\"tagDefinitions\":{\"description\":\"Additional tags to support when parsing documentation comments with TSDoc.\",\"type\":\"array\",\"items\":{\"$ref\":\"#/definitions/tsdocTagDefinition\"}},\"supportedHtmlElements\":{\"description\":\"The HTML element names that are supported in this configuration. Used in conjunction with the \\\"reportUnsupportedHtmlElements\\\" setting.\",\"type\":\"array\",\"items\":{\"type\":\"string\",\"pattern\":\"^[a-zA-Z0-9-]+$\"}},\"reportUnsupportedHtmlElements\":{\"description\":\"Whether an error should be reported when an unsupported HTML element is encountered in a doc comment. Defaults to \\\"true\\\" if the \\\"supportedHtmlElements\\\" field is present in this file, \\\"false\\\" if not.\",\"type\":\"boolean\"},\"supportForTags\":{\"description\":\"A collection of key/value pairs. The key is a TSDoc tag name (e.g. \\\"@myTag\\\") that must be defined in this configuration. The value is a boolean indicating whether the tag is supported. The TSDoc parser may report warnings when unsupported tags are encountered. If \\\"supportForTags\\\" is specified for at least one tag, then the \\\"reportUnsupportedTags\\\" validation check is enabled by default.\",\"type\":\"object\",\"patternProperties\":{\"@[a-zA-Z][a-zA-Z0-9]*$\":{\"type\":\"boolean\"}},\"additionalItems\":false}},\"required\":[\"$schema\"],\"additionalProperties\":false,\"definitions\":{\"tsdocTagDefinition\":{\"description\":\"Configuration for a custom supported TSDoc tag.\",\"type\":\"object\",\"properties\":{\"tagName\":{\"description\":\"Name of the custom tag. TSDoc tag names start with an at-sign (@) followed by ASCII letters using camelCase capitalization.\",\"type\":\"string\"},\"syntaxKind\":{\"description\":\"Syntax kind of the custom tag. \\\"inline\\\" means that this tag can appear inside other documentation sections (example: {@link}). \\\"block\\\" means that this tag starts a new documentation section (example: @remarks). \\\"modifier\\\" means that this tag's presence indicates an aspect of the associated API item (example: @internal).\",\"type\":\"string\",\"enum\":[\"inline\",\"block\",\"modifier\"]},\"allowMultiple\":{\"description\":\"If true, then this tag may appear multiple times in a doc comment. By default, a tag may only appear once.\",\"type\":\"boolean\"}},\"required\":[\"tagName\",\"syntaxKind\"],\"additionalProperties\":false}}}";
const jsonSchema = jju.parse(jsonSchemaContent, { mode: 'cjson' });
return ajv.compile(jsonSchema);
}
@@ -0,0 +1,36 @@
diff --git a/dist/rollup-plugin-typescript2.cjs.js b/dist/rollup-plugin-typescript2.cjs.js
index 9ab972b041cc76f8f786d6a20f3efb53c364cad6..13e056a3c0971eb18b307d91fad096a9f3b9de79 100644
--- a/dist/rollup-plugin-typescript2.cjs.js
+++ b/dist/rollup-plugin-typescript2.cjs.js
@@ -29799,6 +29799,13 @@ const typescript = (options) => {
declarations[key] = { type: result.dts, map: result.dtsmap };
context.debug(() => `${safe.exports.blue("generated declarations")} for '${key}'`);
}
+ // if a user sets this compilerOption, they probably want another plugin (e.g. Babel, ESBuild) to transform their TS instead, while rpt2 just type-checks and/or outputs declarations
+ // note that result.code is non-existent if emitDeclarationOnly per https://github.com/ezolenko/rollup-plugin-typescript2/issues/268
+ if (parsedConfig.options.emitDeclarationOnly)
+ {
+ context.debug(() => `${blue("emitDeclarationOnly")} enabled, not transforming TS'`);
+ return undefined;
+ }
const transformResult = { code: result.code, map: { mappings: "" } };
if (result.map) {
if (pluginOptions.sourceMapCallback)
diff --git a/dist/rollup-plugin-typescript2.es.js b/dist/rollup-plugin-typescript2.es.js
index e43bf8f03bc6792b61d8352e04bb6466712426c2..420e8f0d0d109076bc72e9d60240077235a9ba11 100644
--- a/dist/rollup-plugin-typescript2.es.js
+++ b/dist/rollup-plugin-typescript2.es.js
@@ -29770,6 +29770,13 @@ const typescript = (options) => {
declarations[key] = { type: result.dts, map: result.dtsmap };
context.debug(() => `${safe.exports.blue("generated declarations")} for '${key}'`);
}
+ // if a user sets this compilerOption, they probably want another plugin (e.g. Babel, ESBuild) to transform their TS instead, while rpt2 just type-checks and/or outputs declarations
+ // note that result.code is non-existent if emitDeclarationOnly per https://github.com/ezolenko/rollup-plugin-typescript2/issues/268
+ if (parsedConfig.options.emitDeclarationOnly)
+ {
+ context.debug(() => `${blue("emitDeclarationOnly")} enabled, not transforming TS'`);
+ return undefined;
+ }
const transformResult = { code: result.code, map: { mappings: "" } };
if (result.map) {
if (pluginOptions.sourceMapCallback)
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
+786
View File
File diff suppressed because one or more lines are too long
+11
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.2.1.cjs
+2 -2
View File
@@ -175,8 +175,8 @@
END OF TERMS AND CONDITIONS
Copyright 2015 - 2021 Noel Buechler
Copyright 2015 - 2021 Amish Shah
Copyright 2021 Noel Buechler
Copyright 2015 Amish Shah
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+27 -21
View File
@@ -8,7 +8,11 @@
<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="Tests status" /></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>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>
</p>
</div>
@@ -24,7 +28,7 @@ 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
@@ -38,37 +42,38 @@ pnpm add 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 (`npm install @discordjs/voice`)
- [@discordjs/voice](https://www.npmjs.com/package/@discordjs/voice) for interacting with the Discord Voice API (`npm install @discordjs/voice`)
## Example usage
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
npm install discord.js @discordjs/rest
yarn add discord.js @discordjs/rest
pnpm add discord.js @discordjs/rest
```
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.js');
const commands = [{
const commands = [
{
name: 'ping',
description: 'Replies with Pong!'
}];
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.');
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) {
@@ -78,16 +83,17 @@ const rest = new REST({ version: '9' }).setToken('token');
```
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}!`);
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
await interaction.reply('Pong!');
@@ -99,10 +105,10 @@ client.login('token');
## Links
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/discord.js/tree/main/packages/website))
- [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.
See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-v14.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)
View File
+93
View File
@@ -0,0 +1,93 @@
import { relative, resolve } from 'node:path';
import glob from 'fast-glob';
import typescript from 'rollup-plugin-typescript2';
import { defineBuildConfig, BuildEntry } from 'unbuild';
interface ConfigOptions {
entries: (BuildEntry | string)[];
minify: boolean;
emitCJS: boolean;
externals: string[];
cjsBridge: boolean;
sourcemap: boolean;
preserveModules: boolean;
preserveModulesRoot: string;
declaration: boolean;
typeCheck: boolean;
}
export function createUnbuildConfig({
entries = [{ builder: 'rollup', input: 'src/index' }],
minify = false,
emitCJS = true,
cjsBridge = true,
externals = [],
sourcemap = true,
preserveModules = true,
preserveModulesRoot = 'src',
declaration = true,
typeCheck = false,
}: Partial<ConfigOptions> = {}) {
const files = glob
.sync('**', { cwd: 'src' })
.map((file) => [`${file.slice(0, -2)}cjs`, `${file.slice(0, -2)}mjs`])
.flat();
return defineBuildConfig({
entries,
clean: true,
rollup: {
esbuild: {
minify,
minifyIdentifiers: false,
},
emitCJS,
cjsBridge,
json: {
namedExports: false,
},
},
externals: [...files, ...externals],
hooks: {
'rollup:options': (_, options) => {
// @ts-expect-error: This will always be an array
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
options.output![0] = {
// @ts-expect-error: This will always be an array
...options.output![0],
sourcemap,
preserveModules,
preserveModulesRoot,
};
if (emitCJS) {
// @ts-expect-error: This will always be an array
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
options.output![1] = {
// @ts-expect-error: This will always be an array
...options.output![1],
sourcemap,
preserveModules,
preserveModulesRoot,
};
}
if (declaration) {
options.plugins?.unshift(
typescript({
check: typeCheck,
tsconfig: relative(__dirname, resolve(process.cwd(), 'tsconfig.json')),
tsconfigOverride: {
compilerOptions: {
emitDeclarationOnly: true,
},
},
}),
);
}
},
},
});
}
+26
View File
@@ -0,0 +1,26 @@
codecov:
notify:
after_n_builds: 6
strict_yaml_branch: main
coverage:
range: '50...90'
status:
project:
default:
target: auto
threshold: 5%
informational: true
patch: off
flag_management:
default_rules:
statuses:
- type: project
target: auto
threshold: 2%
informational: true
comment:
require_changes: true
after_n_builds: 6
-5
View File
@@ -1,5 +0,0 @@
- name: General
files:
- name: Welcome
id: welcome
path: ../../README.md
-22490
View File
File diff suppressed because it is too large Load Diff
+32 -52
View File
@@ -1,30 +1,17 @@
{
"name": "discord.js",
"version": "13.13.1",
"name": "@discordjs/discord.js",
"version": "0.0.0",
"description": "A powerful library for interacting with the Discord API",
"private": true,
"scripts": {
"test": "npm run lint && npm run docs:test && npm run lint:typings && npm run test:typescript",
"test:typescript": "tsc --noEmit && tsd",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"lint:typings": "tslint typings/index.d.ts",
"format": "prettier --write src/**/*.js typings/**/*.ts",
"prepare": "is-ci || husky install",
"docs": "docgen --source src --custom docs/index.yml --output docs/docs.json",
"docs:test": "docgen --source src --custom docs/index.yml",
"prepublishOnly": "npm run test",
"changelog": "git cliff --prepend CHANGELOG.md -u",
"release": "cliff-jumper"
},
"main": "./src/index.js",
"types": "./typings/index.d.ts",
"files": [
"src",
"typings"
],
"directories": {
"lib": "src",
"test": "test"
"build": "yarn workspaces foreach --parallel --topological run build",
"test": "yarn workspaces foreach --parallel --topological run test",
"lint": "yarn workspaces foreach --parallel --topological run lint",
"format": "yarn workspaces foreach --parallel --topological run format",
"fmt": "yarn format",
"postinstall": "is-ci || husky install",
"docs": "yarn workspaces foreach --parallel --topological run docs",
"update": "yarn upgrade-interactive"
},
"contributors": [
"Crawl <icrawltogo@gmail.com>",
@@ -33,7 +20,6 @@
"SpaceEEC <spaceeec@yahoo.com>",
"Antonio Roman <kyradiscord@gmail.com>"
],
"license": "Apache-2.0",
"keywords": [
"discord",
"api",
@@ -50,41 +36,35 @@
"url": "https://github.com/discordjs/discord.js/issues"
},
"homepage": "https://discord.js.org",
"dependencies": {
"@discordjs/builders": "^0.16.0",
"@discordjs/collection": "^0.7.0",
"@sapphire/async-queue": "^1.5.0",
"@types/node-fetch": "^2.6.2",
"@types/ws": "^8.5.3",
"discord-api-types": "^0.33.5",
"form-data": "^4.0.0",
"node-fetch": "^2.6.7",
"ws": "^8.9.0"
},
"devDependencies": {
"@commitlint/cli": "^17.1.2",
"@commitlint/config-angular": "^17.1.0",
"@discordjs/docgen": "^0.11.1",
"@favware/cliff-jumper": "^1.8.8",
"@favware/npm-deprecate": "^1.0.5",
"@types/node": "^16.11.45",
"@commitlint/cli": "^17.0.3",
"@commitlint/config-angular": "^17.0.3",
"@favware/cliff-jumper": "^1.8.5",
"@favware/npm-deprecate": "^1.0.4",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"conventional-changelog-cli": "^2.2.2",
"dtslint": "^4.2.1",
"eslint": "^8.25.0",
"eslint": "^8.20.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.3.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"fast-glob": "^3.2.11",
"husky": "^8.0.1",
"is-ci": "^3.0.1",
"jest": "^29.1.2",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1",
"tsd": "^0.24.1",
"tslint": "^6.1.3",
"typescript": "^4.8.4"
"typescript": "^4.7.4"
},
"resolutions": {
"rollup-plugin-typescript2@0.32.1": "patch:rollup-plugin-typescript2@npm:0.32.1#.yarn/patches/rollup-plugin-typescript2-npm-0.32.1-b5887420f2.patch",
"@microsoft/tsdoc-config": "patch:@microsoft/tsdoc-config@npm:0.16.1#.yarn/patches/@microsoft-tsdoc-config-npm-0.16.1-81031b1bbf.patch"
},
"engines": {
"node": ">=16.6.0",
"npm": ">=7.0.0"
}
"node": ">=16.9.0"
},
"workspaces": [
"packages/*"
],
"packageManager": "yarn@3.2.1"
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "../../.eslintrc.json"
}
+29
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/
+1
View File
@@ -0,0 +1 @@
module.exports = require('../../.lintstagedrc.json');
+9
View File
@@ -0,0 +1,9 @@
# Autogenerated
CHANGELOG.md
.turbo
dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
tsup.config.*.mjs
+1
View File
@@ -0,0 +1 @@
module.exports = require('../../.prettierrc.json');
+190
View File
@@ -0,0 +1,190 @@
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 2022 Noel Buechler
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.
+34
View File
@@ -0,0 +1,34 @@
<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://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>
</p>
</div>
## Links
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/discord.js/tree/main/packages/website))
- [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-v14.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/scripts)
- [Related libraries](https://discord.com/developers/docs/topics/community-resources#libraries)
## Contributing
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).
@@ -0,0 +1,22 @@
import { describe, test, expect } from 'vitest';
import { formatTag } from '../src';
describe('Format Tag', () => {
test('GIVEN tag with a prefix THEN format tag to not contain the prefix', () => {
expect(formatTag('@discordjs/rest@0.4.0')).toEqual({ package: 'rest', semver: '0.4.0' });
expect(formatTag('@discordjs/collection@0.6.0')).toEqual({ package: 'collection', semver: '0.6.0' });
expect(formatTag('@discordjs/proxy@0.1.0')).toEqual({ package: 'proxy', semver: '0.1.0' });
expect(formatTag('@discordjs/builders@0.13.0')).toEqual({ package: 'builders', semver: '0.13.0' });
expect(formatTag('@discordjs/voice@0.9.0')).toEqual({ package: 'voice', semver: '0.9.0' });
});
test('GIVEN tag with no prefix THEN return tag', () => {
expect(formatTag('13.5.1')).toEqual({ package: 'discord.js', semver: '13.5.1' });
expect(formatTag('13.7.0')).toEqual({ package: 'discord.js', semver: '13.7.0' });
});
test('GIVEN no or invalid tag THEN return null', () => {
expect(formatTag('')).toEqual(null);
expect(formatTag('abc')).toEqual(null);
});
});
+3
View File
@@ -0,0 +1,3 @@
import { createUnbuildConfig } from '../../build.config';
export default createUnbuildConfig({ minify: true });
+65
View File
@@ -0,0 +1,65 @@
{
"name": "@discordjs/actions",
"version": "0.1.0",
"description": "A set of actions that we use for our workflows",
"private": true,
"scripts": {
"test": "vitest run",
"build": "unbuild",
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
"fmt": "yarn format"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
},
"directories": {
"lib": "src",
"test": "__tests__"
},
"files": [
"dist"
],
"contributors": [
"Crawl <icrawltogo@gmail.com>"
],
"license": "Apache-2.0",
"keywords": [
"api",
"bot",
"client",
"node",
"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": {
"@actions/core": "^1.9.0",
"tslib": "^2.4.0"
},
"devDependencies": {
"@types/node": "^16.11.45",
"c8": "^7.12.0",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "0.32.1",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.7.6",
"vitest": "^0.19.1"
},
"engines": {
"node": ">=16.9.0"
}
}
+14
View File
@@ -0,0 +1,14 @@
name: 'Format Tag'
description: 'Formats a git tag to remove potentially prefixes'
inputs:
tag:
description: 'The input tag'
required: true
outputs:
package:
description: 'The package string that was extracted from this tag'
semver:
description: 'The semver string that was extracted from this tag'
runs:
using: node16
main: ../../dist/formatTag/index.js
@@ -0,0 +1,12 @@
export function formatTag(tag: string) {
const parsed = /(^@.*\/(?<package>.*)@v?)?(?<semver>\d+.\d+.\d+)-?.*/.exec(tag);
if (parsed?.groups) {
return {
package: parsed.groups.package ?? 'discord.js',
semver: parsed.groups.semver,
};
}
return null;
}
+10
View File
@@ -0,0 +1,10 @@
import { getInput, setOutput } from '@actions/core';
import { formatTag } from './formatTag';
const tag = getInput('tag', { required: true });
const parsed = formatTag(tag);
if (parsed) {
setOutput('package', parsed.package);
setOutput('semver', parsed.semver);
}
+1
View File
@@ -0,0 +1 @@
export * from './formatTag/formatTag';
@@ -0,0 +1,58 @@
name: 'Upload Coverage'
description: 'Uploads code coverage reports to codecov with separate flags for separate packages'
runs:
using: 'composite'
steps:
- name: Upload Builders Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/builders/coverage/cobertura-coverage.xml
flags: builders
- name: Upload Collection Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/collection/coverage/cobertura-coverage.xml
flags: collection
- name: Upload Discord.js Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/discord.js/coverage/cobertura-coverage.xml
flags: discord.js
- name: Upload Proxy Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/proxy/coverage/cobertura-coverage.xml
flags: proxy
- name: Upload Rest Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/rest/coverage/cobertura-coverage.xml
flags: rest
- name: Upload Voice Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/voice/coverage/cobertura-coverage.xml
flags: voice
- name: Upload Website Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/website/coverage/cobertura-coverage.xml
flags: website
- name: Upload WS Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/ws/coverage/cobertura-coverage.xml
flags: ws
- name: Upload Utilities Coverage
uses: codecov/codecov-action@v3
with:
files: ./packages/actions/coverage/cobertura-coverage.xml, ./packages/scripts/coverage/cobertura-coverage.xml
flags: utilities
+20
View File
@@ -0,0 +1,20 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"allowJs": true
},
"include": [
"**/*.ts",
"**/*.tsx",
"**/*.js",
"**/*.mjs",
"**/*.jsx",
"**/*.test.ts",
"**/*.test.js",
"**/*.test.mjs",
"**/*.spec.ts",
"**/*.spec.js",
"**/*.spec.mjs"
],
"exclude": []
}
+4
View File
@@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.json",
"include": ["src/**/*.ts"]
}
+9
View File
@@ -0,0 +1,9 @@
import { createTsupConfig } from '../../tsup.config';
export default createTsupConfig({
entry: ['src/index.ts', 'src/formatTag/index.ts'],
format: ['cjs'],
skipNodeModulesBundle: false,
noExternal: ['@actions/core'],
minify: true,
});
+5
View File
@@ -0,0 +1,5 @@
{
"name": "builders",
"org": "discordjs",
"packagePath": "packages/builders"
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "../../.eslintrc.json"
}
+29
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.json
!docs/README.md
!docs/examples/
!docs/examples/*.md
# Miscellaneous
.tmp/
coverage/
+1
View File
@@ -0,0 +1 @@
module.exports = require('../../.lintstagedrc.json');
+9
View File
@@ -0,0 +1,9 @@
# Autogenerated
CHANGELOG.md
.turbo
dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
tsup.config.*.mjs
+1
View File
@@ -0,0 +1 @@
module.exports = require('../../.prettierrc.json');
+252
View File
@@ -0,0 +1,252 @@
# Changelog
All notable changes to this project will be documented in this file.
# [@discordjs/builders@1.0.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.16.0...@discordjs/builders@1.0.0) - (2022-07-17)
## Info
- 1.0.0 release bump, no new features.
# [@discordjs/builders@0.16.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.15.0...@discordjs/builders@0.16.0) - (2022-07-17)
## Bug Fixes
- Slash command name regex (#8265) ([32f9056](https://github.com/discordjs/discord.js/commit/32f9056b15edede3bab07de96afb4b56d3a9ecca))
- **TextInputBuilder:** Parse `custom_id`, `label`, and `style` (#8216) ([2d9dfa3](https://github.com/discordjs/discord.js/commit/2d9dfa3c6ea4bb972da2f7e088d148b798c866d9))
## Documentation
- Add codecov coverage badge to readmes (#8226) ([f6db285](https://github.com/discordjs/discord.js/commit/f6db285c073898a749fe4591cbd4463d1896daf5))
## Features
- **builder:** Add max min length in string option (#8214) ([96c8d21](https://github.com/discordjs/discord.js/commit/96c8d21f95eb366c46ae23505ba9054f44821b25))
- Codecov (#8219) ([f10f4cd](https://github.com/discordjs/discord.js/commit/f10f4cdcd88ca6be7ec735ed3a415ba13da83db0))
- **docgen:** Update typedoc ([b3346f4](https://github.com/discordjs/discord.js/commit/b3346f4b9b3d4f96443506643d4631dc1c6d7b21))
- Website (#8043) ([127931d](https://github.com/discordjs/discord.js/commit/127931d1df7a2a5c27923c2f2151dbf3824e50cc))
- **docgen:** Typescript support ([3279b40](https://github.com/discordjs/discord.js/commit/3279b40912e6aa61507bedb7db15a2b8668de44b))
- Docgen package (#8029) ([8b979c0](https://github.com/discordjs/discord.js/commit/8b979c0245c42fd824d8e98745ee869f5360fc86))
## Refactor
- **builder:** Remove `unsafe*Builder`s (#8074) ([a4d1862](https://github.com/discordjs/discord.js/commit/a4d18629828234f43f03d1bd4851d4b727c6903b))
- Remove @sindresorhus/is as it's now esm only (#8133) ([c6f285b](https://github.com/discordjs/discord.js/commit/c6f285b7b089b004776fbeb444fe973a68d158d8))
- Move all the config files to root (#8033) ([769ea0b](https://github.com/discordjs/discord.js/commit/769ea0bfe78c4f1d413c6b397c604ffe91e39c6a))
## Typings
- Remove expect error (#8242) ([7e6dbaa](https://github.com/discordjs/discord.js/commit/7e6dbaaed900c07d1a04e23bbbf9cd0d1b0501c5))
- **builder:** Remove casting (#8241) ([8198da5](https://github.com/discordjs/discord.js/commit/8198da5cd0898e06954615a2287853321e7ebbd4))
# [@discordjs/builders@0.15.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.14.0...@discordjs/builders@0.15.0) - (2022-06-06)
## Features
- Allow builders to accept rest params and arrays (#7874) ([ad75be9](https://github.com/discordjs/discord.js/commit/ad75be9a9cf90c8624495df99b75177e6c24022f))
- Use vitest instead of jest for more speed ([8d8e6c0](https://github.com/discordjs/discord.js/commit/8d8e6c03decd7352a2aa180f6e5bc1a13602539b))
- Add scripts package for locally used scripts ([f2ae1f9](https://github.com/discordjs/discord.js/commit/f2ae1f9348bfd893332a9060f71a8a5f272a1b8b))
# [@discordjs/builders@0.15.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.14.0...@discordjs/builders@0.15.0) - (2022-06-05)
## Features
- Allow builders to accept rest params and arrays (#7874) ([ad75be9](https://github.com/discordjs/discord.js/commit/ad75be9a9cf90c8624495df99b75177e6c24022f))
- Use vitest instead of jest for more speed ([8d8e6c0](https://github.com/discordjs/discord.js/commit/8d8e6c03decd7352a2aa180f6e5bc1a13602539b))
- Add scripts package for locally used scripts ([f2ae1f9](https://github.com/discordjs/discord.js/commit/f2ae1f9348bfd893332a9060f71a8a5f272a1b8b))
# [@discordjs/builders@0.14.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.13.0...@discordjs/builders@0.14.0) - (2022-06-04)
## Bug Fixes
- **builders:** Leftover invalid null type ([8a7cd10](https://github.com/discordjs/discord.js/commit/8a7cd10554a2a71cd2fe7f6a177b5f4f43464348))
- **SlashCommandBuilder:** Import `Permissions` correctly (#7921) ([7ce641d](https://github.com/discordjs/discord.js/commit/7ce641d33a4af6586d5e7beffbe7d38619dcf1a2))
- Add localizations for subcommand builders and option choices (#7862) ([c1b5e73](https://github.com/discordjs/discord.js/commit/c1b5e731daa9cbbfca03a046e47cb1221ee1ed7c))
## Features
- Export types from `interactions/slashCommands/mixins` (#7942) ([68d5169](https://github.com/discordjs/discord.js/commit/68d5169f66c96f8fe5be17a1c01cdd5155607ab2))
- **builders:** Add new command permissions v2 (#7861) ([de3f157](https://github.com/discordjs/discord.js/commit/de3f1573f07dda294cc0fbb1ca4b659eb2388a12))
- **builders:** Improve embed errors and predicates (#7795) ([ec8d87f](https://github.com/discordjs/discord.js/commit/ec8d87f93272cc9987f9613735c0361680c4ed1e))
## Refactor
- Use arrays instead of rest parameters for builders (#7759) ([29293d7](https://github.com/discordjs/discord.js/commit/29293d7bbb5ed463e52e5a5853817e5a09cf265b))
## Styling
- Cleanup tests and tsup configs ([6b8ef20](https://github.com/discordjs/discord.js/commit/6b8ef20cb3af5b5cfd176dd0aa0a1a1e98551629))
# [@discordjs/builders@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))
## 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))
## 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))
## 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))
# [@discordjs/builders@0.12.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.11.0...@discordjs/builders@0.12.0) - (2022-01-24)
## 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
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.
+56
View File
@@ -0,0 +1,56 @@
<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/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=builders" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></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/discord.js/tree/main/packages/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-v14.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).
@@ -0,0 +1,151 @@
import { APIActionRowComponent, APIMessageActionRowComponent, ButtonStyle, ComponentType } from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
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();
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 2', () => {
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'),
)
.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);
expect(new ActionRowBuilder().addComponents([button]).toJSON()).toEqual(rowWithButtonData);
expect(new ActionRowBuilder().addComponents([selectMenu]).toJSON()).toEqual(rowWithSelectMenuData);
});
});
});
@@ -0,0 +1,147 @@
import {
APIButtonComponentWithCustomId,
APIButtonComponentWithURL,
ButtonStyle,
ComponentType,
} from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
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));
});
});
});
@@ -0,0 +1,73 @@
import {
APIActionRowComponent,
APIButtonComponent,
APIMessageActionRowComponent,
APISelectMenuComponent,
APITextInputComponent,
ButtonStyle,
ComponentType,
TextInputStyle,
} from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
import {
ActionRowBuilder,
ButtonBuilder,
createComponentBuilder,
SelectMenuBuilder,
TextInputBuilder,
} from '../../src/index';
describe('createComponentBuilder', () => {
test.each([ButtonBuilder, SelectMenuBuilder, TextInputBuilder])(
'passing an instance of %j should return itself',
(Builder) => {
const builder = new Builder();
expect(createComponentBuilder(builder)).toBe(builder);
},
);
test('GIVEN an action row component THEN returns a ActionRowBuilder', () => {
const actionRow: APIActionRowComponent<APIMessageActionRowComponent> = {
components: [],
type: ComponentType.ActionRow,
};
expect(createComponentBuilder(actionRow)).toBeInstanceOf(ActionRowBuilder);
});
test('GIVEN a button component THEN returns a ButtonBuilder', () => {
const button: APIButtonComponent = {
custom_id: 'abc',
style: ButtonStyle.Primary,
type: ComponentType.Button,
};
expect(createComponentBuilder(button)).toBeInstanceOf(ButtonBuilder);
});
test('GIVEN a select menu component THEN returns a SelectMenuBuilder', () => {
const selectMenu: APISelectMenuComponent = {
custom_id: 'abc',
options: [],
type: ComponentType.SelectMenu,
};
expect(createComponentBuilder(selectMenu)).toBeInstanceOf(SelectMenuBuilder);
});
test('GIVEN a text input component THEN returns a TextInputBuilder', () => {
const textInput: APITextInputComponent = {
custom_id: 'abc',
label: 'abc',
style: TextInputStyle.Short,
type: ComponentType.TextInput,
};
expect(createComponentBuilder(textInput)).toBeInstanceOf(TextInputBuilder);
});
test('GIVEN an unknown component type THEN throws error', () => {
// @ts-expect-error
expect(() => createComponentBuilder({ type: 'invalid' })).toThrowError();
});
});
@@ -0,0 +1,177 @@
import { APISelectMenuComponent, APISelectMenuOption, ComponentType } from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
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([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,
},
})
.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(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();
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();
// @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().setOptions(tooManyOptions)).toThrowError();
expect(() =>
selectMenu()
.addOptions({ label: 'test', value: 'test' })
.addOptions(...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 option types THEN does not throw', () => {
expect(() =>
selectMenu().addOptions({
label: 'test',
value: 'test',
}),
).not.toThrowError();
expect(() => selectMenu().addOptions(selectMenuOption().setLabel('test').setValue('test'))).not.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 SelectMenuBuilder(selectMenuDataWithoutOptions)
.addOptions([new SelectMenuOptionBuilder(selectMenuOptionData)])
.toJSON(),
).toEqual(selectMenuData);
expect(new SelectMenuOptionBuilder(selectMenuOptionData).toJSON()).toEqual(selectMenuOptionData);
});
});
});
@@ -0,0 +1,133 @@
import { APITextInputComponent, ComponentType, TextInputStyle } from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
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 2', () => {
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 2', () => {
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();
expect(() => {
// Issue #8107
// @ts-expect-error: shapeshift maps the enum key to the value when parsing
textInputComponent().setCustomId('Custom').setLabel('Guess').setStyle('Short').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);
});
});
@@ -0,0 +1,148 @@
import { PermissionFlagsBits } from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
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();
});
test('GIVEN valid builder with dmPermission false THEN does not throw error', () => {
expect(() => getBuilder().setName('foo').setDMPermission(false)).not.toThrowError();
});
});
describe('Context menu 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 invalid name localizations THEN does 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,
});
});
});
describe('permissions', () => {
test('GIVEN valid permission string THEN does not throw error', () => {
expect(() => getBuilder().setDefaultMemberPermissions('1')).not.toThrowError();
});
test('GIVEN valid permission bitfield THEN does not throw error', () => {
expect(() =>
getBuilder().setDefaultMemberPermissions(PermissionFlagsBits.AddReactions | PermissionFlagsBits.AttachFiles),
).not.toThrowError();
});
test('GIVEN null permissions THEN does not throw error', () => {
expect(() => getBuilder().setDefaultMemberPermissions(null)).not.toThrowError();
});
test('GIVEN invalid inputs THEN does throw error', () => {
expect(() => getBuilder().setDefaultMemberPermissions('1.1')).toThrowError();
expect(() => getBuilder().setDefaultMemberPermissions(1.1)).toThrowError();
});
});
});
});
@@ -0,0 +1,222 @@
import {
APIApplicationCommandAttachmentOption,
APIApplicationCommandBooleanOption,
APIApplicationCommandChannelOption,
APIApplicationCommandIntegerOption,
APIApplicationCommandMentionableOption,
APIApplicationCommandNumberOption,
APIApplicationCommandRoleOption,
APIApplicationCommandStringOption,
APIApplicationCommandUserOption,
ApplicationCommandOptionType,
ChannelType,
} from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
import {
SlashCommandAttachmentOption,
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);
const getAttachmentOption = () =>
new SlashCommandAttachmentOption().setName('attachment').setDescription('attachment').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().setMinLength(1).setMaxLength(10).toJSON()).toEqual<APIApplicationCommandStringOption>({
name: 'owo',
description: 'Testing 123',
type: ApplicationCommandOptionType.String,
required: true,
max_length: 10,
min_length: 1,
});
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,
});
});
test('GIVEN an attachment option THEN calling toJSON should return a valid JSON', () => {
expect(getAttachmentOption().toJSON()).toEqual<APIApplicationCommandAttachmentOption>({
name: 'attachment',
description: 'attachment',
type: ApplicationCommandOptionType.Attachment,
required: true,
});
});
});
@@ -0,0 +1,512 @@
import { APIApplicationCommandOptionChoice, ChannelType, PermissionFlagsBits } from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
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();
expect(() => SlashCommandAssertions.validateName('hello-world_command')).not.toThrowError();
expect(() => SlashCommandAssertions.validateName('aˇ㐆1٢〣²अก')).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('ABC')).toThrowError();
expect(() => SlashCommandAssertions.validateName('ABC123$%^&')).toThrowError();
expect(() => SlashCommandAssertions.validateName('help ping')).toThrowError();
expect(() => SlashCommandAssertions.validateName('🦦')).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();
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')
.setDMPermission(false)
.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();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
expect(() => getBuilder().addBooleanOption(null)).toThrowError();
// @ts-expect-error Checking if not providing anything, or an invalid return type causes an error
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 invalid name localizations THEN does 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 invalid description localizations THEN does 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,
});
});
});
describe('permissions', () => {
test('GIVEN valid permission string THEN does not throw error', () => {
expect(() => getBuilder().setDefaultMemberPermissions('1')).not.toThrowError();
});
test('GIVEN valid permission bitfield THEN does not throw error', () => {
expect(() =>
getBuilder().setDefaultMemberPermissions(PermissionFlagsBits.AddReactions | PermissionFlagsBits.AttachFiles),
).not.toThrowError();
});
test('GIVEN null permissions THEN does not throw error', () => {
expect(() => getBuilder().setDefaultMemberPermissions(null)).not.toThrowError();
});
test('GIVEN invalid inputs THEN does throw error', () => {
expect(() => getBuilder().setDefaultMemberPermissions('1.1')).toThrowError();
expect(() => getBuilder().setDefaultMemberPermissions(1.1)).toThrowError();
});
});
});
});
@@ -0,0 +1,173 @@
import {
APIModalInteractionResponseCallbackData,
APITextInputComponent,
ComponentType,
TextInputStyle,
} from 'discord-api-types/v10';
import { describe, test, expect } from 'vitest';
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();
expect(() =>
// @ts-expect-error: You can pass a TextInputBuilder and it will add it to an action row
modal().setTitle('test').setCustomId('foobar').addComponents(new TextInputBuilder()),
).not.toThrowError();
});
test('GIVEN invalid fields THEN builder does throw', () => {
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',
},
],
},
{
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),
),
)
.addComponents([
new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(
new TextInputBuilder().setCustomId('custom id').setLabel('label').setStyle(TextInputStyle.Paragraph),
),
])
.toJSON(),
).toEqual(modalData);
});
describe('equals()', () => {
const textInput1 = new TextInputBuilder()
.setCustomId('custom id')
.setLabel('label')
.setStyle(TextInputStyle.Paragraph);
const textInput2: APITextInputComponent = {
type: ComponentType.TextInput,
custom_id: 'custom id',
label: 'label',
style: TextInputStyle.Paragraph,
};
test('GIVEN equal builders THEN returns true', () => {
const equalTextInput = new TextInputBuilder()
.setCustomId('custom id')
.setLabel('label')
.setStyle(TextInputStyle.Paragraph);
expect(textInput1.equals(equalTextInput)).toBeTruthy();
});
test('GIVEN the same builder THEN returns true', () => {
expect(textInput1.equals(textInput1)).toBeTruthy();
});
test('GIVEN equal builder and data THEN returns true', () => {
expect(textInput1.equals(textInput2)).toBeTruthy();
});
test('GIVEN different builders THEN returns false', () => {
const diffTextInput = new TextInputBuilder()
.setCustomId('custom id')
.setLabel('label 2')
.setStyle(TextInputStyle.Paragraph);
expect(textInput1.equals(diffTextInput)).toBeFalsy();
});
test('GIVEN different text input builder and data THEN returns false', () => {
const diffTextInputData: APITextInputComponent = {
type: ComponentType.TextInput,
custom_id: 'custom id',
label: 'label 2',
style: TextInputStyle.Short,
};
expect(textInput1.equals(diffTextInputData)).toBeFalsy();
});
});
});
@@ -0,0 +1,418 @@
import { describe, test, expect } from 'vitest';
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)).toEqual(alpha.length * 6);
});
test('GIVEN an embed with zero characters THEN returns amount of characters', () => {
const embed = new EmbedBuilder();
expect(embedLength(embed.data)).toEqual(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' });
embed.addFields([{ name: 'foo', value: 'bar' }]);
expect(embed.toJSON()).toStrictEqual({
fields: [
{ name: 'foo', value: 'bar' },
{ name: 'foo', value: 'bar' },
],
});
});
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' }],
});
});
test('GIVEN an embed using Embed#spliceFields THEN returns valid toJSON data 2', () => {
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();
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();
expect(() => embed.setFields(Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' })))).toThrowError();
});
describe('GIVEN invalid field amount THEN throws error', () => {
test('1', () => {
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('2', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'bar' })).toThrowError();
});
});
describe('GIVEN invalid field name length THEN throws error', () => {
test('3', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: 'a'.repeat(257), value: 'bar' })).toThrowError();
});
});
describe('GIVEN invalid field value length THEN throws error', () => {
test('4', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'a'.repeat(1025) })).toThrowError();
});
});
});
});
@@ -0,0 +1,203 @@
import { URL } from 'node:url';
import { describe, test, expect, vitest } from 'vitest';
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\n```'>(codeBlock('discord.js')).toEqual('```\ndiscord.js\n```');
});
test('GIVEN "discord.js" with "js" as language THEN returns "```js\\ndiscord.js```"', () => {
expect<'```js\ndiscord.js\n```'>(codeBlock('js', 'discord.js')).toEqual('```js\ndiscord.js\n```');
});
});
describe('inlineCode', () => {
test('GIVEN "discord.js" THEN returns "`discord.js`"', () => {
expect<'`discord.js`'>(inlineCode('discord.js')).toEqual('`discord.js`');
});
});
describe('italic', () => {
test('GIVEN "discord.js" THEN returns "_discord.js_"', () => {
expect<'_discord.js_'>(italic('discord.js')).toEqual('_discord.js_');
});
});
describe('bold', () => {
test('GIVEN "discord.js" THEN returns "**discord.js**"', () => {
expect<'**discord.js**'>(bold('discord.js')).toEqual('**discord.js**');
});
});
describe('underscore', () => {
test('GIVEN "discord.js" THEN returns "__discord.js__"', () => {
expect<'__discord.js__'>(underscore('discord.js')).toEqual('__discord.js__');
});
});
describe('strikethrough', () => {
test('GIVEN "discord.js" THEN returns "~~discord.js~~"', () => {
expect<'~~discord.js~~'>(strikethrough('discord.js')).toEqual('~~discord.js~~');
});
});
describe('quote', () => {
test('GIVEN "discord.js" THEN returns "> discord.js"', () => {
expect<'> discord.js'>(quote('discord.js')).toEqual('> discord.js');
});
});
describe('blockQuote', () => {
test('GIVEN "discord.js" THEN returns ">>> discord.js"', () => {
expect<'>>> discord.js'>(blockQuote('discord.js')).toEqual('>>> 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')).toEqual('<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/'))).toEqual('<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')).toEqual(
'[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'))).toEqual(
'[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'),
).toEqual('[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'),
).toEqual('[discord.js](https://discord.js.org/ "Official Documentation")');
});
});
describe('spoiler', () => {
test('GIVEN "discord.js" THEN returns "||discord.js||"', () => {
expect<'||discord.js||'>(spoiler('discord.js')).toEqual('||discord.js||');
});
});
describe('Mentions', () => {
describe('userMention', () => {
test('GIVEN userId THEN returns "<@[userId]>"', () => {
expect(userMention('139836912335716352')).toEqual('<@139836912335716352>');
});
});
describe('channelMention', () => {
test('GIVEN channelId THEN returns "<#[channelId]>"', () => {
expect(channelMention('829924760309334087')).toEqual('<#829924760309334087>');
});
});
describe('roleMention', () => {
test('GIVEN roleId THEN returns "<&[roleId]>"', () => {
expect(roleMention('815434166602170409')).toEqual('<@&815434166602170409>');
});
});
});
describe('formatEmoji', () => {
test('GIVEN static emojiId THEN returns "<:_:${emojiId}>"', () => {
expect<`<:_:851461487498493952>`>(formatEmoji('851461487498493952')).toEqual('<:_:851461487498493952>');
});
test('GIVEN static emojiId WITH animated explicitly false THEN returns "<:_:[emojiId]>"', () => {
expect<`<:_:851461487498493952>`>(formatEmoji('851461487498493952', false)).toEqual('<:_:851461487498493952>');
});
test('GIVEN animated emojiId THEN returns "<a:_:${emojiId}>"', () => {
expect<`<a:_:827220205352255549>`>(formatEmoji('827220205352255549', true)).toEqual('<a:_:827220205352255549>');
});
});
describe('time', () => {
test('GIVEN no arguments THEN returns "<t:${bigint}>"', () => {
vitest.useFakeTimers();
vitest.setSystemTime(1566424897579);
expect<`<t:${bigint}>`>(time()).toEqual('<t:1566424897>');
vitest.useRealTimers();
});
test('GIVEN a date THEN returns "<t:${bigint}>"', () => {
expect<`<t:${bigint}>`>(time(new Date(1867424897579))).toEqual('<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')).toEqual('<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)).toEqual(
'<t:1867424897:R>',
);
});
test('GIVEN a date THEN returns "<t:${time}>"', () => {
expect<'<t:1867424897>'>(time(1867424897)).toEqual('<t:1867424897>');
});
test('GIVEN a date and a style from string THEN returns "<t:${time}:${style}>"', () => {
expect<'<t:1867424897:d>'>(time(1867424897, 'd')).toEqual('<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)).toEqual('<t:1867424897:R>');
});
});
describe('Faces', () => {
test('GIVEN Faces.Shrug THEN returns "¯\\_(ツ)\\_/¯"', () => {
expect<'¯\\_(ツ)\\_/¯'>(Faces.Shrug).toEqual('¯\\_(ツ)\\_/¯');
});
test('GIVEN Faces.Tableflip THEN returns "(╯°□°)╯︵ ┻━┻"', () => {
expect<'(╯°□°)╯︵ ┻━┻'>(Faces.Tableflip).toEqual('(╯°□°)╯︵ ┻━┻');
});
test('GIVEN Faces.Unflip THEN returns "┬─┬ ( ゜-゜ノ)"', () => {
expect<'┬─┬ ( ゜-゜ノ)'>(Faces.Unflip).toEqual('┬─┬ ( ゜-゜ノ)');
});
});
});
+42
View File
@@ -0,0 +1,42 @@
import { describe, test, expect } from 'vitest';
import {
isJSONEncodable,
isEquatable,
ActionRowBuilder,
enableValidators,
disableValidators,
isValidationEnabled,
} from '../src/index';
describe('isEquatable', () => {
test('returns true if the object is equatable', () => {
expect(isEquatable({ equals: () => true })).toBeTruthy();
});
test('returns false if the object is not equatable', () => {
expect(isEquatable({})).toBeFalsy();
});
});
describe('isJSONEncodable', () => {
test('returns true if the object is JSON encodable', () => {
expect(isJSONEncodable({ toJSON: () => ({}) })).toBeTruthy();
expect(isJSONEncodable(new ActionRowBuilder())).toBeTruthy();
});
test('returns false if the object is not JSON encodable', () => {
expect(isJSONEncodable({})).toBeFalsy();
});
});
describe('validation', () => {
test('enables validation', () => {
enableValidators();
expect(isValidationEnabled()).toBeTruthy();
});
test('disables validation', () => {
disableValidators();
expect(isValidationEnabled()).toBeFalsy();
});
});
+376
View File
@@ -0,0 +1,376 @@
/**
* Config file for API Extractor. For more info, please visit: https://api-extractor.com
*/
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
/**
* Optionally specifies another JSON config file that this file extends from. This provides a way for
* standard settings to be shared across multiple projects.
*
* If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains
* the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be
* resolved using NodeJS require().
*
* SUPPORTED TOKENS: none
* DEFAULT VALUE: ""
*/
// "extends": "./shared/api-extractor-base.json"
// "extends": "my-package/include/api-extractor-base.json"
/**
* Determines the "<projectFolder>" token that can be used with other config file settings. The project folder
* typically contains the tsconfig.json and package.json config files, but the path is user-defined.
*
* The path is resolved relative to the folder of the config file that contains the setting.
*
* The default value for "projectFolder" is the token "<lookup>", which means the folder is determined by traversing
* parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder
* that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error
* will be reported.
*
* SUPPORTED TOKENS: <lookup>
* DEFAULT VALUE: "<lookup>"
*/
// "projectFolder": "..",
/**
* (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor
* analyzes the symbols exported by this module.
*
* The file extension must be ".d.ts" and not ".ts".
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
*/
"mainEntryPointFilePath": "<projectFolder>/docs/dist/index.d.ts",
/**
* A list of NPM package names whose exports should be treated as part of this package.
*
* For example, suppose that Webpack is used to generate a distributed bundle for the project "library1",
* and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part
* of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly
* imports library2. To avoid this, we can specify:
*
* "bundledPackages": [ "library2" ],
*
* This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
* local files for library1.
*/
"bundledPackages": [],
/**
* Determines how the TypeScript compiler engine will be invoked by API Extractor.
*/
"compiler": {
/**
* Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* Note: This setting will be ignored if "overrideTsconfig" is used.
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
*/
// "tsconfigFilePath": "<projectFolder>/tsconfig.json",
/**
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
* The object must conform to the TypeScript tsconfig schema:
*
* http://json.schemastore.org/tsconfig
*
* If omitted, then the tsconfig.json file will be read from the "projectFolder".
*
* DEFAULT VALUE: no overrideTsconfig section
*/
// "overrideTsconfig": {
// . . .
// }
/**
* This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended
* and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when
* dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses
* for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck.
*
* DEFAULT VALUE: false
*/
// "skipLibCheck": true,
},
/**
* Configures how the API report file (*.api.md) will be generated.
*/
"apiReport": {
/**
* (REQUIRED) Whether to generate an API report.
*/
"enabled": false
/**
* The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce
* a full file path.
*
* The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/".
*
* SUPPORTED TOKENS: <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<unscopedPackageName>.api.md"
*/
// "reportFileName": "<unscopedPackageName>.api.md",
/**
* Specifies the folder where the API report file is written. The file name portion is determined by
* the "reportFileName" setting.
*
* The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy,
* e.g. for an API review.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/temp/"
*/
// "reportFolder": "<projectFolder>/temp/",
/**
* Specifies the folder where the temporary report file is written. The file name portion is determined by
* the "reportFileName" setting.
*
* After the temporary file is written to disk, it is compared with the file in the "reportFolder".
* If they are different, a production build will fail.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/temp/"
*/
// "reportTempFolder": "<projectFolder>/temp/"
},
/**
* Configures how the doc model file (*.api.json) will be generated.
*/
"docModel": {
/**
* (REQUIRED) Whether to generate a doc model file.
*/
"enabled": true,
/**
* The output path for the doc model file. The file extension should be ".api.json".
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/temp/<unscopedPackageName>.api.json"
*/
"apiJsonFilePath": "<projectFolder>/docs/docs.api.json"
},
/**
* Configures how the .d.ts rollup file will be generated.
*/
"dtsRollup": {
/**
* (REQUIRED) Whether to generate the .d.ts rollup file.
*/
"enabled": false
/**
* Specifies the output path for a .d.ts rollup file to be generated without any trimming.
* This file will include all declarations that are exported by the main entry point.
*
* If the path is an empty string, then this file will not be written.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/dist/<unscopedPackageName>.d.ts"
*/
// "untrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>.d.ts",
/**
* Specifies the output path for a .d.ts rollup file to be generated with trimming for an "alpha" release.
* This file will include only declarations that are marked as "@public", "@beta", or "@alpha".
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: ""
*/
// "alphaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-alpha.d.ts",
/**
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release.
* This file will include only declarations that are marked as "@public" or "@beta".
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: ""
*/
// "betaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-beta.d.ts",
/**
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release.
* This file will include only declarations that are marked as "@public".
*
* If the path is an empty string, then this file will not be written.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: ""
*/
// "publicTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-public.d.ts",
/**
* When a declaration is trimmed, by default it will be replaced by a code comment such as
* "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the
* declaration completely.
*
* DEFAULT VALUE: false
*/
// "omitTrimmingComments": true
},
/**
* Configures how the tsdoc-metadata.json file will be generated.
*/
"tsdocMetadata": {
/**
* Whether to generate the tsdoc-metadata.json file.
*
* DEFAULT VALUE: true
*/
// "enabled": true,
/**
* Specifies where the TSDoc metadata file should be written.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* The default value is "<lookup>", which causes the path to be automatically inferred from the "tsdocMetadata",
* "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup
* falls back to "tsdoc-metadata.json" in the package folder.
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<lookup>"
*/
// "tsdocMetadataFilePath": "<projectFolder>/dist/tsdoc-metadata.json"
},
/**
* Specifies what type of newlines API Extractor should use when writing output files. By default, the output files
* will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead.
* To use the OS's default newline kind, specify "os".
*
* DEFAULT VALUE: "crlf"
*/
"newlineKind": "lf",
/**
* Configures how API Extractor reports error and warning messages produced during analysis.
*
* There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages.
*/
"messages": {
/**
* Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing
* the input .d.ts files.
*
* TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551"
*
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
*/
"compilerMessageReporting": {
/**
* Configures the default routing for messages that don't match an explicit rule in this table.
*/
"default": {
/**
* Specifies whether the message should be written to the the tool's output log. Note that
* the "addToApiReportFile" property may supersede this option.
*
* Possible values: "error", "warning", "none"
*
* Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail
* and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes
* the "--local" option), the warning is displayed but the build will not fail.
*
* DEFAULT VALUE: "warning"
*/
"logLevel": "warning"
/**
* When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md),
* then the message will be written inside that file; otherwise, the message is instead logged according to
* the "logLevel" option.
*
* DEFAULT VALUE: false
*/
// "addToApiReportFile": false
}
// "TS2551": {
// "logLevel": "warning",
// "addToApiReportFile": true
// },
//
// . . .
},
/**
* Configures handling of messages reported by API Extractor during its analysis.
*
* API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag"
*
* DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings
*/
"extractorMessageReporting": {
"default": {
"logLevel": "warning"
// "addToApiReportFile": false
}
// "ae-extra-release-tag": {
// "logLevel": "warning",
// "addToApiReportFile": true
// },
//
// . . .
},
/**
* Configures handling of messages reported by the TSDoc parser when analyzing code comments.
*
* TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text"
*
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
*/
"tsdocMessageReporting": {
"default": {
"logLevel": "warning"
// "addToApiReportFile": false
}
// "tsdoc-link-tag-unescaped-text": {
// "logLevel": "warning",
// "addToApiReportFile": true
// },
//
// . . .
}
}
}
+3
View File
@@ -0,0 +1,3 @@
import { createUnbuildConfig } from '../../build.config';
export default createUnbuildConfig();
+63
View File
@@ -0,0 +1,63 @@
[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.scope %}\
**{{commit.scope}}:** \
{% endif %}\
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}](https://github.com/discordjs/discord.js/commit/{{ commit.id }}))\
{% if commit.breaking %}\
{% for breakingChange in commit.footers %}\
\n{% raw %} {% endraw %}- **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
{% endfor %}\
{% endif %}\
{% 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@[0-9]*"
ignore_tags = ""
topo_order = false
sort_commits = "newest"
+1
View File
@@ -0,0 +1 @@
## [View the documentation here.](https://discord.js.org/#/docs/builders)
@@ -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();
```
+1
View File
@@ -0,0 +1 @@
[{ "name": "General", "files": [{ "name": "Welcome", "id": "welcome", "path": "../../README.md" }] }]
+84
View File
@@ -0,0 +1,84 @@
{
"name": "@discordjs/builders",
"version": "1.0.0",
"description": "A set of builders that you can use when creating your bot",
"scripts": {
"test": "vitest run",
"build": "unbuild",
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
"fmt": "yarn format",
"docs": "downlevel-dts . docs --to=3.7 && docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local",
"prepack": "yarn lint && yarn test && yarn build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/builders/*'",
"release": "cliff-jumper"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"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": "^3.5.1",
"discord-api-types": "^0.36.3",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.1",
"tslib": "^2.4.0"
},
"devDependencies": {
"@discordjs/docgen": "workspace:^",
"@favware/cliff-jumper": "^1.8.5",
"@microsoft/api-extractor": "^7.28.6",
"@types/node": "^16.11.45",
"c8": "^7.12.0",
"downlevel-dts": "^0.10.0",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "0.32.1",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.7.6",
"vitest": "^0.19.1"
},
"engines": {
"node": ">=16.9.0"
},
"publishConfig": {
"access": "public"
}
}
@@ -0,0 +1,66 @@
import {
type APIActionRowComponent,
ComponentType,
APIMessageActionRowComponent,
APIModalActionRowComponent,
APIActionRowComponentTypes,
} from 'discord-api-types/v10';
import { ComponentBuilder } from './Component';
import { createComponentBuilder } from './Components';
import type { ButtonBuilder } from './button/Button';
import type { SelectMenuBuilder } from './selectMenu/SelectMenu';
import type { TextInputBuilder } from './textInput/TextInput';
import { normalizeArray, type RestOrArray } from '../util/normalizeArray';
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.
*/
public addComponents(...components: RestOrArray<T>) {
this.components.push(...normalizeArray(components));
return this;
}
/**
* Sets the components in this action row
*
* @param components - The components to set this row to
*/
public setComponents(...components: RestOrArray<T>) {
this.components.splice(0, this.components.length, ...normalizeArray(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']>>;
}
}
@@ -0,0 +1,99 @@
import { s } from '@sapphire/shapeshift';
import { APIMessageComponentEmoji, ButtonStyle } from 'discord-api-types/v10';
import { SelectMenuOptionBuilder } from './selectMenu/SelectMenuOption';
import { isValidationEnabled } from '../util/validation';
export const customIdValidator = s.string
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(100)
.setValidationEnabled(isValidationEnabled);
export const emojiValidator = s
.object({
id: s.string,
name: s.string,
animated: s.boolean,
})
.partial.strict.setValidationEnabled(isValidationEnabled);
export const disabledValidator = s.boolean;
export const buttonLabelValidator = s.string
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(80)
.setValidationEnabled(isValidationEnabled);
export const buttonStyleValidator = s.nativeEnum(ButtonStyle);
export const placeholderValidator = s.string.lengthLessThanOrEqual(150).setValidationEnabled(isValidationEnabled);
export const minMaxValidator = s.number.int
.greaterThanOrEqual(0)
.lessThanOrEqual(25)
.setValidationEnabled(isValidationEnabled);
export const labelValueDescriptionValidator = s.string
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(100)
.setValidationEnabled(isValidationEnabled);
export const jsonOptionValidator = s
.object({
label: labelValueDescriptionValidator,
value: labelValueDescriptionValidator,
description: labelValueDescriptionValidator.optional,
emoji: emojiValidator.optional,
default: s.boolean.optional,
})
.setValidationEnabled(isValidationEnabled);
export const optionValidator = s.instance(SelectMenuOptionBuilder).setValidationEnabled(isValidationEnabled);
export const optionsValidator = optionValidator.array
.lengthGreaterThanOrEqual(0)
.setValidationEnabled(isValidationEnabled);
export const optionsLengthValidator = s.number.int
.greaterThanOrEqual(0)
.lessThanOrEqual(25)
.setValidationEnabled(isValidationEnabled);
export function validateRequiredSelectMenuParameters(options: SelectMenuOptionBuilder[], customId?: string) {
customIdValidator.parse(customId);
optionsValidator.parse(options);
}
export const defaultValidator = s.boolean;
export function validateRequiredSelectMenuOptionParameters(label?: string, value?: string) {
labelValueDescriptionValidator.parse(label);
labelValueDescriptionValidator.parse(value);
}
export const urlValidator = s.string
.url({
allowedProtocols: ['http:', 'https:', 'discord:'],
})
.setValidationEnabled(isValidationEnabled);
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');
}
}
@@ -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;
}
}
@@ -0,0 +1,50 @@
import { APIMessageComponent, APIModalComponent, ComponentType } from 'discord-api-types/v10';
import {
ActionRowBuilder,
type AnyComponentBuilder,
type MessageComponentBuilder,
type ModalComponentBuilder,
} from './ActionRow';
import { ComponentBuilder } from './Component';
import { ButtonBuilder } from './button/Button';
import { SelectMenuBuilder } from './selectMenu/SelectMenu';
import { TextInputBuilder } from './textInput/TextInput';
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}`);
}
}
@@ -0,0 +1,101 @@
import {
ComponentType,
ButtonStyle,
type APIMessageComponentEmoji,
type APIButtonComponent,
type APIButtonComponentWithURL,
type APIButtonComponentWithCustomId,
} from 'discord-api-types/v10';
import {
buttonLabelValidator,
buttonStyleValidator,
customIdValidator,
disabledValidator,
emojiValidator,
urlValidator,
validateRequiredButtonParameters,
} from '../Assertions';
import { ComponentBuilder } from '../Component';
/**
* Represents a button component
*/
export class ButtonBuilder 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 = buttonStyleValidator.parse(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 = urlValidator.parse(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 = customIdValidator.parse(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 = emojiValidator.parse(emoji);
return this;
}
/**
* Sets whether this button is disabled
*
* @param disabled - Whether to disable this button
*/
public setDisabled(disabled = true) {
this.data.disabled = disabledValidator.parse(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 = buttonLabelValidator.parse(label);
return this;
}
public toJSON(): APIButtonComponent {
validateRequiredButtonParameters(
this.data.style,
this.data.label,
this.data.emoji,
(this.data as APIButtonComponentWithCustomId).custom_id,
(this.data as APIButtonComponentWithURL).url,
);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
} as APIButtonComponent;
}
}
@@ -0,0 +1,127 @@
import { APISelectMenuOption, ComponentType, type APISelectMenuComponent } from 'discord-api-types/v10';
import { SelectMenuOptionBuilder } from './SelectMenuOption';
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray';
import {
customIdValidator,
disabledValidator,
jsonOptionValidator,
minMaxValidator,
optionsLengthValidator,
placeholderValidator,
validateRequiredSelectMenuParameters,
} from '../Assertions';
import { ComponentBuilder } from '../Component';
/**
* Represents a select menu component
*/
export class SelectMenuBuilder extends ComponentBuilder<APISelectMenuComponent> {
/**
* The options within this select menu
*/
public readonly options: SelectMenuOptionBuilder[];
public constructor(data?: Partial<APISelectMenuComponent>) {
const { options, ...initData } = data ?? {};
super({ type: ComponentType.SelectMenu, ...initData });
this.options = options?.map((o) => new SelectMenuOptionBuilder(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 = placeholderValidator.parse(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 = minMaxValidator.parse(minValues);
return this;
}
/**
* Sets the maximum values that must be selected in the select menu
*
* @param maxValues - The maximum values that must be selected
*/
public setMaxValues(maxValues: number) {
this.data.max_values = minMaxValidator.parse(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 = customIdValidator.parse(customId);
return this;
}
/**
* Sets whether this select menu is disabled
*
* @param disabled - Whether this select menu is disabled
*/
public setDisabled(disabled = true) {
this.data.disabled = disabledValidator.parse(disabled);
return this;
}
/**
* Adds options to this select menu
*
* @param options - The options to add to this select menu
* @returns
*/
public addOptions(...options: RestOrArray<SelectMenuOptionBuilder | APISelectMenuOption>) {
options = normalizeArray(options);
optionsLengthValidator.parse(this.options.length + options.length);
this.options.push(
...options.map((option) =>
option instanceof SelectMenuOptionBuilder
? option
: new SelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
),
);
return this;
}
/**
* Sets the options on this select menu
*
* @param options - The options to set on this select menu
*/
public setOptions(...options: RestOrArray<SelectMenuOptionBuilder | APISelectMenuOption>) {
options = normalizeArray(options);
optionsLengthValidator.parse(options.length);
this.options.splice(
0,
this.options.length,
...options.map((option) =>
option instanceof SelectMenuOptionBuilder
? option
: new SelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
),
);
return this;
}
public toJSON(): APISelectMenuComponent {
validateRequiredSelectMenuParameters(this.options, this.data.custom_id);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
options: this.options.map((o) => o.toJSON()),
} as APISelectMenuComponent;
}
}
@@ -0,0 +1,73 @@
import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v10';
import {
defaultValidator,
emojiValidator,
labelValueDescriptionValidator,
validateRequiredSelectMenuOptionParameters,
} from '../Assertions';
/**
* Represents a option within a select menu component
*/
export class SelectMenuOptionBuilder {
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 = labelValueDescriptionValidator.parse(label);
return this;
}
/**
* Sets the value of this option
*
* @param value - The value of this option
*/
public setValue(value: string) {
this.data.value = labelValueDescriptionValidator.parse(value);
return this;
}
/**
* Sets the description of this option
*
* @param description - The description of this option
*/
public setDescription(description: string) {
this.data.description = labelValueDescriptionValidator.parse(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 = defaultValidator.parse(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 = emojiValidator.parse(emoji);
return this;
}
public toJSON(): APISelectMenuOption {
validateRequiredSelectMenuOptionParameters(this.data.label, this.data.value);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
...this.data,
} as APISelectMenuOption;
}
}

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